Browse Source

Viewport: Fix lagging overlay clipping rectangle on viewport owning window (affecting sync of multi-layered docking overlays). This was extremely tricky to find and fix (*). (#1541)
(*) Merely assigning viewport->Pos = pos in UpdateMovingWindow() broke a series of thing because the code that assign viewports and viewport flags relied on moving window leaving its own viewport the first time to set the NoInputs flag.

omar 7 years ago
parent
commit
7e6700d261
1 changed files with 8 additions and 2 deletions
  1. 8 2
      imgui.cpp

+ 8 - 2
imgui.cpp

@@ -3612,6 +3612,8 @@ static void ImGui::UpdateMovingWindow()
             {
                 MarkIniSettingsDirty(moving_window);
                 SetWindowPos(moving_window, pos, ImGuiCond_Always);
+                if (moving_window->ViewportOwned) // Synchronize viewport immediately because some overlays may relies on clipping rectangle before we Begin() into the window.
+                    moving_window->Viewport->Pos = pos;
             }
             FocusWindow(g.MovingWindow);
         }
@@ -6612,8 +6614,12 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
     }
     else if (g.MovingWindow && g.MovingWindow->RootWindow == window && IsMousePosValid())
     {
-        // Transition to a standalone viewport
-        if (!window->Viewport->GetRect().Contains(window->Rect()))
+        // Transition to our own viewport when leaving our host boundaries + set the NoInputs flag (which will be cleared in UpdateMovingWindow when releasing the mouse)
+        // If we are already in our own viewport, if need to set the NoInputs flag.
+        bool own_viewport = window->Viewport->Window == window; // We test window->Viewport->Window because window->ViewportOwned is not valid during this function.
+        bool leave_host_viewport = !own_viewport && !window->Viewport->GetRect().Contains(window->Rect());
+        bool move_from_own_viewport = own_viewport && !(window->Viewport->Flags & ImGuiViewportFlags_NoInputs);
+        if (leave_host_viewport || move_from_own_viewport)
             window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoInputs);
     }
     else if (GetWindowAlwaysWantOwnViewport(window))