diff --git a/src/Menu.cpp b/src/Menu.cpp index 0c69343e75..e53f1fcb59 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -954,6 +954,10 @@ void Menu::ProcessInputEventQueue() logger::trace("Detected key code {} ({})", event.keyCode, key); if (key == event.keyCode) key = MapVirtualKeyEx(event.keyCode, MAPVK_VSC_TO_VK_EX, GetKeyboardLayout(0)); + + const bool wasCapturingHotkey = IsCapturingHotkeyInput(); + const bool allowSetupCloseKey = wasCapturingHotkey && HomePageRenderer::ShouldShowFirstTimeSetup() && + (key == VK_RETURN || key == VK_ESCAPE); if (!event.IsPressed()) { // Skip key release if it was used to close the first-time setup dialog if (HomePageRenderer::ShouldSkipKeyRelease(key)) { @@ -1028,7 +1032,13 @@ void Menu::ProcessInputEventQueue() std::function action; }; KeyAction keyActions[] = { - { settings.ToggleKey, [this]() { if (!HomePageRenderer::ShouldShowFirstTimeSetup()) IsEnabled = !IsEnabled; } }, + { settings.ToggleKey, [this]() { + if (!HomePageRenderer::ShouldShowFirstTimeSetup()) { + IsEnabled = !IsEnabled; + if (IsEnabled) + ImGui::GetIO().ClearInputKeys(); // Prevent toggle key from remaining "held" in ImGui after open. + } + } }, { settings.SkipCompilationKey, [this, shaderCache]() { if (!ShouldSwallowInput() && shaderCache->IsCompiling()) shaderCache->backgroundCompilation = true; } }, { settings.EffectToggleKey, [shaderCache]() { shaderCache->SetEnabled(!shaderCache->IsEnabled()); } }, { settings.ShaderBlockPrevKey, [this, shaderCache]() { if (settings.EnableShaderBlocking) shaderCache->IterateShaderBlock(); } }, @@ -1080,9 +1090,13 @@ void Menu::ProcessInputEventQueue() bool isHotkey = ShouldSwallowInput() && std::any_of(std::begin(hotkeys), std::end(hotkeys), [key](const auto* combo) { return InputCombo::MatchesKeyboardCombo(*combo, key); }); - if (!isHotkey) { + // Always forward key-up events. Suppress key-down during active hotkeys, + // and during hotkey capture except setup close keys (Enter/Escape). + const bool isKeyDown = event.IsPressed(); + const bool suppressForwarding = isKeyDown && (isHotkey || (wasCapturingHotkey && !allowSetupCloseKey)); + if (!suppressForwarding) { // DirectInput loses key-up events after alt-tab; validate against OS state. - bool pressed = event.IsPressed() && (GetAsyncKeyState(key) & Constants::KEY_PRESSED_MASK); + bool pressed = isKeyDown && (GetAsyncKeyState(key) & Constants::KEY_PRESSED_MASK); io.AddKeyEvent(Util::Input::VirtualKeyToImGuiKey(key), pressed); if (key == VK_LCONTROL || key == VK_RCONTROL) @@ -1098,6 +1112,12 @@ void Menu::ProcessInputEventQueue() _keyEventQueue.clear(); } +bool Menu::IsCapturingHotkeyInput() const +{ + return settingToggleKey || settingSkipCompilationKey || settingsEffectsToggle || + settingOverlayToggleKey || settingShaderBlockPrevKey || settingShaderBlockNextKey || settingWeatherEditorToggleKey; +} + void Menu::addToEventQueue(KeyEvent e) { std::unique_lock mutex(_inputEventMutex); diff --git a/src/Menu.h b/src/Menu.h index 61d5861c34..37f4c3d5e0 100644 --- a/src/Menu.h +++ b/src/Menu.h @@ -501,5 +501,6 @@ class Menu void addToEventQueue(KeyEvent e); void ProcessInputEventQueue(); + bool IsCapturingHotkeyInput() const; winrt::com_ptr dxgiAdapter3; }; \ No newline at end of file