From 17c4e7a2ff9869a09ee9b8928efef4a3ee029ea8 Mon Sep 17 00:00:00 2001 From: phantom10111 Date: Thu, 4 Apr 2024 09:15:07 +0200 Subject: [PATCH] Reset input redirection on screen change It's possible for LUA to redirect input and not bring it back when screen is ending (and there are existing bugs like this in Simply Love). Considering that each screen is a separate entity, it seems like this shouldn't be possible and each screen should handle redirection separately. Split redirection state per each screen in the stack and clear it once screen is ending. --- src/Screen.cpp | 3 +++ src/ScreenManager.cpp | 22 +++++++++++++--------- src/ScreenManager.h | 7 ------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Screen.cpp b/src/Screen.cpp index c63a259bd0..be254d134a 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -106,6 +106,9 @@ void Screen::EndScreen() { this->PlayCommand( "End" ); m_bRunning = false; + + m_InputCallbacks.clear(); + m_DelayedCallbackRemovals.clear(); } void Screen::Update( float fDeltaTime ) diff --git a/src/ScreenManager.cpp b/src/ScreenManager.cpp index e0506e7b74..a5c6d919a4 100644 --- a/src/ScreenManager.cpp +++ b/src/ScreenManager.cpp @@ -96,12 +96,20 @@ namespace ScreenManagerUtil * and was given to us for use, and it's not ours to free. */ bool m_bDeleteWhenDone; + // m_input_redirected exists to allow the theme to prevent input being + // passed to the normal Screen::Input function, on a per-player basis. + // Input is still passed to lua callbacks, so it's intended for the case + // where someone has a custom menu on a screen and needs to disable normal + // input for navigating the custom menu to work. -Kyz + bool m_input_redirected[NUM_PLAYERS]; + ScreenMessage m_SendOnPop; LoadedScreen() { m_pScreen = nullptr; m_bDeleteWhenDone = true; + ZERO( m_input_redirected ); m_SendOnPop = SM_None; } }; @@ -365,20 +373,15 @@ bool ScreenManager::IsStackedScreen( const Screen *pScreen ) const bool ScreenManager::get_input_redirected(PlayerNumber pn) { - if(pn >= m_input_redirected.size()) - { + if(g_ScreenStack.empty() || pn < 0 || pn >= NUM_PLAYERS) return false; - } - return m_input_redirected[pn]; + return g_ScreenStack.back().m_input_redirected[pn]; } void ScreenManager::set_input_redirected(PlayerNumber pn, bool redir) { - while(pn >= m_input_redirected.size()) - { - m_input_redirected.push_back(false); - } - m_input_redirected[pn]= redir; + if(!g_ScreenStack.empty() && pn >= 0 && pn < NUM_PLAYERS) + g_ScreenStack.back().m_input_redirected[pn]= redir; } /* Pop the top screen off the stack, sending SM_LoseFocus messages and @@ -395,6 +398,7 @@ ScreenMessage ScreenManager::PopTopScreenInternal( bool bSendLoseFocus ) if( bSendLoseFocus ) ls.m_pScreen->HandleScreenMessage( SM_LoseFocus ); ls.m_pScreen->EndScreen(); + ZERO( ls.m_input_redirected ); if( g_setPersistantScreens.find(ls.m_pScreen->GetName()) != g_setPersistantScreens.end() ) { diff --git a/src/ScreenManager.h b/src/ScreenManager.h index 67860fee75..c3d443d542 100644 --- a/src/ScreenManager.h +++ b/src/ScreenManager.h @@ -93,13 +93,6 @@ private: // It's "AfterInput" because the debug overlay carries out actions in Input. bool m_bReloadOverlayScreensAfterInput; - // m_input_redirected exists to allow the theme to prevent input being - // passed to the normal Screen::Input function, on a per-player basis. - // Input is still passed to lua callbacks, so it's intended for the case - // where someone has a custom menu on a screen and needs to disable normal - // input for navigating the custom menu to work. -Kyz - std::vector m_input_redirected; - Screen *MakeNewScreen( const RString &sName ); void LoadDelayedScreen(); bool ActivatePreparedScreenAndBackground( const RString &sScreenName );