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 113310 - Unset bg when mapping override-redirect toplevels
Unset bg when mapping override-redirect toplevels
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: X11
2.2.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2003-05-19 21:54 UTC by Soren Sandmann Pedersen
Modified: 2011-02-04 16:17 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
A proof-of-concept patch (12.61 KB, patch)
2004-02-03 17:59 UTC, Soren Sandmann Pedersen
none Details | Review
New patch that doesn't do aggressive invalidation (8.41 KB, patch)
2004-04-26 20:50 UTC, Soren Sandmann Pedersen
none Details | Review
New patch that doesn't do aggressive invalidation (11.11 KB, patch)
2004-04-26 21:30 UTC, Soren Sandmann Pedersen
none Details | Review
op (13.65 KB, patch)
2004-06-12 17:57 UTC, Soren Sandmann Pedersen
none Details | Review
The committed patch (12.16 KB, patch)
2004-07-09 22:44 UTC, Soren Sandmann Pedersen
none Details | Review

Description Soren Sandmann Pedersen 2003-05-19 21:54:44 UTC
To reduce flicker, GtkMenu's windows should have a background of None so 
they won't be gray for a moment before drawing the menu.
Comment 1 Owen Taylor 2003-05-20 16:20:05 UTC
Actually, thinking about it a little more, I've changed
my mind, and I thinki we should do something generically
for all override-redirect toplevels.

But instead of setting bg=NONE permanently, I think we
should do a recursive  gdk_window_tmp_unset_bg() before mapping
the window, and then reset the backgrounds afterwards.

This is very much similar to what we do when moving windows
(and perhaps we should also do it when mapping child windows...
that might reduce flicker a bit when switching notebook
tabs with entries in them, though you still get flicker on
unmap, and that's probably more noticeable.)

Retitling accordingly, though feel free to change back if
you disagree.
Comment 2 Soren Sandmann Pedersen 2003-05-21 18:41:43 UTC
If we did this when mapping child windows, what about mapping the new
windows before unmapping the old when switching pages in a notebook?
The effect would be to inhibit the clearing to background from any
unmaps of windows occuppying the same position.

I think this could be done with good effect for drop-down menus too.
When you move the mouse across a menu bar, if you map the new menu
before unmapping the old, and the new menu had bg=none, you wouldn't
see a flash from clearing to the background before drawing the new menu.

It may also be worth considering whether to set bg=None for the parent
of the unmapped window. That way we won't get any flashing at all.
Comment 3 Owen Taylor 2003-05-21 19:09:30 UTC
I don't see how mapping the new before unmapping the old
fixes the problem for either dialogs or menus.

For notebooks, frequently you have a situation where
there is one entry on the old page and no entries
on the new page. I guess it would help for the
case of switching between near-identical notebook pages.

For menus, there is typically only a small overlap
between the old and new menus.

The idea of unsetting the parent background on subwindow
unmap seems sound, and should completely fix all
GtkNotebook flicker.

I suppose there is a small win to the map/unmap-ordering for
the menus case, but the idea of further complicating
the logic in GtkMenu* just doesn't appeal to me.
Comment 4 Soren Sandmann Pedersen 2004-02-03 17:59:40 UTC
Created attachment 24033 [details] [review]
A proof-of-concept patch
Comment 5 Soren Sandmann Pedersen 2004-02-03 18:13:06 UTC
The patch I just attached does three things:

1) predictive expose when mapping override redirect and child windows 
   (see bug 113040)

2) temporarily unsets its background before mapping override redirect
   and child windows

3) when unmapping a window, temporarily unset the background of _all_
   known windows intersection the same position on the screen.

The idea behind (3) is that when you unmap a menu, it will usually
be on top of an application window, so unsetting the background of
that window will prevent an annoying clear-to-background. For things
like gnome-terminal where the application window is white and the
menus are gray, the effect is noticably less flicker.

Also the patch eliminates the annoying flicker when switching notebook
pages with subwindows in them. Gnumeric is good example of that.

I consider this patch only proof-of-concept because I think it does
too much window walking, and the hack to allow recursive invalidation
of the root window is probably not such a good idea.
Comment 6 Soren Sandmann Pedersen 2004-02-03 18:20:33 UTC
If it wasn't clear, the patch does predictive exposes for all known
windows intersecting the position of the unmapped window.
Comment 7 Soren Sandmann Pedersen 2004-02-12 17:04:59 UTC
After trying the patch for a while, I don't think the predictive
exposing of all known windows is good, because if you have many
overlapping toplevels from the same application, popping down a menu
in one of them will cause all other toplevels to be redrawn.  In the
case of nautilus and list views this is very noticable.

The recursive bg-unsetting of all known windows is a nice effect and
can be done quickly. (It is just noise on the profile).

One possible problem is that the gtk+ version of Emacs relies on the
assumption that exposed areas are being cleared to the background
without double buffering. This is not true currently because we
already do the bg-unsetting trick in various places, but applying this
patch makes it much more apparent (you can see menu leftovers on the
text area in Emacs).
Comment 8 Soren Sandmann Pedersen 2004-04-26 20:50:41 UTC
Created attachment 27122 [details] [review]
New patch that doesn't do aggressive invalidation
Comment 9 Soren Sandmann Pedersen 2004-04-26 21:30:13 UTC
Created attachment 27126 [details] [review]
New patch that doesn't do aggressive invalidation

Sorry, that wasn't right. Here is the patch.
Comment 10 Owen Taylor 2004-06-07 20:42:50 UTC
Let's go ahead and commit this to HEAD. I think the gtk-emacs assumption
is just broken and they need to fix their code. (The fact that they
haven't released a stable version of emacs with that code makes it
easier for me to go ahead and say this.)

Comments:
 
 - I'd like to see viewability checks here; we could be spending a 
   lot of time tweaking the background of windows we know aren't
   viewable.
 
 - For pre_unmap(), for GDK_WINDOW_CHILD(), start_window just needs
   to be the parent, not the toplevel.

Quibble:

 - 'list' as iterator variable.
Comment 11 Soren Sandmann Pedersen 2004-06-12 17:54:36 UTC
I noticed a bug with this patch too. Windows without EXPOSURE in their
event_mask may not get their background drawn. Fixed in the new patch.

Comment 12 Soren Sandmann Pedersen 2004-06-12 17:57:20 UTC
Created attachment 28642 [details] [review]
op
Comment 13 Owen Taylor 2004-07-08 18:30:25 UTC
I think that we shouldn't unset the background for windows without the EXPOSURE
mask - if you unset the EXPOSURE mask, to me, that says that you want what the
X server is going to draw.

What do you think about moving the viewability checks into the unset_bg/reset_bg
calls? I'm a little nervous not having the checks at all in the unmap case ...
we might be doing a *lot* of X traffic on windows that we know aren't
viewable in some cases. (Unfortunately, the place that it would help
most - in other toplevel windows - doesn't work, since managed toplevel
windows always need to be considered viewable.)
Comment 14 Soren Sandmann Pedersen 2004-07-09 22:44:49 UTC
Created attachment 29390 [details] [review]
The committed patch

I don't think it's a good idea to move the viewability checks into
unset_bg/reset_bg, because that would make the whole operation O(d^2) where d
is the depth of the window hierarchy. What I did instead was to just stop the
recursion when we see an unmapped window. This works because a window never
changes mapped state between unset and reset, not even when we are unmapping a
window. (In that case the mapped state is calculated before pre_unmap()).

I committed the attached patch.