mirror of
				https://github.com/glfw/glfw.git
				synced 2025-10-31 04:32:26 +00:00 
			
		
		
		
	Wayland: Implement cursor-shape-v1 protocol
This commit is contained in:
		
							parent
							
								
									e7ea71be03
								
							
						
					
					
						commit
						69cc9fe0a8
					
				
							
								
								
									
										152
									
								
								deps/wayland/cursor-shape-v1.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								deps/wayland/cursor-shape-v1.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,152 @@ | ||||
| <?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="1"> | ||||
|     <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="1"> | ||||
|     <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 | ||||
|       </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"/> | ||||
|     </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> | ||||
							
								
								
									
										1182
									
								
								deps/wayland/tablet-unstable-v2.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1182
									
								
								deps/wayland/tablet-unstable-v2.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -105,6 +105,8 @@ if (GLFW_BUILD_WAYLAND) | ||||
|     generate_wayland_protocol("fractional-scale-v1.xml") | ||||
|     generate_wayland_protocol("xdg-activation-v1.xml") | ||||
|     generate_wayland_protocol("xdg-decoration-unstable-v1.xml") | ||||
|     generate_wayland_protocol("tablet-unstable-v2.xml") | ||||
|     generate_wayland_protocol("cursor-shape-v1.xml") | ||||
| endif() | ||||
| 
 | ||||
| if (WIN32 AND GLFW_BUILD_SHARED_LIBRARY) | ||||
|  | ||||
| @ -49,6 +49,8 @@ | ||||
| #include "fractional-scale-v1-client-protocol.h" | ||||
| #include "xdg-activation-v1-client-protocol.h" | ||||
| #include "idle-inhibit-unstable-v1-client-protocol.h" | ||||
| #include "tablet-unstable-v2-client-protocol.h" | ||||
| #include "cursor-shape-v1-client-protocol.h" | ||||
| 
 | ||||
| // NOTE: Versions of wayland-scanner prior to 1.17.91 named every global array of
 | ||||
| //       wl_interface pointers 'types', making it impossible to combine several unmodified
 | ||||
| @ -91,6 +93,14 @@ | ||||
| #include "idle-inhibit-unstable-v1-client-protocol-code.h" | ||||
| #undef types | ||||
| 
 | ||||
| #define types _glfw_tablet_types | ||||
| #include "tablet-unstable-v2-client-protocol-code.h" | ||||
| #undef types | ||||
| 
 | ||||
| #define types _glfw_cursor_shape_types | ||||
| #include "cursor-shape-v1-client-protocol-code.h" | ||||
| #undef types | ||||
| 
 | ||||
