Open tmssngr opened 2 weeks ago
Expected behavior For 150% Windows/monitor zoom level, I expect
150
to be reported, for 175% I expect to get175
. Otherwise the image datas I report back are too small for 150% zoom level.
Can you please explain where this expectation comes from? The behavior should have never been like this. Actually, the behavior of having the device zoom being "rounded" to multiples of 100 is intended as being established several years ago: https://eclipse.dev/eclipse/news/4.6/platform.php#swt-autoscale-tweaks
If the application is supposed to scale everything according to the actual native zoom (including images), you should use swt.autoScale=quarter
or swt.autoScale=exact
.
My expectation comes from the fact that numbers like 100
or 200
are used. If the rounding to 100
would be the goal, I would have expected the use of 1
and 2
(factor).
Background: until now we were using swt.autoScale=none
because this gave us access to the full resolution on Windows with 4k monitors.
Is there also a mode where my solely my ImageDataProvider
decides what image to use (without any magic auto-zooming under the hood)?
BTW, how I can request the actual shell's zoom level now?
I have to admit that I do not understand the actual issue: is there any behavior that has changed? With swt.autoScale=none
, the zoom value should have always been rounded to a multiple of 100. none
is not a valid value for swt.autoScale
, so the code always defaults back to this:
https://github.com/eclipse-platform/eclipse.platform.swt/blob/d30571a8ec3a756f7b806574f15506e153b07254/bundles/org.eclipse.swt/Eclipse%20SWT/common/org/eclipse/swt/internal/DPIUtil.java#L651-L653
Also the image constructor retrieving the image data has always taken this device zoom, if I am not mistaken. So would be interesting to know where the behavior has actually changed in comparison to, e.g., the previous release of Eclipse SWT.
Is there also a mode where my solely my
ImageDataProvider
decides what image to use (without any magic auto-zooming under the hood)?
In the ImageDataProvider
, you can do whatever you want. No one forces you to consider the zoom value passed to it. However, the question is how you want to provide properly scaled image data if you do not consider the context and its scaling. With the improved HiDPI support coming up (https://eclipse.dev/eclipse/news/4.34/platform.php#rescale-on-runtime-preference), you need to consider the context in which an image is used to adapt it to the zoom level of the monitor currently working on. If you do not want to support this kind of functionality in the future, you could fall back to, e.g., the non-API DPIUtil#getNativeDeviceZoom()
to retrieve the original zoom value of the OS.
BTW, how I can request the actual shell's zoom level now?
A shell does not have any public API to retrieve its zoom. It has the See comment belowgetZoom()
method to retrieve the zoom used by SWT (which in your scenario is 100/200/...) and it has nativeZoom
with the original native zoom of the application, but none of them is accessible outside SWT. In which scenario do you need to retrieve the zoom of a shell?
A shell does not have any public API to retrieve its zoom.
Shell.getMonitor().getZoom()
?
In the ImageDataProvider, you can do whatever you want. No one forces you to consider the zoom value passed to it. However, the question is how you want to provide properly scaled image data if you do not consider the context and its scaling.
I've tried our application with the new SWT library with swt.autoScale
set to quarter
or exact
. It caused auto-scaling for some images (e.g. in buttons), because there were some scaling artefacts visible, e.g. duplicate pixels where in the 100% and 200% images were just 1-pixel width.
What can I do to use our 200% zoom images for a system zoom level of 150%? How can I avoid any auto-scaling for the image datas provided by my ImageDataProvider
?
Also the image constructor retrieving the image data has always taken this device zoom, if I am not mistaken. So would be interesting to know where the behavior has actually changed in comparison to, e.g., the previous release of Eclipse SWT.
We were using the swt.autoScale=false
(sorry, my above mentioned none
was the wrong value) on Windows since SWT began to supported HiDPI, because it looked better. Now I assume that the new monitor-specific zoom handling seems to require that we avoid this hack.
What can I do to use our 200% zoom images for a system zoom level of 150%? How can I avoid any auto-scaling for the image datas provided by my
ImageDataProvider
?
From my understanding, for a system zoom of 150%, the 200% images will only be used when using quarter
or exact
mode (and then scaled down from 200% to 150%). If you are using integer200
or false
, the effective application zoom is 100% and thus the 100% images are requested by SWT. But it should have always been like this. Auto-scaling of images is only performed if the image is not provided in the same zoom as required by the consumer, e.g., if you provide a 200% image while the application requests a 150% one. But if you are running your application with swt.autoScale=false
, it should have never used the 200% images, has it?
We were using the
swt.autoScale=false
(sorry, my above mentionednone
was the wrong value) on Windows since SWT began to supported HiDPI, because it looked better. Now I assume that the new monitor-specific zoom handling seems to require that we avoid this hack.
The new monitor-specific scaling should not affect the existing behavior in any way. It is supposed to be an opt-in feature (for now). So if anything works different for you then it did before, there is probably some regression that we missed so far. We actively test integer200
(as the default) and quarter
(as the "reasonable") mode, so we may have missed some changes that unintentionally affected the false
mode.
So SWT always performs auto-scaling for images (e.g. for zoom levels like 150% or 175%) and there is no way to avoid it?
So SWT always performs auto-scaling for images (e.g. for zoom levels like 150% or 175%) and there is no way to avoid it?
It depends:
quarter
and exact
for swt.autoScale
, SWT will auto scale images for matching zoom levels like 150% or 175% (in case there is no according image present, as you may also provide a proper 150% image).integer200
and false
for swt.autoScale
, there will usually be no auto scaling, as effectively zoom values will be limited to 100% and 200% with these settings (and with false
even only 100%). Images are actually the reason for these scaling modes, as in general the quarter/exact scaling makes more sense but requires (rasterized) images to be rescaled. Once we support SVG render at runtime, that would become obsolete.But as said: this is existing behavior of SWT for years, and none of the recent changes should have affected that.
How do I get the exact bounds of the loaded image (with swt.autoScale
unset)? Note, that getBoundsInPixels()
is deprecated and hence no allowed answer. ;)
Background: we are loading an image containing multiple sub-images:
The code that extracts the subimages knows the subimage counts per row/column and hence asserts that bounds.width % columnCount == 0
and bounds.height % rowCount == 0
.
Describe the bug An
ImageDataProvider
can be used to provide differentImageData
instances for the passed zoom level. This does not work correctly - the passed zoom level is incorrect. It "snaps" to multiples of 100. For 150% zoom level on Windows 11, I'm getting the value100
, for 175% zoom level I'm getting200
.To Reproduce Run this snippet on Windows 11 with different monitor zoom levels (I only have one 4k monitor attached):
It will log the reported zoom level.
Expected behavior For 150% Windows/monitor zoom level, I expect
150
to be reported, for 175% I expect to get175
. Otherwise the image datas I report back are too small for 150% zoom level.Screenshots For 150% zoom level:
For 175% zoom level:
Environment:
Select the platform(s) on which the behavior is seen:
Additional OS info (e.g. OS version, Linux Desktop, etc) Tried on Windows 11 23H2 with one 32" 4k monitor attached.
Workaround (or) Additional context Set swt.autoScale to false, but this will cause other problems.