diff --git a/include/input/keyboard.h b/include/input/keyboard.h index 2bd335a6..d080d30a 100644 --- a/include/input/keyboard.h +++ b/include/input/keyboard.h @@ -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 */ diff --git a/src/input/cursor.c b/src/input/cursor.c index 0cc25e15..538afd80 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -17,9 +17,10 @@ #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) { diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 2281cc7c..0bf6e290 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -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; diff --git a/src/interactive.c b/src/interactive.c index f552de8f..bd620edb 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -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; diff --git a/src/regions.c b/src/regions.c index f52a5619..112cc6e3 100644 --- a/src/regions.c +++ b/src/regions.c @@ -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 * diff --git a/src/workspaces.c b/src/workspaces.c index 7837fbe4..79f416b0 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -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 {