keyboard: cancel key repeat on vt change

...(calling `wlr_session_change_vt()`) because when the session is
switched, the access to the keyboard is lost and therefore the RELEASE
event will not be passed to the compositor.

Fixes bug whereby compositor crashes on VT change on FreeBSD.

Fixes #1424
This commit is contained in:
Johan Malm 2024-01-14 19:52:43 +00:00 committed by Johan Malm
parent e05bedb140
commit 774eb2170f

View file

@ -13,6 +13,12 @@
#include "view.h" #include "view.h"
#include "workspaces.h" #include "workspaces.h"
enum lab_key_handled {
LAB_KEY_HANDLED_FALSE = 0,
LAB_KEY_HANDLED_TRUE = 1,
LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED,
};
struct keysyms { struct keysyms {
const xkb_keysym_t *syms; const xkb_keysym_t *syms;
int nr_syms; int nr_syms;
@ -298,12 +304,14 @@ handle_key_release(struct server *server, uint32_t evdev_keycode)
} }
static bool static bool
handle_change_vt_key(struct server *server, struct keysyms *translated) handle_change_vt_key(struct server *server, struct keyboard *keyboard,
struct keysyms *translated)
{ {
for (int i = 0; i < translated->nr_syms; i++) { for (int i = 0; i < translated->nr_syms; i++) {
unsigned int vt = unsigned int vt =
translated->syms[i] - XKB_KEY_XF86Switch_VT_1 + 1; translated->syms[i] - XKB_KEY_XF86Switch_VT_1 + 1;
if (vt >= 1 && vt <= 12) { if (vt >= 1 && vt <= 12) {
keyboard_cancel_keybind_repeat(keyboard);
change_vt(server, vt); change_vt(server, vt);
return true; return true;
} }
@ -377,7 +385,7 @@ handle_cycle_view_key(struct server *server, struct keyinfo *keyinfo)
} }
} }
static bool static enum lab_key_handled
handle_compositor_keybindings(struct keyboard *keyboard, handle_compositor_keybindings(struct keyboard *keyboard,
struct wlr_keyboard_key_event *event) struct wlr_keyboard_key_event *event)
{ {
@ -395,9 +403,9 @@ 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, &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 true; return LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED;
} }
/* /*
@ -504,7 +512,13 @@ keyboard_key_notify(struct wl_listener *listener, void *data)
/* 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);
bool handled = handle_compositor_keybindings(keyboard, event); enum lab_key_handled handled =
handle_compositor_keybindings(keyboard, event);
if (handled == LAB_KEY_HANDLED_TRUE_AND_VT_CHANGED) {
return;
}
if (handled) { if (handled) {
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
start_keybind_repeat(seat->server, keyboard, event); start_keybind_repeat(seat->server, keyboard, event);