nap icon indicating copy to clipboard operation
nap copied to clipboard

High DPI scaling Linux/X11

Open cklosters opened this issue 5 months ago • 0 comments

It's not really a bug, more of an annoyance: With the latest upgrade to [SDL2 2.30.7] the the dpi of the individual displays is now (finally) correct. This means that when 'EnableHighDPI' is enabled on Linux the gui is scaled appropiately - relative to a base dpi of 96 (the dpi windows reports with a scaling factor of 100%.)

But the end result is different because the DPI on windows is variable (based on selected scale against a dpi of 96), where the dpi on Linux is not? Meaning that the actual desktop scaling factor is currently not taken into consideration when computing the internal scale on Linux / X11. This should be resolved under Wayland but at the moment SDL2 reverts back to the X11 compatibility layer. Experimenting with SDL_GetCurrentDesktopDisplayMode, SDL_GetWindowSize and SDL_GetCurrentDisplayMode always return the full (not scaled, native) pixel resolution. If it would return the correct scaling factor we would be able to compensate internally.

To solve this I can try to get the desktop scaling factor in X11, wait for SDL3 or make Wayland the default. Wayland as a standalone video driver is not yet included because we currently still target Ubuntu 20.04. Wayland support can be enabled when we drop 20.04 as a target, starting with NAP 0.8.0. This means that for now, under a wayland session, the xwayland compatibility layer will be used to run NAP compiled apps under wayland.

You can change the IMGuiServiceConfiguration - GlobalScale factor in combination with the RenderServiceConfiguration -EnableHighDPI setting to work around this problem, if you experience scaling issues right now on Linux.

From the SDL2 docs:

WARNING: This reports the DPI that the hardware reports, and it is not always reliable! It is almost always better to use SDL_GetWindowSize() to find the window size, which might be in logical points instead of pixels, and then SDL_GL_GetDrawableSize(), SDL_Vulkan_GetDrawableSize(), SDL_Metal_GetDrawableSize(), or SDL_GetRendererOutputSize(), and compare the two values to get an actual scaling value between the two. We will be rethinking how high-dpi details should be managed in SDL3 to make things more consistent, reliable, and clear.

cklosters avatar Sep 06 '24 20:09 cklosters