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 155190 - Invalidate widget areas if it needs allocation
Invalidate widget areas if it needs allocation
Status: RESOLVED DUPLICATE of bug 135903
Product: gtk+
Classification: Platform
Component: Widget: Other
2.4.x
Other Linux
: High normal
: Small fix
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2004-10-12 14:15 UTC by Alexey Morozov
Modified: 2005-01-20 19:24 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
The same in the C (much easier to debug) (1.87 KB, text/plain)
2005-01-18 18:05 UTC, Nickolay V. Shmyrev
  Details
Another testcase (2.26 KB, text/plain)
2005-01-18 18:07 UTC, Nickolay V. Shmyrev
  Details
Patch to CVS (483 bytes, patch)
2005-01-19 17:19 UTC, Nickolay V. Shmyrev
none Details | Review

Description Alexey Morozov 2004-10-12 14:15:27 UTC
A friend of mine encountered a strange behavior (probably bug) in
GTK+-2.4.x

The problem description:

There's a container w/ one or several GtkImage's in it. After performing
'hide' on the container, the entire window becomes smaller. 'show'ing
the container restores window size, BUT 'expose' event is delivered only
to parts of the GtkImage(s) (which would be shown if window size wasn't
changed). This behaviour can be observed if the window has resizable =
false.

Here's the demostration program (pygtk) URL:

http://dfo.antex.ru/files/unix/gtkbug.py
Comment 1 Nickolay V. Shmyrev 2005-01-18 18:05:07 UTC
Created attachment 36198 [details]
The same in the C (much easier to debug)
Comment 2 Nickolay V. Shmyrev 2005-01-18 18:07:51 UTC
Created attachment 36199 [details]
Another testcase

This test is closer to the problem, it just logs "allocate" and "expose"
events.

Here is the example of it's output:

** Message: Allocate event recieved for GtkWindow
** Message:	 Rectangle 0 0 48 92
** Message: Expose event recieved 3 rects for GtkWindow
** Message:	 Rectangle 0 0 48 16
** Message:	 Rectangle 41 16 7 1
** Message:	 Rectangle 0 17 48 75

Note that instead of 1 rectangle window gets region that is intersection of 3
rectanges. More interesting is that width of 2-nd rectangle is always the
spacing of VBox. So, probably, there are vbox problems :)
Comment 3 Nickolay V. Shmyrev 2005-01-19 17:19:10 UTC
Created attachment 36250 [details] [review]
Patch to CVS

I've found the reasons of such behaviour. The situation is following - after
widget hide/show it's GTK_ALLOC_NEEDED flag becomes true, but allocation
remains the same. After show, the whole widget tree is reallocated but since
allocation of  
widget is not changed, the corresponding area is not invalidated (currently gtk
check only that size of position changed). Gtk redraws only areas that was
under widgets in hidded state and since in that place there was no widgets
(there was vbox spacing) this area is not redrawn. 

The proposed patch should fix that issue. It just check for ALLOC_NEEDED flag
of a widget and invalidates it's rectangle.
Comment 4 Owen Taylor 2005-01-19 19:32:32 UTC
I think the problem/fix is likely deeper than this .. your patch
probably breaks gtk_widget_set_redraw_on_allocate().
Comment 5 Nickolay V. Shmyrev 2005-01-19 21:10:55 UTC
Here is the code that I'd like to see:

     if (size_changed || need_alloc)
        {
          if (GTK_WIDGET_REDRAW_ON_ALLOC (widget))
            {
              /* Invalidate union(old_allaction,widget->allocation) in widget->w
              */
              GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation)
             gdk_region_union_with_rect (invalidate, &old_allocation);

              gtk_widget_invalidate_widget_windows (widget, invalidate);
              gdk_region_destroy (invalidate);
            }
        }

It's clear that if redraw_on_allocate will be false, nothing will be changed.
Even more, problem is exactly in that place. I think it's possible to write an
example that will illustrate it more precisely. The only problem that after
show/hide no invalidate occurs.
Comment 6 Nickolay V. Shmyrev 2005-01-20 18:04:29 UTC
The second interesting question there is implementation of gtk_widget_queue_resize

void
gtk_widget_queue_resize (GtkWidget *widget)
{
  g_return_if_fail (GTK_IS_WIDGET (widget));

  if (GTK_WIDGET_REALIZED (widget))
    {
        gtk_widget_queue_shallow_draw (widget);
    }

  _gtk_size_group_queue_resize (widget);
}


What is gtk_widget_queue_shallow_draw is doing here? I thought that redraws
should be queued only in size_allocation. The call above is just unneeded
resource loss.
Comment 7 Owen Taylor 2005-01-20 18:22:17 UTC
gtk_widget_queue_resize() is guaranteed to cause a redraw on the widget ...
usually it is called when some internal state of the widget changes that
affects the appearance and possibly the size. See 
gtk_widget_queue_resize_no_redraw().
Comment 8 Nickolay V. Shmyrev 2005-01-20 19:22:39 UTC
Comment on attachment 36250 [details] [review]
Patch to CVS

Now I see that patch above breaks exactly that function
(gtk_widget_queue_resize_no_redraw). In every resize ALLOC_NEEDED is set, and
with patch it causes redraw on widget.
Comment 9 Nickolay V. Shmyrev 2005-01-20 19:24:33 UTC
Actually it's just an duplicate of older bug, so marking it so.

*** This bug has been marked as a duplicate of 135903 ***