You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Merge pull request #106251 from ArchercatNEO/wayland-cursor-shape
[Wayland] Implement the cursor-shape-v1 protocol
This commit is contained in:
@@ -46,6 +46,14 @@ env.NoCache(
|
||||
"protocol/viewporter.gen.h", "#thirdparty/wayland-protocols/stable/viewporter/viewporter.xml"
|
||||
),
|
||||
env.WAYLAND_API_CODE("protocol/viewporter.gen.c", "#thirdparty/wayland-protocols/stable/viewporter/viewporter.xml"),
|
||||
env.WAYLAND_API_HEADER(
|
||||
"protocol/cursor_shape.gen.h",
|
||||
"#thirdparty/wayland-protocols/staging/cursor-shape/cursor-shape-v1.xml",
|
||||
),
|
||||
env.WAYLAND_API_CODE(
|
||||
"protocol/cursor_shape.gen.c",
|
||||
"#thirdparty/wayland-protocols/staging/cursor-shape/cursor-shape-v1.xml",
|
||||
),
|
||||
env.WAYLAND_API_HEADER(
|
||||
"protocol/fractional_scale.gen.h",
|
||||
"#thirdparty/wayland-protocols/staging/fractional-scale/fractional-scale-v1.xml",
|
||||
@@ -158,6 +166,7 @@ env.NoCache(
|
||||
source_files = [
|
||||
"protocol/wayland.gen.c",
|
||||
"protocol/viewporter.gen.c",
|
||||
"protocol/cursor_shape.gen.c",
|
||||
"protocol/fractional_scale.gen.c",
|
||||
"protocol/xdg_shell.gen.c",
|
||||
"protocol/xdg_system_bell.gen.c",
|
||||
|
||||
@@ -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;
|
||||
@@ -1454,6 +1479,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);
|
||||
@@ -1485,6 +1514,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;
|
||||
@@ -3330,6 +3364,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];
|
||||
|
||||
@@ -4892,6 +4932,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);
|
||||
}
|
||||
@@ -4959,6 +5003,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);
|
||||
}
|
||||
|
||||
@@ -51,10 +51,11 @@
|
||||
// These must go after the Wayland client include to work properly.
|
||||
#include "wayland/protocol/idle_inhibit.gen.h"
|
||||
#include "wayland/protocol/primary_selection.gen.h"
|
||||
// These three protocol headers name wl_pointer method arguments as `pointer`,
|
||||
// These four protocol headers name wl_pointer method arguments as `pointer`,
|
||||
// which is the same name as X11's pointer typedef. This trips some very
|
||||
// annoying shadowing warnings. A `#define` works around this issue.
|
||||
#define pointer wl_pointer
|
||||
#include "wayland/protocol/cursor_shape.gen.h"
|
||||
#include "wayland/protocol/pointer_constraints.gen.h"
|
||||
#include "wayland/protocol/pointer_gestures.gen.h"
|
||||
#include "wayland/protocol/relative_pointer.gen.h"
|
||||
@@ -187,6 +188,9 @@ public:
|
||||
struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager = nullptr;
|
||||
uint32_t wp_fractional_scale_manager_name = 0;
|
||||
|
||||
struct wp_cursor_shape_manager_v1 *wp_cursor_shape_manager = nullptr;
|
||||
uint32_t wp_cursor_shape_manager_name = 0;
|
||||
|
||||
struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;
|
||||
uint32_t xdg_decoration_manager_name = 0;
|
||||
|
||||
@@ -416,6 +420,8 @@ public:
|
||||
|
||||
uint32_t pointer_enter_serial = 0;
|
||||
|
||||
struct wp_cursor_shape_device_v1 *wp_cursor_shape_device = nullptr;
|
||||
|
||||
struct zwp_relative_pointer_v1 *wp_relative_pointer = nullptr;
|
||||
struct zwp_locked_pointer_v1 *wp_locked_pointer = nullptr;
|
||||
struct zwp_confined_pointer_v1 *wp_confined_pointer = nullptr;
|
||||
@@ -547,9 +553,32 @@ private:
|
||||
// especially as usually screen scales don't change continuously.
|
||||
int cursor_scale = 1;
|
||||
|
||||
// Use cursor-shape-v1 protocol if the compositor supports it.
|
||||
wp_cursor_shape_device_v1_shape standard_cursors[DisplayServer::CURSOR_MAX] = {
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT, //CURSOR_ARROW
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT, //CURSOR_IBEAM
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER, //CURSOR_POINTING_HAND
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR, //CURSOR_CROSS
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_WAIT, //CURSOR_WAIT
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_PROGRESS, //CURSOR_BUSY
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRAB, //CURSOR_DRAG
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRABBING, //CURSOR_CAN_DROP
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NO_DROP, //CURSOR_FORBIDDEN
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE, //CURSOR_VSIZE
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE, //CURSOR_HSIZE
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE, //CURSOR_BDIAGSIZE
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE, //CURSOR_FDIAGSIZE
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE, //CURSOR_MOVE
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ROW_RESIZE, //CURSOR_VSPLIT
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COL_RESIZE, //CURSOR_HSPLIT
|
||||
wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_HELP, //CURSOR_HELP
|
||||
};
|
||||
|
||||
// Fallback to reading $XCURSOR and system themes if the compositor does not.
|
||||
struct wl_cursor_theme *wl_cursor_theme = nullptr;
|
||||
struct wl_cursor *wl_cursors[DisplayServer::CURSOR_MAX] = {};
|
||||
|
||||
// User-defined cursor overrides. Take precedence over standard and wl cursors.
|
||||
HashMap<DisplayServer::CursorShape, CustomCursor> custom_cursors;
|
||||
|
||||
DisplayServer::CursorShape cursor_shape = DisplayServer::CURSOR_ARROW;
|
||||
|
||||
4
thirdparty/wayland-protocols/staging/cursor-shape/README
vendored
Normal file
4
thirdparty/wayland-protocols/staging/cursor-shape/README
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
cursor-shape protocol
|
||||
|
||||
Maintainers:
|
||||
Simon Ser <contact@emersion.fr> (@emersion)
|
||||
162
thirdparty/wayland-protocols/staging/cursor-shape/cursor-shape-v1.xml
vendored
Normal file
162
thirdparty/wayland-protocols/staging/cursor-shape/cursor-shape-v1.xml
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="cursor_shape_v1">
|
||||
<copyright>
|
||||
Copyright 2018 The Chromium Authors
|
||||
Copyright 2023 Simon Ser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="wp_cursor_shape_manager_v1" version="2">
|
||||
<description summary="cursor shape manager">
|
||||
This global offers an alternative, optional way to set cursor images. This
|
||||
new way uses enumerated cursors instead of a wl_surface like
|
||||
wl_pointer.set_cursor does.
|
||||
|
||||
Warning! The protocol described in this file is currently in the testing
|
||||
phase. Backward compatible changes may be added together with the
|
||||
corresponding interface version bump. Backward incompatible changes can
|
||||
only be done by creating a new major version of the extension.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the manager">
|
||||
Destroy the cursor shape manager.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_pointer">
|
||||
<description summary="manage the cursor shape of a pointer device">
|
||||
Obtain a wp_cursor_shape_device_v1 for a wl_pointer object.
|
||||
|
||||
When the pointer capability is removed from the wl_seat, the
|
||||
wp_cursor_shape_device_v1 object becomes inert.
|
||||
</description>
|
||||
<arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/>
|
||||
<arg name="pointer" type="object" interface="wl_pointer"/>
|
||||
</request>
|
||||
|
||||
<request name="get_tablet_tool_v2">
|
||||
<description summary="manage the cursor shape of a tablet tool device">
|
||||
Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2 object.
|
||||
|
||||
When the zwp_tablet_tool_v2 is removed, the wp_cursor_shape_device_v1
|
||||
object becomes inert.
|
||||
</description>
|
||||
<arg name="cursor_shape_device" type="new_id" interface="wp_cursor_shape_device_v1"/>
|
||||
<arg name="tablet_tool" type="object" interface="zwp_tablet_tool_v2"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="wp_cursor_shape_device_v1" version="2">
|
||||
<description summary="cursor shape for a device">
|
||||
This interface allows clients to set the cursor shape.
|
||||
</description>
|
||||
|
||||
<enum name="shape">
|
||||
<description summary="cursor shapes">
|
||||
This enum describes cursor shapes.
|
||||
|
||||
The names are taken from the CSS W3C specification:
|
||||
https://w3c.github.io/csswg-drafts/css-ui/#cursor
|
||||
with a few additions.
|
||||
|
||||
Note that there are some groups of cursor shapes that are related:
|
||||
The first group is drag-and-drop cursors which are used to indicate
|
||||
the selected action during dnd operations. The second group is resize
|
||||
cursors which are used to indicate resizing and moving possibilities
|
||||
on window borders. It is recommended that the shapes in these groups
|
||||
should use visually compatible images and metaphors.
|
||||
</description>
|
||||
<entry name="default" value="1" summary="default cursor"/>
|
||||
<entry name="context_menu" value="2" summary="a context menu is available for the object under the cursor"/>
|
||||
<entry name="help" value="3" summary="help is available for the object under the cursor"/>
|
||||
<entry name="pointer" value="4" summary="pointer that indicates a link or another interactive element"/>
|
||||
<entry name="progress" value="5" summary="progress indicator"/>
|
||||
<entry name="wait" value="6" summary="program is busy, user should wait"/>
|
||||
<entry name="cell" value="7" summary="a cell or set of cells may be selected"/>
|
||||
<entry name="crosshair" value="8" summary="simple crosshair"/>
|
||||
<entry name="text" value="9" summary="text may be selected"/>
|
||||
<entry name="vertical_text" value="10" summary="vertical text may be selected"/>
|
||||
<entry name="alias" value="11" summary="drag-and-drop: alias of/shortcut to something is to be created"/>
|
||||
<entry name="copy" value="12" summary="drag-and-drop: something is to be copied"/>
|
||||
<entry name="move" value="13" summary="drag-and-drop: something is to be moved"/>
|
||||
<entry name="no_drop" value="14" summary="drag-and-drop: the dragged item cannot be dropped at the current cursor location"/>
|
||||
<entry name="not_allowed" value="15" summary="drag-and-drop: the requested action will not be carried out"/>
|
||||
<entry name="grab" value="16" summary="drag-and-drop: something can be grabbed"/>
|
||||
<entry name="grabbing" value="17" summary="drag-and-drop: something is being grabbed"/>
|
||||
<entry name="e_resize" value="18" summary="resizing: the east border is to be moved"/>
|
||||
<entry name="n_resize" value="19" summary="resizing: the north border is to be moved"/>
|
||||
<entry name="ne_resize" value="20" summary="resizing: the north-east corner is to be moved"/>
|
||||
<entry name="nw_resize" value="21" summary="resizing: the north-west corner is to be moved"/>
|
||||
<entry name="s_resize" value="22" summary="resizing: the south border is to be moved"/>
|
||||
<entry name="se_resize" value="23" summary="resizing: the south-east corner is to be moved"/>
|
||||
<entry name="sw_resize" value="24" summary="resizing: the south-west corner is to be moved"/>
|
||||
<entry name="w_resize" value="25" summary="resizing: the west border is to be moved"/>
|
||||
<entry name="ew_resize" value="26" summary="resizing: the east and west borders are to be moved"/>
|
||||
<entry name="ns_resize" value="27" summary="resizing: the north and south borders are to be moved"/>
|
||||
<entry name="nesw_resize" value="28" summary="resizing: the north-east and south-west corners are to be moved"/>
|
||||
<entry name="nwse_resize" value="29" summary="resizing: the north-west and south-east corners are to be moved"/>
|
||||
<entry name="col_resize" value="30" summary="resizing: that the item/column can be resized horizontally"/>
|
||||
<entry name="row_resize" value="31" summary="resizing: that the item/row can be resized vertically"/>
|
||||
<entry name="all_scroll" value="32" summary="something can be scrolled in any direction"/>
|
||||
<entry name="zoom_in" value="33" summary="something can be zoomed in"/>
|
||||
<entry name="zoom_out" value="34" summary="something can be zoomed out"/>
|
||||
<entry name="dnd_ask" value="35" summary="drag-and-drop: the user will select which action will be carried out (non-css value)" since="2"/>
|
||||
<entry name="all_resize" value="36" summary="resizing: something can be moved or resized in any direction (non-css value)" since="2"/>
|
||||
</enum>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_shape" value="1"
|
||||
summary="the specified shape value is invalid"/>
|
||||
</enum>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the cursor shape device">
|
||||
Destroy the cursor shape device.
|
||||
|
||||
The device cursor shape remains unchanged.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="set_shape">
|
||||
<description summary="set device cursor to the shape">
|
||||
Sets the device cursor to the specified shape. The compositor will
|
||||
change the cursor image based on the specified shape.
|
||||
|
||||
The cursor actually changes only if the input device focus is one of
|
||||
the requesting client's surfaces. If any, the previous cursor image
|
||||
(surface or shape) is replaced.
|
||||
|
||||
The "shape" argument must be a valid enum entry, otherwise the
|
||||
invalid_shape protocol error is raised.
|
||||
|
||||
This is similar to the wl_pointer.set_cursor and
|
||||
zwp_tablet_tool_v2.set_cursor requests, but this request accepts a
|
||||
shape instead of contents in the form of a surface. Clients can mix
|
||||
set_cursor and set_shape requests.
|
||||
|
||||
The serial parameter must match the latest wl_pointer.enter or
|
||||
zwp_tablet_tool_v2.proximity_in serial number sent to the client.
|
||||
Otherwise the request will be ignored.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="serial number of the enter event"/>
|
||||
<arg name="shape" type="uint" enum="shape"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
Reference in New Issue
Block a user