2
0
Эх сурвалжийг харах

Viewports, Backends: GLFW: Fix windows resizing incorrectly due to GLFW firing window positioning callbacks on next frame after window is resized manually. (#2117)

+ Docking fixed PVS warning
Rokas Kupstys 5 жил өмнө
parent
commit
7f8b076f2b

+ 19 - 8
examples/imgui_impl_glfw.cpp

@@ -491,9 +491,10 @@ struct ImGuiViewportDataGlfw
 {
 {
     GLFWwindow* Window;
     GLFWwindow* Window;
     bool        WindowOwned;
     bool        WindowOwned;
+    int         IgnoreWindowPosEventFrame;
     int         IgnoreWindowSizeEventFrame;
     int         IgnoreWindowSizeEventFrame;
 
 
-    ImGuiViewportDataGlfw()  { Window = NULL; WindowOwned = false; IgnoreWindowSizeEventFrame = -1; }
+    ImGuiViewportDataGlfw()  { Window = NULL; WindowOwned = false; IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
     ~ImGuiViewportDataGlfw() { IM_ASSERT(Window == NULL); }
     ~ImGuiViewportDataGlfw() { IM_ASSERT(Window == NULL); }
 };
 };
 
 
@@ -503,10 +504,25 @@ static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
         viewport->PlatformRequestClose = true;
         viewport->PlatformRequestClose = true;
 }
 }
 
 
+// GLFW may dispatch window pos/size events after calling glfwSetWindowPos()/glfwSetWindowSize().
+// However: depending on the platform the callback may be invoked at different time:
+// - on Windows it appears to be called within the glfwSetWindowPos()/glfwSetWindowSize() call
+// - on Linux it is queued and invoked during glfwPollEvents()
+// Because the event doesn't always fire on glfwSetWindowXXX() we use a frame counter tag to only
+// ignore recent glfwSetWindowXXX() calls.
 static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
 static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
 {
 {
     if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
     if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
+    {
+        if (ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData)
+        {
+            bool ignore_event = (ImGui::GetFrameCount() <= data->IgnoreWindowPosEventFrame + 1);
+            //data->IgnoreWindowPosEventFrame = -1;
+            if (ignore_event)
+                return;
+        }
         viewport->PlatformRequestMove = true;
         viewport->PlatformRequestMove = true;
+    }
 }
 }
 
 
 static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
 static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
@@ -515,14 +531,8 @@ static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
     {
     {
         if (ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData)
         if (ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData)
         {
         {
-            // GLFW may dispatch window size event after calling glfwSetWindowSize().
-            // However depending on the platform the callback may be invoked at different time: on Windows it
-            // appears to be called within the glfwSetWindowSize() call whereas on Linux it is queued and invoked
-            // during glfwPollEvents().
-            // Because the event doesn't always fire on glfwSetWindowSize() we use a frame counter tag to only
-            // ignore recent glfwSetWindowSize() calls.
             bool ignore_event = (ImGui::GetFrameCount() <= data->IgnoreWindowSizeEventFrame + 1);
             bool ignore_event = (ImGui::GetFrameCount() <= data->IgnoreWindowSizeEventFrame + 1);
-            data->IgnoreWindowSizeEventFrame = -1;
+            //data->IgnoreWindowSizeEventFrame = -1;
             if (ignore_event)
             if (ignore_event)
                 return;
                 return;
         }
         }
@@ -658,6 +668,7 @@ static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport)
 static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
 static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
 {
 {
     ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
     ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
+    data->IgnoreWindowPosEventFrame = ImGui::GetFrameCount();
     glfwSetWindowPos(data->Window, (int)pos.x, (int)pos.y);
     glfwSetWindowPos(data->Window, (int)pos.x, (int)pos.y);
 }
 }
 
 

+ 2 - 2
imgui.cpp

@@ -13350,8 +13350,8 @@ static void ImGui::DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockN
     // Build a tentative future node (reuse same structure because it is practical. Shape will be readjusted when previewing a split)
     // Build a tentative future node (reuse same structure because it is practical. Shape will be readjusted when previewing a split)
     data->FutureNode.HasCloseButton = (host_node ? host_node->HasCloseButton : host_window->HasCloseButton) || (root_payload->HasCloseButton);
     data->FutureNode.HasCloseButton = (host_node ? host_node->HasCloseButton : host_window->HasCloseButton) || (root_payload->HasCloseButton);
     data->FutureNode.HasWindowMenuButton = host_node ? true : ((host_window->Flags & ImGuiWindowFlags_NoCollapse) == 0);
     data->FutureNode.HasWindowMenuButton = host_node ? true : ((host_window->Flags & ImGuiWindowFlags_NoCollapse) == 0);
-    data->FutureNode.Pos = host_node ? ref_node_for_rect->Pos : host_window->Pos;
-    data->FutureNode.Size = host_node ? ref_node_for_rect->Size : host_window->Size;
+    data->FutureNode.Pos = ref_node_for_rect ? ref_node_for_rect->Pos : host_window->Pos;
+    data->FutureNode.Size = ref_node_for_rect ? ref_node_for_rect->Size : host_window->Size;
 
 
     // Calculate drop shapes geometry for allowed splitting directions
     // Calculate drop shapes geometry for allowed splitting directions
     IM_ASSERT(ImGuiDir_None == -1);
     IM_ASSERT(ImGuiDir_None == -1);