imgui icon indicating copy to clipboard operation
imgui copied to clipboard

Fix windows framebuffer scaling for glfw

Open Krasjet opened this issue 3 years ago • 3 comments

The current framebuffer scaling for GLFW backend is obtained by dividing the framebuffer size by window size, but this is unreliable and only works on macOS.

On Windows, it is possible to let GLFW scale the framebuffer according to monitor DPI (similar to macOS behavior) using the hint

glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);

but unlike macOS, the window size and framebuffer size is always the same on Windows. The automatic scaling scales both the framebuffer and window size. The actual framebuffer scaling should be obtained from glfwGetWindowContentScale. Try the following:

int w, h;
glfwGetWindowSize(win, &w, &h);
ImGui::Text("window size: %d %d", w, h);
glfwGetFramebufferSize(win, &w, &h);
ImGui::Text("framebuffer size: %d %d", w, h);
float x, y;
glfwGetWindowContentScale(win, &x, &y);
ImGui::Text("glfw scale: %f %f", x, y);

You should see both the window size and framebuffer size changes after moving the window to a different DPI screen.

Therefore, the actual DisplaySize for ImGui should be computed by framebuffer size divided by the content scale. Because GLFW mouse position is based on window size, there is some additional mouse position scaling that needs to be done.

Krasjet avatar Aug 18 '22 05:08 Krasjet

I suspect the mouse position here also needs to be scaled, but I'm not familiar with the use case for this so I can't test it.

        if (io.WantSetMousePos)
            glfwSetCursorPos(bd->Window, (double)io.MousePos.x, (double)io.MousePos.y);

Krasjet avatar Aug 18 '22 05:08 Krasjet