diff --git a/include/labwc.h b/include/labwc.h index 6e5d7fdd..53fc3995 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -148,6 +148,14 @@ struct seat { struct lab_set bound_buttons; + /* + * True when key-press events for any modifier keys has been sent to + * the client after the last wl_keyboard.enter event. This is used to + * check whether we should send wl_keyboard.{leave,enter} action + * invocations. See actions_run() for details. + */ + bool modifier_press_sent; + struct { bool active; struct { diff --git a/src/action.c b/src/action.c index ce4f077f..40cbbf40 100644 --- a/src/action.c +++ b/src/action.c @@ -1301,4 +1301,18 @@ actions_run(struct view *activator, struct server *server, " This is a BUG. Please report.", action->type); } } + + /* + * We send wl_keyboard.{leave,enter} to the clint when we have sent + * key-press events to it since the last wl_keyboard.leave event. + * This prevents firefox to show its menu bar when a keybind with + * Alt key is executed. + */ + struct seat *seat = &server->seat; + if (seat->modifier_press_sent) { + struct wlr_surface *focused_surface = + seat->seat->keyboard_state.focused_surface; + seat_focus_surface(seat, NULL); + seat_focus_surface(seat, focused_surface); + } } diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 78e31881..2eeb6b9c 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -503,12 +503,10 @@ miss_shift_toggle: static enum lab_key_handled handle_compositor_keybindings(struct keyboard *keyboard, - struct wlr_keyboard_key_event *event) + struct keyinfo *keyinfo, struct wlr_keyboard_key_event *event) { struct seat *seat = keyboard->base.seat; struct server *server = seat->server; - struct wlr_keyboard *wlr_keyboard = keyboard->wlr_keyboard; - struct keyinfo keyinfo = get_keyinfo(wlr_keyboard, event->keycode); bool locked = seat->server->session_lock_manager->locked; key_state_set_pressed(event->keycode, @@ -529,7 +527,7 @@ handle_compositor_keybindings(struct keyboard *keyboard, } /* Catch C-A-F1 to C-A-F12 to change tty */ - if (handle_change_vt_key(server, keyboard, &keyinfo.translated)) { + if (handle_change_vt_key(server, keyboard, &keyinfo->translated)) { key_state_store_pressed_key_as_bound(event->keycode); return LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED; } @@ -542,13 +540,13 @@ handle_compositor_keybindings(struct keyboard *keyboard, if (!locked) { if (server->input_mode == LAB_INPUT_STATE_MENU) { key_state_store_pressed_key_as_bound(event->keycode); - handle_menu_keys(server, &keyinfo.translated); + handle_menu_keys(server, &keyinfo->translated); return true; } if (server->osd_state.cycle_view) { key_state_store_pressed_key_as_bound(event->keycode); - handle_cycle_view_key(server, &keyinfo); + handle_cycle_view_key(server, keyinfo); return true; } } @@ -556,7 +554,7 @@ handle_compositor_keybindings(struct keyboard *keyboard, /* * Handle compositor keybinds */ - cur_keybind = match_keybinding(server, &keyinfo, keyboard->is_virtual); + cur_keybind = match_keybinding(server, keyinfo, keyboard->is_virtual); if (cur_keybind && (!locked || cur_keybind->allow_when_locked)) { /* * Update key-state before action_run() because the action @@ -585,8 +583,10 @@ handle_keybind_repeat(void *data) .keycode = keyboard->keybind_repeat_keycode, .state = WL_KEYBOARD_KEY_STATE_PRESSED }; + struct keyinfo keyinfo = + get_keyinfo(keyboard->wlr_keyboard, event.keycode); - handle_compositor_keybindings(keyboard, &event); + handle_compositor_keybindings(keyboard, &keyinfo, &event); int next_repeat_ms = 1000 / keyboard->keybind_repeat_rate; wl_event_source_timer_update(keyboard->keybind_repeat, next_repeat_ms); @@ -629,13 +629,15 @@ keyboard_key_notify(struct wl_listener *listener, void *data) struct seat *seat = keyboard->base.seat; struct wlr_keyboard_key_event *event = data; struct wlr_seat *wlr_seat = seat->seat; + struct keyinfo keyinfo = get_keyinfo(keyboard->wlr_keyboard, event->keycode); + idle_manager_notify_activity(seat->seat); /* any new press/release cancels current keybind repeat */ keyboard_cancel_keybind_repeat(keyboard); enum lab_key_handled handled = - handle_compositor_keybindings(keyboard, event); + handle_compositor_keybindings(keyboard, &keyinfo, event); if (handled == LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED) { return; @@ -655,6 +657,7 @@ keyboard_key_notify(struct wl_listener *listener, void *data) wlr_seat_set_keyboard(wlr_seat, keyboard->wlr_keyboard); wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, event->keycode, event->state); + seat->modifier_press_sent |= keyinfo.is_modifier; } } diff --git a/src/seat.c b/src/seat.c index f87cc6e9..ef179fd0 100644 --- a/src/seat.c +++ b/src/seat.c @@ -668,6 +668,8 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, bool is_lock_surface) return; } + seat->modifier_press_sent = false; + if (!surface) { wlr_seat_keyboard_notify_clear_focus(seat->seat); input_method_relay_set_focus(seat->input_method_relay, NULL);