diff --git a/imgui.cpp b/imgui.cpp index 844932913..9de7c9b36 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4623,7 +4623,7 @@ void ImGui::NewFrame() // Closing the focused window restore focus to the first active root window in descending z-order 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. // 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; } + // Find last focused child (if any) and focus it instead. + if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL) + window = NavRestoreLastChildNavWindow(window); + // Apply focus if (g.NavWindow != window) { @@ -7003,8 +7007,7 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind continue; if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) { - ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window); - FocusWindow(focus_window, flags); + FocusWindow(window, flags); 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; if (focus_window && !focus_window->WasActive && popup_window) - { - // Fallback - FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_None); - } + FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild); // Fallback else - { - if (g.NavLayer == ImGuiNavLayer_Main && focus_window) - focus_window = NavRestoreLastChildNavWindow(focus_window); - FocusWindow(focus_window); - } + FocusWindow(focus_window, (g.NavLayer == ImGuiNavLayer_Main) ? ImGuiFocusRequestFlags_RestoreFocusedChild : ImGuiFocusRequestFlags_None); } } @@ -11854,7 +11850,7 @@ static void ImGui::NavUpdateWindowing() bool apply_toggle_layer = false; 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) g.NavWindowingTarget = NULL; @@ -11983,9 +11979,9 @@ static void ImGui::NavUpdateWindowing() { ClearActiveID(); NavRestoreHighlightAfterMove(); - apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window); 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) NavInitWindow(apply_focus_window, false); diff --git a/imgui_internal.h b/imgui_internal.h index 5e71419b1..900d5cf68 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -913,7 +913,8 @@ enum ImGuiSeparatorFlags_ enum ImGuiFocusRequestFlags_ { 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_ diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index fb445b99b..3a2e6c269 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7084,7 +7084,7 @@ void ImGui::EndMainMenuBar() // FIXME: With this strategy we won't be able to restore a NULL focus. ImGuiContext& g = *GImGui; 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(); }