[Wayland] Inhibit compositor shortcuts

... with the dedicated wayland protocol.

This way, rofi can re-use compositor bindings. The canonical example is
window switching with Alt-Tab.
This commit is contained in:
lbonn 2024-02-27 14:09:18 +01:00
parent 2ddef0f8ac
commit d53738170c
3 changed files with 30 additions and 0 deletions

View file

@ -14,6 +14,7 @@ typedef enum {
WAYLAND_GLOBAL_COMPOSITOR,
WAYLAND_GLOBAL_SHM,
WAYLAND_GLOBAL_LAYER_SHELL,
WAYLAND_GLOBAL_KEYBOARD_SHORTCUTS_INHIBITOR,
WAYLAND_GLOBAL_CURSOR_SHAPE,
_WAYLAND_GLOBAL_SIZE,
} wayland_global_name;
@ -51,6 +52,8 @@ typedef struct {
struct zwlr_layer_shell_v1 *layer_shell;
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *kb_shortcuts_inhibit_manager;
struct wl_shm *shm;
size_t buffer_count;
struct {
@ -116,6 +119,7 @@ struct _wayland_seat {
#define WL_SHM_INTERFACE_VERSION 1
#define WL_SEAT_INTERFACE_VERSION 5
#define WL_LAYER_SHELL_INTERFACE_VERSION 1
#define WL_KEYBOARD_SHORTCUTS_INHIBITOR_INTERFACE_VERSION 1
#define WL_OUTPUT_INTERFACE_MIN_VERSION 2
#ifdef WL_OUTPUT_NAME_SINCE_VERSION

View file

@ -290,6 +290,7 @@ if wayland_enabled
protocols = files(
wayland_sys_protocols_dir + '/stable/xdg-shell/xdg-shell.xml',
wayland_sys_protocols_dir + '/unstable/primary-selection/primary-selection-unstable-v1.xml',
wayland_sys_protocols_dir + '/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml',
'protocols/wlr-foreign-toplevel-management-unstable-v1.xml',
'protocols/wlr-layer-shell-unstable-v1.xml',
)

View file

@ -65,6 +65,7 @@
#endif
#include "primary-selection-unstable-v1-protocol.h"
#include "wlr-layer-shell-unstable-v1-protocol.h"
#include "keyboard-shortcuts-inhibit-unstable-v1-protocol.h"
#define wayland_output_get_dpi(output, scale, dimension) \
((output)->current.physical_##dimension > 0 && (scale) > 0 \
@ -1257,6 +1258,8 @@ static void wayland_registry_handle_global(void *data,
struct wl_registry *registry,
uint32_t name, const char *interface,
uint32_t version) {
g_debug("wayland registry: interface %s", interface);
if (g_strcmp0(interface, wl_compositor_interface.name) == 0) {
wayland->global_names[WAYLAND_GLOBAL_COMPOSITOR] = name;
wayland->compositor =
@ -1267,6 +1270,11 @@ static void wayland_registry_handle_global(void *data,
wayland->layer_shell =
wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface,
MIN(version, WL_LAYER_SHELL_INTERFACE_VERSION));
} else if (g_strcmp0(interface, zwp_keyboard_shortcuts_inhibit_manager_v1_interface.name) == 0) {
wayland->global_names[WAYLAND_GLOBAL_KEYBOARD_SHORTCUTS_INHIBITOR] = name;
wayland->kb_shortcuts_inhibit_manager =
wl_registry_bind(registry, name, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface,
MIN(version, WL_KEYBOARD_SHORTCUTS_INHIBITOR_INTERFACE_VERSION));
} else if (g_strcmp0(interface, wl_shm_interface.name) == 0) {
wayland->global_names[WAYLAND_GLOBAL_SHM] = name;
wayland->shm = wl_registry_bind(registry, name, &wl_shm_interface,
@ -1337,6 +1345,10 @@ static void wayland_registry_handle_global_remove(void *data,
zwlr_layer_shell_v1_destroy(wayland->layer_shell);
wayland->layer_shell = NULL;
break;
case WAYLAND_GLOBAL_KEYBOARD_SHORTCUTS_INHIBITOR:
zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(wayland->kb_shortcuts_inhibit_manager);
wayland->kb_shortcuts_inhibit_manager = NULL;
break;
case WAYLAND_GLOBAL_SHM:
wl_shm_destroy(wayland->shm);
wayland->shm = NULL;
@ -1552,6 +1564,19 @@ static gboolean wayland_display_late_setup(void) {
zwlr_layer_surface_v1_add_listener(
wayland->wlr_surface, &wayland_layer_shell_surface_listener, NULL);
if (wayland->kb_shortcuts_inhibit_manager) {
g_debug("inhibit shortcuts from compositor");
GHashTableIter iter;
wayland_seat *seat;
g_hash_table_iter_init(&iter, wayland->seats);
while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&seat)) {
// we don't need to keep track of these, they will get inactive when the
// surface is destroyed
zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(wayland->kb_shortcuts_inhibit_manager,
wayland->surface, seat->seat);
}
}
wl_surface_add_listener(wayland->surface, &wayland_surface_interface,
wayland);
wl_surface_commit(wayland->surface);