tryphotino / photino.Blazor

https://tryphotino.io
Apache License 2.0
328 stars 62 forks source link

HighDPI issues #105

Closed IceReaper closed 5 months ago

IceReaper commented 8 months ago

Windows 11 again -> When using a 200% display scale, the window dimensions api breaks. Basically SetSize does not take the scale into account, and my mouse cursor coordinates are also not taking that into account. I end up having a window which is too small, and a resize behavior which resizes only half the resolution. If SetSize would take the scale into account and multiply the values, this problem would be gone.

Andersen27 commented 8 months ago

Looks like PhotinoNET.Monitor structure should have Scale property.

In theory this should work:

ottodobretsberger commented 7 months ago

Thanks for this suggestion. We will add this to our backlog, but haven't determined its position in our priority queue yet.

IceReaper commented 7 months ago

It should also somehow address a window being moved from one screen to another with a different DPI setting.

IceReaper commented 7 months ago

Here is some usage code with some comment about whats going wrong:

    private async Task ObserveScale(CancellationToken token)
    {
        double initialRatio = await JsRuntime.InvokeAsync<double>("eval", token, "devicePixelRatio");
        double initialDpi = App.MainWindow.ScreenDpi;
        double baseDpi = initialDpi / initialRatio;
        double currentDpi = baseDpi;

        while (!token.IsCancellationRequested)
        {
            // TODO The library does not expose yet whether we are still resizing or moving the window.
            // TODO 1. If the dpi change is triggered by resizing across monitors, this logic will glitch.
            // TODO    The solution would be to add an event to the library to inform when resizing starts and ends.
            // TODO    And while a resize is in progress, we should skip this logic.
            // TODO 2. If the dpi change is triggered by moving the window across monitors, this logic will also glitch.
            // TODO    This is mainly because the library seems to cache the old window size while moving.
            // TODO    This causes the library overwriting the new size with the old size.
            if (Math.Abs(App.MainWindow.ScreenDpi - currentDpi) != 0)
            {
                double currentRatio = currentDpi / baseDpi;
                double targetRatio = App.MainWindow.ScreenDpi / baseDpi;
                double factor = targetRatio / currentRatio;

                Point minSize = App.MainWindow.MinSize;
                Size currentSize = App.MainWindow.Size;

                // TODO MinSize appears to be always 0,0. That is a library bug, remove when fixed in library!
                if (minSize is { X: 0, Y: 0 })
                    minSize = new Point((int)(Program.MinWidth * currentRatio), (int)(Program.MinHeight * currentRatio));

                App.MainWindow.MinSize = new Point((int)(minSize.X * factor), (int)(minSize.Y * factor));
                App.MainWindow.Size = new Size((int)(currentSize.Width * factor), (int)(currentSize.Height * factor));

                currentDpi = App.MainWindow.ScreenDpi;
            }

            await Task.Delay(TimeSpan.FromMilliseconds(100), token);
        }
    }

At best, we do not need to do this magic after all, and the Photino window expects all sizes to be for 100% scale, and automatically handles resizing and adjusting min sizes itself.

pm64 commented 6 months ago

@IceReaper @Andersen27 do we have enough information to cobble together a PR? I'm working to get up to speed on this code base, definitely not my area of expertise, but I may also be able to contribute. I think this is a critical defect, undermining lots of important use cases.

May I ask if this is this just a matter of putting in the time? Or are there unknowns here that still need to be solved? @Andersen27 proposes a pretty compelling roadmap to having a Scale property on PhotinoNET.Monitor, this would seem to give us a decent running start..

Andersen27 commented 6 months ago

PR 1: https://github.com/tryphotino/photino.Native/pull/128 PR 2: https://github.com/tryphotino/photino.NET/pull/175

Just adding the Scale property for Monitor structure, without correcting the interaction with the window. But at least developers will get this info.

MikeYeager commented 5 months ago

Pull request was merged into debug branch.