Przeglądaj źródła

Viewports: Fixes erroneous popup closure on closing a previous popup. (#6462, #6299)

Avoid applying imgui-side focus when focus change is due to a viewport destruction.
ocornut 2 lat temu
rodzic
commit
3418d50949
2 zmienionych plików z 12 dodań i 3 usunięć
  1. 2 0
      docs/CHANGELOG.txt
  2. 10 3
      imgui.cpp

+ 2 - 0
docs/CHANGELOG.txt

@@ -163,6 +163,8 @@ Docking+Viewports Branch:
   closure of Modal windows. Regression from 1.89.5. (#6357, #6299)
 - Viewports: Fixed loss of imgui-side focus when dragging a secondary viewport back in
   main viewport, due to platform-side handling changes. Regression from 1.89.5 (#6299)
+- Viewports: Avoid applying imgui-side focus when focus change is due to a viewport
+  destruction. Fixes erroneous popup closure on closing a previous popup. (#6462, #6299)
 - Viewports: Added void* ImGuiPlatformMonitor::PlatformHandle field (backend-dependant),
   for usage by user code.
 - Backends: GLFW: Preserve monitor list when there are no monitor, may briefly

+ 10 - 3
imgui.cpp

@@ -14004,6 +14004,10 @@ static void ImGui::UpdateViewportsNewFrame()
         // Focused viewport has changed?
         if (focused_viewport && g.PlatformLastFocusedViewportId != focused_viewport->ID)
         {
+            IMGUI_DEBUG_LOG_VIEWPORT("[viewport] Focused viewport changed %08X -> %08X, attempting to apply our focus.\n", g.PlatformLastFocusedViewportId, focused_viewport->ID);
+            const ImGuiViewport* prev_focused_viewport = FindViewportByID(g.PlatformLastFocusedViewportId);
+            const bool prev_focused_has_been_destroyed = (prev_focused_viewport == NULL) || (prev_focused_viewport->PlatformWindowCreated == false);
+
             // Store a tag so we can infer z-order easily from all our windows
             // We compare PlatformLastFocusedViewportId so newly created viewports with _NoFocusOnAppearing flag
             // will keep the front most stamp instead of losing it back to their parent viewport.
@@ -14011,10 +14015,12 @@ static void ImGui::UpdateViewportsNewFrame()
                 focused_viewport->LastFocusedStampCount = ++g.ViewportFocusedStampCount;
             g.PlatformLastFocusedViewportId = focused_viewport->ID;
 
-            // Focus associated dear imgui window if focus didn't happen with a click within imgui boundaries (#6299)
-            // e.g. Clicking platform title bar.
+            // Focus associated dear imgui window
+            // - if focus didn't happen with a click within imgui boundaries, e.g. Clicking platform title bar. (#6299)
+            // - if focus didn't happen because we destroyed another window (#6462)
             // FIXME: perhaps 'FocusTopMostWindowUnderOne()' can handle the 'focused_window->Window != NULL' case as well.
-            if (!IsAnyMouseDown())
+            const bool apply_imgui_focus_on_focused_viewport = !IsAnyMouseDown() && !prev_focused_has_been_destroyed;
+            if (apply_imgui_focus_on_focused_viewport)
             {
                 focused_viewport->LastFocusedHadNavWindow |= (g.NavWindow != NULL) && (g.NavWindow->Viewport == focused_viewport); // Update so a window changing viewport won't lose focus.
                 ImGuiFocusRequestFlags focus_request_flags = ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild;
@@ -14714,6 +14720,7 @@ void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport)
     ImGuiContext& g = *GImGui;
     if (viewport->PlatformWindowCreated)
     {
+        IMGUI_DEBUG_LOG_VIEWPORT("[viewport] Destroy Platform Window %08X '%s'\n", viewport->ID, viewport->Window ? viewport->Window->Name : "n/a");
         if (g.PlatformIO.Renderer_DestroyWindow)
             g.PlatformIO.Renderer_DestroyWindow(viewport);
         if (g.PlatformIO.Platform_DestroyWindow)