]> git.mdlowis.com Git - proto/labwc.git/commitdiff
keyboard: add keyboard_get_all_modifiers()
authorConsolatis <35009135+Consolatis@users.noreply.github.com>
Fri, 10 Jan 2025 10:02:58 +0000 (11:02 +0100)
committerHiroaki Yamamoto <hrak1529@gmail.com>
Sun, 12 Jan 2025 21:28:37 +0000 (06:28 +0900)
And make mousebind handlers use that one.
Also remove keyboard_any_modifiers_pressed() and replace its usage
with the new function.

Without this patch we would only request the modifier state of the
keyboard group which makes mousebinds involving keyboard modifiers
break for virtual keyboards like when using wayvnc. Same story for
hiding the workspace overlay or snapping to regions.

Fixes: #2511
include/input/keyboard.h
src/input/cursor.c
src/input/keyboard.c
src/interactive.c
src/regions.c
src/workspaces.c

index 2bd335a6203157723428bf1ada186b54b994358b..d080d30a94f954a7754066ccf040bc3774dc94d4 100644 (file)
@@ -22,6 +22,6 @@ void keyboard_update_layout(struct seat *seat, xkb_layout_index_t layout);
 void keyboard_cancel_keybind_repeat(struct keyboard *keyboard);
 void keyboard_cancel_all_keybind_repeats(struct seat *seat);
 
-bool keyboard_any_modifiers_pressed(struct wlr_keyboard *keyboard);
+uint32_t keyboard_get_all_modifiers(struct seat *seat);
 
 #endif /* LABWC_KEYBOARD_H */
index 0cc25e15824da03f2d56b5d0f731f1d6ef0da4cd..538afd80d2cb8712cf123091109da863f5b6480f 100644 (file)
 #include "dnd.h"
 #include "idle.h"
 #include "input/gestures.h"
-#include "input/touch.h"
+#include "input/keyboard.h"
 #include "input/tablet.h"
 #include "input/tablet-tool.h"
+#include "input/touch.h"
 #include "labwc.h"
 #include "layers.h"
 #include "menu/menu.h"
@@ -892,9 +893,7 @@ handle_release_mousebinding(struct server *server,
        }
 
        struct mousebind *mousebind;
