mirror of
https://github.com/encounter/SDL.git
synced 2025-12-09 05:27:48 +00:00
Implement keyboard grab support for Wayland
Use zwp_keyboard_shortcuts_inhibit_manager_v1 to allow SDL applications to capture system keyboard shortcuts like Alt+Tab when keyboard grab is enabled via SDL_HINT_GRAB_KEYBOARD.
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include "relative-pointer-unstable-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
#include "xdg-shell-unstable-v6-client-protocol.h"
|
||||
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef SDL_INPUT_LINUXEV
|
||||
#include <linux/input.h>
|
||||
@@ -1418,6 +1419,37 @@ int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_WindowData *w = window->driverdata;
|
||||
SDL_VideoData *d = input->display;
|
||||
|
||||
if (!d->key_inhibitor_manager)
|
||||
return -1;
|
||||
|
||||
if (w->key_inhibitor)
|
||||
return 0;
|
||||
|
||||
w->key_inhibitor =
|
||||
zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(d->key_inhibitor_manager,
|
||||
w->surface,
|
||||
input->seat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Wayland_input_ungrab_keyboard(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *w = window->driverdata;
|
||||
|
||||
if (w->key_inhibitor) {
|
||||
zwp_keyboard_shortcuts_inhibitor_v1_destroy(w->key_inhibitor);
|
||||
w->key_inhibitor = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -49,6 +49,9 @@ 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);
|
||||
|
||||
extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input);
|
||||
extern int Wayland_input_ungrab_keyboard(SDL_Window *window);
|
||||
|
||||
#endif /* SDL_waylandevents_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "xdg-shell-unstable-v6-client-protocol.h"
|
||||
#include "xdg-decoration-unstable-v1-client-protocol.h"
|
||||
#include "org-kde-kwin-server-decoration-manager-client-protocol.h"
|
||||
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
|
||||
|
||||
#define WAYLANDVID_DRIVER_NAME "wayland"
|
||||
|
||||
@@ -393,6 +394,8 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
Wayland_display_add_relative_pointer_manager(d, id);
|
||||
} else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
|
||||
Wayland_display_add_pointer_constraints(d, id);
|
||||
} else if (strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) {
|
||||
d->key_inhibitor_manager = wl_registry_bind(d->registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1);
|
||||
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
|
||||
d->data_device_manager = wl_registry_bind(d->registry, id, &wl_data_device_manager_interface, SDL_min(3, version));
|
||||
} else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
|
||||
@@ -493,6 +496,9 @@ Wayland_VideoQuit(_THIS)
|
||||
Wayland_display_destroy_pointer_constraints(data);
|
||||
Wayland_display_destroy_relative_pointer_manager(data);
|
||||
|
||||
if (data->key_inhibitor_manager)
|
||||
zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(data->key_inhibitor_manager);
|
||||
|
||||
if (data->xkb_context) {
|
||||
WAYLAND_xkb_context_unref(data->xkb_context);
|
||||
data->xkb_context = NULL;
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef struct {
|
||||
struct wl_data_device_manager *data_device_manager;
|
||||
struct zxdg_decoration_manager_v1 *decoration_manager;
|
||||
struct org_kde_kwin_server_decoration_manager *kwin_server_decoration_manager;
|
||||
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *key_inhibitor_manager;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
||||
@@ -636,10 +636,15 @@ Wayland_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
|
||||
{
|
||||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
if (grabbed)
|
||||
if (grabbed) {
|
||||
Wayland_input_confine_pointer(window, data->input);
|
||||
else
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE))
|
||||
Wayland_input_grab_keyboard(window, data->input);
|
||||
} else {
|
||||
Wayland_input_ungrab_keyboard(window);
|
||||
Wayland_input_unconfine_pointer(data->input);
|
||||
}
|
||||
}
|
||||
|
||||
int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef struct {
|
||||
struct zwp_locked_pointer_v1 *locked_pointer;
|
||||
struct zxdg_toplevel_decoration_v1 *server_decoration;
|
||||
struct org_kde_kwin_server_decoration *kwin_server_decoration;
|
||||
struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
struct qt_extended_surface *extended_surface;
|
||||
|
||||
Reference in New Issue
Block a user