On Tue, Aug 29, 2006 at 10:18:30PM +0200, Viktor Griph wrote:
> On Tue, 29 Aug 2006, Viktor Griph wrote:
> 
> >On Tue, 29 Aug 2006, Dominik Vogt wrote:
> >
> >>On Mon, Aug 28, 2006 at 08:07:31PM +0200, Viktor Griph wrote:
> >>>On Mon, 28 Aug 2006, Andreas Ehliar wrote:
> >>>
> >>>>I have a problem with fpga_editor as reported in bug 4062.  With some
> >>>>help from #fvwm I managed to find something suspicious. fpga_editor
> >>>>does an UnmapWindow request and a MapWindow request right after each
> >>>>other.
> >>>>
> >>>>An example program that does the same is located at
> >>>>http://www.da.isy.liu.se/~ehliar/priv/map_unmap.c .
> >>>>
> >>>>The example program will show a window for 1 second and it will then
> >>>>disappear if running under fvwm.
> >>>>
> >>>>The bug seems very similar to the bug reported in this thread:
> >>>>http://www.mail-archive.com/fvwm@hpc.uh.edu/msg08195.html
> >>>>
> >>>>
> >>>
> >>>This bug is related to the handling of MapRequests in fvwm. (See
> >>>http://www.mail-archive.com/fvwm-workers@lists.math.uh.edu/msg15491.html.)
> >>>I know  of three different ways to address it, but don't know if there is
> >>>any downside to them.
> >>
> >>>The different approches are
> >>>1) Change AddWindow to look at the trigger event for the mapped window if
> >>>the window in the execution context is gone. I think this is too late in
> >>>the line to address this.
> >>
> >>>2) Change the Handling of MapRequest to call AddWindow with the window
> >>>being mapped in the execution context. (I think this is better than 1)
> >>
> >>I don't actually understand the problem or the suggested
> >>solutions.  Can you explain it a bit?
> >>
> >
> >The problem is that, if the program calls MapWindow before the window has 
> >been reparented to the root it will get a XMapRequest with window= old 
> >decoration parent window and window set to the client. Handle event sets 
> >the window of the execution context to xany.window (parent in this case) 
> >if the parent window is not root. When this is a destroyed decoration it 
> >will be passed to AddWindow in the function called from HandleMapRequest. 
> >the suggested fix would be to modify the context to have the window of the 
> >MapRequest event set to the context before calling AddWindow if the 
> >trigger event is a MapRequest. (I'm not entirely sure on how 
> >CaptureAllWindows works, but I believe this logic would be ennouh to keep 
> >it working correctly.)
> >
> >>>3) Decide that Maps following Unmaps is a bad application behaviour and
> >>>have the handling of Unmap check if the window is about to remap before
> >>>deciding to destroy it.
> >>
> >>That's wrong.  If a window is unmapped the window structure must
> >>be destroyed.  There is no reliable way to find out if the window
> >>is remapped or if it was destroyed and a different window got the
> >>same id.
> >>
> >
> >The idea was to check for a MapRequest of FW_W_PARENT before reparenting 
> >the window, while the server is grabbed, and if sush event exists not 
> >unparent it. The problem is only if the window is mapped again before the 
> >client is reparented to root.
> >
> 
> Would this patch really break anything? It does not use the windowid of 
> the client, but only that of the decorations, and since the decorations 
> haven't been destroyed yet this can't be a reused window id. It does solve 
> the problem with the MapWindow immediatly after the UnmapWindow call, and 
> does so without triggering re-placement of the window.
> 
> --- fvwm/events.c       20 Mar 2006 20:32:35 -0000      1.518
> +++ fvwm/events.c       29 Aug 2006 20:07:59 -0000
> @@ -3624,6 +3624,13 @@
>                                 XUnmapWindow(dpy, 
> fw->wmhints->icon_window);
>                         }
>                 }
> +               else if (FCheckTypedWindowEvent(
> +                           dpy,  FW_W_PARENT(fw), MapRequest, &dummy))
> +               {
> +                       XMapWindow(dpy, te->xunmap.window);
> +                       MyXUngrabServer(dpy);
> +                       return;
> +               }
>                 else
>                 {
>                         RestoreWithdrawnLocation(fw, False, Scr.Root);

I have committed a fix for this.  At the end of HandleUnmapNotify,
check for pending MapRequests for that window, replace the window
and parent with the client window and root, then call
dispatch_event immediately.  (See attached patch).

Ciao

Dominik ^_^  ^_^

 --
Dominik Vogt, [EMAIL PROTECTED]
Index: events.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/fvwm/events.c,v
retrieving revision 1.518
diff -u -B -b -u -r1.518 events.c
--- events.c    20 Mar 2006 20:32:35 -0000      1.518
+++ events.c    30 Aug 2006 09:12:20 -0000
@@ -3512,11 +3515,15 @@
        int dstx, dsty;
        Window dumwin;
        XEvent dummy;
+       XEvent map_event;
        const XEvent *te = ea->exc->x.etrigger;
        int weMustUnmap;
        Bool focus_grabbed;
        Bool must_return = False;
+       Bool do_map = False;
        FvwmWindow * const fw = ea->exc->w.fw;
+       Window pw;
+       Window cw;
 
        DBUG("HandleUnmapNotify", "Routine Entered");
 
@@ -3545,6 +3552,8 @@
                        return;
                }
        }
+       cw = FW_W(fw);
+       pw = FW_W_PARENT(fw);
        if (te->xunmap.window == FW_W_FRAME(fw))
        {
                SET_ICONIFY_PENDING(fw , 0);
@@ -3635,6 +3644,12 @@
                }
                XSync(dpy, 0);
                MyXUngrabServer(dpy);
+               if (FCheckTypedWindowEvent(dpy, pw, MapRequest, &map_event))
+               {
+                       /* the client tried to map the window again while it
+                        * was still inside the decoration windows */
+                       do_map = True;
+               }
        }
        destroy_window(fw);
        if (focus_grabbed == True)
@@ -3644,6 +3659,14 @@
        EWMH_ManageKdeSysTray(te->xunmap.window, te->type);
        EWMH_WindowDestroyed();
        GNOME_SetClientList();
+       if (do_map == True)
+       {
+               map_event.xmaprequest.window = cw;
+               map_event.xmaprequest.parent = Scr.Root;
+               dispatch_event(&map_event);
+               /* note: we really should handle all map and unmap notify
+                * events for that window in a loop here */
+       }
 
        return;
 }

Attachment: signature.asc
Description: Digital signature

Reply via email to