Nav: Fixed issues with nav request being transferred to another window when calling SetKeyboardFocusHere() and simultaneous changing window focus. (#4449)

This commit is contained in:
ocornut
2022-06-10 19:25:53 +02:00
parent 0b1bcfcc20
commit 076d8fc868
3 changed files with 20 additions and 7 deletions

View File

@ -7383,7 +7383,10 @@ void ImGui::SetKeyboardFocusHere(int offset)
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(offset >= -1); // -1 is allowed but not below
g.NavWindow = window;
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
if (offset == -1)
@ -9574,8 +9577,11 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
// Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text)
const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent;
if (g.NavWindow != window)
g.NavInitRequest = false;
g.NavWindow = window;
{
g.NavWindow = window;
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
g.NavId = id;
g.NavLayer = nav_layer;
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
@ -9823,7 +9829,12 @@ static void ImGui::NavProcessItem()
// Update window-relative bounding box of navigated item
if (g.NavId == id)
{
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
if (g.NavWindow != window)
{
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
g.NavLayer = window->DC.NavLayerCurrent;
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
g.NavIdIsAlive = true;
@ -9901,10 +9912,11 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM
g.NavMoveScrollFlags = scroll_flags;
g.NavMoveForwardToNextFrame = false;
g.NavMoveKeyMods = g.IO.KeyMods;
g.NavTabbingCounter = 0;
g.NavMoveResultLocal.Clear();
g.NavMoveResultLocalVisible.Clear();
g.NavMoveResultOther.Clear();
g.NavTabbingCounter = 0;
g.NavTabbingResultFirst.Clear();
NavUpdateAnyRequestFlag();
}
@ -9971,7 +9983,7 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
{
ImGuiContext& g = *GImGui;
if (layer == ImGuiNavLayer_Main)
g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow);
g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); // FIXME-NAV: Should clear ongoing nav requests?
ImGuiWindow* window = g.NavWindow;
if (window->NavLastIds[layer] != 0)
{
@ -10451,7 +10463,6 @@ void ImGui::NavUpdateCreateTabbingRequest()
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down;
NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
g.NavTabbingResultFirst.Clear();
g.NavTabbingCounter = -1;
}