Fix screen grabbing zones coordinates when screen scaling is used
When the app is running on a system which uses screen scaling factor other than "1.0", then grabber widget logical coordinates will differ from physical coordinates. Physical coordinates could be calculated by multiplying logical coordinates to a device pixel ratio.
Can one of the admins verify this patch?
Can one of the admins verify this patch?
Thanks for the PR!
Which OS are you testing on? On windows this value seems to be always 1 even when using scaling.
ok to test
When device pixel ratio is 1, then probably everything should work as expected, shouldn't it?
In my case it was Linux/KDE and screen scaling was set to 2 manually in KDE settings.
Also please note that I haven't tested it on multi-screen multi-DPI environment. BTW does Lightpack support such configurations properly?
When device pixel ratio is 1, then probably everything should work as expected, shouldn't it?
Oh yes, I didn't mean to imply this would break something.
In my case it was Linux/KDE and screen scaling was set to 2 manually in KDE settings.
SG. I'm not familiar with scaling on linux, but I assume that's the standard way people would change the scaling.
Also please note that I haven't tested it on multi-screen multi-DPI environment. BTW does Lightpack support such configurations properly?
At least on windows, Prismatik is kind of scaling agnostic. It uses desktop coordinates for the widgets and those match with the screenshot coordinates when adjusting for the screen position. The windows scaling doesn't change the resolution.
In your case different screens could have different ratios I assume, so rather than using the QApp's ratio, you should use the ratio given by the Window, i.e. the Widget: grabWidget->devicePixelRatio()
Oh, my bad. I've taken the ratio from the wrong place. Will fix.
At least on windows, Prismatik is kind of scaling agnostic. It uses desktop coordinates for the widgets and those match with the screenshot coordinates when adjusting for the screen position. The windows scaling doesn't change the resolution.
Hmm. Qt scaling works pretty similar on each platform. Does UI look properly scaled when you use it on high-DPI screens?
Windows scaling is a mess and most things look acceptable only after restarting them after changing the scale.
For example, this is Prismatik when I set my windows scaling to 200%:

I'm not sure why most of the text size does not scale properly in Prismatik...
Ah, got it. App does not use Qt scaling in your case. That's why devicePixelRatio is 1. Instead you tell Windows to
scale the app. So the app is rendered in low-resolution and then up-scaled. To llok good, the app should enable auto-scaling. Also the devicePixelRatio will become 2 :) In my case KDE enables Qt scaling through the environment. In Windows the same approach is also possible, but the better way is to enable scaling in the code. However this is another task. I'll take a look at it later.
I'm pretty sure it's not the case that windows scales the app. If that were the case, proportions of the elements in the UI would remain the same, but I guess that's not really relevant for this change.
In your case different screens could have different ratios I assume, so rather than using the QApp's ratio, you should use the ratio given by the Window, i.e. the Widget:
grabWidget->devicePixelRatio()
probably grabWidget->screen()->devicePixelRatio()
also I think this might break the widget scaling on macOS, where it currently works (or did anyway) as is, so maybe wrap it in #ifdef MACOS or something for now
I'll try to check it there.
probably
grabWidget->screen()->devicePixelRatio()
Docs for QGuiApplication: "Use this function only when you don't know which window you are targeting. If you do know the target window, use QWindow::devicePixelRatio() instead." Docs for QWindow: "Note: For windows not backed by a platform window, ..., the function will fall back to the associated QScreen's device pixel ratio."
The widget's method should be preferred IIUC.
also I think this might break the widget scaling on macOS, where it currently works (or did anyway) as is, so maybe wrap it in
#ifdef MACOSor something for now
Indeed, docs: "Common values are 1.0 on normal displays and 2.0 on Apple "retina" displays."
I believe it's currently working on MacOS because we're adjusting for the pixel ratio in the grabber. We might want to do the same for the X grabber instead of changing the maths here, WDYT?
Docs for QGuiApplication: "Use this function only when you don't know which window you are targeting. If you do know the target window, use QWindow::devicePixelRatio() instead." Docs for QWindow: "Note: For windows not backed by a platform window, ..., the function will fall back to the associated QScreen's device pixel ratio."
The widget's method should be preferred IIUC.
I just tested app, widget, widget->screen and widget returned 1.00 while the other two 1.25 (as per settings), but I only have 1 screen, so it'll be whichever works for multiple screens :D
Indeed, docs: "Common values are 1.0 on normal displays and 2.0 on Apple "retina" displays."
macOS allows (in some cases?) for intermediate values (with some blurriness), I don't know if Qt returns the right values now, I used the native api at the time
I believe it's currently working on MacOS because we're adjusting for the pixel ratio in the grabber. We might want to do the same for the X grabber instead of changing the maths here, WDYT?
the scale is used in mac grabber so we capture a 1x image (since the capture allows almost any target scaling), but the scale returned to GrabberBase isn't adjusted, so it's as if it was already multiplied
the other grabbers aren't as flexible (speaking of which, maybe we can bump DDupl DownscaleMipLevel to 4 when 200% is used?)
So IF Qt method works everywhere and the native apis aren't required maybe it's better to just centralise in GrabberBase
But.. I tested in XFCE, and the scaling doesn't affect Qt apps (you indeed need to set some specific env vars), but if Prismatik is the only Qt app you run in background maybe you won't bother/think scaling properly, so maybe that'll need a native call?... way too hot to think right now for me!
Qt6 has changed the coordinate system to a scaling dependent one, so things need to be adjusted. I did that on master meanwhile but could use help testing this on Mac on Linux systems