mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-19 16:21:44 +00:00
wayland: Add cursor-shape-v1 protocol support
This is the preferred method of handling the cursor shape on KDE 6 and likely other window managers going forward.
Manual backport of c2e9693
This commit is contained in:
@@ -64,6 +64,7 @@
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
#include "../../events/imKStoUCS.h"
|
||||
#include "../../events/SDL_keysym_to_scancode_c.h"
|
||||
#include "cursor-shape-v1-client-protocol.h"
|
||||
|
||||
/* Clamp the wl_seat version on older versions of libwayland. */
|
||||
#if SDL_WAYLAND_CHECK_VERSION(1, 21, 0)
|
||||
@@ -178,6 +179,17 @@ static SDL_bool Wayland_SurfaceHasActiveTouches(struct wl_surface *surface)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
void Wayland_CreateCursorShapeDevice(struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_VideoData *viddata = input->display;
|
||||
|
||||
if (viddata->cursor_shape_manager) {
|
||||
if (input->pointer && !input->cursor_shape) {
|
||||
input->cursor_shape = wp_cursor_shape_manager_v1_get_pointer(viddata->cursor_shape_manager, input->pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns SDL_TRUE if a key repeat event was due */
|
||||
static SDL_bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t elapsed)
|
||||
{
|
||||
@@ -1394,10 +1406,15 @@ static void seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
input->pointer = wl_seat_get_pointer(seat);
|
||||
SDL_memset(&input->pointer_curr_axis_info, 0, sizeof(input->pointer_curr_axis_info));
|
||||
input->display->pointer = input->pointer;
|
||||
Wayland_CreateCursorShapeDevice(input);
|
||||
wl_pointer_set_user_data(input->pointer, input);
|
||||
wl_pointer_add_listener(input->pointer, &pointer_listener,
|
||||
input);
|
||||
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) {
|
||||
if (input->cursor_shape) {
|
||||
wp_cursor_shape_device_v1_destroy(input->cursor_shape);
|
||||
input->cursor_shape = NULL;
|
||||
}
|
||||
wl_pointer_destroy(input->pointer);
|
||||
input->pointer = NULL;
|
||||
input->display->pointer = NULL;
|
||||
@@ -2532,6 +2549,10 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
|
||||
wl_keyboard_destroy(input->keyboard);
|
||||
}
|
||||
|
||||
if (input->cursor_shape) {
|
||||
wp_cursor_shape_device_v1_destroy(input->cursor_shape);
|
||||
}
|
||||
|
||||
if (input->pointer) {
|
||||
wl_pointer_destroy(input->pointer);
|
||||
}
|
||||
|
@@ -92,6 +92,7 @@ struct SDL_WaylandInput
|
||||
SDL_WaylandDataDevice *data_device;
|
||||
SDL_WaylandPrimarySelectionDevice *primary_selection_device;
|
||||
SDL_WaylandTextInput *text_input;
|
||||
struct wp_cursor_shape_device_v1 *cursor_shape;
|
||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||
SDL_WindowData *pointer_focus;
|
||||
SDL_WindowData *keyboard_focus;
|
||||
@@ -175,6 +176,8 @@ extern int Wayland_input_ungrab_keyboard(SDL_Window *window);
|
||||
extern void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager *tablet_manager);
|
||||
extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input);
|
||||
|
||||
extern void Wayland_CreateCursorShapeDevice(struct SDL_WaylandInput *input);
|
||||
|
||||
#endif /* SDL_waylandevents_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -41,6 +41,8 @@
|
||||
#include "wayland-cursor.h"
|
||||
#include "SDL_waylandmouse.h"
|
||||
|
||||
#include "cursor-shape-v1-client-protocol.h"
|
||||
|
||||
#include "SDL_hints.h"
|
||||
#include "../../SDL_hints_c.h"
|
||||
|
||||
@@ -481,8 +483,10 @@ static SDL_Cursor *Wayland_CreateSystemCursor(SDL_SystemCursor id)
|
||||
}
|
||||
cursor->driverdata = (void *)cdata;
|
||||
|
||||
cdata->surface = wl_compositor_create_surface(data->compositor);
|
||||
wl_surface_set_user_data(cdata->surface, NULL);
|
||||
if (!data->cursor_shape_manager) {
|
||||
cdata->surface = wl_compositor_create_surface(data->compositor);
|
||||
wl_surface_set_user_data(cdata->surface, NULL);
|
||||
}
|
||||
|
||||
/* Note that we can't actually set any other cursor properties, as this
|
||||
* is output-specific. See wayland_get_system_cursor for the rest!
|
||||
@@ -533,6 +537,55 @@ static void Wayland_FreeCursor(SDL_Cursor *cursor)
|
||||
SDL_free(cursor);
|
||||
}
|
||||
|
||||
static void Wayland_SetSystemCursorShape(struct SDL_WaylandInput *input, SDL_SystemCursor id)
|
||||
{
|
||||
Uint32 shape;
|
||||
|
||||
switch (id) {
|
||||
case SDL_SYSTEM_CURSOR_ARROW:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_IBEAM:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAIT:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_WAIT;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_CROSSHAIR:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAITARROW:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_PROGRESS;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENWSE:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENESW:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEWE:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENS:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEALL:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALL_SCROLL;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_NO:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NOT_ALLOWED;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_HAND:
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER;
|
||||
break;
|
||||
default:
|
||||
SDL_assert(0); /* Should never be here... */
|
||||
shape = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT;
|
||||
}
|
||||
|
||||
wp_cursor_shape_device_v1_set_shape(input->cursor_shape, input->pointer_enter_serial, shape);
|
||||
}
|
||||
|
||||
static int Wayland_ShowCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
@@ -550,7 +603,10 @@ static int Wayland_ShowCursor(SDL_Cursor *cursor)
|
||||
|
||||
/* TODO: High-DPI custom cursors? -flibit */
|
||||
if (!data->shm_data) {
|
||||
if (!wayland_get_system_cursor(d, data, &scale)) {
|
||||
if (input->cursor_shape) {
|
||||
Wayland_SetSystemCursorShape(input, data->system_cursor);
|
||||
return 0;
|
||||
} else if (!wayland_get_system_cursor(d, data, &scale)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -58,6 +58,7 @@
|
||||
#include "viewporter-client-protocol.h"
|
||||
#include "primary-selection-unstable-v1-client-protocol.h"
|
||||
#include "fractional-scale-v1-client-protocol.h"
|
||||
#include "cursor-shape-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
@@ -875,6 +876,11 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
|
||||
d->viewporter = wl_registry_bind(d->registry, id, &wp_viewporter_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "wp_fractional_scale_manager_v1") == 0) {
|
||||
d->fractional_scale_manager = wl_registry_bind(d->registry, id, &wp_fractional_scale_manager_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "wp_cursor_shape_manager_v1") == 0) {
|
||||
d->cursor_shape_manager = wl_registry_bind(d->registry, id, &wp_cursor_shape_manager_v1_interface, 1);
|
||||
if (d->input) {
|
||||
Wayland_CreateCursorShapeDevice(d->input);
|
||||
}
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
|
||||
Wayland_touch_create(d, id);
|
||||
@@ -1121,6 +1127,11 @@ static void Wayland_VideoCleanup(_THIS)
|
||||
data->fractional_scale_manager = NULL;
|
||||
}
|
||||
|
||||
if (data->cursor_shape_manager) {
|
||||
wp_cursor_shape_manager_v1_destroy(data->cursor_shape_manager);
|
||||
data->cursor_shape_manager = NULL;
|
||||
}
|
||||
|
||||
if (data->compositor) {
|
||||
wl_compositor_destroy(data->compositor);
|
||||
data->compositor = NULL;
|
||||
|
@@ -70,6 +70,7 @@ typedef struct
|
||||
} shell;
|
||||
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
|
||||
struct zwp_pointer_constraints_v1 *pointer_constraints;
|
||||
struct wp_cursor_shape_manager_v1 *cursor_shape_manager;
|
||||
struct wl_data_device_manager *data_device_manager;
|
||||
struct zwp_primary_selection_device_manager_v1 *primary_selection_device_manager;
|
||||
struct zxdg_decoration_manager_v1 *decoration_manager;
|
||||
|
Reference in New Issue
Block a user