This patch fixes a problem with recently un-mapped windows.  If a program
issues a window request to fvwm and that window has un-mapped itself, fvwm
prompts the user with a 'cross-hairs' mouse icon to select the window target
for the command.  In all cases the user will have no idea what is going on.

This patch implements a list of recently used window ids.  
When the window request is received:
    if the window id is zero, the user is prompted as usual.
    if the window id is a known, valid window,
        the command is sent to the requested target.
    if the window id is unknown, but seen before, we do not process the request.
    else the user is prompted as usual.

Please apply this patch.
Rich

diff -urNp fvwm-2.5.24/fvwm/add_window.c fvwm/fvwm/add_window.c
--- fvwm-2.5.24/fvwm/add_window.c       2007-11-16 11:19:48.000000000 -0600
+++ fvwm/fvwm/add_window.c      2008-01-15 17:07:59.000000000 -0600
@@ -123,6 +123,7 @@ static void delete_client_context(FvwmWi
            XCNOENT && cw == fw)
        {
                XDeleteContext(dpy, FW_W(fw), FvwmContext);
+               XSaveContext(dpy, FW_W(fw), LruFvwmContext, (caddr_t) None);
        }
 
        return;
@@ -843,6 +844,8 @@ static void setup_frame_window(
                InputOutput, CopyFromParent, valuemask | CWCursor, &attributes);
        XSaveContext(dpy, FW_W(fw), FvwmContext, (caddr_t) fw);
        XSaveContext(dpy, FW_W_FRAME(fw), FvwmContext, (caddr_t) fw);
+       XDeleteContext(dpy, FW_W(fw), LruFvwmContext);
+       XDeleteContext(dpy, FW_W_FRAME(fw), LruFvwmContext);
 
        return;
 }
@@ -858,6 +861,7 @@ static void setup_title_window(
                dpy, FW_W_FRAME(fw), 0, 0, 1, 1, 0, Pdepth, InputOutput,
                Pvisual, valuemask, pattributes);
        XSaveContext(dpy, FW_W_TITLE(fw), FvwmContext, (caddr_t) fw);
+       XDeleteContext(dpy, FW_W_TITLE(fw), LruFvwmContext);
 
        return;
 }
@@ -870,6 +874,7 @@ static void destroy_title_window(FvwmWin
                FW_W_TITLE(fw) = None;
        }
        XDeleteContext(dpy, FW_W_TITLE(fw), FvwmContext);
+       XSaveContext(dpy, FW_W_TITLE(fw), LruFvwmContext, (caddr_t) None);
        XFlush(dpy);
        FW_W_TITLE(fw) = None;
 
@@ -918,12 +923,14 @@ static void setup_button_windows(
                        XSaveContext(
                                dpy, FW_W_BUTTON(fw, i), FvwmContext,
                                (caddr_t)fw);
+                       XDeleteContext(dpy, FW_W_BUTTON(fw, i), LruFvwmContext);
                }
                else if (FW_W_BUTTON(fw, i) != None && !has_button)
                {
                        /* destroy the current button window */
                        XDestroyWindow(dpy, FW_W_BUTTON(fw, i));
                        XDeleteContext(dpy, FW_W_BUTTON(fw, i), FvwmContext);
+                       XSaveContext(dpy, FW_W_BUTTON(fw, i), LruFvwmContext, 
(caddr_t) None);
                        is_deleted = True;
                        FW_W_BUTTON(fw, i) = None;
                }
@@ -951,6 +958,7 @@ static void destroy_button_windows(FvwmW
                                FW_W_BUTTON(fw, i) = None;
                        }
                        XDeleteContext(dpy, FW_W_BUTTON(fw, i), FvwmContext);
+                       XSaveContext(dpy, FW_W_BUTTON(fw, i), LruFvwmContext, 
(caddr_t) None);
                        is_deleted = True;
                        FW_W_BUTTON(fw, i) = None;
                }
@@ -1006,6 +1014,7 @@ static void setup_parent_window(FvwmWind
                &attributes);
 
        XSaveContext(dpy, FW_W_PARENT(fw), FvwmContext, (caddr_t) fw);
