children exceeding table rows/cols



hi.

tables that are allocated smaller space than their requisition
tend to over-allocate children. that is, allocate children at
sizes that exceed the columns/rows the children are attached
to or even the table boundaries.

i'd like to suggest to make a few but very effective changes
to gtk_table_size_allocate_pass2() to properly constrain the
child allocations in such cases:

1) constrain children to col/row boundaries (and set a lower limit
   for allocation dimensions of 0, the purpose of which will be
   explained below):
          if (child->xfill)
            {
-             allocation.width = MAX (1, max_width - (gint)child->xpadding * 2);
+             allocation.width = MAX (0, max_width - (gint)child->xpadding * 2);
              allocation.x = x + (max_width - allocation.width) / 2;
            }
          else
            {
-             allocation.width = child_requisition.width;
+             allocation.width = MIN (child_requisition.width, max_width);
              allocation.x = x + (max_width - allocation.width) / 2;
            }

          if (child->yfill)
            {
-             allocation.height = MAX (1, max_height - (gint)child->ypadding * 2);
+             allocation.height = MAX (0, max_height - (gint)child->ypadding * 2);
              allocation.y = y + (max_height - allocation.height) / 2;
            }
          else
            {
-             allocation.height = child_requisition.height;
+             allocation.height = MIN (child_requisition.height, max_height);
              allocation.y = y + (max_height - allocation.height) / 2;
            }
   here, max_width/max_height allready contain the amount of space allocated
   to the child in rows and cols.

2) the allocation of rows/cols of a table may still exceed the table allocation
   due to premature abortion of its shrinking process (FYI, this is due to the
   condition while (total_nshrink > 0 && extra > 0) in size_allocate_pass1()).
   the simple solution to deal with mis-allocations due to this is to constrain
   children to the table allocation (short of hacking a different shrinking
   logic into the table):
+ /* constrain child allocation to table */ + if (allocation.x + allocation.width > widget->allocation.x + widget->allocation.width) + allocation.width -= allocation.x + allocation.width - widget->allocation.x - widget->allocation.width; + if (allocation.y + allocation.height > widget->allocation.y + widget->allocation.height) + allocation.height -= allocation.y + allocation.height - widget->allocation.y - widget->allocation.height;
          gtk_widget_size_allocate (child->widget, &allocation);

3) the above changes can lead to allocation width/height <= 0, which is an
   invalid allocation size as far as gtk_widget_size_allocate() is concerned.
   what we really want in these cases is to not show the child, since there
   is no space available. setting child visibility could be a solution to this
   e.g. by doing:
-         gtk_widget_size_allocate (child->widget, &allocation);
+         if (allocation.width > 0 && allocation.height > 0)
+           {
+             gtk_widget_set_child_visible (child->widget, TRUE);
+             gtk_widget_size_allocate (child->widget, &allocation);
+           }
+         else
+             gtk_widget_set_child_visible (child->widget, FALSE);
   this does rely on the fact that child visibility may be changed during size
   allocation (in particular, it shouldn't queue a resize).


META: i'm not going to make these changes myself, the ideas come from another
      code base and i justed wanted the fixes to get a chance to be folded
      back into gtk+, which is also why the above is only a pseudo patch.

---
ciaoTJ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]