Focus: move focused child restore code in FocusWindow() with ImGuiFocusRequestFlags_RestoreFocusedChild flag. (#6357)

# Conflicts:
#	imgui.cpp
This commit is contained in:
ocornut 2023-04-21 17:46:41 +02:00
parent 30eceaf95f
commit 01ca196530
3 changed files with 14 additions and 17 deletions

View File

@ -4623,7 +4623,7 @@ void ImGui::NewFrame()
// Closing the focused window restore focus to the first active root window in descending z-order // Closing the focused window restore focus to the first active root window in descending z-order
if (g.NavWindow && !g.NavWindow->WasActive) if (g.NavWindow && !g.NavWindow->WasActive)
FocusTopMostWindowUnderOne(NULL, NULL, NULL, ImGuiFocusRequestFlags_None); FocusTopMostWindowUnderOne(NULL, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild);
// No window should be open at the beginning of the frame. // No window should be open at the beginning of the frame.
// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
@ -6941,6 +6941,10 @@ void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags)
return; return;
} }
// Find last focused child (if any) and focus it instead.
if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL)
window = NavRestoreLastChildNavWindow(window);
// Apply focus // Apply focus
if (g.NavWindow != window) if (g.NavWindow != window)
{ {
@ -7003,8 +7007,7 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind
continue; continue;
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
{ {
ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window); FocusWindow(window, flags);
FocusWindow(focus_window, flags);
return; return;
} }
} }
@ -10272,16 +10275,9 @@ void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_
{ {
ImGuiWindow* focus_window = (popup_window && popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : popup_backup_nav_window; ImGuiWindow* focus_window = (popup_window && popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : popup_backup_nav_window;
if (focus_window && !focus_window->WasActive && popup_window) if (focus_window && !focus_window->WasActive && popup_window)
{ FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild); // Fallback
// Fallback
FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_None);
}
else else
{ FocusWindow(focus_window, (g.NavLayer == ImGuiNavLayer_Main) ? ImGuiFocusRequestFlags_RestoreFocusedChild : ImGuiFocusRequestFlags_None);
if (g.NavLayer == ImGuiNavLayer_Main && focus_window)
focus_window = NavRestoreLastChildNavWindow(focus_window);
FocusWindow(focus_window);
}
} }
} }
@ -11854,7 +11850,7 @@ static void ImGui::NavUpdateWindowing()
bool apply_toggle_layer = false; bool apply_toggle_layer = false;
ImGuiWindow* modal_window = GetTopMostPopupModal(); ImGuiWindow* modal_window = GetTopMostPopupModal();
bool allow_windowing = (modal_window == NULL); bool allow_windowing = (modal_window == NULL); // FIXME: This prevent CTRL+TAB from being usable with windows over a popup
if (!allow_windowing) if (!allow_windowing)
g.NavWindowingTarget = NULL; g.NavWindowingTarget = NULL;
@ -11983,9 +11979,9 @@ static void ImGui::NavUpdateWindowing()
{ {
ClearActiveID(); ClearActiveID();
NavRestoreHighlightAfterMove(); NavRestoreHighlightAfterMove();
apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window);
ClosePopupsOverWindow(apply_focus_window, false); ClosePopupsOverWindow(apply_focus_window, false);
FocusWindow(apply_focus_window); FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild);
apply_focus_window = g.NavWindow;
if (apply_focus_window->NavLastIds[0] == 0) if (apply_focus_window->NavLastIds[0] == 0)
NavInitWindow(apply_focus_window, false); NavInitWindow(apply_focus_window, false);

View File

@ -913,7 +913,8 @@ enum ImGuiSeparatorFlags_
enum ImGuiFocusRequestFlags_ enum ImGuiFocusRequestFlags_
{ {
ImGuiFocusRequestFlags_None = 0, ImGuiFocusRequestFlags_None = 0,
ImGuiFocusRequestFlags_UnlessBelowModal = 1 << 0, // Do not set focus if the window is below a modal. ImGuiFocusRequestFlags_RestoreFocusedChild = 1 << 0, // Find last focused child (if any) and focus it instead.
ImGuiFocusRequestFlags_UnlessBelowModal = 1 << 1, // Do not set focus if the window is below a modal.
}; };
enum ImGuiTextFlags_ enum ImGuiTextFlags_

View File

@ -7084,7 +7084,7 @@ void ImGui::EndMainMenuBar()
// FIXME: With this strategy we won't be able to restore a NULL focus. // FIXME: With this strategy we won't be able to restore a NULL focus.
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest) if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest)
FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal); FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild);
End(); End();
} }