GNOME Bugzilla – Bug 699301
GtkStack: animate size changes in the nonhomogeneous case
Last modified: 2015-07-20 22:01:09 UTC
<alex_away> mclasen: Its not really very hard. In e.g. gtk_stack_get_preferred_width(), instead of <alex_away> *minimum_width = MAX (*minimum_width, priv->last_visible_surface_allocation.width); <alex_away> *natural_width = MAX (*natural_width, priv->last_visible_surface_allocation.width); <alex_away> you need to tween the two instead of MAX <alex_away> Well, there might be some other thing affected too to handle an allocation smaller than the child request (and clip) <alex_away> but, its not really a lot of code <mclasen> alex_away: I guess there might be some extra complications because we want this to animate the resize of the toplevel ?
I don't think there's any real complications from animating the size of the toplevel - at least for a non-resizable window. If you set things up so that the computed size of the toplevel animated smoothly, the toplevel animated smoothly. If you want to *also* allow the toplevel to resize, then at that point things get tricky and ill-defined. Someone (probably the application) would need to remember different toplevel sizes for different pages of the stack, turn off resizing during animation, tween between the remembered sizes (respecting minimum sizes), and then turn resizing back on.
Created attachment 243317 [details] [review] GtkStack: Interpolate sizes In the non-homogeneous case, animate size changes as well.
Created attachment 287698 [details] how it looks
so, this is not quite right. There are several problems. One of them is that we actually reallocating the children to the intermediate sizes. Another problem is that the alignment of children is off - the larger child is moving in 'from above'. Additionally, the proper alignment depends on which edge of the stack we want to keep put - for a popover menu that pops below, that will be the top edge, but for one that pops above, it will be the bottom edge. I think what we want is to keep the children allocated to their final sizes, and just interpolate the size of the 'view' window. Getting the alignment right may require to use one bin window per child, and position them next to each other.
*** Bug 730308 has been marked as a duplicate of this bug. ***
there's also the option of chaining the resizing transition to the slide transition, i.e.: tween(slide_left).on_completed(tween(height)) with the added check on the target size, since it would look jarring if we tweened to a clipped content in case the target height is bigger than the source height: if (end_height < start_height) tween(slide_left).on_complete(tween(height)) else tween(height).on_complete(tween(slide_left)) we're closing fast to animation framework territory, here.
Review of attachment 243317 [details] [review]: doesn't quite work
So I just pushed a version of this to wip/baedert/stack-size-interpolate: https://git.gnome.org/browse/gtk+/log/?h=wip/baedert/stack-size-interpolate Ignore the unrelated commits (*sigh*). I think the result is esp. interesting in popover menus, but should of course work for all other cases as well.
Seems to work nicely in quick testing. Well done!
I agree with mclasen: the resizing is really nice.
As far as I am concerned, we should get this merged.
Okay, pushed. Thanks!
So, this is causing problems in gnome-builder. https://git.gnome.org/browse/gtk+/tree/gtk/gtkstack.c#n2111 Here we allocate MAX (nat, allocation->height) for the current widget. We do that so the size of the new visible widget won't change when sliding in (that is, when allocation->height will change). Builder has a widget in there that contains a GtkTextView with potentially a lot of text, so the natural height will be very large and we will always allocate the natural height for that textview. I'm not sure how to fix that. During a transition, the height we allocate for the child might well be greater than allocation->height and the transition will resize the stack to the new visible child's natural height later. Any hints?
Created attachment 306027 [details] [review] test case to reproduce the problem Ok this is actually really easy to reproduce. The stack will allocate the child's natural height, but the WM will restrict the height to the screen size (something you don't notice in gnome-builder since it's probably maximized).
I think I'll suggest that we should make the size animation optional, and opt-in. Then we can use it just for the popover menus, and avoid breaking any other users accidentally.
So add a property to GtkStack or have some gtk+ internal API to enable the size transition?
A boolean property would be my suggestion
Created attachment 307685 [details] [review] GtkStack: Add interpolate-size property And use it to determine whether we should actually interpolate between stack sizes or not.
Created attachment 307686 [details] [review] GtkPopover: Set interpolate-size on the stack... ... in gtk_popover_bind_model.
Review of attachment 307685 [details] [review]: Looks good
Review of attachment 307686 [details] [review]: GtkPopoverMenu will need the same, please.
Created attachment 307698 [details] [review] GtkPopover: Set interpolate-size on the stack... ... in gtk_popover_bind_model and gtk_popover_menu_init
Review of attachment 307698 [details] [review]: looks fine, go ahead.
Pushed both of them, thanks. Need to find out why git-bz doesn't add bug urls anymore :/