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 144030 - Gdk invalidates obscured windows
Gdk invalidates obscured windows
Status: RESOLVED WONTFIX
Product: gtk+
Classification: Platform
Component: Backend: X11
2.4.x
Other Linux
: Normal normal
: Medium fix
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2004-06-09 15:04 UTC by Billy Biggs
Modified: 2014-03-24 03:07 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
C example (2.37 KB, text/x-c)
2004-06-16 03:34 UTC, Billy Biggs
Details

Description Billy Biggs 2004-06-09 15:04:30 UTC
gdkgeometry-x11.c invalidates the newly exposed portion of a window when the
clip region changes (for example, during a resize of the window).  Since this is
an internal invalidation, expose events are sent to the GdkWindow even if it is
obscured.

This can cause a lot of work to happen unnecessarily.  In Eclipse, we often have
GdkWindow objects which can be obscured.  See this bug:

  http://bugs.eclipse.org/bugs/show_bug.cgi?id=65269

Our workaround in eclipse is to listen for VisibilityNotify events on each
GdkWindow for our own widgets, and avoid redrawing if they are not visible.

Is there something which can be done better in Gdk to handle this case?  The
following patch saved a lot of work in Eclipse, so I am curious about why Gdk is
invalidating this region itself.

Index: gdk/x11/gdkgeometry-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkgeometry-x11.c,v
retrieving revision 1.22
diff -p -u -r1.22 gdkgeometry-x11.c   
--- a/gdk/x11/gdkgeometry-x11.c 10 May 2004 20:51:19 -0000      1.22
+++ b/gdk/x11/gdkgeometry-x11.c 8 Jun 2004 18:13:31 -0000
@@ -1146,7 +1146,10 @@ gdk_window_clip_changed (GdkWindow *wind
   if (!gdk_region_empty (new_clip_region))
     {
       gdk_window_tmp_unset_bg (window);
-      gdk_window_invalidate_region (window, new_clip_region, FALSE);
+      /*
+       * Is this invalidate unnecessary?
+       * gdk_window_invalidate_region (window, new_clip_region, FALSE);
+       */
     }

   gdk_region_destroy (new_clip_region);
Comment 1 Owen Taylor 2004-06-09 15:27:57 UTC
We do the invalidate because it means that we can repaint without
a round trip to the server, which greatly improves appearance for
scrolling and similar.

Having lots of obscured windows seems rather odd to me ... is the 
problem that not-front-notebook tabs are just lowered, not unmapped
in SWT? (No expose events should be generated for windows where
some ancestor is unmapped.)
Comment 2 Billy Biggs 2004-06-09 15:57:27 UTC
For SWT notebooks, child widgets are unmapped like normal.  However, in Eclipse
we do have notebooks which just play z-order games.  Our notebooks may be
changed to use unmapping in the future, but right now it's apparently easier to
play focus games and other tricks when the widgets are not unmapped.

There are other places in Eclipse where we obscure windows, for example we have
resizable views which pop up over part the eclipse window and obscure what's
underneath.  However, I can't think of a good use case right now where what's
below would be resized.
Comment 3 Billy Biggs 2004-06-16 03:34:50 UTC
Created attachment 28741 [details]
C example

Here is a C program which demonstrates the effect.  The application shows a
label and below the label is a drawing area which is filled on expose.	It
prints information about exposes and visibility events.  It can be used to
demonstrate ways in which obscured windows are told to draw, sometimes when
they don't have to.

Examples:
1. Move the window so that its title bar is visible, but the drawing area is
below your screen.  Resizing the window causes the drawing area to get exposes.


2. An effect of guffaw scrolling: position the window as in step 1, and resize
it larger.  The window becomes visible, is told to draw, but on layout jumps
back to being obscured (but still redraws).

3. Similarly, set the window to be STATE_BELOW.  The drawing area gets exposes
even when it is not visible.

4. Resize the window so you have to scroll to the drawing area, we no longer
get exposes (nice!).  :)

5. Resize the window large and small rapidly, notice how many of the exposes
came at times when the last state the widget saw was that it was obscured.
Comment 4 Soren Sandmann Pedersen 2004-06-16 11:13:12 UTC
I don't think we should lose the paint-without-roundtrip optimization.

We could track visibility notifies; there is even a thread about that here:

  http://mail.gnome.org/archives/gtk-devel-list/2003-April/msg00026.html

To make it work in the presence of backing store on the X server we would have
to maintain the invalid region for the window while the window is obscured, then
paint it when the window becomes partially or completely unobscured.

A simple way to do this might be to call gdk_window_freeze_updates() when the
window becomes fully obscured and gdk_window_thaw_updates() when the window
becomes unobscured. But see bug 144272.
Comment 5 Billy Biggs 2005-02-24 05:02:14 UTC
In SWT, we currently listen to visibility events on all widgets and windows we
create and block expose events if they are not visible.  While it clearly
improves some benchmarks, a lot of events are generated and so it hurts in other
ways (as well, this technique is scary and has had a few bugs).

Personally, I'm not convinced that the paint-without-roundtrip optimization is
worth it, especially in this particular case of resizing a window.  I don't
think this affects scrolling, and since layout is deferred and menus use a
background of None, painting in this case seems especially unnecessary.
Comment 6 Matthias Clasen 2014-03-24 03:07:20 UTC
closing out ancient bugs