From 7787bb46e0561dff2aa9ae7b248ffaef81088d8c Mon Sep 17 00:00:00 2001 From: Gaven Rendell Date: Fri, 2 Apr 2021 13:40:01 -0400 Subject: [PATCH 1/3] Handle mod key edge-cases in tiling WMs This commit ignores keypresses when the mod key is held. The reasoning is that an odd interaction happens between SDL applications and tiling window managers. Tiling window managers like Xmonad and i3 usually use the mod ("windows") key and a number to change workspaces. When changing workspaces, however, the WMs still send the number key through instead of "eating" it. It's not clear why, exactly, but it seems universal. Mod+1 -> Goes to workspace #1 Mod+2 -> Goes to workspace #2 ... Mod+9 -> Goes to workspace #9 Most applications don't even see the number key being sent, so if you move to workspace 1, Firefox won't type "1" into the browser bar, Vim won't type "1" into your file, etc. But SDL applications, for whatever reason, DO see this keydown. Of course, they'll handle it like a regular key press. So if you move to workspace 1, which contains OpenRCT, it inadvertently toggles x-ray mode. I first found this bug in another SDL game, The Powder Toy. After some discussion with the devs, they fixed it like this, by ignoring keydown events when the mod key is pressed, since the mod key is reserved for the window manager anyway. It works well and should be in the next release. https://github.com/The-Powder-Toy/The-Powder-Toy/compare/c7619387ace6a24c4bd31e6899073ef3a91bcf7a...93b920a57f4d3843a8e6234e360fcf5e919181a6 I did the same thing here. --- contributors.md | 1 + src/openrct2-ui/UiContext.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/contributors.md b/contributors.md index 25c4082a91..34c3d18bde 100644 --- a/contributors.md +++ b/contributors.md @@ -178,6 +178,7 @@ The following people are not part of the development team, but have been contrib * (ocalhoun6) * Sean Payne (seanmajorpayne) * Soham Roy (sohamroy19) +* Gaven Rendell (Rendello) ## Toolchain * (Balletie) - macOS diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 9031f447a1..12faf27b7a 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -523,6 +523,12 @@ public: #endif case SDL_KEYDOWN: { + // Ignore keydowns when mod is held. Handles edge cases + // where window managers don't eat the keypresses. + if (SDL_GetModState() & KMOD_GUI) + { + break; + } _textComposition.HandleMessage(&e); auto ie = GetInputEventFromSDLEvent(e); ie.State = InputEventState::Down; From 33fa31e6d0b2fd2f4ff899851eca143e5a2358a5 Mon Sep 17 00:00:00 2001 From: Gaven Rendell Date: Fri, 2 Apr 2021 20:14:56 -0400 Subject: [PATCH 2/3] Exclude Win/Mac from ignoring mod key --- src/openrct2-ui/UiContext.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 12faf27b7a..8ef79e62a5 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -523,12 +523,15 @@ public: #endif case SDL_KEYDOWN: { - // Ignore keydowns when mod is held. Handles edge cases - // where window managers don't eat the keypresses. +#if !(defined(__MACOSX__) || defined(__WINDOWS__)) + // Ignore winkey keydowns. Handles edge case where *NIX + // tiling window managers don't eat the keypresses when + // changing workspaces. if (SDL_GetModState() & KMOD_GUI) { break; } +#endif _textComposition.HandleMessage(&e); auto ie = GetInputEventFromSDLEvent(e); ie.State = InputEventState::Down; From 86cf0dc916d0d6430c0a6e6e9be12bd92255b9d3 Mon Sep 17 00:00:00 2001 From: Gaven Rendell Date: Sun, 4 Apr 2021 13:00:18 -0400 Subject: [PATCH 3/3] Remove Windows check --- src/openrct2-ui/UiContext.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 8ef79e62a5..b5510dec5e 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -523,10 +523,10 @@ public: #endif case SDL_KEYDOWN: { -#if !(defined(__MACOSX__) || defined(__WINDOWS__)) - // Ignore winkey keydowns. Handles edge case where *NIX - // tiling window managers don't eat the keypresses when - // changing workspaces. +#ifndef __MACOSX__ + // Ignore winkey keydowns. Handles edge case where tiling + // window managers don't eat the keypresses when changing + // workspaces. if (SDL_GetModState() & KMOD_GUI) { break;