From a16029e7c9c4ca6d71120f19632e897671260bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 25 Jun 2022 23:05:41 +0200 Subject: [PATCH] =?UTF-8?q?input:=20ignore=20=E2=80=9Ckeyboard=20key?= =?UTF-8?q?=E2=80=9D=20events=20on=20seats=20without=20keyboard=20focus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two ways this can happen: 1. The compositor did not send a “keyboard enter” event before sending the key release event. 2. The compositor did send a “keyboard enter” event, but did so before sending a “keyboard map” event. In this case, the seat’s XKB context hasn’t yet been set, and foot ignores the “keyboard enter” event. Regardless of the root cause, this causes foot to crash because the seat instance in foot isn’t able to track which terminal window instance is being focused. While this is a compositor bug, it still makes sense to detect this in foot, and ignore such events, to ensure the user doesn’t lose any work. Closes #1097 --- CHANGELOG.md | 3 +++ input.c | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dec74bc1..f2d84b72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,9 +80,12 @@ * Workaround for buggy compositors (e.g. some versions of GNOME) allowing drag-and-drops even though foot has reported it does not support the offered mime-types ([#1092][1092]). +* Crash when compositor sends a _”keyboard key”_ event without a prior + _”keyboard enter”_ event ([#1097][1097]). [1055]: https://codeberg.org/dnkl/foot/issues/1055 [1092]: https://codeberg.org/dnkl/foot/issues/1092 +[1097]: https://codeberg.org/dnkl/foot/issues/1092 ### Security diff --git a/input.c b/input.c index fca46050..cd2608fd 100644 --- a/input.c +++ b/input.c @@ -1572,6 +1572,18 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { struct seat *seat = data; + + if (unlikely(seat->kbd_focus == NULL)) { + LOG_WARN( + "compositor sent 'keyboard key %s' event on seat %s " + "without a prior 'keyboard enter' event", + (state == WL_KEYBOARD_KEY_STATE_PRESSED + ? "pressed" + : "released"), + seat->name); + return; + } + key_press_release(seat, seat->kbd_focus, serial, key + 8, state); }