From 20b8ca1601a8a80770110860ae70d4487c95081b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 12 Aug 2022 16:13:25 +0200 Subject: [PATCH] input: ignore pointer motion events on unknown surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases, the compositor sends a pointer enter event with a NULL surface. It’s unclear if this is a compositor bug, or a race (where the compositor sends an enter event on a CSD surface at the same time foot unmaps the CSDs). Regardless, this causes seat->mouse_focus to be unset, which triggers a crash in foot on the next pointer motion event. This patch does two things: a) log a warning when we receive a pointer event with a NULL surface b) ignore motion events where seat->mouse_focus is NULL --- CHANGELOG.md | 3 +++ input.c | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c10be50..5fa35a63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,9 @@ ### Fixed * Compiling against wayland-protocols < 1.25 +* Crash on buggy compositors (GNOME) that sometimes send pointer-enter + events with a NULL surface. Foot now ignores these events, and the + subsequent motion and leave events. ### Security diff --git a/input.c b/input.c index 847ff6af..50336679 100644 --- a/input.c +++ b/input.c @@ -1709,11 +1709,9 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { - xassert(surface != NULL); - xassert(serial != 0); - - if (surface == NULL) { + if (unlikely(surface == NULL)) { /* Seen on mutter-3.38 */ + LOG_WARN("compositor sent pointer_enter event with a NULL surface"); return; } @@ -1866,6 +1864,16 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, struct seat *seat = data; struct wayland *wayl = seat->wayl; struct terminal *term = seat->mouse_focus; + + if (unlikely(term == NULL)) { + /* Typically happens when the compositor sent a pointer enter + * event with a NULL surface - see wl_pointer_enter(). + * + * In this case, we never set seat->mouse_focus (since we + * can’t map the enter event to a specific window). */ + return; + } + struct wl_window *win = term->window; LOG_DBG("pointer_motion: pointer=%p, x=%d, y=%d", (void *)wl_pointer,