From d5b7ef0c58523526c33c475f22b4cb4cdaa064f2 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 26 Jan 2026 18:19:55 -0600 Subject: [PATCH] Don't pump events in SdlGamepadKeyNavigation This can cause reentrancy issues by invoking Qt-based event processing while in the context of SDL (via libdecor's GTK loop). Fixes #1802 --- app/gui/sdlgamepadkeynavigation.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/gui/sdlgamepadkeynavigation.cpp b/app/gui/sdlgamepadkeynavigation.cpp index 88693b87..b346badd 100644 --- a/app/gui/sdlgamepadkeynavigation.cpp +++ b/app/gui/sdlgamepadkeynavigation.cpp @@ -51,7 +51,11 @@ void SdlGamepadKeyNavigation::enable() // on first init of the GC subsystem. We can't depend on them due to // overlapping lifetimes of SdlGamepadKeyNavigation instances, so we // will attach ourselves. - SDL_PumpEvents(); + // + // NB: We use SDL_JoystickUpdate() instead of SDL_PumpEvents() because + // the latter can do a bit more work that we want (like handling video + // events that we intentionally do not want to process yet). + SDL_JoystickUpdate(); SDL_FlushEvent(SDL_CONTROLLERDEVICEADDED); // Open all currently attached game controllers @@ -99,17 +103,19 @@ void SdlGamepadKeyNavigation::onPollingTimerFired() { SDL_Event event; + // Update joystick state without pumping other events (see enable() comment) + SDL_JoystickUpdate(); + // Discard any pending button events on the first poll to avoid picking up // stale input data from the stream session (like the quit combo). if (m_FirstPoll) { - SDL_PumpEvents(); SDL_FlushEvent(SDL_CONTROLLERBUTTONDOWN); SDL_FlushEvent(SDL_CONTROLLERBUTTONUP); - m_FirstPoll = false; } - while (SDL_PollEvent(&event)) { + // Peep events rather than polling to avoid calling SDL_PumpEvents() + while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 1) { switch (event.type) { case SDL_QUIT: // SDL may send us a quit event since we initialize