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