wayland: track real keyboard modifiers in wl_state.current_mods

The seat keyboard may be the XWayland virtual keyboard when a client
has focus, which carries no modifier state.  Reading
seat->keyboard_state.keyboard->modifiers.depressed for button events
then yields 0 even when the user holds Alt, so frameMouseDown's
MOD_MASK check always fails and Alt+drag never starts.

Add current_mods to wl_compositor_state.  Update it from the real
keyboard in handle_keyboard_modifiers, which fires on every modifier
change from the physical device regardless of seat focus.  Use
wl_state.current_mods in handle_pointer_button to populate
u.button.state and to gate the client-forwarding suppression.
This commit is contained in:
lkn 2026-06-06 20:47:16 +02:00
parent 16e07f751c
commit 0b12c7ad71
3 changed files with 10 additions and 7 deletions

View File

@ -272,10 +272,7 @@ handle_pointer_button(struct wl_listener *listener, void *data)
case 0x112: wev.u.button.button = 2; break;
default: wev.u.button.button = (ev->button - 0x110) + 1; break;
}
{
struct wlr_keyboard *kb = wl_state.seat ? wl_state.seat->keyboard_state.keyboard : NULL;
wev.u.button.state = kb ? kb->modifiers.depressed : 0;
}
wev.u.button.state = wl_state.current_mods;
/* For WINGs views, resolve the child widget at click coordinates.
* Two cases:
* 1. fb->id >= 0x20000000 — fb IS a WINGs view frame_buf, use directly.
@ -334,9 +331,7 @@ handle_pointer_button(struct wl_listener *listener, void *data)
* will handle the event (move or resize), and the app must not see it. */
Bool forward_to_client = True;
if (ev->state == WLR_BUTTON_PRESSED && wl_state.seat) {
struct wlr_keyboard *_kb = wl_state.seat->keyboard_state.keyboard;
unsigned int _mods = _kb ? _kb->modifiers.depressed : 0;
if (_mods & wPreferences.modifier_mask) {
if (wl_state.current_mods & wPreferences.modifier_mask) {
double _sx, _sy;
struct wl_toplevel_view *_tv = NULL;
struct wlr_surface *_surf = view_surface_at(

View File

@ -105,4 +105,8 @@ handle_keyboard_modifiers(struct wl_listener *listener, void *data)
struct wlr_keyboard *kb = wl_state.seat->keyboard_state.keyboard;
if (!kb) return;
wlr_seat_keyboard_notify_modifiers(wl_state.seat, &kb->modifiers);
/* Cache the real keyboard's depressed modifiers so pointer button
* handlers can read them regardless of which keyboard the seat
* currently has focused (e.g. XWayland virtual keyboard). */
wl_state.current_mods = kb->modifiers.depressed;
}

View File

@ -399,6 +399,10 @@ struct wl_compositor_state {
/* Keyboard grab: when true, key events are queued for WMMaskEvent but not
* forwarded to Wayland clients (used by Alt-Tab cycling). */
bool keyboard_grabbed;
/* Current depressed modifier mask from the real keyboard, updated by
* handle_keyboard_modifiers. Used by handle_pointer_button to populate
* u.button.state so frameMouseDown can detect Alt/Super+drag. */
unsigned int current_mods;
};
extern struct wl_compositor_state wl_state;