diff --git a/imgui.cpp b/imgui.cpp index 2ba3aacd9..484c8513f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9378,7 +9378,7 @@ static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) routing_entry->RoutingCurrScore = routing_entry->RoutingNextScore; routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry routing_entry->RoutingNext = ImGuiKeyOwner_NoOwner; - routing_entry->RoutingNextScore = 255; + routing_entry->RoutingNextScore = 0; if (routing_entry->RoutingCurr == ImGuiKeyOwner_NoOwner) continue; rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer @@ -9447,23 +9447,24 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord) return routing_data; } -// Current score encoding (lower is highest priority): -// - 0: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverActive -// - 1: ImGuiInputFlags_ActiveItem or ImGuiInputFlags_RouteFocused (if item active) -// - 2: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused -// - 3+: ImGuiInputFlags_RouteFocused (if window in focus-stack) -// - 254: ImGuiInputFlags_RouteGlobal -// - 255: never route +// Current score encoding +// - 0: Never route +// - 1: ImGuiInputFlags_RouteGlobal (lower priority) +// - 100..199: ImGuiInputFlags_RouteFocused (if window in focus-stack) +// 200: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused +// 300: ImGuiInputFlags_RouteActive or ImGuiInputFlags_RouteFocused (if item active) +// 400: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverActive +// - 500..599: ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteOverActive (if window in focus-stack) (higher priority) // 'flags' should include an explicit routing policy static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInputFlags flags) { ImGuiContext& g = *GImGui; if (flags & ImGuiInputFlags_RouteFocused) { - // ActiveID gets top priority + // ActiveID gets high priority // (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it) if (owner_id != 0 && g.ActiveId == owner_id) - return 1; + return 300; // Score based on distance to focused window (lower is better) // Assuming both windows are submitting a routing request, @@ -9473,25 +9474,27 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput // - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score. // This essentially follow the window->ParentWindowForFocusRoute chain. if (focus_scope_id == 0) - return 255; + return 0; for (int index_in_focus_path = 0; index_in_focus_path < g.NavFocusRoute.Size; index_in_focus_path++) if (g.NavFocusRoute.Data[index_in_focus_path].ID == focus_scope_id) - return 3 + index_in_focus_path; - return 255; + return 199 - index_in_focus_path; + return 0; } else if (flags & ImGuiInputFlags_RouteActive) { if (owner_id != 0 && g.ActiveId == owner_id) - return 1; - return 255; + return 300; + return 0; } else if (flags & ImGuiInputFlags_RouteGlobal) { if (flags & ImGuiInputFlags_RouteOverActive) - return 0; + return 400; + if (owner_id != 0 && g.ActiveId == owner_id) + return 300; if (flags & ImGuiInputFlags_RouteOverFocused) - return 2; - return 254; + return 200; + return 1; } IM_ASSERT(0); return 0; @@ -9587,17 +9590,17 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I 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) + if (score == 0) return false; // Submit routing for NEXT frame (assuming score is sufficient) - // FIXME: Could expose a way to use a "serve last" policy for same score resolution (using <= instead of <). + // FIXME: Could expose a way to use a "serve last" policy for same score resolution (using >= instead of >). ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); - //const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score <= routing_data->RoutingNextScore) : (score < routing_data->RoutingNextScore); - if (score < routing_data->RoutingNextScore) + //const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score >= routing_data->RoutingNextScore) : (score > routing_data->RoutingNextScore); + if (score > routing_data->RoutingNextScore) { routing_data->RoutingNext = owner_id; - routing_data->RoutingNextScore = (ImU8)score; + routing_data->RoutingNextScore = (ImU16)score; } // Return routing state for CURRENT frame diff --git a/imgui_internal.h b/imgui_internal.h index 1510271a0..c9c1f1333 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1556,12 +1556,12 @@ struct ImGuiKeyRoutingData { ImGuiKeyRoutingIndex NextEntryIndex; ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits. - ImU8 RoutingCurrScore; // [DEBUG] For debug display - ImU8 RoutingNextScore; // Lower is better (0: perfect score) + ImU16 RoutingCurrScore; // [DEBUG] For debug display + ImU16 RoutingNextScore; // Lower is better (0: perfect score) ImGuiID RoutingCurr; ImGuiID RoutingNext; - ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; } + ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 0; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; } }; // Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.