From f795f7e07fae4b5703785c75338b36a7d00f8599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Oct 2026 23:16:47 +0200 Subject: [PATCH] UI: A press and release in one event is a press only for the top screen Key ups go to every screen, so keys don't get stuck, and that included events that are a press and a release at once, like iOS's back swipe. So with settings open from the pause menu, a back swipe made the pause screen try to close too. It isn't on top, so finishDialog refused, but the screen had already stopped taking input, and once settings closed it was left on top, ignoring everything. Co-Authored-By: Claude Opus 5.5 (1M context) --- Common/UI/ScreenManager.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Common/UI/ScreenManager.cpp b/Common/UI/ScreenManager.cpp index f16960f32b..2ae10e113a 100644 --- a/Common/UI/ScreenManager.cpp +++ b/Common/UI/ScreenManager.cpp @@ -106,10 +106,13 @@ void ScreenManager::ProcessInputEvent(const QueuedEvent &event) { case QueuedEventType::KEY: { const KeyInput &key = event.key; - // Send key up to every screen layer, to avoid stuck keys. + // Send key up to every screen layer, to avoid stuck keys. A press and release in one (iOS's back swipe, + // the mouse wheel) is a press only for the top one, or every dialog below would act on it too. if (key.flags & KeyInputFlags::UP) { - for (auto &layer : stack_) { - layer.screen->key(key); + KeyInput upOnly = key; + upOnly.flags &= ~KeyInputFlags::DOWN; + for (size_t i = 0; i < stack_.size(); i++) { + stack_[i].screen->key(i == stack_.size() - 1 ? key : upOnly); } } else if (!stack_.empty()) { stack_.back().screen->key(key);