You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
The per-window-auto-scaling enabled in c35c568 broke the ScrolledComposite behavior (for displaying scrollbars only if needed) used for displaying dialogs in our applications.
Expected behavior
The ScrolledComposite should work as with commit 577b1d6 or earlier.
The behavior is unchanged when at 100% zoom. For fractional zooms, the expected behavior is probably impossible to achieve with the integer-based precision of SWT's logical coordinate system but requires a rewrite and API exchange for SWT coordinates.
It might be possible to improve specific calculations/roundings to achieve better compatibility here, but it might not be that easy and, in particular, the time might be better invested into finding a proper UI definition than aligning sizes with each other in a custom way. There are layouts available for achieving the intended behavior which take care of fitting controls into each other. In case there are also issues when defining an according UI with layouts, I would rather invest time into fixing that.
IMHO the problem is that after scaling up and down the label.computeSize(r.width, SWT.DEFAULT) will return one pixel larger than r.width which is not expected. Are there any cases where for width or height != SWT.DEFAULT a different size is returned? Otherwise I would consider to change Control.computeSize:
publicPointcomputeSize (intwHint, inthHint, booleanchanged){
checkWidget ();
intzoom = computeBoundsZoom();
//We should never return a size that is to small, RoundingMode.UP ensures we at worst case report//a size that is a bit too large by half a pointreturnWin32DPIUtils.pixelToPointAsSufficientlyLargeSize(computeSizeInPixels(newPoint(wHint, hHint), zoom, changed), zoom);
}
to
publicPointcomputeSize (intwHint, inthHint, booleanchanged){
checkWidget ();
intzoom = computeBoundsZoom();
//We should never return a size that is to small, RoundingMode.UP ensures we at worst case report//a size that is a bit too large by half a pointfinalPointsize = Win32DPIUtils.pixelToPointAsSufficientlyLargeSize(computeSizeInPixels(newPoint(wHint, hHint), zoom, changed), zoom);
if (wHint != SWT.DEFAULT) size.x = wHint;
if (hHint != SWT.DEFAULT) size.y = hHint;
returnsize;
}
changed the title [-][Windows] Per-window-auto-scaling broke ScrolledComposite[/-][+][Windows] Per-window-auto-scaling broke computerSize(wHint, SWT.DEFAULT)[/+]on Mar 6, 2026
There are multiple issues summing up here. One is that the label.computeSize() call rounds up resulting in a width that is one point to large. But that's not the root cause, as it's fed with a value retrieved from getClientArea() that is already imprecise (too large).
getClientArea() is rounded value. The problem with getClientArea() is that there is no "proper" way of rounding that value. You have two use cases from consumer side requiring different rounding:
The consumer wants to fit something in the client area (like done here), then you would like to rather have a rounded-down value.
The consumer wants to fill the whole client area (e.g., for refresh the drawing), then you would like to rather have a rounded-up value.
An additional problem is that when converting rectangles between point and pixels, it's values are already rounded (so there is no Rectangle.OfFloat result with a rounding method that might be adapted). So as a consumer of `getClientArea(), you have no chance of reconstruction the actual/precise values. Maybe that's something that could be improved, but we need to be aware as we had quite some issues with not rounding or inconsistently rounding a rectangle's values due to the variety of its use cases.
IMHO the problem is that after scaling up and down the label.computeSize(r.width, SWT.DEFAULT) will return one pixel larger than r.width which is not expected. Are there any cases where for width or height != SWT.DEFAULT a different size is returned?
As mentioned above, that's not the root cause of the issue. And yes, there are of course cases in which the resulting width/height can be a different than the passed size. That's why those values are called "hints". The control can make use of them in whatever way it wants to compute the actual size. Otherwise there would not even be any need of calling computeSize() when you have the desired values at hand anyway.
I think, more and more I better understand that the rounding introduces problems, but duplicating all size/position methods for points and pixels is no alternative.
Otherwise there would not even be any need of calling computeSize() when you have the desired values at hand anyway.
Here we want to know the height for a given width because of text wrapping.
duplicating all size/position methods for points and pixels is no alternative.
Yes, in particular because SWT is intended to abstract from pixel values and relieve consumers from the necessity to deal with zooms. It's just that for fractional scaling it's difficult to achieve a proper behavior in every case due to the logical position/size values being integer-based. What we did at some places is to carry precise values in Point/Rectangle instances that are passed around under the hood. In this case, we might want to have getClientArea() yield a Rectangle that carries precise values, but the calculations on top of that would have to process those precise values as well. And you would need to be able to pass precise values to a computeSize() calculation, which is currently not possible due to the method accepting two integer values. Resolving all of that leads to something like in the following commit, which would fix most of the reported issue (but of course not in an acceptable way): HeikoKlare@a39d48b
Here we want to know the height for a given width because of text wrapping.
I see. What might also work here is to take the original client area width into account when setting the minimum size of the scrolled composite. I.e., in the listener, instead of ...
Activity
HeikoKlare commentedon Mar 5, 2026
The behavior is unchanged when at 100% zoom. For fractional zooms, the expected behavior is probably impossible to achieve with the integer-based precision of SWT's logical coordinate system but requires a rewrite and API exchange for SWT coordinates.
It might be possible to improve specific calculations/roundings to achieve better compatibility here, but it might not be that easy and, in particular, the time might be better invested into finding a proper UI definition than aligning sizes with each other in a custom way. There are layouts available for achieving the intended behavior which take care of fitting controls into each other. In case there are also issues when defining an according UI with layouts, I would rather invest time into fixing that.
tmssngr commentedon Mar 5, 2026
Just a guess without having looked at the implementation: maybe
computeSizeshould always round up so it definitely has enough space?tmssngr commentedon Mar 6, 2026
IMHO the problem is that after scaling up and down the
label.computeSize(r.width, SWT.DEFAULT)will return one pixel larger thanr.widthwhich is not expected. Are there any cases where for width or height != SWT.DEFAULT a different size is returned? Otherwise I would consider to change Control.computeSize:to
[-][Windows] Per-window-auto-scaling broke ScrolledComposite[/-][+][Windows] Per-window-auto-scaling broke computerSize(wHint, SWT.DEFAULT)[/+]HeikoKlare commentedon Mar 6, 2026
That's exactly what it does:
eclipse.platform.swt/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Control.java
Line 645 in ae58361
There are multiple issues summing up here. One is that the
label.computeSize()call rounds up resulting in a width that is one point to large. But that's not the root cause, as it's fed with a value retrieved fromgetClientArea()that is already imprecise (too large).getClientArea()is rounded value. The problem withgetClientArea()is that there is no "proper" way of rounding that value. You have two use cases from consumer side requiring different rounding:An additional problem is that when converting rectangles between point and pixels, it's values are already rounded (so there is no Rectangle.OfFloat result with a rounding method that might be adapted). So as a consumer of `getClientArea(), you have no chance of reconstruction the actual/precise values. Maybe that's something that could be improved, but we need to be aware as we had quite some issues with not rounding or inconsistently rounding a rectangle's values due to the variety of its use cases.
As mentioned above, that's not the root cause of the issue. And yes, there are of course cases in which the resulting width/height can be a different than the passed size. That's why those values are called "hints". The control can make use of them in whatever way it wants to compute the actual size. Otherwise there would not even be any need of calling
computeSize()when you have the desired values at hand anyway.tmssngr commentedon Mar 6, 2026
I think, more and more I better understand that the rounding introduces problems, but duplicating all size/position methods for points and pixels is no alternative.
Here we want to know the height for a given width because of text wrapping.
HeikoKlare commentedon Mar 6, 2026
Yes, in particular because SWT is intended to abstract from pixel values and relieve consumers from the necessity to deal with zooms. It's just that for fractional scaling it's difficult to achieve a proper behavior in every case due to the logical position/size values being integer-based. What we did at some places is to carry precise values in Point/Rectangle instances that are passed around under the hood. In this case, we might want to have
getClientArea()yield a Rectangle that carries precise values, but the calculations on top of that would have to process those precise values as well. And you would need to be able to pass precise values to acomputeSize()calculation, which is currently not possible due to the method accepting two integer values. Resolving all of that leads to something like in the following commit, which would fix most of the reported issue (but of course not in an acceptable way):HeikoKlare@a39d48b
I see. What might also work here is to take the original client area width into account when setting the minimum size of the scrolled composite. I.e., in the listener, instead of ...
... you may do:
For me, that seems to solve the issue.