1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-09 12:50:35 +00:00

[Wayland] Implement the cursor-shape-v1 protocol

Related #106229. The cursor-shape protocol allows us to not have to deal with cursor theming and instead depend on the
compositor for it.
This still does not quite solve the issue when the compositor doesn't implement the protocol
(or running under the x11 backend) but for gnome/kde and a few more this should resolve things.
This commit is contained in:
ArchercatNEO
2025-05-10 18:08:19 +01:00
parent 19bb18716e
commit 3cd7b5b9a8
5 changed files with 253 additions and 1 deletions

View File

@@ -547,6 +547,12 @@ void WaylandThread::_wl_registry_on_global(void *data, struct wl_registry *wl_re
registry->wp_viewporter_name = name;
}
if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) {
registry->wp_cursor_shape_manager = (struct wp_cursor_shape_manager_v1 *)wl_registry_bind(wl_registry, name, &wp_cursor_shape_manager_v1_interface, 1);
registry->wp_cursor_shape_manager_name = name;
return;
}
if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0) {
registry->wp_fractional_scale_manager = (struct wp_fractional_scale_manager_v1 *)wl_registry_bind(wl_registry, name, &wp_fractional_scale_manager_v1_interface, 1);
registry->wp_fractional_scale_manager_name = name;
@@ -753,6 +759,25 @@ void WaylandThread::_wl_registry_on_global_remove(void *data, struct wl_registry
return;
}
if (name == registry->wp_cursor_shape_manager_name) {
if (registry->wp_cursor_shape_manager) {
wp_cursor_shape_manager_v1_destroy(registry->wp_cursor_shape_manager);
registry->wp_cursor_shape_manager = nullptr;
}
registry->wp_cursor_shape_manager_name = 0;
for (struct wl_seat *wl_seat : registry->wl_seats) {
SeatState *ss = wl_seat_get_seat_state(wl_seat);
ERR_FAIL_NULL(ss);
if (ss->wp_cursor_shape_device) {
wp_cursor_shape_device_v1_destroy(ss->wp_cursor_shape_device);
ss->wp_cursor_shape_device = nullptr;
}
}
}
if (name == registry->wp_fractional_scale_manager_name) {
for (KeyValue<DisplayServer::WindowID, WindowState> &pair : registry->wayland_thread->windows) {
WindowState ws = pair.value;
@@ -1452,6 +1477,10 @@ void WaylandThread::_wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat
ss->wl_pointer = wl_seat_get_pointer(wl_seat);
wl_pointer_add_listener(ss->wl_pointer, &wl_pointer_listener, ss);
if (ss->registry->wp_cursor_shape_manager) {
ss->wp_cursor_shape_device = wp_cursor_shape_manager_v1_get_pointer(ss->registry->wp_cursor_shape_manager, ss->wl_pointer);
}
if (ss->registry->wp_relative_pointer_manager) {
ss->wp_relative_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(ss->registry->wp_relative_pointer_manager, ss->wl_pointer);
zwp_relative_pointer_v1_add_listener(ss->wp_relative_pointer, &wp_relative_pointer_listener, ss);
@@ -1483,6 +1512,11 @@ void WaylandThread::_wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat
ss->wl_pointer = nullptr;
}
if (ss->wp_cursor_shape_device) {
wp_cursor_shape_device_v1_destroy(ss->wp_cursor_shape_device);
ss->wp_cursor_shape_device = nullptr;
}
if (ss->wp_relative_pointer) {
zwp_relative_pointer_v1_destroy(ss->wp_relative_pointer);
ss->wp_relative_pointer = nullptr;
@@ -3328,6 +3362,12 @@ void WaylandThread::seat_state_update_cursor(SeatState *p_ss) {
// We can't really reasonably scale custom cursors, so we'll let the
// compositor do it for us (badly).
scale = 1;
} else if (thread->registry.wp_cursor_shape_manager) {
wp_cursor_shape_device_v1_shape wp_shape = thread->standard_cursors[shape];
wp_cursor_shape_device_v1_set_shape(p_ss->wp_cursor_shape_device, p_ss->pointer_enter_serial, wp_shape);
// We should avoid calling the `wl_pointer_set_cursor` at the end of this method.
return;
} else {
struct wl_cursor *wl_cursor = thread->wl_cursors[shape];
@@ -4890,6 +4930,10 @@ void WaylandThread::destroy() {
wl_data_device_destroy(ss->wl_data_device);
}
if (ss->wp_cursor_shape_device) {
wp_cursor_shape_device_v1_destroy(ss->wp_cursor_shape_device);
}
if (ss->wp_relative_pointer) {
zwp_relative_pointer_v1_destroy(ss->wp_relative_pointer);
}
@@ -4957,6 +5001,10 @@ void WaylandThread::destroy() {
zxdg_decoration_manager_v1_destroy(registry.xdg_decoration_manager);
}
if (registry.wp_cursor_shape_manager) {
wp_cursor_shape_manager_v1_destroy(registry.wp_cursor_shape_manager);
}
if (registry.wp_fractional_scale_manager) {
wp_fractional_scale_manager_v1_destroy(registry.wp_fractional_scale_manager);
}