backend/x11: Hide cursor with Xfixes
This commit is contained in:
parent
70ae76304e
commit
d3ee69f76b
|
@ -12,6 +12,7 @@
|
||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/xinput.h>
|
#include <xcb/xinput.h>
|
||||||
|
|
||||||
#include <wlr/backend/interface.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);
|
struct wlr_x11_backend *x11 = get_x11_backend_from_backend(backend);
|
||||||
x11->started = true;
|
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);
|
wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->keyboard_dev);
|
||||||
|
|
||||||
for (size_t i = 0; i < x11->requested_outputs; ++i) {
|
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_renderer_destroy(x11->renderer);
|
||||||
wlr_egl_finish(&x11->egl);
|
wlr_egl_finish(&x11->egl);
|
||||||
|
|
||||||
if (x11->cursor) {
|
|
||||||
xcb_free_cursor(x11->xcb, x11->cursor);
|
|
||||||
}
|
|
||||||
if (x11->xlib_conn) {
|
if (x11->xlib_conn) {
|
||||||
XCloseDisplay(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 =
|
const xcb_query_extension_reply_t *ext;
|
||||||
xcb_get_extension_data(x11->xcb, &xcb_input_id);
|
|
||||||
|
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) {
|
if (!ext || !ext->present) {
|
||||||
wlr_log(WLR_ERROR, "X11 does not support Xinput extension");
|
wlr_log(WLR_ERROR, "X11 does not support Xinput extension");
|
||||||
goto error_display;
|
goto error_display;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/xinput.h>
|
#include <xcb/xinput.h>
|
||||||
|
|
||||||
#include <wlr/interfaces/wlr_input_device.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;
|
x11->time = ev->time;
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ x11_required = [
|
||||||
'x11-xcb',
|
'x11-xcb',
|
||||||
'xcb',
|
'xcb',
|
||||||
'xcb-xinput',
|
'xcb-xinput',
|
||||||
|
'xcb-xfixes',
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach lib : x11_required
|
foreach lib : x11_required
|
||||||
|
|
|
@ -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_KEY_RELEASE |
|
||||||
XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS |
|
XCB_INPUT_XI_EVENT_MASK_BUTTON_PRESS |
|
||||||
XCB_INPUT_XI_EVENT_MASK_BUTTON_RELEASE |
|
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);
|
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);
|
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_map_window(x11->xcb, output->win);
|
||||||
xcb_flush(x11->xcb);
|
xcb_flush(x11->xcb);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ struct wlr_x11_output {
|
||||||
|
|
||||||
struct wl_event_source *frame_timer;
|
struct wl_event_source *frame_timer;
|
||||||
int frame_delay;
|
int frame_delay;
|
||||||
|
|
||||||
|
bool cursor_hidden;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_x11_backend {
|
struct wlr_x11_backend {
|
||||||
|
@ -64,9 +66,6 @@ struct wlr_x11_backend {
|
||||||
// The time we last received an event
|
// The time we last received an event
|
||||||
xcb_timestamp_t time;
|
xcb_timestamp_t time;
|
||||||
|
|
||||||
// A blank cursor
|
|
||||||
xcb_cursor_t cursor;
|
|
||||||
|
|
||||||
uint8_t xinput_opcode;
|
uint8_t xinput_opcode;
|
||||||
|
|
||||||
struct wl_listener display_destroy;
|
struct wl_listener display_destroy;
|
||||||
|
|
Loading…
Reference in New Issue