From 719475637095a2794a2385856abb300e00afc761 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jan 2024 12:48:04 +0100 Subject: [PATCH] Shortcut: fixed single mod-key Shortcut from working e.g. Shortcut(ImGuiKey_LeftCtrl) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 34 ++++++++++++++++++++++++++-------- imgui_internal.h | 3 ++- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c6d0f0bf..7278ddb7 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,6 +66,8 @@ Other changes: update stopped setting default values. (#7232) [@GrigoryGraborenko] - Backends: WebGPU: Fixed pipeline layout leak. (#7245) [@rajveermalviya] - Backends: OpenGL3: Backup and restore GL_PIXEL_UNPACK_BUFFER. (#7253) +- Internals: Various improvements related to yet unpublicized shortcut routing and input ownerhip + systems. ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 768cf950..040e6712 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8115,6 +8115,26 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) // - Shortcut() [Internal] //----------------------------------------------------------------------------- +ImGuiKeyChord ImGui::FixupKeyChord(ImGuiContext* ctx, ImGuiKeyChord key_chord) +{ + // Convert ImGuiMod_Shortcut and add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified. + ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); + if (IsModKey(key)) + { + if (key == ImGuiKey_LeftCtrl || key == ImGuiKey_RightCtrl) + key_chord |= ImGuiMod_Ctrl; + if (key == ImGuiKey_LeftShift || key == ImGuiKey_RightShift) + key_chord |= ImGuiMod_Shift; + if (key == ImGuiKey_LeftAlt || key == ImGuiKey_RightAlt) + key_chord |= ImGuiMod_Alt; + if (key == ImGuiKey_LeftSuper || key == ImGuiKey_RightSuper) + key_chord |= ImGuiMod_Super; + } + if (key_chord & ImGuiMod_Shortcut) + return (key_chord & ~ImGuiMod_Shortcut) | (ctx->IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl); + return key_chord; +} + ImGuiKeyData* ImGui::GetKeyData(ImGuiContext* ctx, ImGuiKey key) { ImGuiContext& g = *ctx; @@ -8198,8 +8218,7 @@ const char* ImGui::GetKeyName(ImGuiKey key) const char* ImGui::GetKeyChordName(ImGuiKeyChord key_chord) { ImGuiContext& g = *GImGui; - if (key_chord & ImGuiMod_Shortcut) - key_chord = ConvertShortcutMod(key_chord); + key_chord = FixupKeyChord(&g, key_chord); ImFormatString(g.TempKeychordName, IM_ARRAYSIZE(g.TempKeychordName), "%s%s%s%s%s", (key_chord & ImGuiMod_Ctrl) ? "Ctrl+" : "", (key_chord & ImGuiMod_Shift) ? "Shift+" : "", @@ -8420,8 +8439,8 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteMask_)); // Check that only 1 routing flag is used IM_ASSERT(owner_id != ImGuiKeyOwner_Any && owner_id != ImGuiKeyOwner_None); - if (key_chord & ImGuiMod_Shortcut) - key_chord = ConvertShortcutMod(key_chord); + // Convert ImGuiMod_Shortcut and add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified. + key_chord = FixupKeyChord(&g, key_chord); // [DEBUG] Debug break requested by user if (g.DebugBreakInShortcutRouting == key_chord) @@ -8489,9 +8508,9 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI // Note: this cannot be turned into GetShortcutRouting() because we do the owner_id->routing_id translation, name would be more misleading. bool ImGui::TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id) { + ImGuiContext& g = *GImGui; const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id); - if (key_chord & ImGuiMod_Shortcut) - key_chord = ConvertShortcutMod(key_chord); + key_chord = FixupKeyChord(&g, key_chord); ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); // FIXME: Could avoid creating entry. return routing_data->RoutingCurr == routing_id; } @@ -9422,8 +9441,7 @@ bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord) bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags) { ImGuiContext& g = *GImGui; - if (key_chord & ImGuiMod_Shortcut) - key_chord = ConvertShortcutMod(key_chord); + key_chord = FixupKeyChord(&g, key_chord); ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_); if (g.IO.KeyMods != mods) return false; diff --git a/imgui_internal.h b/imgui_internal.h index c256ec22..f26ebcea 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3159,7 +3159,8 @@ namespace ImGui inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; } inline bool IsMouseKey(ImGuiKey key) { return key >= ImGuiKey_Mouse_BEGIN && key < ImGuiKey_Mouse_END; } inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; } - inline ImGuiKeyChord ConvertShortcutMod(ImGuiKeyChord key_chord) { ImGuiContext& g = *GImGui; IM_ASSERT_PARANOID(key_chord & ImGuiMod_Shortcut); return (key_chord & ~ImGuiMod_Shortcut) | (g.IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl); } + inline bool IsModKey(ImGuiKey key) { return key >= ImGuiKey_LeftCtrl && key <= ImGuiKey_RightSuper; } + ImGuiKeyChord FixupKeyChord(ImGuiContext* ctx, ImGuiKeyChord key_chord); inline ImGuiKey ConvertSingleModFlagToKey(ImGuiContext* ctx, ImGuiKey key) { ImGuiContext& g = *ctx;