Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rendering errors caused by dragging the window across monitors with different DPI scaling. #7757

Open
wants to merge 2 commits into
base: docking
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions backends/imgui_impl_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()

// Forward Declarations
static void ImGui_ImplGlfw_UpdateMonitors();
static void ImGui_ImplGlfw_UpdateViewports();
static void ImGui_ImplGlfw_InitMultiViewportSupport();
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport();

Expand Down Expand Up @@ -977,6 +978,7 @@ void ImGui_ImplGlfw_NewFrame()
bd->Time = current_time;

bd->MouseIgnoreButtonUp = false;
ImGui_ImplGlfw_UpdateViewports();
ImGui_ImplGlfw_UpdateMouseData();
ImGui_ImplGlfw_UpdateMouseCursor();

Expand Down Expand Up @@ -1058,6 +1060,7 @@ struct ImGui_ImplGlfw_ViewportData
{
GLFWwindow* Window;
bool WindowOwned;
bool PlatformRequestResizeNextFrame;
int IgnoreWindowPosEventFrame;
int IgnoreWindowSizeEventFrame;
#ifdef _WIN32
Expand All @@ -1068,6 +1071,25 @@ struct ImGui_ImplGlfw_ViewportData
~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); }
};

static void ImGui_ImplGlfw_UpdateViewports()
{
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
for (int n = 0; n < platform_io.Viewports.Size; n++)
{
ImGuiViewport* viewport = platform_io.Viewports[n];
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData){
if(vd->PlatformRequestResizeNextFrame){
// The previous frame's windowSizeCallback was invoked when glfwSetWindowPos was used, not triggered by glfwPollEvent.
// At this point, some critical operations that depend on PlatformRequestResize have already been completed.
// The PlatformRequestResize flag is cleared at the end of the frame,
// so we delay the operation to the current frame to ensure that the PlatformRequestResize behavior is fully completed.
viewport->PlatformRequestResize = true;
vd->PlatformRequestResizeNextFrame = false;
}
}
}
}

static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
{
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
Expand Down Expand Up @@ -1105,6 +1127,15 @@ static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
//data->IgnoreWindowSizeEventFrame = -1;
if (ignore_event)
return;

bool delay_to_next_frame = (ImGui::GetFrameCount() <= vd->IgnoreWindowPosEventFrame + 1);

if(delay_to_next_frame){
// glfwSetWindowPos and glfwSetWindowSizeCallback are called in the same frame
// we should not process the resize event in this frame
vd->PlatformRequestResizeNextFrame = true;
return;
}
}
viewport->PlatformRequestResize = true;
}
Expand Down