On Mon, Nov 21, 2016 at 12:27:45AM +0000, Jürgen Hartmann wrote:
> Concerning side effects, I can't say anything since I have no idea what
> to look for.
> 
> > Now, if I'd understand what (a) the patch in
> > HandleMapRequestKeepRaised() is supposed to do,
> 
> Which patch do you mean? Does the piece of code that you disable in events.c
> origins from an earlier patch?

Yes, it that piece may have been an attempt to fix the same or a
similar bug with another application.

It's really complicated, but let me try to explain what's going
on, in case we need to understand why I made the current patch -
at some time in the distant future.

--

1)

Window managers have special powers in X.  In the presence of a
window manager, certain requests of the clients are "redirected"
to the window manager for confirmation.  In the case at hand,
clients cannot map top level windows without the window manager's
consent (i.e. the MapRequest event gets redirected to the window
manager).  The same is not true for unmapping.  Clients can always
unmap their windows; the window manager is just informed when that
happens.

2)

There is this old "Inter Client Communication Conventions Manual"
version 2, that defines three distinct window states that any
window manager should implement: normal, iconic and withdrawn.
The latter means that neither the window nor its icon are visible.  
The ICCCM2 also describes how to get a window from each state into
the other two states.

3)

To withdraw a normal or iconic window, the client is supposed to
first unmap the main window.  As the window may not be mapped at
that time, for example if its iconic, the window manager may not
receive an UnmapNotify event for that.  To make sure that the
window manager gets it, the client is supposed to send a synthetic
UnmapNotify event to the root window (the window manager always
gets events for the root window).  (This synthetic event contains
the id of the unmapped window.)  In response to this event, the
window manager is supposed to write down that the window is now in
withdrawn state, and unmap the *icon window* if its visible.

4)

In HandleUnmapEvent() there was some code from the ancient past of
fvwm, that - whenever fvwm received an UnmapNotify (that it did
not trigger itself) - *it would unmap the window (that is was just
told has already been unmapped*.  I can only guess why this code
was there, maybe the author thought that the client was asking for
permission to unmap the window.

5)

For some strange reason, when vmplayer wants to un-fullscreen a
window, it requests the window manager to end fullscreen state,
then withdraws the window as described above, and after that I
lost interest in event debugging.  Supposedly it maps the window
again after that.

==>

Putting it all together:

  * vmplayer requests end of fullscreen mode
  * vmplayer unmaps the window
  * vmplayer sends the synthetic event as described above
  * vmplayer maps the window again (which needs fvwm's consent).
  * fvwm receives the events generated by vmplayer
  * fvwm looks at the two UnmapNotify events it gets (one real and
    the syntehtic one) and calls XUnmapWindow.  This generates
    another UnmapNotify event.
 * fvwm sees the MapRequest and generates the decorations
   for the window.
 * fvwm receives the UnmapNotify it generated itself, destroys the
   decorations and leaves the window unmapped.

Duh.

Obviously vmplayer cannot handle this strange situation and ends
up with no window mapped.

--

As far as I understand it, HandleUnmapNotify() is broken at least
since the day in 1998 when the fvwm sources were moved to CVS.
I've spent much time thinking about this, reading the ICCCM2 and
the Xlib manuals, and now I'm convinced that HandleUnmapNotify()
must never unmap the client window itself.  (The *icon* window is
a different story.)  However, since there's no documentation about
this bit of code, it's hard to guess whether there are or were
really broken clients that needed this buggy window manager
behaviour.  Anyway, if there are such clients, they won't work on
any modern window manager.

Over the years there were several patches to fix problems caused
by unmapping windows in HandleUnmapNotify, but none of us ever
figured out the real bug for more than fifteen years.  :-/

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt

Reply via email to