Re: Reparenting cleanup



"Andrea Vettorello" <andrea vettorello gmail com> writes:
> I've a lot of homeworks to do before i'm on par with the ICCCM and
> EWMH stuff, anyway seems that gnome-power-preferences the first thing
> it does when creating a new window is to hide it to avoid a
> redrawing...

New windows start hidden, that is normal.  What is not normal is that
immediately after telling X to display the window (MapWindow),
gnome-power-preferences tells X to hide it again (UnmapWindow).

When there is a window manager, the X server redirects MapWindow
requests to the wm (with MapRequest events).  This allows the wm to
create the frame while the window is still hidden and map the framed
window all at once.  Unmapping is not similarly redirected: it happens
immediately and the wm is only notified afterwards.

Hence the window ends up getting unmapped by gnome-power-preferences
before it is mapped by Sawfish.  Unmapping an already unmapped window
is a no-op.  In particular it does not create a notification event for
the wm to see.  For this reason a client that unmaps its window -
which might be iconified and thus already unmapped - is required to
send a synthetic UnmapNotify event to the wm.

I think this is how it plays out (+ relates to mapping and - to unmapping):
+ GPP tries to map the window.  X sends a MapRequest to Sawfish.
- GPP tries to unmap the window.  Nothing happens: it is already unmapped.
- GPP sends a synthetic UnmapNotify.
+ Sawfish gets the MapRequest and starts to prepare the window.
+ Sawfish finally maps the window and drops back to its normal event loop.
- Sawfish gets the UnmapNotify and removes the window frame.
+ GPP gets a MapNotify event for its window.

Now Sawfish thinks that the window has been withdrawn, i.e., unmapped
by GPP, but the X server regards the window as mapped, and that is
what you see.  GPP probably does not know what to think: it has
unmapped the window but events just keep coming in, first the
MapNotify and later probably actual input events.

I would tend to call this a client error.  It is just pointless to
map and unmap a window that way.  However, there may be another race
condition lurking here.  Consider a client with an iconified window
and the following sequence:
- The client decides to withdraw the window.
+ By chance, the user just now commands the wm to uniconify the window.
- The client unmaps the window.  Nothing happens: already unmapped.
- The client sends a synthetic UnmapNotify.
+ The wm maps the window.  A MapNotify event ensues.
- The wm gets the UnmapNotify and removes the window frame.
+ The client gets the MapNotify.

The end result is essentially the same, but here no one is doing
anything wrong or even obviously stupid.  Just unfortunate timing.

I can think of two possible wm-side solutions.  One would be that the
wm would watch out for synthetic UnmapNotify events about windows that
it thinks are mapped.  Such windows should then be unmapped by the wm.
Another one would be for the MapRequest handler to peek for
UnmapNotify events immediately before mapping the window.  The first
solution has the advantage of not containing the words "immediately
before".  You typically need a server grab to make sure it really is
_immediately_ before.  The second solution has the advantage that it
does not map windows that have been unmapped by the client.  The
client might no longer be prepared to draw such windows.  It might be
a good idea to look at other window managers to see how they cope with
this, if they do.

-- 
	Timo Korvola		<URL:http://www.iki.fi/tkorvola>



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