diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index 495796fd..f1d38701 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -491,9 +491,10 @@ struct ImGuiViewportDataGlfw { GLFWwindow* Window; bool WindowOwned; + int IgnoreWindowPosEventFrame; int IgnoreWindowSizeEventFrame; - ImGuiViewportDataGlfw() { Window = NULL; WindowOwned = false; IgnoreWindowSizeEventFrame = -1; } + ImGuiViewportDataGlfw() { Window = NULL; WindowOwned = false; IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; } ~ImGuiViewportDataGlfw() { IM_ASSERT(Window == NULL); } }; @@ -503,10 +504,25 @@ static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window) 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) { 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; + } } 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) { - // 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); - data->IgnoreWindowSizeEventFrame = -1; + //data->IgnoreWindowSizeEventFrame = -1; if (ignore_event) return; } @@ -658,6 +668,7 @@ static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport) static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos) { ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData; + data->IgnoreWindowPosEventFrame = ImGui::GetFrameCount(); glfwSetWindowPos(data->Window, (int)pos.x, (int)pos.y); } diff --git a/imgui.cpp b/imgui.cpp index 23ce906c..54743e34 100644 --- a/imgui.cpp +++ b/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) 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.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 IM_ASSERT(ImGuiDir_None == -1);