nanogui icon indicating copy to clipboard operation
nanogui copied to clipboard

Per-monitor DPI scaling

Open Wouterdek opened this issue 4 years ago • 0 comments

NanoGUI already supports scaling applications based on the DPI of the monitor. However, most GUI frameworks (including Qt, GTK3, WxWidgets, WPF/UWP, ...) now support "per-monitor DPI" and it seems NanoGUI does not. The idea here is that as an application window is dragged from one monitor to another, the window is rerendered with the DPI value of the second screen. This makes sure GUI elements maintain a consistent physical size, independent of screen size or resolution.

Below are two screenshots of a NanoGUI application on two different monitors on the same Windows computer. Notice that the application did not scale correctly in the second image, while Firefox in the background did.

monitor1 monitor2

It might be very simple to support this in NanoGUI. The snippet below offloads all the hard work of detecting DPI changes to GLFW. The rescaling uses the pre-existing mPixelRatio and get_pixel_ratio.

glfwSetWindowContentScaleCallback(mGLFWWindow,
    [](GLFWwindow* w, float xScale, float yScale) {
        auto it = __nanogui_screens.find(w);
        if (it == __nanogui_screens.end())
            return;
        Screen* s = it->second;
        
        s->mPixelRatio = get_pixel_ratio(w);
        if(!s->mFullscreen) {
            auto width = s->mSize.x() * s->mPixelRatio;
            auto height = s->mSize.y() * s->mPixelRatio;
            glfwSetWindowSize(w, width, height);
            s->resizeCallbackEvent(width, height);
        }
    }
);

The only issue here is that glfwSetWindowContentScaleCallback is a GLFW 3.3 function, while NanoGUI seems to be using 3.2.

Wouterdek avatar Apr 20 '20 10:04 Wouterdek