From 1a291ab118dab4bcf0d3df0752125583c4594911 Mon Sep 17 00:00:00 2001 From: Tudor Brindus Date: Fri, 17 Apr 2020 13:55:44 -0400 Subject: [PATCH] wayland: add support for SDL_SetWindowGrab --- src/video/wayland/SDL_waylandevents.c | 59 +++++++++++++++++++++++++ src/video/wayland/SDL_waylandevents_c.h | 3 ++ src/video/wayland/SDL_waylandvideo.c | 1 + src/video/wayland/SDL_waylandwindow.c | 11 +++++ src/video/wayland/SDL_waylandwindow.h | 1 + 5 files changed, 75 insertions(+) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 2ec5b19a4b74a..90486595e3cbc 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -65,6 +65,7 @@ struct SDL_WaylandInput { struct wl_keyboard *keyboard; SDL_WaylandDataDevice *data_device; struct zwp_relative_pointer_v1 *relative_pointer; + struct zwp_confined_pointer_v1 *confined_pointer; SDL_WindowData *pointer_focus; SDL_WindowData *keyboard_focus; @@ -1263,6 +1264,64 @@ int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input) return 0; } +static void +confined_pointer_confined(void *data, + struct zwp_confined_pointer_v1 *confined_pointer) +{ +} + +static void +confined_pointer_unconfined(void *data, + struct zwp_confined_pointer_v1 *confined_pointer) +{ +} + +static const struct zwp_confined_pointer_v1_listener confined_pointer_listener = { + confined_pointer_confined, + confined_pointer_unconfined, +}; + +int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input) +{ + SDL_WindowData *w = window->driverdata; + SDL_VideoData *d = input->display; + struct zwp_confined_pointer_v1 *confined_pointer; + + if (!d->pointer_constraints) + return -1; + + if (!input->pointer) + return -1; + + /* A confine may already be active, in which case we should destroy it and + * create a new one. */ + if (input->confined_pointer) + Wayland_input_unconfine_pointer(input); + + confined_pointer = + zwp_pointer_constraints_v1_confine_pointer(d->pointer_constraints, + w->surface, + input->pointer, + NULL, + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + zwp_confined_pointer_v1_add_listener(confined_pointer, + &confined_pointer_listener, + window); + + input->confined_pointer = confined_pointer; + return 0; +} + +int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input) +{ + if (input->confined_pointer) { + zwp_confined_pointer_v1_destroy(input->confined_pointer); + input->confined_pointer = NULL; + } + + return 0; +} + #endif /* SDL_VIDEO_DRIVER_WAYLAND */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h index f8ba197d85808..96aaa397f03fd 100644 --- a/src/video/wayland/SDL_waylandevents_c.h +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -43,6 +43,9 @@ extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d); extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input); extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input); +extern int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input); +extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input); + extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id); extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d); diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index a3144b84e0123..68ae16e25864e 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -184,6 +184,7 @@ Wayland_CreateDevice(int devindex) device->ShowWindow = Wayland_ShowWindow; device->SetWindowFullscreen = Wayland_SetWindowFullscreen; device->MaximizeWindow = Wayland_MaximizeWindow; + device->SetWindowGrab = Wayland_SetWindowGrab; device->RestoreWindow = Wayland_RestoreWindow; device->SetWindowBordered = Wayland_SetWindowBordered; device->SetWindowSize = Wayland_SetWindowSize; diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 193040b7d2599..830faba780cc4 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -628,6 +628,17 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window) WAYLAND_wl_display_flush( viddata->display ); } +void +Wayland_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (grabbed) + Wayland_input_confine_pointer(window, data->input); + else + Wayland_input_unconfine_pointer(data->input); +} + int Wayland_CreateWindow(_THIS, SDL_Window *window) { SDL_WindowData *data; diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 322ce6378ea78..93ba121b84a7e 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -88,6 +88,7 @@ extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen); extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window); +extern void Wayland_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void Wayland_RestoreWindow(_THIS, SDL_Window * window); extern void Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern int Wayland_CreateWindow(_THIS, SDL_Window *window);