+       XDeleteContext(dpy, FW_W_PARENT(fw), LruFvwmContext);
 
        return;
 }
@@ -1081,11 +1090,13 @@ static void setup_resize_handle_windows(
                        InputOutput, Pvisual, valuemask, &attributes);
                XSaveContext(
                        dpy, FW_W_CORNER(fw, i), FvwmContext, (caddr_t)fw);
+               XDeleteContext(dpy, FW_W_CORNER(fw, i), LruFvwmContext);
                attributes.win_gravity = s_grav[i];
                FW_W_SIDE(fw, i) = XCreateWindow(
                        dpy, FW_W_FRAME(fw), -1, -1, 1, 1, 0, Pdepth,
                        InputOutput, Pvisual, valuemask, &attributes);
                XSaveContext(dpy, FW_W_SIDE(fw, i), FvwmContext, (caddr_t)fw);
+               XDeleteContext(dpy, FW_W_SIDE(fw, i), LruFvwmContext);
        }
        setup_resize_handle_cursors(fw);
 
@@ -1101,6 +1112,8 @@ static void destroy_resize_handle_window
        {
                XDeleteContext(dpy, FW_W_SIDE(fw, i), FvwmContext);
                XDeleteContext(dpy, FW_W_CORNER(fw, i), FvwmContext);
+               XSaveContext(dpy, FW_W_SIDE(fw, i), LruFvwmContext, (caddr_t) 
None);
+               XSaveContext(dpy, FW_W_CORNER(fw, i), LruFvwmContext, (caddr_t) 
None);
                if (!do_only_delete_context)
                {
                        XDestroyWindow(dpy, FW_W_SIDE(fw, i));
@@ -1249,6 +1262,8 @@ static void destroy_auxiliary_windows(
        {
                XDeleteContext(dpy, FW_W_FRAME(fw), FvwmContext);
                XDeleteContext(dpy, FW_W_PARENT(fw), FvwmContext);
+               XSaveContext(dpy, FW_W_FRAME(fw), LruFvwmContext, (caddr_t) 
None);
+               XSaveContext(dpy, FW_W_PARENT(fw), LruFvwmContext, (caddr_t) 
None);
                delete_client_context(fw);
                XDestroyWindow(dpy, FW_W_FRAME(fw));
        }
@@ -1387,6 +1402,7 @@ static void destroy_icon(FvwmWindow *fw)
        {
                XDestroyWindow(dpy, FW_W_ICON_TITLE(fw));
                XDeleteContext(dpy, FW_W_ICON_TITLE(fw), FvwmContext);
+               XSaveContext(dpy, FW_W_ICON_TITLE(fw), LruFvwmContext, 
(caddr_t) None);
                XFlush(dpy);
        }
        if (FW_W_ICON_PIXMAP(fw) != None)
@@ -1400,6 +1416,7 @@ static void destroy_icon(FvwmWindow *fw)
                        XUnmapWindow(dpy, FW_W_ICON_PIXMAP(fw));
                }
                XDeleteContext(dpy, FW_W_ICON_PIXMAP(fw), FvwmContext);
+               XSaveContext(dpy, FW_W_ICON_PIXMAP(fw), LruFvwmContext, 
(caddr_t) None);
        }
        clear_icon(fw);
        XFlush(dpy);
diff -urNp fvwm-2.5.24/fvwm/externs.h fvwm/fvwm/externs.h
--- fvwm-2.5.24/fvwm/externs.h  2007-01-14 03:52:02.000000000 -0600
+++ fvwm/fvwm/externs.h 2008-01-15 17:00:03.000000000 -0600
@@ -42,6 +42,7 @@ extern int master_pid;
 extern Display *dpy;
 extern int x_fd;
 extern XContext FvwmContext;
+extern XContext LruFvwmContext;
 extern Bool fFvwmInStartup;
 extern Bool DoingCommandLine;
 extern Bool debugging;
diff -urNp fvwm-2.5.24/fvwm/fvwm.c fvwm/fvwm/fvwm.c
--- fvwm-2.5.24/fvwm/fvwm.c     2007-11-16 09:36:59.000000000 -0600
+++ fvwm/fvwm/fvwm.c    2008-01-15 17:00:07.000000000 -0600
@@ -156,6 +156,7 @@ Bool fFvwmInStartup = True;     /* Set t
 Bool DoingCommandLine = False;  /* Set True before each cmd line arg */
 
 XContext FvwmContext;           /* context for fvwm windows */
+XContext LruFvwmContext;        /* context for LRU fvwm windows */
 XContext MenuContext;           /* context for fvwm menus */
 
 int JunkX = 0, JunkY = 0;
@@ -1092,6 +1093,7 @@ static void CreateGCs(void)
 static void InitVariables(void)
 {
        FvwmContext = XUniqueContext();
+       LruFvwmContext = XUniqueContext();
        MenuContext = XUniqueContext();
 
        /* initialize some lists */
diff -urNp fvwm-2.5.24/fvwm/icons.c fvwm/fvwm/icons.c
--- fvwm-2.5.24/fvwm/icons.c    2007-07-26 03:00:43.000000000 -0500
+++ fvwm/fvwm/icons.c   2008-01-15 17:00:10.000000000 -0600
@@ -631,6 +631,7 @@ void CreateIconWindow(FvwmWindow *fw, in
                        XDeleteContext(dpy, FW_W_ICON_TITLE(fw), FvwmContext);
                        XDestroyWindow(dpy, FW_W_ICON_TITLE(fw));
                        XFlush(dpy);
+                       XSaveContext(dpy, FW_W_ICON_TITLE(fw), LruFvwmContext, 
(caddr_t) None);
                        FW_W_ICON_TITLE(fw) = None;
                }
        }
@@ -740,6 +741,7 @@ void CreateIconWindow(FvwmWindow *fw, in
                XDestroyWindow(dpy, old_icon_pixmap_w);
                XDeleteContext(dpy, old_icon_pixmap_w, FvwmContext);
                XFlush(dpy);
+               XSaveContext(dpy, old_icon_pixmap_w, LruFvwmContext, (caddr_t) 
None);
                is_old_icon_shaped = False;
        }
 
@@ -782,6 +784,7 @@ void CreateIconWindow(FvwmWindow *fw, in
        {
                XSaveContext(
                        dpy, FW_W_ICON_TITLE(fw), FvwmContext, (caddr_t)fw);
+               XDeleteContext(dpy, FW_W_ICON_TITLE(fw), LruFvwmContext);
                XDefineCursor(
                        dpy, FW_W_ICON_TITLE(fw), Scr.FvwmCursors[CRS_DEFAULT]);
                GrabAllWindowKeysAndButtons(
@@ -798,6 +801,7 @@ void CreateIconWindow(FvwmWindow *fw, in
        {
                XSaveContext(
                        dpy, FW_W_ICON_PIXMAP(fw), FvwmContext, (caddr_t)fw);
+               XDeleteContext(dpy, FW_W_ICON_PIXMAP(fw), LruFvwmContext);
                XDefineCursor(
                        dpy, FW_W_ICON_PIXMAP(fw),
                        Scr.FvwmCursors[CRS_DEFAULT]);
diff -urNp fvwm-2.5.24/fvwm/module_interface.c fvwm/fvwm/module_interface.c
--- fvwm-2.5.24/fvwm/module_interface.c 2007-09-04 14:07:16.000000000 -0500
+++ fvwm/fvwm/module_interface.c        2008-01-15 17:00:18.000000000 -0600
@@ -660,9 +660,15 @@ void module_input_execute(struct fmodule
        int flags;
 
        memset(&e, 0, sizeof(e));
+       if (None == input->window) {
+               ecc.w.fw = NULL;
+       } else
        if (XFindContext(dpy, input->window, FvwmContext,
                                 (caddr_t *)&ecc.w.fw) == XCNOENT)
        {
+               if (XCNOENT != XFindContext(dpy, input->window, LruFvwmContext, 
(caddr_t *) &ecc.w.fw))
+                       return;         /* input->window is a recently 
destroyed Window */
+
                ecc.w.fw = NULL;
                input->window = None;
        }

Reply via email to