cursor-shape: add support for server side cursor shapes

This implements support for the new cursor-shape-v1 protocol. When
available, we use it, instead of client-side cursor surfaces, to
select the xcursor shape.

Note that we still need to keep client side pointers, for:

* backward compatibility
* to be able to "hide" the cursor

Closes #1379
This commit is contained in:
Daniel Eklöf 2023-06-27 17:25:57 +02:00
parent ee794a121e
commit c8e13ad393
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 280 additions and 20 deletions

View file

@ -14,6 +14,10 @@
#include <wayland-cursor.h>
#include <xkbcommon/xkbcommon-compose.h>
#if defined(HAVE_CURSOR_SHAPE)
#include <cursor-shape-v1.h>
#endif
#include <tllist.h>
#define LOG_MODULE "wayland"
@ -209,6 +213,11 @@ seat_destroy(struct seat *seat)
if (seat->data_device != NULL)
wl_data_device_release(seat->data_device);
#if defined(HAVE_CURSOR_SHAPE)
if (seat->pointer.shape_device != NULL)
wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device);
#endif
if (seat->wl_keyboard != NULL)
wl_keyboard_release(seat->wl_keyboard);
if (seat->wl_pointer != NULL)
@ -316,9 +325,22 @@ seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
seat->wl_pointer = wl_seat_get_pointer(wl_seat);
wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat);
#if defined(HAVE_CURSOR_SHAPE)
if (seat->wayl->cursor_shape_manager != NULL) {
xassert(seat->pointer.shape_device == NULL);
seat->pointer.shape_device = wp_cursor_shape_manager_v1_get_pointer(
seat->wayl->cursor_shape_manager, seat->wl_pointer);
}
#endif
}
} else {
if (seat->wl_pointer != NULL) {
#if defined(HAVE_CURSOR_SHAPE)
wp_cursor_shape_device_v1_destroy(seat->pointer.shape_device);
seat->pointer.shape_device = NULL;
#endif
wl_pointer_release(seat->wl_pointer);
wl_surface_destroy(seat->pointer.surface.surf);
@ -1167,6 +1189,17 @@ handle_global(void *data, struct wl_registry *registry,
}
#endif
#if defined(HAVE_CURSOR_SHAPE)
else if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) {
const uint32_t required = 1;
if (!verify_iface_version(interface, version, required))
return;
wayl->cursor_shape_manager = wl_registry_bind(
wayl->registry, name, &wp_cursor_shape_manager_v1_interface, required);
}
#endif
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) {
const uint32_t required = 1;
@ -1401,6 +1434,15 @@ wayl_init(struct fdm *fdm, struct key_binding_manager *key_binding_manager,
LOG_WARN("fractional scaling not available");
}
#if defined(HAVE_CURSOR_SHAPE)
if (wayl->cursor_shape_manager == NULL) {
#else
if (true) {
#endif
LOG_WARN("no server-side cursors available, "
"falling back to client-side cursors");
}
if (presentation_timings && wayl->presentation == NULL) {
LOG_ERR("presentation time interface not implemented by compositor");
goto out;
@ -1495,6 +1537,10 @@ wayl_destroy(struct wayland *wayl)
if (wayl->viewporter != NULL)
wp_viewporter_destroy(wayl->viewporter);
#endif
#if defined(HAVE_CURSOR_SHAPE)
if (wayl->cursor_shape_manager != NULL)
wp_cursor_shape_manager_v1_destroy(wayl->cursor_shape_manager);
#endif
#if defined(HAVE_XDG_ACTIVATION)
if (wayl->xdg_activation != NULL)
xdg_activation_v1_destroy(wayl->xdg_activation);