Last update: crab.garden/@alice/11039889393…
---
Since the last update I've been looking at split view sizing.
A while ago @tbernard opened an issue about having dynamic sizes for sidebars, instead of basically just a fixed size (well ok, really it wasn't fixed size, it's the usual GTK natural/minimum sizes + hexpand, but natural size is really hard to control and hexpand is not useful for sidebars, so in practice it is fixed size). So basically, changing the width depending on the window size, similar to what we do in AdwClamp.
With the old widgets this was basically impossible:
- the sidebar itself can't do it even if we had a sidebar widget (we don't) - it doesn't know anything about the window width. It has to be the container, i.e. leaflet/flap.
- leaflet is too generic for this. It's a box/stack with N children, it has no idea what a sidebar is - even though it's basically always used for sidebars
- we could do it in flap, but it still can be used for other things, like titlebars in fullscreen, not necessarily sidebars - so the new sizing would have to be opt in. Besides, the main places where we care about this are using leaflet, not flap
With the new split views though it can work just fine. Both kinds of split views have exactly two children with clear purposes, and none of the above is an issue there. So, they can now do dynamic sizes. That's what crab.garden/@alice/11042193160… was about, as me and Tobias needed a reasonably realistic way to test three-pane layouts, as the most complex case, meanwhile Geary is still using GTK3 and NewsFlash is using Rust and would need a bindings update, so it's easier to just make a demo instead.
So, both AdwNavigationSplitView and AdwOverlaySplitView have 4 new properties:
- :sidebar-width-fraction
- :min-sidebar-width
- :max-sidebar-width
- :sidebar-width-unit
When either split view is not collapsed, the sidebar width is ideally a percentage of the full split view width, set with the :sidebar-width-fraction property. To prevent the sidebar from becoming too wide or too narrow, its width can be clamped between a minimum and a maximum value, set with :min-sidebar-width and :max-sidebar-width properties. Note that all of those properties can be ignored if the minimum width of the widget inside exceeds them, same as with AdwClamp.
Now, what about the Large Text mode? The text becomes larger, and pixel-based sizes aren't ideal for this, same as how it can be suboptimal in AdwClamp.
Meanwhile, breakpoints support non-pixel units, in particular points (pt) that scale with text scale factor. And so, split views can now also use them, set with the :sidebar-width-unit property. They affect the minimum and maximum sidebar width, but not the fraction.
Note that the unit enum has been renamed from AdwBreakpointConditionLengthUnit to AdwLengthUnit to indicate that it's not a breakpoint-specific thing anymore.
There's also a new unit: sp. It stands for scale independent pixels, and is exactly the same thing as in Android where I basically copied it from. It's equivalent to 1px on text scale factor 1, 1.25px with text scale factor 1.25 and so on. So it's kinda like points, but easier to use since it's same as pixels with default settings, instead of 1⅓px. And that's what split views default to, so they will work with large text OOTB.
Finally, AdwOverlaySplitView also uses these sizes in collapsed state. That state mainly exists for narrow widths, and so the width fraction is not really useful there. Instead, it just tries to use the maximum width when possible, and tries to shrink down to minimum width if it doesn't fit otherwise. Additionally, there's a reserved 64px space that the sidebar cannot take in this state, to prevent it from ever expanding to the full width (the default maximum width is 360px, so it would happen on mobile by default otherwise). This value is not customizable by apps, mostly because I haven't figured out any good names for it.
Alice
in reply to Alice • • •Alice
in reply to Alice • • •All swipeable widgets in libadwaita (AdwCarousel, AdwLeaflet, AdwFlap and now AdwNavigationView and AdwOverlaySplitView) use spring animations for finishing the swipe gesture. However, all 3 of the old widgets set clamped=true on their animation, meaning it can never overshoot and go back. This is rather unfortunate, since overshooting when swiped too hard is one of the most noticeable spring animation features.
There were 2 reasons for that:
1. The widgets would need to be able to handle overshooting, which is a behavior break with carousel (though not a very serious one), and is complicated to implement with leaflet
2. Since we don't have overshooting/rubberbanding, if you move the page to the end and then swipe with non-0 velocity, the page will be flinged even though it had already stopped. This can also be seen in Loupe which has a custom widget for swiping between images using AdwSwipeTracker.
The first issue isn't a problem anymore, since we're replacing those widgets anyway. The second issue means we need to have overshoot in swipe tracker. Loupe has set a precedent by having it for pinch zoom, so I went ahead and implemented it, and enabled it in AdwNavigationView and AdwOverlaySplitView. I expect Loupe to enable it as well once bindings are updated.
This is also in main, other than the AdwOverlaySplitView part. :)
Alice
in reply to Alice • • •