Closed IceReaper closed 5 months ago
Looks like PhotinoNET.Monitor
structure should have Scale property.
In theory this should work:
Thanks for this suggestion. We will add this to our backlog, but haven't determined its position in our priority queue yet.
It should also somehow address a window being moved from one screen to another with a different DPI setting.
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.
@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..
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.
Pull request was merged into debug branch.
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.