GNOME Bugzilla – Bug 787021
GtkFlowBox: the orthogonal orientation always requests the most size it could possibly need
Last modified: 2018-05-02 19:01:11 UTC
Created attachment 358777 [details] Minimal test case for GtkFlowBox orientation issue It appears that when a GtkFlowBox orientation is set to Vertical, the width request still acts like the widgets were handled as if the orientation was Horizontal resulting in the children being given more horizontal space than vertical. When combined with increasing the number of children per line, this results in GtkWindows with a large minimum width. I've attached a minimal CMake based project which shows this problem. The .glade file was created in Glade 3.20. To compile and run under Windows/MinGW: - unzip file and navigate to folder - mkdir build && cd build - cmake .. -G "MSYS Makefiles" -D'CMAKE_MAKE_PROGRAM:STRING=mingw32-make' - mingw32-make - cd ../bin - ./UKHF_Testing Same process applies under Linux with swapping mingw32-make for just make and changing "MSYS Makefiles" for "Unix Makefiles".
Created attachment 358778 [details] Example of GtkFlowBox behaving correctly when using horizontal orientation
Created attachment 358780 [details] Example of GtkFlowBox behaving incorrectly when using vertical orientation
Thanks for the report. Please can you try to reduce this down to a single C, .ui, or Python file? Single-file attachments are preferred as readers can immediately download and compile them, without having to worry about any particular build system. Moreover, not everyone here will have gtkmm, and even if they do, its presence might cause delays as we try to make sure it's not doing anything extra behind the scenes (which is highly unlikely and would be wrong in this case, but still).
Created attachment 358826 [details] actual minimal test case Here's something that looks more like a test case. Run it with 0 for GTK_ORIENTATION_HORIZONTAL or 1 for GTK_ORIENTATION_VERTICAL. Indeed, the vertical case seems messed up; the RadioButtons get given a lot more width than they need, and hence so does the Window.
Created attachment 358828 [details] result of Attachment 358826 [details] with horizontal FlowBox
Created attachment 358829 [details] result of Attachment 358826 [details] with vertical FlowBox
(In reply to Daniel Boles from comment #3) > Thanks for the report. Please can you try to reduce this down to a single C, > .ui, or Python file? > > Single-file attachments are preferred as readers can immediately download > and compile them, without having to worry about any particular build system. > > Moreover, not everyone here will have gtkmm, and even if they do, its > presence might cause delays as we try to make sure it's not doing anything > extra behind the scenes (which is highly unlikely and would be wrong in this > case, but still). Apologies, I'll try to ensure minimal cases are a single file and not reliant on a particular build system in the future. I appreciate you making the single file example of the issue and verifying the problem.
(In reply to John Murray from comment #0) > It appears that when a GtkFlowBox orientation is set to Vertical, the width > request still acts like the widgets were handled as if the orientation was > Horizontal resulting in the children being given more horizontal space than > vertical. When combined with increasing the number of children per line, > this results in GtkWindows with a large minimum width. Specifically, the FlowBox requests the full width as if it were simply arranging all the children horizontally along a single row.
That seems to be completely intentional, though..., e.g. In gtk_flow_box_measure(), if measuring the horizontal size, with for_size < 0, for a vertically orientated FlowBox: else /* GTK_ORIENTATION_VERTICAL */ { /* Return the width for the minimum height */ gint min_height; gtk_css_gadget_get_preferred_size (gadget, GTK_ORIENTATION_VERTICAL, -1, &min_height, NULL, NULL, NULL); gtk_css_gadget_get_preferred_size (gadget, GTK_ORIENTATION_HORIZONTAL, min_height, &min_width, &nat_width, NULL, NULL); } And if running my example with 0 for GTK_ORIENTATION_HORIZONTAL, you'll see that it does exactly the converse thing: makes the window tall enough that it _could_ hold all the RadioButtons in a single column. This appears to have been intentional; the docs say: > * For instance, with the horizontal orientation, the widgets will be > * arranged from left to right, starting a new row under the previous > * row when necessary. Reducing the width in this case will require more > * rows, so a larger height will be requested. > * > * Likewise, with the vertical orientation, the widgets will be arranged > * from top to bottom, starting a new column to the right when necessary. > * Reducing the height will require more columns, so a larger width will > * be requested. The problem, then, is that when the FlowBox gets more size in a given direction, its request in the other direction isn't reduced accordingly - so the orthogonal orientation to its own always gets the size it would need in the most extreme case, rather than the size it needs right now. I'm trying a better title... I'm not sure that ever succeeds. :)
(Is it just me, or does Bugzilla love to randomly upgrade priorities?)
(In reply to Daniel Boles from comment #10) > (Is it just me, or does Bugzilla love to randomly upgrade priorities?) This is my first time using Bugzilla to report an issue so I can't really say. You're right though that it affects horizontal orientation as well. Trying the test case you created and expanding the window width so it becomes two rows still doesn't allow a reduction in the vertical height of the window. So it is by design and not an implementation bug then. Frustrating. It makes it difficult to use the vertical orientation. Makes it difficult to use the horizontal one as well when there are enough children. :\
Created attachment 358847 [details] Horizontal orientation with many widgets. Minimum height from GtkFlowBox has made window too big to display
(In reply to John Murray from comment #11) > So it is by design and not an implementation bug then. Frustrating. It makes > it difficult to use the vertical orientation. Makes it difficult to use the > horizontal one as well when there are enough children. :\ Not really, I think my initial reading was just too superficial. GTK+ has a concept of height-for-width and width-for-height requests, so this should not be a problem: (In reply to Daniel Boles from comment #9) > The problem, then, is that when the FlowBox gets more size in a given > direction, its request in the other direction isn't reduced accordingly - so > the orthogonal orientation to its own always gets the size it would need in > the most extreme case, rather than the size it needs right now. That's what hfw/wfh request modes exist to avoid. The problem is that unless I'm missing something (which I often am), they don't seem to be working properly here, for whatever reason. FlowBox has code paths for when the orthogonal for_size is >= 0, to request an appropriate size along the measured orientation - but that doesn't seem to matter in this case, so we get the requests we're seeing here. This is going to take either someone who already knows all the fine details explaining (and maybe fixing this), or some ignoramus like me spending time analysing it.
(In reply to Daniel Boles from comment #13) > > This is going to take either someone who already knows all the fine details > explaining (and maybe fixing this), or some ignoramus like me spending time > analysing it. I still appreciate the time you've spent looking at the issue so far. If/when I get some spare time, I may have a look at the GtkFlowBox code myself but I'm currently in the middle of a GUI migration. For now, I'll just have to use the horizontal orientation. Thanks again.
Of course, things weren't as bad at they seemed! :-) It looks like wrapping the FlowBox in a GtkScrolledWindow resolves this, presumably due to sizing wizardry that I'm still getting to grips with: * The initial size of the window is sane * You can resize it pretty much any way, and things seem to reflow well. Can you give that a shot, maybe experiment with the different policies, and see if you can arrive at the result you wanted? So probably this is all intentional: obviously a viewport/scroller is going to be needed for toplevel dimensions that would otherwise result in underallocation. Intuitively, I would've expected a FlowBox to support shrinking down along its orthogonal dimension, by reflowing the children, at least until it got too small. However, my understanding of the sizing machinery is again rudimentary still. Either what you and I expected is not possible, or it is but was not judged to be worth the complexity of handling in FlowBox itself, when ScrolledWindow exists.
(In reply to Daniel Boles from comment #15) > Of course, things weren't as bad at they seemed! :-) > > > It looks like wrapping the FlowBox in a GtkScrolledWindow resolves this, > presumably due to sizing wizardry that I'm still getting to grips with: > > * The initial size of the window is sane > * You can resize it pretty much any way, and things seem to reflow well. > > Can you give that a shot, maybe experiment with the different policies, and > see if you can arrive at the result you wanted? > > > So probably this is all intentional: obviously a viewport/scroller is going > to be needed for toplevel dimensions that would otherwise result in > underallocation. > > Intuitively, I would've expected a FlowBox to support shrinking down along > its orthogonal dimension, by reflowing the children, at least until it got > too small. However, my understanding of the sizing machinery is again > rudimentary still. Either what you and I expected is not possible, or it is > but was not judged to be worth the complexity of handling in FlowBox itself, > when ScrolledWindow exists. Wrapping the FlowBox with a Viewport inside a ScrolledWindow has indeed produced the effect that I wanted in the first place. Thank you. I would suggest putting something in the documentation regarding placement within a ScrolledWindow. I think you're correct that it wasn't judged to be worth working on in lieu of putting in a ScrolledWindow
(In reply to John Murray from comment #16) > Wrapping the FlowBox with a Viewport inside a ScrolledWindow has indeed > produced the effect that I wanted in the first place. Thank you. Great! Btw, if you manually added a Viewport, now you don't need to do that in GTK+ 3, as if you add a non-Scrollable child, the ScrolledWindow will interpose a Viewport for you. > I would suggest putting something in the documentation regarding placement > within a ScrolledWindow Yeah, I think it could only be a good thing to add a 'gotcha' paragraph for this. > I think you're correct that it wasn't judged to be worth > working on in lieu of putting in a ScrolledWindow That's definitely the most logical explanation. That said, some other containers exhibit similar - if probably not so sophisticated - overflow/reflow behaviour, without having inflated minimal sizes. Those are probably more simplistic, though.
(In reply to Daniel Boles from comment #17) > > Btw, if you manually added a Viewport, now you don't need to do that in GTK+ > 3, as if you add a non-Scrollable child, the ScrolledWindow will interpose a > Viewport for you. > As part of this migration from VCL, most of the UI is being created in Glade which dictates a Viewport be placed first but thank you, I'll try to remember that if/when I have to manually create any UI elements. I guess we just have to wait for someone to confirm this was by design and that wrapping with a ScrolledWindow was the intent? Or for the documentation to have the suggestion added? I'm not sure what the next step should be for this report.
(In reply to John Murray from comment #18) > As part of this migration from VCL, most of the UI is being created in Glade > which dictates a Viewport be placed first but thank you, I'll try to > remember that if/when I have to manually create any UI elements. Ah, yeah, that makes sense. (In reply to John Murray from comment #18) > I guess we just have to wait for someone to confirm this was by design and > that wrapping with a ScrolledWindow was the intent? Or for the documentation > to have the suggestion added? I'm not sure what the next step should be for > this report. I'll try to get to adding a comment to the documentation soon. Like you, I presume what we have is totally intentional but would like to wait a bit and see if someone can confirm that. I have a limited understanding of the fine details of sizing, so I can't really assess how feasible the behaviour you and I expected would be for FlowBox to do itself. I suspect comparing to somewhat similar widgets, e.g. GtkIconView, and - better - implementing a new widget with custom sizing - would be very revealing.
Created attachment 359312 [details] [review] FlowBox: Explain how to avoid inflated min size along the orthogonal orientation. It seems a FlowBox on its own can only handle being shrunk along its main orientation. The orthogonal requests a huge min size – reserving what it would need if the main orientation got its min size, which would flow all children in 1 line orthogonally. Adding it to a ScrolledWindow (any policy) enables free shrinking, so size_allocate() can reflow how users in this situation probably expect. -- This’ll have to do, unless someone else can give a better explanation for it.
Created attachment 359313 [details] [review] FlowBox: Explain how to avoid inflated min size along the orthogonal orientation. It seems a FlowBox on its own can only handle being shrunk along its main orientation. The orthogonal requests a huge min size – reserving what it would need if the main orientation got its min size, which would flow all children in 1 line orthogonally. Adding it to a ScrolledWindow (any policy) enables free shrinking, so size_allocate() can reflow how users in this situation probably expect. -- Talk about shrinking only, since upsizing is always possible.
Comment on attachment 359313 [details] [review] FlowBox: Explain how to avoid inflated min size Attachment 359313 [details] pushed as d207e03 - FlowBox: Explain how to avoid inflated min size
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gtk/issues/897.