-
-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correct image scaling on GTK #2119
Conversation
How is is possible for a native widget to resize without a set_bounds call? And it should be triggered after every image change, because of the |
Its not so much that the set_bounds doesn't happen; it's when the set_bounds gets the wrong size, because of where it happens in the drawing/rehint sequence. In the tests, this manifested when setting a size on widget that already had a valid layout, or when changing the image itself (which implicitly changes the hints). |
Even if set_bounds initially gets the wrong size, surely it gets the correct size in a later call before everything settles down, in which case the previous implementation would have resized the image at that time. If it doesn't ever get the correct size, then we should fix that rather than working around it. |
Hrm - I thought this was the appropriate fix, as it was applying the image resize as a direct function of the actual widget changing size; but I can take another look in the morning if you feel there's something deeper that needs investigating. |
Also - it's not that it never gets the right size; there's just a specific sequence of changes that can cause problems, and those circumstances come up in the tests. |
After some detailed spelunking, I maintain the PR is correct, and it's not papering over any underlying problems (or, at least, to the extent that it is, it's a very deep problem that I don't think needs to be solved right now). Take the At the start of the test, there is a window whose only content is an unstyled ImageView ("the widget"), containing a 144x72 image ("the image"). The test will set an explicit width and height on the image, which should set the size of the widget and make the image fill the entire space of the widget, ignoring aspect ratio. In the process of setting up the test, the image is set on the widget, which triggers a series of refreshes, and the widget is added to the window as The size that is provided to the So - the first repaint occurs, the widget is rehinted, a size hint of 144x72 is determined, the layout is recomputed based on that layout, and the widget has it's GTK size set to 144x72. No This means that the only call to One fix here would be to explicitly call The test sets an explicit size on the widget of 200x300. Test setup makes 2 alterations to The key observation is that in GTK, Thus, I maintain that the PR is correct as presented.
That said - there may be a potential optimization here. The initial "false" layout that causes the |
OK, that makes sense. I'd previously thought that this was introduced in #1794, but now I see that the GTK |
The discrepancy stems from how GTK itself, and in particular the hinting process, works. On every other toolkit, you can make a change (e.g., changing the text of a label), and that immediately changes the hinted size of the widget, so you can immediately recompute the layout that is affected by the change, and apply those size changes to reposition or resize the widget in the overall layout. On GTK, changing the label doesn't immediately alter the hinted size of the widget. The widget doesn't change internal size until a size allocation is requested. That then hooks into the layout process itself. On every other platform, we can (at some level) arbitrarily request that a widget be positioned at a specific location. This is what So - at least at present, |
OK, my first thought was that Android might have the same problem, but it distinguishes between what size the widget would like to be ( Maybe there's some equivalent to this on GTK, but there's no need to look into it now. |
If there is, I haven't been able to find it. It seems to be related to the allocation process; but I haven't seen a way to directly trigger a re-allocation, short of triggering a whole-window redraw. |
In the process of checking box/child handling #1903 I ran the entire test suite, and noticed a regression in behaviour that the testbed suite wasn't picking up.
The imageview tests validate the size of the ImageView itself, and validate the aspect ratio handling of the image view, but doesn't validate the size of the actual image itself.
On every backend other than GTK, this doesn't matter, because the ImageView is responsible for scaling the underling image. The size of the widget and the scaling behaviour is all that needs to be validated.
However, on GTK, it's the responsibility of the user to scale the pixbuf being rendered by the ImageView to the appropriate size, performing any aspect ratio change etc. This worked when #1956 landed; but somewhere along the way, we've made a subtle change to the order of events fired, and as a result, some size change events don't result in a set_bounds call that causes a resize of the image. For example, if you have a valid layout with an ImageView, then change the image, the imageView changes size, but there's no set_bounds call, and as a result, you end up with a 200x100 imageview displaying a 640x480 image (the size that was present at the last set_bounds).
This has been corrected by performing the native rescaling in direct response to a GTK set-allocation signal - the underlying signal that tells GTK that the widget has changed size. At that point, we know the size the image should be, so we just need to make the pixbuf adhere to that size.
This is then backed up by an explicit test of the actual underlying image size. This test is a no-op on every platform except GTK, because the size of the rendered image isn't under user control.
It also corrects an edge case where the initial pixbuf set on an imageview wasn't necessarily being scaled to the correct size.
PR Checklist: