Docking: Fixed focus restore lagging by a frame when a tab stops being submitted. (#2109) Building on a little build of technical debt there, should transition toward a more general docking-agnostic system (#2304)

This commit is contained in:
omar
2019-03-28 18:43:27 +01:00
parent 5af385ea78
commit 9bf6509c6e
4 changed files with 32 additions and 7 deletions

View File

@ -1040,7 +1040,7 @@ static float NavUpdatePageUpPageDown(int allowed_dir_flags);
static inline void NavUpdateAnyRequestFlag();
static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
static ImVec2 NavCalcPreferredRefPos();
static void NavSaveLastChildNavWindow(ImGuiWindow* nav_window);
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
// Misc
@ -8143,7 +8143,9 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags mov
}
}
static void ImGui::NavSaveLastChildNavWindow(ImGuiWindow* nav_window)
// FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0).
// This way we could find the last focused window among our children. It would be much less confusing this way?
static void ImGui::NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window)
{
ImGuiWindow* parent_window = nav_window;
while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
@ -8152,10 +8154,16 @@ static void ImGui::NavSaveLastChildNavWindow(ImGuiWindow* nav_window)
parent_window->NavLastChildNavWindow = nav_window;
}
// Call when we are expected to land on Layer 0 after FocusWindow()
// Restore the last focused child.
// Call when we are expected to land on the Main Layer (0) after FocusWindow()
static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window)
{
return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window;
if (window->NavLastChildNavWindow && window->NavLastChildNavWindow->WasActive)
return window->NavLastChildNavWindow;
if (window->DockNodeAsHost && window->DockNodeAsHost->TabBar)
if (ImGuiTabItem* tab = TabBarFindMostRecentlySelectedTabForActiveWindow(window->DockNodeAsHost->TabBar))
return tab->Window;
return window;
}
static void NavRestoreLayer(ImGuiNavLayer layer)
@ -8380,7 +8388,7 @@ static void ImGui::NavUpdate()
// Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0
if (g.NavWindow)
NavSaveLastChildNavWindow(g.NavWindow);
NavSaveLastChildNavWindowIntoParent(g.NavWindow);
if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0)
g.NavWindow->NavLastChildNavWindow = NULL;
@ -8833,7 +8841,7 @@ static void ImGui::NavUpdateWindowing()
// Move to parent menu if necessary
ImGuiWindow* new_nav_window = g.NavWindow;
while (new_nav_window->ParentWindow
&& (new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0
&& (new_nav_window->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) == 0
&& (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0
&& (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
new_nav_window = new_nav_window->ParentWindow;