-
-       uint32_t modifiers = wlr_keyboard_get_modifiers(
-                       &server->seat.keyboard_group->keyboard);
+       uint32_t modifiers = keyboard_get_all_modifiers(&server->seat);
 
        wl_list_for_each(mousebind, &rc.mousebinds, link) {
                if (ssd_part_contains(mousebind->context, ctx->type)
@@ -961,9 +960,7 @@ handle_press_mousebinding(struct server *server, struct cursor_context *ctx,
        struct mousebind *mousebind;
        bool double_click = is_double_click(rc.doubleclick_time, button, ctx);
        bool consumed_by_frame_context = false;
-
-       uint32_t modifiers = wlr_keyboard_get_modifiers(
-                       &server->seat.keyboard_group->keyboard);
+       uint32_t modifiers = keyboard_get_all_modifiers(&server->seat);
 
        wl_list_for_each(mousebind, &rc.mousebinds, link) {
                if (ssd_part_contains(mousebind->context, ctx->type)
@@ -1287,9 +1284,7 @@ handle_cursor_axis(struct server *server, struct cursor_context *ctx,
 {
        struct mousebind *mousebind;
        bool handled = false;
-
-       uint32_t modifiers = wlr_keyboard_get_modifiers(
-                       &server->seat.keyboard_group->keyboard);
+       uint32_t modifiers = keyboard_get_all_modifiers(&server->seat);
 
        enum direction direction = LAB_DIRECTION_INVALID;
        if (event->orientation == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
index 2281cc7cebda35ad30ad0f674913574abe1c516c..0bf6e290bbb223ed96427b9393c848754d25b030 100644 (file)
@@ -54,17 +54,30 @@ change_vt(struct server *server, unsigned int vt)
        wlr_session_change_vt(server->session, vt);
 }
 
-bool
-keyboard_any_modifiers_pressed(struct wlr_keyboard *keyboard)
+uint32_t
+keyboard_get_all_modifiers(struct seat *seat)
 {
-       xkb_mod_index_t i;
-       for (i = 0; i < xkb_keymap_num_mods(keyboard->keymap); i++) {
-               if (xkb_state_mod_index_is_active(keyboard->xkb_state,
-                               i, XKB_STATE_MODS_DEPRESSED)) {
-                       return true;
+       /*
+        * As virtual keyboards like used by wayvnc are not part of the keyboard group,
+        * we need to additionally get the modifiers of the virtual keyboards in addition
+        * to the physical ones in the keyboard group. This ensures that mousebinds with
+        * keyboard modifiers are detected correctly when using for example a VNC client
+        * via wayvnc to control labwc. This function also gets called to decide when to
+        * hide the window switcher and workspace OSDs and to indicate if the user wants
+        * to snap a window to a region during a window move operation.
+        */
+       struct input *input;
+       uint32_t modifiers = wlr_keyboard_get_modifiers(&seat->keyboard_group->keyboard);
+       wl_list_for_each(input, &seat->inputs, link) {
+               if (input->wlr_input_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
+                       continue;
+               }
+               struct keyboard *kb = wl_container_of(input, kb, base);
+               if (kb->is_virtual) {
+                       modifiers |= wlr_keyboard_get_modifiers(kb->wlr_keyboard);
                }
        }
-       return false;
+       return modifiers;
 }
 
 static void
@@ -139,7 +152,7 @@ keyboard_modifiers_notify(struct wl_listener *listener, void *data)
                                        == LAB_INPUT_STATE_WINDOW_SWITCHER;
 
        if (window_switcher_active || seat->workspace_osd_shown_by_modifier) {
-               if (!keyboard_any_modifiers_pressed(wlr_keyboard)) {
+               if (!keyboard_get_all_modifiers(seat)) {
                        if (window_switcher_active) {
                                if (key_state_nr_bound_keys()) {
                                        should_cancel_cycling_on_next_key_release = true;
index f552de8fb0e743a6376db7fb238f8f544342e1af..bd620edb894d2cc28424050adee5dd83d0faeac8 100644 (file)
@@ -95,8 +95,7 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
                }
 
                /* Prevent region snapping when just moving via A-Left mousebind */
-               struct wlr_keyboard *keyboard = &seat->keyboard_group->keyboard;
-               seat->region_prevent_snap = keyboard_any_modifiers_pressed(keyboard);
+               seat->region_prevent_snap = keyboard_get_all_modifiers(seat);
 
                cursor_shape = LAB_CURSOR_GRAB;
                break;
index f52a56197d34226969b9dc20939eae989a2b5ad0..112cc6e3c96b0249fc57b742bf3bda2d062724c7 100644 (file)
@@ -25,8 +25,7 @@ regions_should_snap(struct server *server)
                return false;
        }
 
-       struct wlr_keyboard *keyboard = &server->seat.keyboard_group->keyboard;
-       return keyboard_any_modifiers_pressed(keyboard);
+       return keyboard_get_all_modifiers(&server->seat);
 }
 
 struct region *
index 7837fbe4449e97601644045fb22b6fc6f65ff937..79f416b049cb35ce80b7473c097da226ed4e30d7 100644 (file)
@@ -287,8 +287,7 @@ _osd_show(struct server *server)
                        wlr_scene_node_set_enabled(&output->workspace_osd->node, true);
                }
        }
-       struct wlr_keyboard *keyboard = &server->seat.keyboard_group->keyboard;
-       if (keyboard_any_modifiers_pressed(keyboard)) {
+       if (keyboard_get_all_modifiers(&server->seat)) {
                /* Hidden by release of all modifiers */
                server->seat.workspace_osd_shown_by_modifier = true;
        } else {