aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/x11/backend.c36
-rw-r--r--backend/x11/input_device.c31
-rw-r--r--backend/x11/meson.build1
-rw-r--r--backend/x11/output.c8
-rw-r--r--include/backend/x11.h5
5 files changed, 59 insertions, 22 deletions
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index ce747976..38715631 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -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;
diff --git a/backend/x11/input_device.c b/backend/x11/input_device.c
index 08d982e6..a50f478a 100644
--- a/backend/x11/input_device.c
+++ b/backend/x11/input_device.c
@@ -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;
+ }
}
}
diff --git a/backend/x11/meson.build b/backend/x11/meson.build
index d9fd8d91..19e873ab 100644
--- a/backend/x11/meson.build
+++ b/backend/x11/meson.build
@@ -3,6 +3,7 @@ x11_required = [
'x11-xcb',
'xcb',
'xcb-xinput',
+ 'xcb-xfixes',
]
foreach lib : x11_required
diff --git a/backend/x11/output.c b/backend/x11/output.c
index ba70d5cb..6f98c590 100644
--- a/backend/x11/output.c
+++ b/backend/x11/output.c
@@ -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);
diff --git a/include/backend/x11.h b/include/backend/x11.h
index 94de129f..1a8341f6 100644
--- a/include/backend/x11.h
+++ b/include/backend/x11.h
@@ -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;