diff --git a/imgui.cpp b/imgui.cpp index 51c0a1770..2a719d463 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8659,7 +8659,7 @@ static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord) // - Routes and key ownership are attributed at the beginning of next frame based on best score and mod state. // (Conceptually this does a "Submit for next frame" + "Test for current frame". // As such, it could be called TrySetXXX or SubmitXXX, or the Submit and Test operations should be separate.) -bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id) +bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id, ImGuiID focus_scope_id) { ImGuiContext& g = *GImGui; IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteTypeMask_)); // Check that only 1 routing flag is used @@ -8708,8 +8708,7 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I } } - // FIXME-SHORTCUT: A way to configure the location/focus-scope to test would render this more flexible. - const int score = CalcRoutingScore(g.CurrentFocusScopeId, owner_id, flags); + const int score = CalcRoutingScore(focus_scope_id, owner_id, flags); IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> score %d\n", GetKeyChordName(key_chord), flags, owner_id, score); if (score == 255) return false; @@ -9716,7 +9715,7 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags) bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id) { - //ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; //IMGUI_DEBUG_LOG("Shortcut(%s, flags=%X, owner_id=0x%08X)\n", GetKeyChordName(key_chord, g.TempBuffer.Data, g.TempBuffer.Size), flags, owner_id); // When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any. @@ -9728,8 +9727,13 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID own if (owner_id == ImGuiKeyOwner_Any || owner_id == ImGuiKeyOwner_NoOwner) owner_id = GetRoutingIdFromOwnerId(owner_id); + // Where do we evaluate route for? + ImGuiID focus_scope_id = g.CurrentFocusScopeId; + if (flags & ImGuiInputFlags_RouteFromRootWindow) + focus_scope_id = g.CurrentWindow->RootWindow->ID; // See PushFocusScope() call in Begin() + // Submit route - if (!SetShortcutRouting(key_chord, flags, owner_id)) + if (!SetShortcutRouting(key_chord, flags, owner_id, focus_scope_id)) return false; // Default repeat behavior for Shortcut() diff --git a/imgui.h b/imgui.h index a47af9e6e..bc1ec840b 100644 --- a/imgui.h +++ b/imgui.h @@ -1489,10 +1489,11 @@ enum ImGuiInputFlags_ ImGuiInputFlags_RouteGlobalOverFocused = 1 << 14, // Global route (higher priority): unless an active item registered the route, e.g. CTRL+A registered by InputText will take priority over this). ImGuiInputFlags_RouteGlobalHighest = 1 << 15, // Global route (highest priority): unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overridden by this) ImGuiInputFlags_RouteAlways = 1 << 16, // Do not register route, poll keys directly. - ImGuiInputFlags_RouteUnlessBgFocused = 1 << 17, // Option combine with others: global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. + ImGuiInputFlags_RouteUnlessBgFocused = 1 << 17, // Option: global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. + ImGuiInputFlags_RouteFromRootWindow = 1 << 18, // Option: route evaluated from the point of view of root window rather than current window. // Flags for SetNextItemShortcut() - ImGuiInputFlags_Tooltip = 1 << 18, // Automatically display a tooltip when hovering item. + ImGuiInputFlags_Tooltip = 1 << 19, // Automatically display a tooltip when hovering item. }; #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO diff --git a/imgui_internal.h b/imgui_internal.h index 32f479c32..37bbd7843 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1478,10 +1478,11 @@ enum ImGuiInputFlagsPrivate_ ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_, ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobalOverFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalHighest | ImGuiInputFlags_RouteAlways, + ImGuiInputFlags_RouteOptionsMask_ = ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_RouteFromRootWindow, ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_, ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat, - ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteUnlessBgFocused, - ImGuiInputFlags_SupportedBySetNextItemShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_Tooltip, + ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_, + ImGuiInputFlags_SupportedBySetNextItemShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_ | ImGuiInputFlags_Tooltip, ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, }; @@ -3264,7 +3265,7 @@ namespace ImGui // - You can chain two unrelated windows in the focus stack using SetWindowParentWindowForFocusRoute() // e.g. if you have a tool window associated to a document, and you want document shortcuts to run when the tool is focused. IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id); - IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id); // routing policy and owner_id needs to be explicit and cannot be 0 + IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id, ImGuiID focus_scope_id); // routing policy and owner_id needs to be explicit and cannot be 0 IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id); IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord);