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
This commit is contained in:
Fabrice de Gans 2024-09-29 13:59:19 -07:00 committed by GitHub
parent e1c2ecc584
commit 7fa90531e6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 24 additions and 18 deletions

View File

@ -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()

View File

@ -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;

View File

@ -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;
}

View File

@ -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; }