From 96839b445e32e46d87a44fd43a9cdd60c806f7e1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jan 2024 15:43:19 +0100 Subject: [PATCH] Nav: Improve handling of Alt key to toggle menu so that key ownership may be claimed on indiviudal left/right alt key without intefering with the other. See test "inputs_owner_single_mod" --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 27 ++++++++++++++++----------- imgui_internal.h | 2 ++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 7278ddb7..5ec7a2ed 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -54,6 +54,8 @@ Other changes: - Nav: Fixed SetKeyboardFocusHere() not working when current nav focus is in different scope, regression from 1.90.1 related to code scoping Tab presses to local scope. (#7226) [@bratpilz] - Nav: Fixed pressing Escape while in a child window with _NavFlattened flag. (#7237) +- Nav: Improve handling of Alt key to toggle menu so that key ownership may be claimed on + indiviudal left/right alt key without intefering with the other. - Debug Tools: Metrics: Fixed debug break in SetShortcutRouting() not handling ImGuiMod_Shortcut redirect. - Debug Tools: Debug Log: Added "Input Routing" logging. - Debug Tools: Added "nop" to IM_DEBUG_BREAK macro on GCC to work around GDB bug (#7266) [@Peter0x44] diff --git a/imgui.cpp b/imgui.cpp index 040e6712..8bfc66cb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12627,28 +12627,33 @@ static void ImGui::NavUpdateWindowing() } // Keyboard: Press and Release ALT to toggle menu layer - // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer. - // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway. - if (nav_keyboard_active && IsKeyPressed(ImGuiMod_Alt, ImGuiKeyOwner_None)) - { - g.NavWindowingToggleLayer = true; - g.NavInputSource = ImGuiInputSource_Keyboard; - } + const ImGuiKey windowing_toggle_keys[] = { ImGuiKey_LeftAlt, ImGuiKey_RightAlt }; + for (ImGuiKey windowing_toggle_key : windowing_toggle_keys) + if (nav_keyboard_active && IsKeyPressed(windowing_toggle_key, ImGuiKeyOwner_None)) + { + g.NavWindowingToggleLayer = true; + g.NavWindowingToggleKey = windowing_toggle_key; + g.NavInputSource = ImGuiInputSource_Keyboard; + break; + } if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard) { // We cancel toggling nav layer when any text has been typed (generally while holding Alt). (See #370) // We cancel toggling nav layer when other modifiers are pressed. (See #4439) + // - AltGR is Alt+Ctrl on some layout but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). // We cancel toggling nav layer if an owner has claimed the key. - if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper || TestKeyOwner(ImGuiMod_Alt, ImGuiKeyOwner_None) == false) + if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper) + g.NavWindowingToggleLayer = false; + if (TestKeyOwner(g.NavWindowingToggleKey, ImGuiKeyOwner_None) == false || TestKeyOwner(ImGuiMod_Alt, ImGuiKeyOwner_None) == false) g.NavWindowingToggleLayer = false; - // Apply layer toggle on release + // Apply layer toggle on Alt release // Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss. - if (IsKeyReleased(ImGuiMod_Alt) && g.NavWindowingToggleLayer) + if (IsKeyReleased(g.NavWindowingToggleKey) && g.NavWindowingToggleLayer) if (g.ActiveId == 0 || g.ActiveIdAllowOverlap) if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev)) apply_toggle_layer = true; - if (!IsKeyDown(ImGuiMod_Alt)) + if (!IsKeyDown(g.NavWindowingToggleKey)) g.NavWindowingToggleLayer = false; } diff --git a/imgui_internal.h b/imgui_internal.h index f26ebcea..92507062 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2078,6 +2078,7 @@ struct ImGuiContext float NavWindowingTimer; float NavWindowingHighlightAlpha; bool NavWindowingToggleLayer; + ImGuiKey NavWindowingToggleKey; ImVec2 NavWindowingAccumDeltaPos; ImVec2 NavWindowingAccumDeltaSize; @@ -2329,6 +2330,7 @@ struct ImGuiContext NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingToggleLayer = false; + NavWindowingToggleKey = ImGuiKey_None; DimBgRatio = 0.0f;