backend/x11: Hide cursor with Xfixes

This commit is contained in:
Scott Anderson 2018-11-11 14:51:22 +13:00
parent 70ae76304e
commit d3ee69f76b
5 changed files with 59 additions and 22 deletions

View File

@ -12,6 +12,7 @@
#include <X11/Xlib-xcb.h>
#include <wayland-server.h>
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
#include <xcb/xinput.h>
#include <wlr/backend/interface.h>
@ -106,15 +107,6 @@ static bool backend_start(struct wlr_backend *backend) {
struct wlr_x11_backend *x11 = get_x11_backend_from_backend(backend);
x11->started = true;
// create a blank cursor
xcb_pixmap_t pix = xcb_generate_id(x11->xcb);
xcb_create_pixmap(x11->xcb, 1, pix, x11->screen->root, 1, 1);
x11->cursor = xcb_generate_id(x11->xcb);
xcb_create_cursor(x11->xcb, x11->cursor, pix, pix, 0, 0, 0, 0, 0, 0,
0, 0);
xcb_free_pixmap(x11->xcb, pix);
wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->keyboard_dev);
for (size_t i = 0; i < x11->requested_outputs; ++i) {
@ -148,9 +140,6 @@ static void backend_destroy(struct wlr_backend *backend) {
wlr_renderer_destroy(x11->renderer);
wlr_egl_finish(&x11->egl);
if (x11->cursor) {
xcb_free_cursor(x11->xcb, x11->cursor);
}
if (x11->xlib_conn) {
XCloseDisplay(x11->xlib_conn);
}
@ -233,8 +222,27 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
}
}
const xcb_query_extension_reply_t *ext =
xcb_get_extension_data(x11->xcb, &xcb_input_id);
const xcb_query_extension_reply_t *ext;
ext = xcb_get_extension_data(x11->xcb, &xcb_xfixes_id);
if (!ext || !ext->present) {
wlr_log(WLR_ERROR, "X11 does not support Xfixes extension");
goto error_display;
}
xcb_xfixes_query_version_cookie_t fixes_cookie =
xcb_xfixes_query_version(x11->xcb, 4, 0);
xcb_xfixes_query_version_reply_t *fixes_reply =
xcb_xfixes_query_version_reply(x11->xcb, fixes_cookie, NULL);
if (!fixes_reply || fixes_reply->major_version < 4) {
wlr_log(WLR_ERROR, "X11 does not support required Xfixes version");
free(fixes_reply);
goto error_display;
}
free(fixes_reply);
ext = xcb_get_extension_data(x11->xcb, &xcb_input_id);
if (!ext || !ext->present) {
wlr_log(WLR_ERROR, "X11 does not support Xinput extension");
goto error_display;

View File

@ -9,6 +9,7 @@
#endif
#include <xcb/xcb.h>
#include <xcb/xfixes.h>
#include <xcb/xinput.h>
#include <wlr/interfaces/wlr_input_device.h>
@ -164,6 +165,36 @@ void handle_x11_xinput_event(struct wlr_x11_backend *x11,
x11->time = ev->time;
break;
}
case XCB_INPUT_ENTER: {
xcb_input_enter_event_t *ev = (xcb_input_enter_event_t *)event;
output = get_x11_output_from_window_id(x11, ev->event);
if (!output) {
return;
}
if (!output->cursor_hidden) {
xcb_xfixes_hide_cursor(x11->xcb, output->win);
xcb_flush(x11->xcb);
output->cursor_hidden = true;
}
break;
}
case XCB_INPUT_LEAVE: {
xcb_input_leave_event_t *ev = (xcb_input_leave_event_t *)event;
output = get_x11_output_from_window_id(x11, ev->event);
if (!output) {
return;
}
if (output->cursor_hidden) {
xcb_xfixes_show_cursor(x11->xcb, output->win);
xcb_flush(x11->xcb);
output->cursor_hidden = false;
}
break;
}
}
}

View File

@ -3,6 +3,7 @@ x11_required = [
'x11-xcb',
'xcb',
'xcb-xinput',
'xcb-xfixes',
]
foreach lib : x11_required

View File

@ -168,7 +168,9 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
XCB_INPUT_XI_EVENT_MASK_KEY_RELEASE |
XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS |
XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE |
XCB_INPUT_XI_EVENT_MASK_MOTION,
XCB_INPUT_XI_EVENT_MASK_MOTION |
XCB_INPUT_XI_EVENT_MASK_ENTER |
XCB_INPUT_XI_EVENT_MASK_LEAVE,
};
xcb_input_xi_select_events(x11->xcb, output->win, 1, &xinput_mask.head);
@ -190,10 +192,6 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
strlen(title), title);
}
uint32_t cursor_values[] = { x11->cursor };
xcb_change_window_attributes(x11->xcb, output->win, XCB_CW_CURSOR,
cursor_values);
xcb_map_window(x11->xcb, output->win);
xcb_flush(x11->xcb);

View File

@ -33,6 +33,8 @@ struct wlr_x11_output {
struct wl_event_source *frame_timer;
int frame_delay;
bool cursor_hidden;
};
struct wlr_x11_backend {
@ -64,9 +66,6 @@ struct wlr_x11_backend {
// The time we last received an event
xcb_timestamp_t time;
// A blank cursor
xcb_cursor_t cursor;
uint8_t xinput_opcode;
struct wl_listener display_destroy;