Make ImGui (widgets) automatically scale with display scaling

when moving a window between screens with different scaling settings.

What’s currently happening:

  1. Start application on primary display with scaling set to 150%

  2. Move it to a secondary display with scaling set to 100%
    The widgets stay at the same size and are “cut off”.

Instead they should rescale, to the same size they’d have when started on a (primary) display set to 100%.

I think I tracked down the issue (to a certain point). VL.ImGui.Skia.ToSkiaLayer already does factor in the display scaling. For that it uses DipFactor() in VL.UI.Core.DipHelpers.

Unfortunately this method seems only to return the DIPFactor of the primary monitor.

But the factor should be dependent on the window ImGui is rendered into (and on which display it’s located).

This works and dynamically updates when moving the window to another monitor for example:

I also came accross that one:

Could something like that be added to ToSkiaLayer (or where necessary) or can we get access to the scaling parameter so it can be set patch-wise?


DPI.vl (19.7 KB)


Somewhat related I guess:

We’ll have to add some sort of abstraction to do this or we end up with another windows dependency right in the core. That’s why it will take some thinking and can’t be done straight away. But since UI is on the horizon again it might be tackled then since we for sure will hit the same issue.


Just hacked this into ToSkiaLayer:

public unsafe ToSkiaLayer(float scaling = 1.0f)
    _context = new SkiaContext();
    using (_context.MakeCurrent())
        _io = ImGui.GetIO();
        _io.NativePtr->IniFilename = null;

        _renderContext = RenderContext.ForCurrentThread();

        _fontPaint = new Handle<SKPaint>(new SKPaint());

        //var scaling = VL.UI.Core.DIPHelpers.DIPFactor();
        updateScaling(fontScaling: scaling, uiScaling: scaling);

Unfortunately it somehow only affects the FontScaling but not the UIScaling.

But could this be made to work and added in the meantime until you finished thinking up the proper solution?

Mentioned this in the chat already but still for reference: