From 7fa90531e6b451a8edfdd0b2942f38d5cd9f068d Mon Sep 17 00:00:00 2001 From: Fabrice de Gans Date: Sun, 29 Sep 2024 13:59:19 -0700 Subject: [PATCH] Disable open menu tracking outside of Windows (#1350) Tracking whether or not the menus are opened is necessary on Windows since menus stop the main loop. This is not necessary on other platforms. In particular, on Mac, we do not get a `wxEVT_MENU_CLOSE` event when opening a dialog from a shortcut, resulting in the menu status tracking being incorrect. Fixes #1348 --- cmake/Toolchain-gcc-clang.cmake | 2 +- src/wx/panel.cpp | 4 ---- src/wx/wxvbam.cpp | 23 +++++++++++++---------- src/wx/wxvbam.h | 13 ++++++++++--- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/cmake/Toolchain-gcc-clang.cmake b/cmake/Toolchain-gcc-clang.cmake index f73f25c9..0f668212 100644 --- a/cmake/Toolchain-gcc-clang.cmake +++ b/cmake/Toolchain-gcc-clang.cmake @@ -46,7 +46,7 @@ if(NOT ENABLE_ASM) # inline asm is not allowed with -fPIC endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") - add_compile_options(-ggdb3 -Og -fno-omit-frame-pointer -Wall -Wextra) + add_compile_options(-ggdb3 -fno-omit-frame-pointer -Wall -Wextra) else() add_compile_options(-Ofast -fomit-frame-pointer) endif() diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 29d7f7b3..a14a21fb 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -952,10 +952,6 @@ void GameArea::ShowFullScreen(bool full) while (!tlw->popups.empty()) tlw->popups.front()->Close(); - // Some kbd accels can send a menu open event without a close event, - // this happens on Mac in HiDPI mode for the fullscreen toggle accel. - main_frame->SetMenusOpened(false); - // mouse stays blank whenever full-screen HidePointer(); cursz_valid = true; diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index 08e03b65..950970a7 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -894,11 +894,15 @@ EVT_MOVE_START(MainFrame::OnMoveStart) EVT_MOVE_END(MainFrame::OnMoveEnd) EVT_SIZE(MainFrame::OnSize) +#if defined(__WXMSW__) + // For tracking menubar state. EVT_MENU_OPEN(MainFrame::MenuPopped) EVT_MENU_CLOSE(MainFrame::MenuPopped) EVT_MENU_HIGHLIGHT_ALL(MainFrame::MenuPopped) +#endif // defined(__WXMSW__) + END_EVENT_TABLE() void MainFrame::OnActivate(wxActivateEvent& event) @@ -1152,8 +1156,9 @@ void MainFrame::ResetMenuAccelerators() { ResetRecentAccelerators(); } -void MainFrame::MenuPopped(wxMenuEvent& evt) -{ +#if defined(__WXMSW__) + +void MainFrame::MenuPopped(wxMenuEvent& evt) { // We consider the menu closed when the main menubar or system menu is closed, not any submenus. // On Windows nullptr is the system menu. if (evt.GetEventType() == wxEVT_MENU_CLOSE && (evt.GetMenu() == nullptr || evt.GetMenu()->GetMenuBar() == GetMenuBar())) @@ -1166,18 +1171,16 @@ void MainFrame::MenuPopped(wxMenuEvent& evt) // On Windows, opening the menubar will stop the app, but DirectSound will // loop, so we pause audio here. -void MainFrame::SetMenusOpened(bool state) -{ +void MainFrame::SetMenusOpened(bool state) { menus_opened = state; - -#ifdef __WXMSW__ if (menus_opened) soundPause(); else if (!paused) soundResume(); -#endif } +#endif // defined(__WXMSW__) + // ShowModal that also disables emulator loop // uses dialog_opened as a nesting counter int MainFrame::ShowModal(wxDialog* dlg) @@ -1338,12 +1341,12 @@ int wxvbamApp::FilterEvent(wxEvent& event) return wxEventFilter::Event_Skip; } - if (!frame->CanProcessShortcuts()) { + if (event.GetEventType() != VBAM_EVT_USER_INPUT) { + // We only treat "VBAM_EVT_USER_INPUT" events here. return wxEventFilter::Event_Skip; } - if (event.GetEventType() != VBAM_EVT_USER_INPUT) { - // We only treat "VBAM_EVT_USER_INPUT" events here. + if (!frame->CanProcessShortcuts()) { return wxEventFilter::Event_Skip; } diff --git a/src/wx/wxvbam.h b/src/wx/wxvbam.h index 49a1fcb1..c1ab6a67 100644 --- a/src/wx/wxvbam.h +++ b/src/wx/wxvbam.h @@ -219,10 +219,15 @@ public: // possible void StartModal(); void StopModal(); - // however, adding a handler for open/close menu to do the same is unsafe. - // there is no guarantee every show will be matched by a hide. + +#if defined(__WXMSW__) + + // On Windows, we need to disable the audio loop when the menu is open. We also disable + // shortcuts to prevent issues. This is not necessary on other systems. void MenuPopped(wxMenuEvent& evt); +#endif // defined(__WXMSW__) + // flags for enabling commands int cmd_enable; @@ -285,7 +290,9 @@ public: virtual bool MenusOpened() { return menus_opened; } - virtual void SetMenusOpened(bool state); +#if defined(__WXMSW__) + void SetMenusOpened(bool state); +#endif // defined(__WXMSW__) virtual bool DialogOpened() { return dialog_opened != 0; }