diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 034f88fb85..ae585d2fd1 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -970,9 +970,9 @@ namespace MainWindow DestroyWindow(hWnd); break; - case WM_MENUSELECT: - // Called when a menu is opened. Also when an item is selected, but meh. - UpdateMenus((HMENU)lParam); + case WM_INITMENUPOPUP: + // Called when a menu or submenu is about to be opened. + UpdateMenus((HMENU)wParam); WindowsRawInput::NotifyMenu(); trapMouse = false; break; diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index cce9e9759b..ca85814c86 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -63,6 +63,8 @@ extern bool g_TakeScreenshot; namespace MainWindow { extern HINSTANCE hInst; extern bool noFocusPause; + std::vector g_topLevelMenus; + HMENU g_hMenuBackend; static std::unordered_map initialMenuKeys; static std::vector availableShaders; @@ -167,8 +169,11 @@ namespace MainWindow { info.cyMax = 0; info.dwStyle = MNS_CHECKORBMP; info.fMask = MIM_STYLE; + g_topLevelMenus.clear(); for (int i = 0; i < GetMenuItemCount(hMenu); i++) { - SetMenuInfo(GetSubMenu(hMenu, i), &info); + HMENU subMenu = GetSubMenu(hMenu, i); + SetMenuInfo(subMenu, &info); + g_topLevelMenus.push_back(subMenu); } // Always translate first: translating resets the menu. @@ -179,6 +184,9 @@ namespace MainWindow { if (System_GetPropertyBool(SYSPROP_APP_GOLD)) { RemoveMenu(helpMenu, ID_HELP_BUYGOLD, MF_BYCOMMAND); } + + HMENU hMenuOptions = GetSubmenuById(hMenu, ID_OPTIONS_MENU); + g_hMenuBackend = GetSubmenuById(hMenuOptions, ID_OPTIONS_BACKEND_MENU); } static void TranslateMenuItem(const HMENU hMenu, const int menuID, const std::wstring& accelerator = L"", const char *key = nullptr) { @@ -988,8 +996,30 @@ namespace MainWindow { vfpudlg->Show(false); } + static void UpdateBackendSubMenu(HMENU menu); + void UpdateMenus(HMENU menuSelected) { HMENU menu = GetMenu(GetHWND()); + + if (menuSelected) { + // Technically we only need to update the selected menu. + if (menuSelected == g_hMenuBackend) { + UpdateBackendSubMenu(menu); + return; + } + bool found = false; + for (auto topLevelMenu : g_topLevelMenus) { + if (menuSelected == topLevelMenu) { + found = true; + } + } + + if (!found) { + // Don't do anything + return; + } + } + #define CHECKITEM(item,value) CheckMenuItem(menu,item,MF_BYCOMMAND | ((value) ? MF_CHECKED : MF_UNCHECKED)); CHECKITEM(ID_DEBUG_IGNOREILLEGALREADS, g_Config.bIgnoreBadMemAccess); CHECKITEM(ID_DEBUG_SHOWDEBUGSTATISTICS, (DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS); @@ -1197,6 +1227,15 @@ namespace MainWindow { CheckMenuItem(menu, savestateSlot[i], MF_BYCOMMAND | ((i == g_Config.iCurrentStateSlot) ? MF_CHECKED : MF_UNCHECKED)); } +#if !PPSSPP_API(ANY_GL) + EnableMenuItem(menu, ID_DEBUG_GEDEBUGGER, MF_GRAYED); +#endif + + UpdateCommands(); + } + + // This one is pretty expensive so we handle it separately. + static void UpdateBackendSubMenu(HMENU menu) { bool allowD3D11 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11); bool allowOpenGL = g_Config.IsBackendEnabled(GPUBackend::OPENGL); bool allowVulkan = g_Config.IsBackendEnabled(GPUBackend::VULKAN); @@ -1227,12 +1266,6 @@ namespace MainWindow { CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED); break; } - -#if !PPSSPP_API(ANY_GL) - EnableMenuItem(menu, ID_DEBUG_GEDEBUGGER, MF_GRAYED); -#endif - - UpdateCommands(); } void UpdateCommands() {