From 20983773f1f3b71ece6b04890ad2ec7f803668e0 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 23 Oct 2017 12:38:39 +0200 Subject: [PATCH] Nav: MainMenuBar now releases focus when user gets out of the menu layer. WindowingTarget when applying focus to a window with only menus automatically sets the layer. (#787) This is enough for basic mouse/gamepad usage, but 1- previous window gets an unfocused title bar color temporarily, 2- generaly for gamepad and especially keyboard we need much more to get this done right --- imgui.cpp | 14 ++++++++++++-- imgui_internal.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d8d0ae4c..fd7d9447 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2726,6 +2726,10 @@ static void ImGui::NavUpdateWindowing() g.NavDisableMouseHover = true; if (g.NavWindowingTarget->NavLastIds[0] == 0) NavInitWindow(g.NavWindowingTarget, false); + + // If the window only has a menu layer, select it directly + if (g.NavWindowingTarget->DC.NavLayerActiveMask == 0x02) + g.NavLayer = 1; } // Single press toggles NavLayer @@ -4077,7 +4081,7 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items static ImGuiWindow* FindHoveredWindow(ImVec2 pos, bool excluding_childs) { ImGuiContext& g = *GImGui; - for (int i = g.Windows.Size-1; i >= 0; i--) + for (int i = g.Windows.Size - 1; i >= 0; i--) { ImGuiWindow* window = g.Windows[i]; if (!window->Active) @@ -5818,7 +5822,7 @@ void ImGui::FocusPreviousWindow() { ImGuiContext& g = *GImGui; for (int i = g.Windows.Size - 1; i >= 0; i--) - if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) + if (g.Windows[i] != g.NavWindow && g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) { FocusWindow(g.Windows[i]); return; @@ -10293,6 +10297,12 @@ bool ImGui::BeginMainMenuBar() void ImGui::EndMainMenuBar() { EndMenuBar(); + + // When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window + ImGuiContext& g = *GImGui; + if (g.CurrentWindow == g.NavWindow && g.NavLayer == 0) + FocusPreviousWindow(); + End(); PopStyleVar(2); } diff --git a/imgui_internal.h b/imgui_internal.h index 25fb04a6..70c2a19c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -467,7 +467,7 @@ struct ImGuiContext ImVector CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) // Navigation data (for gamepad/keyboard) - ImGuiWindow* NavWindow; // Focused window for navigation + ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusWindow' ImGuiID NavId; // Focused item for navigation ImGuiID NavActivateId; // ~~ IsNavInputPressed(ImGuiNavInput_PadActivate) ? NavId : 0, also set when calling ActivateItem() ImGuiID NavActivateDownId; // ~~ IsNavInputPressed(ImGuiNavInput_PadActivate) ? NavId : 0