mirror of
https://github.com/labwc/labwc.git
synced 2026-04-10 08:21:07 -04:00
action: refresh keyboard focus when running actions with modifiers
Now that2f8afb2and98bf316are reverted, let's introduce another approach to prevent firefox to show its menu bar with Alt-* keybinds. In this commit, wl_keyboard.leave and wl_keyboard.enter events are sent to the client after a action is invoked if the compositor has sent key-release events of modifier keys. This prevents Firefox from showing its menu bar with Alt-* keybinds, while making sure applications like Blender see release events for modifier keys and their key state never get stuck.
This commit is contained in:
parent
bf9a2eeb62
commit
d29ee5eba3
4 changed files with 36 additions and 9 deletions
|
|
@ -148,6 +148,14 @@ struct seat {
|
||||||
|
|
||||||
struct lab_set bound_buttons;
|
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 {
|
struct {
|
||||||
bool active;
|
bool active;
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
14
src/action.c
14
src/action.c
|
|
@ -1301,4 +1301,18 @@ actions_run(struct view *activator, struct server *server,
|
||||||
" This is a BUG. Please report.", action->type);
|
" 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -503,12 +503,10 @@ miss_shift_toggle:
|
||||||
|
|
||||||
static enum lab_key_handled
|
static enum lab_key_handled
|
||||||
handle_compositor_keybindings(struct keyboard *keyboard,
|
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 seat *seat = keyboard->base.seat;
|
||||||
struct server *server = seat->server;
|
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;
|
bool locked = seat->server->session_lock_manager->locked;
|
||||||
|
|
||||||
key_state_set_pressed(event->keycode,
|
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 */
|
/* 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);
|
key_state_store_pressed_key_as_bound(event->keycode);
|
||||||
return LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED;
|
return LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
@ -542,13 +540,13 @@ handle_compositor_keybindings(struct keyboard *keyboard,
|
||||||
if (!locked) {
|
if (!locked) {
|
||||||
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
if (server->input_mode == LAB_INPUT_STATE_MENU) {
|
||||||
key_state_store_pressed_key_as_bound(event->keycode);
|
key_state_store_pressed_key_as_bound(event->keycode);
|
||||||
handle_menu_keys(server, &keyinfo.translated);
|
handle_menu_keys(server, &keyinfo->translated);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server->osd_state.cycle_view) {
|
if (server->osd_state.cycle_view) {
|
||||||
key_state_store_pressed_key_as_bound(event->keycode);
|
key_state_store_pressed_key_as_bound(event->keycode);
|
||||||
handle_cycle_view_key(server, &keyinfo);
|
handle_cycle_view_key(server, keyinfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -556,7 +554,7 @@ handle_compositor_keybindings(struct keyboard *keyboard,
|
||||||
/*
|
/*
|
||||||
* Handle compositor keybinds
|
* 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)) {
|
if (cur_keybind && (!locked || cur_keybind->allow_when_locked)) {
|
||||||
/*
|
/*
|
||||||
* Update key-state before action_run() because the action
|
* Update key-state before action_run() because the action
|
||||||
|
|
@ -585,8 +583,10 @@ handle_keybind_repeat(void *data)
|
||||||
.keycode = keyboard->keybind_repeat_keycode,
|
.keycode = keyboard->keybind_repeat_keycode,
|
||||||
.state = WL_KEYBOARD_KEY_STATE_PRESSED
|
.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;
|
int next_repeat_ms = 1000 / keyboard->keybind_repeat_rate;
|
||||||
wl_event_source_timer_update(keyboard->keybind_repeat,
|
wl_event_source_timer_update(keyboard->keybind_repeat,
|
||||||
next_repeat_ms);
|
next_repeat_ms);
|
||||||
|
|
@ -629,13 +629,15 @@ keyboard_key_notify(struct wl_listener *listener, void *data)
|
||||||
struct seat *seat = keyboard->base.seat;
|
struct seat *seat = keyboard->base.seat;
|
||||||
struct wlr_keyboard_key_event *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
struct wlr_seat *wlr_seat = seat->seat;
|
struct wlr_seat *wlr_seat = seat->seat;
|
||||||
|
struct keyinfo keyinfo = get_keyinfo(keyboard->wlr_keyboard, event->keycode);
|
||||||
|
|
||||||
idle_manager_notify_activity(seat->seat);
|
idle_manager_notify_activity(seat->seat);
|
||||||
|
|
||||||
/* any new press/release cancels current keybind repeat */
|
/* any new press/release cancels current keybind repeat */
|
||||||
keyboard_cancel_keybind_repeat(keyboard);
|
keyboard_cancel_keybind_repeat(keyboard);
|
||||||
|
|
||||||
enum lab_key_handled handled =
|
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) {
|
if (handled == LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED) {
|
||||||
return;
|
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_set_keyboard(wlr_seat, keyboard->wlr_keyboard);
|
||||||
wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
|
wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
|
||||||
event->keycode, event->state);
|
event->keycode, event->state);
|
||||||
|
seat->modifier_press_sent |= keyinfo.is_modifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -668,6 +668,8 @@ seat_focus(struct seat *seat, struct wlr_surface *surface, bool is_lock_surface)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seat->modifier_press_sent = false;
|
||||||
|
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
wlr_seat_keyboard_notify_clear_focus(seat->seat);
|
wlr_seat_keyboard_notify_clear_focus(seat->seat);
|
||||||
input_method_relay_set_focus(seat->input_method_relay, NULL);
|
input_method_relay_set_focus(seat->input_method_relay, NULL);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue