After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 698833 - Regression in GtkGrid after baseline support
Regression in GtkGrid after baseline support
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: .General
3.8.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2013-04-25 12:09 UTC by Tristan Van Berkom
Modified: 2018-04-15 00:30 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Example Glade file (4.09 KB, application/xml)
2013-04-27 07:51 UTC, Tristan Van Berkom
Details

Description Tristan Van Berkom 2013-04-25 12:09:48 UTC
I tracked this regression to this commit:

commit 627685e2a2efd9be72e66dd1a1e8f49aab1d1600

Before this commit, Glade's preferences dialog shows correctly,
after, I get this:
    http://people.gnome.org/~tvb/broken-gtk-grid.png

The setup there (with the "+" and "-" buttons) is basically
a GtkGrid with 3 columns and 2 rows

 o ScrolledWindow { TreeView } left-attach = 0, width = 3

 o "+" Button left-attach = 0, width = 1
 o "-" Button left-attach = 1, width = 1

The "-" button should normally show up at the same size as the "+" button
and also show up directly beside the "+" button.
Comment 1 Matthias Clasen 2013-04-27 03:31:20 UTC
a standalone testcase would be appreciated
Comment 2 Tristan Van Berkom 2013-04-27 07:51:31 UTC
Created attachment 242644 [details]
Example Glade file

Run the attached Glade file with:

glade-previewer -f broken-grid-test.glade

Notice that it behaves normally before the mentioned commit,
and after the mentioned commit there is no way to again obtain
the same functionality, no workaround.

What I have noticed is, this is happening because one widget which spans
the most columns is set to hexpand.
Comment 3 Matthias Clasen 2013-04-29 00:20:17 UTC
'normally' is a pretty unclear description of the expected behavior.

It seems you expect that the grid should prefer to expand the third column, because it has no non-expanding children in it ?

This is not as clear-cut as you might think. In fact, I just reverted a change that made the grid consider columns containing only spanning children as expandable because it caused problems in gnumeric, see bug 698660.

Here is what the grid currently does:

When faced with a spanning, expanding child, if none of the rows it spans is expanding due to a non-spanning expanding child, it marks all the spanned columns as expanding.

You can certainly work around this by putting some invisible child next to the buttons, and marking it as expandable.
That will give the grid the hint to make the third column expandable and leave the first two alone.
Comment 4 Matthias Clasen 2013-04-29 01:05:50 UTC
And with invisible I meant 'non-drawing', if course - e.g. an empty label
Comment 5 Tristan Van Berkom 2013-04-29 05:44:37 UTC
(In reply to comment #3)
> 'normally' is a pretty unclear description of the expected behavior.
> 

By 'normally' I mean, in the way it has been behaving previously, in the
way that it should work in order to not break code which has the same
expectations (which I expect to be, a lot of GtkGrid using code).

> It seems you expect that the grid should prefer to expand the third column,
> because it has no non-expanding children in it ?
> 
> This is not as clear-cut as you might think. In fact, I just reverted a change
> that made the grid consider columns containing only spanning children as
> expandable because it caused problems in gnumeric, see bug 698660.

Not at all ;-)

I expect GtkGrid allocation to be a very delicate and sensitive area to
be making modifications to, don't exactly expect that it's clear cut.

> 
> Here is what the grid currently does:
> 
> When faced with a spanning, expanding child, if none of the rows it spans is
> expanding due to a non-spanning expanding child, it marks all the spanned
> columns as expanding.

This seems to indeed be the behavioural change which caused this regression
to happen, this was not the policy before the mentioned baseline related
commit.

> 
> You can certainly work around this by putting some invisible child next to the
> buttons, and marking it as expandable.
> That will give the grid the hint to make the third column expandable and leave
> the first two alone.

Well, here's to hoping that it wont come to adding padding widgets to the UI,
would be rather sad if GTK+ necessitated that.
Comment 6 Matthias Clasen 2013-04-29 11:57:02 UTC
(In reply to comment #5)
> 
> I expect GtkGrid allocation to be a very delicate and sensitive area to
> be making modifications to, don't exactly expect that it's clear cut.
> 
> > 
> > Here is what the grid currently does:
> > 
> > When faced with a spanning, expanding child, if none of the rows it spans is
> > expanding due to a non-spanning expanding child, it marks all the spanned
> > columns as expanding.
> 
> This seems to indeed be the behavioural change which caused this regression
> to happen, this was not the policy before the mentioned baseline related
> commit.

Yes, it was.
I should know, I wrote the code :-)
As I said, I tried to change this policy in 
https://git.gnome.org/browse/gtk+/commit/?id=5e1a06d1b124f09a1a54d5ae0f38905dbdc2cc81
but had to revert this change in 
https://git.gnome.org/browse/gtk+/commit/?id=13858fde29e9626d1d959d436f87105263bced98

> Well, here's to hoping that it wont come to adding padding widgets to the UI,
> would be rather sad if GTK+ necessitated that.

If you can propose a meaningful policy that would make your empty-except-for-spanning-children column expand while keeping the empty-except-for-spanning-children rows in the 'Spanning' example of testgrid collapsed, I'm all ears.
Comment 7 Tristan Van Berkom 2013-04-29 13:06:37 UTC
The policy as I understand it, is that widgets don't expand unless explicitly
set to expand, which is a concept basically carried over to rows/columns
of a GtkGrid.

In the case that one widget spans multiple columns, it should not be the
deciding factor to cause *all* of it's columns to expand, but rather require
that at least one of the columns it occupies expands.

But I think I can word this into a meaningful policy, here it goes:

Once a widget has declared itself as expanding, there are 2 criteria
for expanding a given column which that widget spans:

  a.) Every other row either agrees with the expanding of the given column,
      or makes no argument for a given column.

      I.e. a column is in agreement for a given row if it explicitly 
      expands or contains no widget in that column.

  b.) Any other row disagrees completely with an expanding widget

      example: one widget expands across 3 columns,
      and another row is full of non-expanding widgets which
      span the same columns.

      In the case of 'b' where we find full disagreement between
      rows, all of the effected columns expand equally.

      Also in terms of code, it would seem that 'b' is the fallback
      case; after having checked with all rows and still not satisfying
      the 'expand' declaration of a given widget, all of the columns
      which that widget span end up expanding.

The same criteria that applies to columns/hexpand, of course applies
to rows/vexpand.

I'm pretty sure the above policy is pretty much what GtkGrid has been
doing up until now, at least it *feels* this way using GtkGrid, I
hope that the above is clear and comprehensible ;-)
Comment 8 Matthias Clasen 2013-04-29 17:00:50 UTC
so, now tell me: does an empty cell 'agree' with expanding, or not ?
Comment 9 Tristan Van Berkom 2013-04-29 17:04:41 UTC
Indeed it does (I think I mentioned that in 'a'), as in it does not make
any argument.
Comment 10 Matthias Clasen 2013-04-30 17:56:03 UTC
But having empty cells expand by default is what breaks the gnumeric use case.

You can try to wiggle your way out by arguing that in that case, you could make another row expand, but then you get into really hairy ordering issues regarding which rows and spanning children you check in which order.