| static void wmBaseHandlePing(void* userData, | ||||
|                              struct xdg_wm_base* wmBase, | ||||
|                              uint32_t serial) | ||||
| @ -208,6 +218,13 @@ static void registryHandleGlobal(void* userData, | ||||
|                              &wp_fractional_scale_manager_v1_interface, | ||||
|                              1); | ||||
|     } | ||||
|     else if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) | ||||
|     { | ||||
|         _glfw.wl.cursorShapeManager = | ||||
|             wl_registry_bind(registry, name, | ||||
|                              &wp_cursor_shape_manager_v1_interface, | ||||
|                              1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void registryHandleGlobalRemove(void* userData, | ||||
| @ -988,6 +1005,10 @@ void _glfwTerminateWayland(void) | ||||
|         xdg_activation_v1_destroy(_glfw.wl.activationManager); | ||||
|     if (_glfw.wl.fractionalScaleManager) | ||||
|         wp_fractional_scale_manager_v1_destroy(_glfw.wl.fractionalScaleManager); | ||||
|     if (_glfw.wl.cursorShapeManager) | ||||
|         wp_cursor_shape_manager_v1_destroy(_glfw.wl.cursorShapeManager); | ||||
|     if (_glfw.wl.cursorShapeDevice) | ||||
|         wp_cursor_shape_device_v1_destroy(_glfw.wl.cursorShapeDevice); | ||||
|     if (_glfw.wl.registry) | ||||
|         wl_registry_destroy(_glfw.wl.registry); | ||||
|     if (_glfw.wl.display) | ||||
|  | ||||
| @ -129,7 +129,9 @@ struct wl_output; | ||||
| #define xdg_activation_v1_interface _glfw_xdg_activation_v1_interface | ||||
| #define xdg_activation_token_v1_interface _glfw_xdg_activation_token_v1_interface | ||||
| #define wl_surface_interface _glfw_wl_surface_interface | ||||
| #define wp_fractional_scale_v1_interface _glfw_wp_fractional_scale_v1_interface | ||||
| //#define wp_cursor_shape_manager_v1_interface _glfw_wp_cursor_shape_interface
 | ||||
| #define fractional _glfw_wp_fractional_scale_v1_interface | ||||
| 
 | ||||
| 
 | ||||
| #define GLFW_WAYLAND_WINDOW_STATE         _GLFWwindowWayland  wl; | ||||
| #define GLFW_WAYLAND_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl; | ||||
| @ -438,6 +440,8 @@ typedef struct _GLFWlibraryWayland | ||||
|     struct zwp_idle_inhibit_manager_v1*     idleInhibitManager; | ||||
|     struct xdg_activation_v1*               activationManager; | ||||
|     struct wp_fractional_scale_manager_v1*  fractionalScaleManager; | ||||
|     struct wp_cursor_shape_manager_v1*      cursorShapeManager; | ||||
|     struct wp_cursor_shape_device_v1*       cursorShapeDevice; | ||||
| 
 | ||||
|     _GLFWofferWayland*          offers; | ||||
|     unsigned int                offerCount; | ||||
| @ -609,6 +613,7 @@ typedef struct _GLFWcursorWayland | ||||
|     int                         width, height; | ||||
|     int                         xhot, yhot; | ||||
|     int                         currentImage; | ||||
|     int                         shape; | ||||
| } _GLFWcursorWayland; | ||||
| 
 | ||||
| GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform); | ||||
|  | ||||
| @ -51,6 +51,7 @@ | ||||
| #include "xdg-activation-v1-client-protocol.h" | ||||
| #include "idle-inhibit-unstable-v1-client-protocol.h" | ||||
| #include "fractional-scale-v1-client-protocol.h" | ||||
| #include "cursor-shape-v1-client-protocol.h" | ||||
| 
 | ||||
| #define GLFW_BORDER_SIZE    4 | ||||
| #define GLFW_CAPTION_HEIGHT 24 | ||||
| @ -1075,9 +1076,67 @@ static GLFWbool createNativeSurface(_GLFWwindow* window, | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
| 
 | ||||
| GLFWbool setCursorShape(int shape) { | ||||
|     int xdgShape = -1; | ||||
| 
 | ||||
|     switch (shape) | ||||
|     { | ||||
|         case GLFW_ARROW_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT; | ||||
|             break; | ||||
|         case GLFW_IBEAM_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT; | ||||
|             break; | ||||
|         case GLFW_CROSSHAIR_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR; | ||||
|             break; | ||||
|         case GLFW_POINTING_HAND_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER; | ||||
|             break; | ||||
|         case GLFW_RESIZE_EW_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE; | ||||
|             break; | ||||
|         case GLFW_RESIZE_NS_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE; | ||||
|             break; | ||||
|         case GLFW_RESIZE_NWSE_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE; | ||||
|             break; | ||||
|         case GLFW_RESIZE_NESW_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE; | ||||
|             break; | ||||
|         case GLFW_RESIZE_ALL_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALL_SCROLL; | ||||
|             break; | ||||
|         case GLFW_NOT_ALLOWED_CURSOR: | ||||
|             xdgShape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NOT_ALLOWED; | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     if (xdgShape == -1) | ||||
|     { | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
| 
 | ||||
|     wp_cursor_shape_device_v1_set_shape(_glfw.wl.cursorShapeDevice, | ||||
|         _glfw.wl.pointerEnterSerial,  | ||||
|         xdgShape); | ||||
| 
 | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
| 
 | ||||
| static void setCursorImage(_GLFWwindow* window, | ||||
|                            _GLFWcursorWayland* cursorWayland) | ||||
| { | ||||
|     if (_glfw.wl.cursorShapeDevice && cursorWayland->shape != 0) | ||||
|     { | ||||
|         GLFWbool ok = setCursorShape(cursorWayland->shape); | ||||
|         if (ok == GLFW_TRUE) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     struct itimerspec timer = {0}; | ||||
|     struct wl_cursor* wlCursor = cursorWayland->cursor; | ||||
|     struct wl_cursor_image* image; | ||||
| @ -1885,6 +1944,10 @@ static void seatHandleCapabilities(void* userData, | ||||
|     { | ||||
|         _glfw.wl.pointer = wl_seat_get_pointer(seat); | ||||
|         wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL); | ||||
|         if (_glfw.wl.cursorShapeManager)  | ||||
|         { | ||||
|             _glfw.wl.cursorShapeDevice = wp_cursor_shape_manager_v1_get_pointer(_glfw.wl.cursorShapeManager, _glfw.wl.pointer); | ||||
|         } | ||||
|     } | ||||
|     else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer) | ||||
|     { | ||||
| @ -2763,6 +2826,8 @@ GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor, | ||||
| 
 | ||||
| GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape) | ||||
| { | ||||
|     cursor->wl.shape = shape; | ||||
| 
 | ||||
|     const char* name = NULL; | ||||
| 
 | ||||
|     // Try the XDG names first
 | ||||
| @ -3064,7 +3129,8 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor) | ||||
|                 NULL, | ||||
|                 0, 0, | ||||
|                 0, 0, | ||||
|                 0 | ||||
|                 0, | ||||
|                 GLFW_ARROW_CURSOR | ||||
|             }; | ||||
| 
 | ||||
|             setCursorImage(window, &cursorWayland); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user