From e139749b5c7a43c4a5c5753ab590fb34a9588f50 Mon Sep 17 00:00:00 2001 From: Zardshard <101750307+Zardshard@users.noreply.github.com> Date: Thu, 13 Apr 2023 12:06:21 -0400 Subject: [PATCH] Simulate all keys being released when when game loses focus (#13336) --- src/client/game.cpp | 26 ++++++++++++++++++-------- src/client/inputhandler.h | 20 ++++++++++++++++++++ src/client/joystick_controller.h | 6 ++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/client/game.cpp b/src/client/game.cpp index ac87fc9c7..280a397f0 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1005,6 +1005,7 @@ private: bool m_invert_mouse = false; bool m_first_loop_after_window_activation = false; bool m_camera_offset_changed = false; + bool m_game_focused; bool m_does_lost_focus_pause_game = false; @@ -1965,20 +1966,29 @@ void Game::processUserInput(f32 dtime) { // Reset input if window not active or some menu is active if (!device->isWindowActive() || isMenuActive() || guienv->hasFocus(gui_chat_console)) { - input->clear(); + if(m_game_focused) { + m_game_focused = false; + infostream << "Game lost focus" << std::endl; + input->releaseAllKeys(); + } else { + input->clear(); + } #ifdef HAVE_TOUCHSCREENGUI g_touchscreengui->hide(); #endif - } + } else { #ifdef HAVE_TOUCHSCREENGUI - else if (g_touchscreengui) { - /* on touchscreengui step may generate own input events which ain't - * what we want in case we just did clear them */ - g_touchscreengui->show(); - g_touchscreengui->step(dtime); - } + if (g_touchscreengui) { + /* on touchscreengui step may generate own input events which ain't + * what we want in case we just did clear them */ + g_touchscreengui->show(); + g_touchscreengui->step(dtime); + } #endif + m_game_focused = true; + } + if (!guienv->hasFocus(gui_chat_console) && gui_chat_console->isOpen()) { gui_chat_console->closeConsoleAtOnce(); } diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index 3db105c51..8e1e75fcb 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -124,6 +124,13 @@ public: push_back(key); } + void append(const KeyList &other) + { + for (const KeyPress &key : other) { + set(key); + } + } + bool operator[](const KeyPress &key) const { return find(key) != end(); } }; @@ -178,6 +185,12 @@ public: mouse_wheel = 0; } + void releaseAllKeys() + { + keyWasReleased.append(keyIsDown); + keyIsDown.clear(); + } + void clearWasKeyPressed() { keyWasPressed.clear(); @@ -263,6 +276,7 @@ public: virtual void step(float dtime) {} virtual void clear() {} + virtual void releaseAllKeys() {} JoystickController joystick; KeyCache keycache; @@ -395,6 +409,12 @@ public: m_receiver->clearInput(); } + void releaseAllKeys() + { + joystick.releaseAllKeys(); + m_receiver->releaseAllKeys(); + } + private: MyEventReceiver *m_receiver = nullptr; v2s32 m_mousepos; diff --git a/src/client/joystick_controller.h b/src/client/joystick_controller.h index cbc60886c..98486df43 100644 --- a/src/client/joystick_controller.h +++ b/src/client/joystick_controller.h @@ -109,6 +109,12 @@ public: bool handleEvent(const irr::SEvent::SJoystickEvent &ev); void clear(); + void releaseAllKeys() + { + m_keys_released |= m_keys_down; + m_keys_down.reset(); + } + bool wasKeyDown(GameKeyType b) { bool r = m_past_keys_pressed[b];