I'd be happy to test a patch, but I'm not too hopeful that you can come up with something that works in all cases.
Comment 11 Tristan Van Berkom 2013-04-30 20:41:16 UTC
(In reply to comment #10)
> But having empty cells expand by default is what breaks the gnumeric use case.
> 

I never said that empty cells expand by default.

I said that empty cells do not challenge the explicit expand which was
requested for the same column in another row (I realize what I tried to
explain above is complex in a way, I tried to not use too many words
in order to describe it).

To reiterate what I said previously, in pseudo code:

foreach (expanding widget in grid) {

   bool did_expand = FALSE;

   foreach (column in columns which the widget spans) {

     foreach (row in grid) {
        if (row[column] == NULL ||
            row[column] == expanding widget) {

            this_column_expands();

            did_expand = TRUE;
        }
     }
   }

   /* Every column which an expanding widget spanned
    * had a disagreement with the expand clause
    */
   if (did_expand == FALSE)
     all_of_the_expanding_widgets_columns_expand();
}

> You can try to wiggle your way out by arguing that in that case, you could make
> another row expand, but then you get into really hairy ordering issues
> regarding which rows and spanning children you check in which order.

I don't think it's that hairy, because the fallback of distributing
expand to all columns of an widget widget kicks in as soon as there
is explicit disagreement found in all of the columns.

So long as there is at least one column which does not explicitly
disagree, you can give expand space to that column.

Of course when a widget only spans one column, it unconditionally
expands it's column (because it would hit the fallback right away).

> 
> I'd be happy to test a patch, but I'm not too hopeful that you can come up with
> something that works in all cases.

I'm really trying to be constructive here, and now I get the feeling
that I'm getting on your nerves, if that's the case well, I'm sorry
for that.

It's quite clear that something has changed in the noted commit
627685e2a2efd9be72e66dd1a1e8f49aab1d1600 which changes the original
behaviour.

From what I understand, your following commits (the first one which
tries to address the breakage but breaks gnumeric in doing so), come
after the original breakage.

Something was obviously lost in the calculation of expanding columns/rows
with original baseline related commit.

You say that you're not hopeful that a solution can be found to work
in all cases, my response to that logically has to be that:

 o Before the mentioned baseline commit, the code must have worked in all
   cases, otherwise gnumeric must have been broken in GTK+ 3.8 and before
   as well.

 o Perhaps the baseline related commit tries to innocently sneak in a
   new requirement, one which is unrealistic to try to satisfy without
   breaking things.

I doubt that the latter is the case, I don't see why baselines would
effect the expanding state of widgets, but I'm quite convinced of the
former.
Comment 12 Tristan Van Berkom 2013-04-30 20:49:48 UTC
(In reply to comment #10)
[...]
> You can try to wiggle your way out by arguing that in that case, you could make
> another row expand...

Also, in order to make sure we are on the same page, we are talking columns
here, not rows (talking both rows and columns certainly makes things even
more confusing).

Until now I've only been talking about the hexpand attribute of child
widgets causing columns to expand, by examining cells in the same columns
while iterating through the sibling rows... whatever algorithm which
applies to hexpand/columns, can work with vexpand/rows as well.
Comment 13 Matthias Clasen 2013-04-30 21:31:06 UTC
(In reply to comment #11)

> > 
> > I'd be happy to test a patch, but I'm not too hopeful that you can come up with
> > something that works in all cases.
> 
> I'm really trying to be constructive here, and now I get the feeling
> that I'm getting on your nerves, if that's the case well, I'm sorry
> for that.

You're not. Sorry if I gave you that impression. This is an interesting problem and I enjoy discussing it.

>  o Before the mentioned baseline commit, the code must have worked in all
>    cases, otherwise gnumeric must have been broken in GTK+ 3.8 and before
>    as well.

I've added the gnumeric testcase to testgrid now, so we can easily find out !


And just to clarify: this is a 1-dimensional problem, I'm talking about rows/columns interchangeably here. We decide their expandability independently and separately.
Comment 14 Daniel Svensson 2013-07-30 20:49:02 UTC
I wonder if I might be stumbling upon the same problem here. I have a GtkGrid like this:

 ------------------
|               |   2   |  3   |
|      1       |---------|
|               |                 |
|               |                 |
|--------|                 |
|               |      4         |
|               |                 |
|       5      |                 |
|               |                 |
|               |                 |
 ------------------

1. left=0, top=0, width=1, height=2, expand=false, align=start
2. left=1, top=0, width=1, height=1, align=start, hexpand=true, vexpand=false
3. left=2, top=0, width=1, height=1, valign=start, halign=end, hexpand=true, vexpand=false
4. left=1, top=1, width=2, height=2, halign=fill, valign=start, hexpand=true, vexpand=false
5. left=0, top=2, width=1, height=1, align=start, expand=false

The behavior I want is that the widget in cell 4, a GtkTreeView, is always aligned at the top of cell 4. The GtkTreeView should be rendered with less height if it's smaller than the contents of 1+5, and larger if larger, but always start-aligned.

A screenshot of this is here:
http://people.xmms2.org/~nano/weird-layout3.png

As you can see, the distance between the GtkTreeView and the labels above it (cells 2 and 3 in my ascii art) differs, when it should be small (margin-top=10 for the GtkTreeView). 

There are a couple of wtf's in that screenshot. While the middle instance of the GtkGrid seems to have the correct (or close to correct?) distance to the above labels, the first instance does not, even if its GtkTreeView is taller than the content of the left column. All instances of this GtkGrid leave too much dead space at the bottom, each with a different amount of dead space. There is no margin-bottom defined.

The alignment/expand of the composed widget as a whole are:
valign=start, halign=fill, hexpand=true, vexpand=false
...and the instances are placed in another GtkGrid when created.

The widgets are laid out the same way in both Gtk master, as in 3.8.2.
Comment 15 Daniel Svensson 2013-07-30 20:50:18 UTC
Formatting failed, uptade ascii drawing:

 ---------------------------------
|               |   2     |   3   |
|      1        |-----------------|
|               |                 |
|               |                 |
|---------------|                 |
|               |       4         |
|               |                 |
|       5       |                 |
|               |                 |
|               |                 |
 ---------------------------------
Comment 16 Matthias Clasen 2013-09-03 13:27:16 UTC
nothing is happening here for 3.10, at this stage
Comment 17 Matthias Clasen 2018-02-10 05:23:31 UTC
We're moving to gitlab! As part of this move, we are moving bugs to NEEDINFO if they haven't seen activity in more than a year. If this issue is still important to you and still relevant with GTK+ 3.22 or master, please reopen it and we will migrate it to gitlab.
Comment 18 Matthias Clasen 2018-04-15 00:30:23 UTC
As announced a while ago, we are migrating to gitlab, and bugs that haven't seen activity in the last year or so will be not be migrated, but closed out in bugzilla.

If this bug is still relevant to you, you can open a new issue describing the symptoms and how to reproduce it with gtk 3.22.x or master in gitlab:

https://gitlab.gnome.org/GNOME/gtk/issues/new