From 20983773f1f3b71ece6b04890ad2ec7f803668e0 Mon Sep 17 00:00:00 2001
From: omar <omarcornut@gmail.com>
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 d8d0ae4c8..fd7d9447e 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 25fb04a6f..70c2a19c0 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -467,7 +467,7 @@ struct ImGuiContext
     ImVector<ImGuiPopupRef> 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