mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-02 03:45:58 +01:00
Merge pull request #380 from emersion/xwayland-root-cursor
Set xwayland root cursor
This commit is contained in:
commit
62734d0553
9 changed files with 148 additions and 10 deletions
|
@ -6,6 +6,7 @@ packages:
|
||||||
- mesa
|
- mesa
|
||||||
- libinput
|
- libinput
|
||||||
- libxkbcommon
|
- libxkbcommon
|
||||||
|
- xcb-util-image
|
||||||
- libcap
|
- libcap
|
||||||
- pixman
|
- pixman
|
||||||
- clang
|
- clang
|
||||||
|
|
|
@ -16,6 +16,7 @@ arch:
|
||||||
- libinput
|
- libinput
|
||||||
- pixman
|
- pixman
|
||||||
- libxkbcommon
|
- libxkbcommon
|
||||||
|
- xcb-util-image
|
||||||
- libcap
|
- libcap
|
||||||
script:
|
script:
|
||||||
- "meson build"
|
- "meson build"
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct wlr_xwm;
|
struct wlr_xwm;
|
||||||
|
struct wlr_xwayland_cursor;
|
||||||
|
|
||||||
struct wlr_xwayland {
|
struct wlr_xwayland {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
@ -25,6 +26,7 @@ struct wlr_xwayland {
|
||||||
struct wl_event_source *sigusr1_source;
|
struct wl_event_source *sigusr1_source;
|
||||||
struct wl_listener destroy_listener;
|
struct wl_listener destroy_listener;
|
||||||
struct wlr_xwm *xwm;
|
struct wlr_xwm *xwm;
|
||||||
|
struct wlr_xwayland_cursor *cursor;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal new_surface;
|
struct wl_signal new_surface;
|
||||||
|
@ -148,6 +150,10 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,
|
||||||
|
|
||||||
void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland);
|
void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland);
|
||||||
|
|
||||||
|
void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland,
|
||||||
|
uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height,
|
||||||
|
int32_t hotspot_x, int32_t hotspot_y);
|
||||||
|
|
||||||
void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland,
|
void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland,
|
||||||
struct wlr_xwayland_surface *surface, bool activated);
|
struct wlr_xwayland_surface *surface, bool activated);
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ pixman = dependency('pixman-1')
|
||||||
xcb = dependency('xcb')
|
xcb = dependency('xcb')
|
||||||
xcb_composite = dependency('xcb-composite')
|
xcb_composite = dependency('xcb-composite')
|
||||||
xcb_xfixes = dependency('xcb-xfixes')
|
xcb_xfixes = dependency('xcb-xfixes')
|
||||||
|
xcb_image = dependency('xcb-image')
|
||||||
|
xcb_render = dependency('xcb-render')
|
||||||
xcb_icccm = dependency('xcb-icccm', required: false)
|
xcb_icccm = dependency('xcb-icccm', required: false)
|
||||||
x11_xcb = dependency('x11-xcb')
|
x11_xcb = dependency('x11-xcb')
|
||||||
libcap = dependency('libcap', required: false)
|
libcap = dependency('libcap', required: false)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <wlr/types/wlr_cursor.h>
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/xcursor.h>
|
#include <wlr/xcursor.h>
|
||||||
|
#include <wlr/xwayland.h>
|
||||||
#include "rootston/server.h"
|
#include "rootston/server.h"
|
||||||
#include "rootston/config.h"
|
#include "rootston/config.h"
|
||||||
#include "rootston/input.h"
|
#include "rootston/input.h"
|
||||||
|
@ -96,6 +97,14 @@ struct roots_input *input_create(struct roots_server *server,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server->desktop->xwayland != NULL) {
|
||||||
|
struct wlr_xcursor_image *xcursor_image = xcursor->images[0];
|
||||||
|
wlr_xwayland_set_cursor(server->desktop->xwayland,
|
||||||
|
xcursor_image->buffer, xcursor_image->width, xcursor_image->width,
|
||||||
|
xcursor_image->height, xcursor_image->hotspot_x,
|
||||||
|
xcursor_image->hotspot_y);
|
||||||
|
}
|
||||||
|
|
||||||
input->wl_seat = wlr_seat_create(server->wl_display, "seat0");
|
input->wl_seat = wlr_seat_create(server->wl_display, "seat0");
|
||||||
if (input->wl_seat == NULL) {
|
if (input->wl_seat == NULL) {
|
||||||
wlr_log(L_ERROR, "Cannot create seat");
|
wlr_log(L_ERROR, "Cannot create seat");
|
||||||
|
|
|
@ -11,6 +11,8 @@ lib_wlr_xwayland = static_library(
|
||||||
xcb,
|
xcb,
|
||||||
xcb_composite,
|
xcb_composite,
|
||||||
xcb_xfixes,
|
xcb_xfixes,
|
||||||
|
xcb_image,
|
||||||
|
xcb_render,
|
||||||
xcb_icccm,
|
xcb_icccm,
|
||||||
pixman,
|
pixman,
|
||||||
],
|
],
|
||||||
|
|
|
@ -29,6 +29,15 @@ static inline int clearenv(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct wlr_xwayland_cursor {
|
||||||
|
uint8_t *pixels;
|
||||||
|
uint32_t stride;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
int32_t hotspot_x;
|
||||||
|
int32_t hotspot_y;
|
||||||
|
};
|
||||||
|
|
||||||
static void safe_close(int fd) {
|
static void safe_close(int fd) {
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -190,6 +199,14 @@ static int xserver_handle_ready(int signal_number, void *data) {
|
||||||
wl_event_source_remove(wlr_xwayland->sigusr1_source);
|
wl_event_source_remove(wlr_xwayland->sigusr1_source);
|
||||||
wlr_xwayland->sigusr1_source = NULL;
|
wlr_xwayland->sigusr1_source = NULL;
|
||||||
|
|
||||||
|
if (wlr_xwayland->cursor != NULL) {
|
||||||
|
struct wlr_xwayland_cursor *cur = wlr_xwayland->cursor;
|
||||||
|
xwm_set_cursor(wlr_xwayland->xwm, cur->pixels, cur->stride, cur->width,
|
||||||
|
cur->height, cur->hotspot_x, cur->hotspot_y);
|
||||||
|
free(cur);
|
||||||
|
wlr_xwayland->cursor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
char display_name[16];
|
char display_name[16];
|
||||||
snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display);
|
snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display);
|
||||||
setenv("DISPLAY", display_name, true);
|
setenv("DISPLAY", display_name, true);
|
||||||
|
@ -298,3 +315,26 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,
|
||||||
free(wlr_xwayland);
|
free(wlr_xwayland);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland,
|
||||||
|
uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height,
|
||||||
|
int32_t hotspot_x, int32_t hotspot_y) {
|
||||||
|
if (wlr_xwayland->xwm != NULL) {
|
||||||
|
xwm_set_cursor(wlr_xwayland->xwm, pixels, stride, width, height,
|
||||||
|
hotspot_x, hotspot_y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(wlr_xwayland->cursor);
|
||||||
|
|
||||||
|
wlr_xwayland->cursor = calloc(1, sizeof(struct wlr_xwayland_cursor));
|
||||||
|
if (wlr_xwayland->cursor == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wlr_xwayland->cursor->pixels = pixels;
|
||||||
|
wlr_xwayland->cursor->stride = stride;
|
||||||
|
wlr_xwayland->cursor->width = width;
|
||||||
|
wlr_xwayland->cursor->height = height;
|
||||||
|
wlr_xwayland->cursor->hotspot_x = hotspot_x;
|
||||||
|
wlr_xwayland->cursor->hotspot_y = hotspot_y;
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,12 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xcb/composite.h>
|
#include <xcb/composite.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
|
#include <xcb/xcb_image.h>
|
||||||
|
#include <xcb/render.h>
|
||||||
#include "wlr/util/log.h"
|
#include "wlr/util/log.h"
|
||||||
#include "wlr/types/wlr_surface.h"
|
#include "wlr/types/wlr_surface.h"
|
||||||
#include "wlr/xwayland.h"
|
#include "wlr/xwayland.h"
|
||||||
|
#include "wlr/xcursor.h"
|
||||||
#include "xwm.h"
|
#include "xwm.h"
|
||||||
|
|
||||||
#ifdef HAS_XCB_ICCCM
|
#ifdef HAS_XCB_ICCCM
|
||||||
|
@ -1035,6 +1038,9 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
||||||
if (!xwm) {
|
if (!xwm) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (xwm->cursor) {
|
||||||
|
xcb_free_cursor(xwm->xcb_conn, xwm->cursor);
|
||||||
|
}
|
||||||
if (xwm->event_source) {
|
if (xwm->event_source) {
|
||||||
wl_event_source_remove(xwm->event_source);
|
wl_event_source_remove(xwm->event_source);
|
||||||
}
|
}
|
||||||
|
@ -1097,7 +1103,6 @@ static void xwm_get_resources(struct wlr_xwm *xwm) {
|
||||||
xfixes_reply->major_version, xfixes_reply->minor_version);
|
xfixes_reply->major_version, xfixes_reply->minor_version);
|
||||||
|
|
||||||
free(xfixes_reply);
|
free(xfixes_reply);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xwm_create_wm_window(struct wlr_xwm *xwm) {
|
static void xwm_create_wm_window(struct wlr_xwm *xwm) {
|
||||||
|
@ -1170,7 +1175,7 @@ static void xwm_get_visual_and_colormap(struct wlr_xwm *xwm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visualtype == NULL) {
|
if (visualtype == NULL) {
|
||||||
wlr_log(L_DEBUG, "no 32 bit visualtype\n");
|
wlr_log(L_DEBUG, "No 32 bit visualtype\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1183,6 +1188,71 @@ static void xwm_get_visual_and_colormap(struct wlr_xwm *xwm) {
|
||||||
xwm->visual_id);
|
xwm->visual_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xwm_get_render_format(struct wlr_xwm *xwm) {
|
||||||
|
xcb_render_query_pict_formats_cookie_t cookie =
|
||||||
|
xcb_render_query_pict_formats(xwm->xcb_conn);
|
||||||
|
xcb_render_query_pict_formats_reply_t *reply =
|
||||||
|
xcb_render_query_pict_formats_reply(xwm->xcb_conn, cookie, NULL);
|
||||||
|
xcb_render_pictforminfo_iterator_t iter =
|
||||||
|
xcb_render_query_pict_formats_formats_iterator(reply);
|
||||||
|
xcb_render_pictforminfo_t *format = NULL;
|
||||||
|
while (iter.rem > 0) {
|
||||||
|
if (iter.data->depth == 32) {
|
||||||
|
format = iter.data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_render_pictforminfo_next(&iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == NULL) {
|
||||||
|
wlr_log(L_DEBUG, "No 32 bit render format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xwm->render_format_id = format->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride,
|
||||||
|
uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y) {
|
||||||
|
if (!xwm->render_format_id) {
|
||||||
|
wlr_log(L_ERROR, "Cannot set xwm cursor: no render format available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (xwm->cursor) {
|
||||||
|
xcb_free_cursor(xwm->xcb_conn, xwm->cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
stride *= 4;
|
||||||
|
int depth = 32;
|
||||||
|
|
||||||
|
xcb_pixmap_t pix = xcb_generate_id(xwm->xcb_conn);
|
||||||
|
xcb_create_pixmap(xwm->xcb_conn, depth, pix, xwm->screen->root, width,
|
||||||
|
height);
|
||||||
|
|
||||||
|
xcb_render_picture_t pic = xcb_generate_id(xwm->xcb_conn);
|
||||||
|
xcb_render_create_picture(xwm->xcb_conn, pic, pix, xwm->render_format_id,
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
xcb_gcontext_t gc = xcb_generate_id(xwm->xcb_conn);
|
||||||
|
xcb_create_gc(xwm->xcb_conn, gc, pix, 0, NULL);
|
||||||
|
|
||||||
|
xcb_put_image(xwm->xcb_conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc,
|
||||||
|
width, height, 0, 0, 0, depth, stride * height * sizeof(uint8_t),
|
||||||
|
pixels);
|
||||||
|
xcb_free_gc(xwm->xcb_conn, gc);
|
||||||
|
|
||||||
|
xwm->cursor = xcb_generate_id(xwm->xcb_conn);
|
||||||
|
xcb_render_create_cursor(xwm->xcb_conn, xwm->cursor, pic, hotspot_x,
|
||||||
|
hotspot_y);
|
||||||
|
xcb_free_pixmap(xwm->xcb_conn, pix);
|
||||||
|
|
||||||
|
uint32_t values[] = {xwm->cursor};
|
||||||
|
xcb_change_window_attributes(xwm->xcb_conn, xwm->screen->root,
|
||||||
|
XCB_CW_CURSOR, values);
|
||||||
|
xcb_flush(xwm->xcb_conn);
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) {
|
struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) {
|
||||||
struct wlr_xwm *xwm = calloc(1, sizeof(struct wlr_xwm));
|
struct wlr_xwm *xwm = calloc(1, sizeof(struct wlr_xwm));
|
||||||
if (xwm == NULL) {
|
if (xwm == NULL) {
|
||||||
|
@ -1219,16 +1289,16 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) {
|
||||||
|
|
||||||
xwm_get_resources(xwm);
|
xwm_get_resources(xwm);
|
||||||
xwm_get_visual_and_colormap(xwm);
|
xwm_get_visual_and_colormap(xwm);
|
||||||
|
xwm_get_render_format(xwm);
|
||||||
|
|
||||||
uint32_t values[1];
|
uint32_t values[] = {
|
||||||
values[0] =
|
|
||||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
||||||
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
|
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
|
||||||
XCB_EVENT_MASK_PROPERTY_CHANGE;
|
XCB_EVENT_MASK_PROPERTY_CHANGE,
|
||||||
|
};
|
||||||
xcb_change_window_attributes(xwm->xcb_conn,
|
xcb_change_window_attributes(xwm->xcb_conn,
|
||||||
xwm->screen->root,
|
xwm->screen->root,
|
||||||
XCB_CW_EVENT_MASK /* | XCB_CW_CURSOR */,
|
XCB_CW_EVENT_MASK,
|
||||||
values);
|
values);
|
||||||
|
|
||||||
xcb_composite_redirect_subwindows(xwm->xcb_conn,
|
xcb_composite_redirect_subwindows(xwm->xcb_conn,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#ifndef XWAYLAND_INTERNALS_H
|
#ifndef XWAYLAND_INTERNALS_H
|
||||||
#define XWAYLAND_INTERNALS_H
|
#define XWAYLAND_INTERNALS_H
|
||||||
|
|
||||||
|
#include <xcb/render.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/xwayland.h>
|
#include <wlr/xwayland.h>
|
||||||
|
|
||||||
|
@ -49,6 +51,8 @@ struct wlr_xwm {
|
||||||
xcb_window_t window;
|
xcb_window_t window;
|
||||||
xcb_visualid_t visual_id;
|
xcb_visualid_t visual_id;
|
||||||
xcb_colormap_t colormap;
|
xcb_colormap_t colormap;
|
||||||
|
xcb_render_pictformat_t render_format_id;
|
||||||
|
xcb_cursor_t cursor;
|
||||||
|
|
||||||
struct wlr_xwayland_surface *focus_surface;
|
struct wlr_xwayland_surface *focus_surface;
|
||||||
|
|
||||||
|
@ -60,8 +64,11 @@ struct wlr_xwm {
|
||||||
struct wl_listener compositor_surface_create;
|
struct wl_listener compositor_surface_create;
|
||||||
};
|
};
|
||||||
|
|
||||||
void xwm_destroy(struct wlr_xwm *xwm);
|
|
||||||
|
|
||||||
struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland);
|
struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland);
|
||||||
|
|
||||||
|
void xwm_destroy(struct wlr_xwm *xwm);
|
||||||
|
|
||||||
|
void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride,
|
||||||
|
uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue