I find I have some diffs in my local sources, that I might as well check
in. It has been a while since I made them, so looking at them they seem
to be about cleaning up RaiseOnWarp and SaveWorkspaceFocus.

I remember that there are ways to get SaveWorkspaceFocus in a somewhat
confused state (my note suggest that this would be if it tries to raise
a window in another workspace) so I have it turned off anyway.

Shall I clean up the commented-out code from below and commit, or should
I not bother?

#
# old_revision [a4554d63ca7723d1314942c56f5e65224147e10c]
#
# patch "ctwm.c"
#  from [92a7863c957acb35f0e3133941561a89ace04bdf]
#    to [7861df4001dbaa4831380d6bdbac7f61628792fe]
# 
# patch "ctwm.man"
#  from [c385bd243f2a15648c06e6cb5d9296dbc72d1179]
#    to [a5f55e11b6b9aa147fcec5a2ccae5cb34443d311]
# 
# patch "events.c"
#  from [be0f52531ec7c2299e41b6e5f8eea9ffcd56b396]
#    to [eb953d9c3d511b86492d3b0feaf0f79ffc17c63f]
# 
# patch "menus.c"
#  from [099ca5c6fd77c789ff8974e3c48fd0ada4020987]
#    to [e2155ac7176b8e5e13ae125b64a1604da931b0f8]
# 
# patch "menus.h"
#  from [f00c50306ff90f9498ffb11d47fcc3e210e9b01f]
#    to [cf30375fe93100a6b01ca77fd4ef0903a6f2254f]
# 
# patch "parse.c"
#  from [f64e39e6f42dbcbcb4deb0775ce09344f9fee04f]
#    to [0cc3cbf9680a8f7cd99d778908847b1537700e5a]
# 
# patch "resize.c"
#  from [158533f362262ddadb3e5b937f3c1d726872abcc]
#    to [67786881a1dccfd7eaeea0924ce7c61ce16cc69a]
# 
# patch "screen.h"
#  from [e3be8919dc8c0b63029d7a0772974bc1e433d9ff]
#    to [563a224723b4f0c82c9eecb749d00f242682d445]
# 
# patch "workmgr.c"
#  from [ea9dbcb2897548e5721e6a6cd2da57223c2dfaad]
#    to [e15ade89451967b36f052fba572ac2552f4ba90b]
#
============================================================
--- ctwm.c      92a7863c957acb35f0e3133941561a89ace04bdf
+++ ctwm.c      7861df4001dbaa4831380d6bdbac7f61628792fe
@@ -151,7 +151,7 @@ Bool PrintErrorMessages = False;    /* cont
 int PreviousScreen;            /* last screen that we were on */
 int FirstScreen;               /* TRUE ==> first screen of display */
 Bool PrintErrorMessages = False;       /* controls error messages */
-Bool ShowWelcomeWindow = True;
+Bool ShowWelcomeWindow = False;
 static int RedirectError;      /* TRUE ==> another window manager running */
 /* for settting RedirectError */
 static int CatchRedirectError(Display *display, XErrorEvent *event);
@@ -1020,7 +1020,7 @@ void InitVariables(void)
     Scr->NoRaiseMove = FALSE;
     Scr->NoRaiseResize = FALSE;
     Scr->NoRaiseDeicon = FALSE;
-    Scr->NoRaiseWarp = FALSE;
+    Scr->RaiseOnWarp = TRUE;
     Scr->DontMoveOff = FALSE;
     Scr->DoZoom = FALSE;
     Scr->TitleFocus = TRUE;
============================================================
--- ctwm.man    c385bd243f2a15648c06e6cb5d9296dbc72d1179
+++ ctwm.man    a5f55e11b6b9aa147fcec5a2ccae5cb34443d311
@@ -1223,6 +1223,8 @@ WorkSpaceMap can be used only to modify 
 This keyword tells \fIctwm\fP to move the actual window when the user is
 moving the small windows in the WorkSpaceMap window. If not present the
 WorkSpaceMap can be used only to modify the occupation of a window.
+Pressing the \fIshift\fP key while dragging a window in the workspace manager
+temporarily toggles this option.
 
 .IP "\fBResizeFont\fP \fIstring\fP" 8
 This variable specifies the font to be used for in the dimensions window when
@@ -1513,6 +1515,9 @@ WindowGeometries {
 }
 .EE
 
+.IP "\fBWindowRegion\fP \fIgeomstring\fP \fIvgrav\fP fIhgrav\fP [{ 
\fIwin\-list\fP }]" 8
+Similar to IconRegion, but for windows.
+
 .IP "\fBWindowRing\fP [{ \fIwin\-list\fP }]" 8
 This variable specifies a list of windows along which the \fBf.warpring\fP
 function cycles. If no argument is given, all the windows are in the ring.
@@ -2201,6 +2206,7 @@ press another button before releasing th
 press another button before releasing the first button.
 
 .IP "\fBf.restart\fP" 8
+.IP "\fBf.twmrc\fP" 8
 This function kills and restarts \fIctwm\fP.
 
 .IP "\fBf.restoregeometry\fP" 8
@@ -2507,8 +2513,6 @@ lists.
 The resource manager should have been used instead of all of the window
 lists.
 .PP
-The \fBIconRegion\fP variable should take a list.
-.PP
 Double clicking very fast to get the constrained move function will sometimes
 cause the window to move, even though the pointer is not moved.
 .PP
============================================================
--- events.c    be0f52531ec7c2299e41b6e5f8eea9ffcd56b396
+++ events.c    eb953d9c3d511b86492d3b0feaf0f79ffc17c63f
@@ -2186,6 +2186,13 @@ void HandleDestroyNotify(void)
        Scr->Focus = (TwmWindow*) NULL;
        FocusOnRoot();
     }
+    if (Scr->SaveWorkspaceFocus) {
+       struct WorkSpace *ws;
+       for (ws = Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->next) {
+           if (ws->save_focus == Tmp_win)
+               ws->save_focus = NULL;
+       }
+    }
     XDeleteContext(dpy, Tmp_win->w, TwmContext);
     XDeleteContext(dpy, Tmp_win->w, ScreenContext);
     XDeleteContext(dpy, Tmp_win->frame, TwmContext);
@@ -3757,15 +3764,18 @@ void HandleLeaveNotify(void)
        if (Scr->RingLeader && Scr->RingLeader == Tmp_win &&
            (Event.xcrossing.detail != NotifyInferior &&
             Event.xcrossing.window != Tmp_win->w)) {
+           //fprintf(stderr, "HandleLeaveNotify: Event.xcrossing.window %x != 
Tmp_win->w %x\n", Event.xcrossing.window, Tmp_win->w);
            if (!inicon) {
-               if (Tmp_win->mapped) {
+               if (Event.xcrossing.window != Tmp_win->frame 
/*Tmp_win->mapped*/) { // XXX
                    Tmp_win->ring.cursor_valid = False;
-               } else {
+                   //fprintf(stderr, "HandleLeaveNotify: cursor_valid = 
False\n");
+               } else {        // Event.xcrossing.window == Tmp_win->frame
                    Tmp_win->ring.cursor_valid = True;
                    Tmp_win->ring.curs_x = (Event.xcrossing.x_root -
                                            Tmp_win->frame_x);
                    Tmp_win->ring.curs_y = (Event.xcrossing.y_root -
                                            Tmp_win->frame_y);
+                   //fprintf(stderr, "HandleLeaveNotify: cursor_valid = True; 
x = %d (%d-%d), y = %d (%d-%d)\n", Tmp_win->ring.curs_x, 
Event.xcrossing.x_root, Tmp_win->frame_x, Tmp_win->ring.curs_y, 
Event.xcrossing.y_root, Tmp_win->frame_y);
                }
            }
            Scr->RingLeader = (TwmWindow *) NULL;
============================================================
--- menus.c     099ca5c6fd77c789ff8974e3c48fd0ada4020987
+++ menus.c     e2155ac7176b8e5e13ae125b64a1604da931b0f8
@@ -2281,6 +2281,7 @@ int ExecuteFunction(int func, char *acti
 
     case F_POPUP:
        tmp_win = (TwmWindow *)action;
+       if (! tmp_win) break;
        if (Scr->WindowFunction.func != 0)
        {
           ExecuteFunction(Scr->WindowFunction.func,
@@ -2300,8 +2301,8 @@ int ExecuteFunction(int func, char *acti
        if (! tmp_win) break;
        if (Scr->WarpUnmapped || tmp_win->mapped) {
            if (!tmp_win->mapped) DeIconify (tmp_win);
-           if (!Scr->NoRaiseWarp) RaiseWindow (tmp_win);
-           WarpToWindow (tmp_win);
+           // if (Scr->RaiseOnWarp) RaiseWindow (tmp_win);
+           WarpToWindow (tmp_win, Scr->RaiseOnWarp);
        }
        break;
 
@@ -3438,8 +3439,8 @@ int ExecuteFunction(int func, char *acti
            if (tw) {
                if (Scr->WarpUnmapped || tw->mapped) {
                    if (!tw->mapped) DeIconify (tw);
-                   if (!Scr->NoRaiseWarp) RaiseWindow (tw);
-                   WarpToWindow (tw);
+                   //if (Scr->RaiseOnWarp) RaiseWindow (tw);
+                   WarpToWindow (tw, Scr->RaiseOnWarp);
                }
            } else {
                XBell (dpy, 0);
@@ -3514,7 +3515,7 @@ int ExecuteFunction(int func, char *acti
                tmp_win->ring.next = tmp_win->ring.prev = Scr->Ring = tmp_win;
            }
        }
-       tmp_win->ring.cursor_valid = False;
+       //tmp_win->ring.cursor_valid = False;
        break;
 
     case F_WARPRING:
@@ -4111,7 +4112,7 @@ void DeIconify(TwmWindow *tmp_win)
     if (isicon && 
        (Scr->WarpCursor ||
         LookInList(Scr->WarpCursorL, tmp_win->full_name, &tmp_win->class)))
-      WarpToWindow (tmp_win);
+      WarpToWindow (tmp_win, 0);
 
     /* now de-iconify and window group transients */
     ReMapTransients(tmp_win);
@@ -4721,7 +4722,7 @@ void WarpAlongRing (XButtonEvent *ev, Bo
        TwmWindow *p = Scr->RingLeader, *t;
 
        Scr->RingLeader = r;
-       WarpToWindow (r);
+       WarpToWindow (r, 1);
 
        if (p && p->mapped &&
            (t = GetTwmWindow(ev->window)) &&
@@ -4729,6 +4730,8 @@ void WarpAlongRing (XButtonEvent *ev, Bo
            p->ring.cursor_valid = True;
            p->ring.curs_x = ev->x_root - t->frame_x;
            p->ring.curs_y = ev->y_root - t->frame_y;
+           //fprintf(stderr, "WarpAlongRing: cursor_valid := True; x := %d 
(%d-%d), y := %d (%d-%d)\n", Tmp_win->ring.curs_x, ev->x_root, t->frame_x, 
Tmp_win->ring.curs_y, ev->y_root, t->frame_y);
+#if 0
            if (p->ring.curs_x < -p->frame_bw || 
                p->ring.curs_x >= p->frame_width + p->frame_bw ||
                p->ring.curs_y < -p->frame_bw || 
@@ -4736,25 +4739,61 @@ void WarpAlongRing (XButtonEvent *ev, Bo
                /* somehow out of window */
                p->ring.curs_x = p->frame_width / 2;
                p->ring.curs_y = p->frame_height / 2;
+               //fprintf(stderr, "WarpAlongRing: outside window; x := %d, y := 
%d\n", Tmp_win->ring.curs_x, Tmp_win->ring.curs_y);
            }
+#endif
        }
     }
 }
 
 
 
-void WarpToWindow (TwmWindow *t)
+void WarpToWindow (TwmWindow *t, int must_raise)
 {
     int x, y;
 
-    if (t->auto_raise || !Scr->NoRaiseWarp) AutoRaiseWindow (t);
     if (t->ring.cursor_valid) {
        x = t->ring.curs_x;
        y = t->ring.curs_y;
+       //fprintf(stderr, "WarpToWindow: cursor_valid; x == %d, y == %d\n", x, 
y);
+
+       // XXX is this correct with 3D borders? Easier check possible?
+       // frame_bw is for the left border.
+       if (x < t->frame_bw)
+           x = t->frame_bw;
+       if (x >= t->frame_width + t->frame_bw)
+           x  = t->frame_width + t->frame_bw - 1;      
+       if (y < t->title_height + t->frame_bw)
+           y = t->title_height + t->frame_bw;
+       if (y >= t->frame_height + t->frame_bw)
+           y  = t->frame_height + t->frame_bw - 1;
+       //fprintf(stderr, "WarpToWindow: adjusted    ; x := %d, y := %d\n", x, 
y);
     } else {
        x = t->frame_width / 2;
        y = t->frame_height / 2;
+       //fprintf(stderr, "WarpToWindow: middle; x := %d, y := %d\n", x, y);
     }
+#if 0
+    int dest_x, dest_y;
+    Window child;
+
+    /*
+     * Check if the proposed position actually is visible. If not, raise the 
window.
+     * "If the coordinates are contained in a mapped
+     * child of dest_w, that child is returned to child_return."
+     * We'll need to check for the right child window; the frame probably.
+     * (What about XXX window boxes?)
+     *
+     * Alternatively, use XQueryPointer() which returns the root window
+     * the pointer is in, but XXX that won't work for VirtualScreens.
+     */
+    if (XTranslateCoordinates(dpy, t->frame, Scr->Root, x, y, &dest_x, 
&dest_y, &child)) {
+       if (child != t->frame)
+           must_raise = 1;
+    }
+#endif
+    //if (t->auto_raise || Scr->RaiseOnWarp) AutoRaiseWindow (t);
+    if (t->auto_raise || must_raise) AutoRaiseWindow (t);
     if (! visible (t)) {
        WorkSpace *wlist;
 
@@ -4763,7 +4802,23 @@ void WarpToWindow (TwmWindow *t)
        }
        if (wlist != NULL) GotoWorkSpace (Scr->currentvs, wlist);
     }
-    XWarpPointer (dpy, None, t->frame, 0, 0, 0, 0, x, y);
+    //XWarpPointer (dpy, None, t->frame, 0, 0, 0, 0, x, y);
+    XWarpPointer (dpy, None, Scr->Root, 0, 0, 0, 0, x + t->frame_x, y + 
t->frame_y);
+#if 1
+    {
+       Window root_return;
+       Window child_return;
+       int root_x_return;
+       int root_y_return;
+       int win_x_return;
+       int win_y_return;
+       unsigned int mask_return;
+
+       if (XQueryPointer(dpy, t->frame, &root_return, &child_return, 
&root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask_return)) {
+           //fprintf(stderr, "XQueryPointer: root_return=%x, child_return=%x, 
root_x_return=%d, root_y_return=%d, win_x_return=%d, win_y_return=%d\n", 
root_return, child_return, root_x_return, root_y_return, win_x_return, 
win_y_return);
+       }
+    }
+#endif
 }
 
 
============================================================
--- menus.h     f00c50306ff90f9498ffb11d47fcc3e210e9b01f
+++ menus.h     cf30375fe93100a6b01ca77fd4ef0903a6f2254f
@@ -257,7 +257,7 @@ extern void WarpAlongRing (XButtonEvent 
 extern void TryToGrid (TwmWindow *tmp_win, int *x, int *y);
 extern void resizeFromCenter(Window w, TwmWindow *tmp_win);
 extern void WarpAlongRing (XButtonEvent *ev, Bool forward);
-extern void WarpToWindow (TwmWindow *t);
+extern void WarpToWindow (TwmWindow *t, int must_raise);
 extern void DisplayPosition (TwmWindow *tmp_win, int x, int y);
 extern void packwindow (TwmWindow *tmp_win, char *direction);
 extern void fillwindow (TwmWindow *tmp_win, char *direction);
============================================================
--- parse.c     f64e39e6f42dbcbcb4deb0775ce09344f9fee04f
+++ parse.c     0cc3cbf9680a8f7cd99d778908847b1537700e5a
@@ -1276,9 +1276,15 @@ int do_single_keyword (int keyword)
        return 1;
 
       case kw0_NoRaiseOnWarp:
-       Scr->NoRaiseWarp = TRUE;
+       Scr->RaiseOnWarp = FALSE;
        return 1;
 
+#if 0
+      case kw0_RaiseOnWarp:
+       Scr->RaiseOnWarp = TRUE;
+       return 1;
+#endif
+
       case kw0_WarpUnmapped:
        Scr->WarpUnmapped = TRUE;
        return 1;
============================================================
--- resize.c    158533f362262ddadb3e5b937f3c1d726872abcc
+++ resize.c    67786881a1dccfd7eaeea0924ce7c61ce16cc69a
@@ -627,6 +627,7 @@ void EndResize(void)
     XUnmapWindow(dpy, Scr->SizeWindow);
 
     tmp_win = GetTwmWindow(ResizeWindow);
+    if (!tmp_win) return;
 
     ConstrainSize (tmp_win, &dragWidth, &dragHeight);
 
@@ -873,6 +874,8 @@ void SetupFrame (TwmWindow *tmp_win, int
     fprintf (stderr, "SetupWindow: x=%d, y=%d, w=%d, h=%d, bw=%d\n",
             x, y, w, h, bw);
 #endif
+    if (!tmp_win)              /* should not happen */
+       return;
 
     if (x >= Scr->rootw)
       x = Scr->rootw - 16;     /* one "average" cursor width */
============================================================
--- screen.h    e3be8919dc8c0b63029d7a0772974bc1e433d9ff
+++ screen.h    563a224723b4f0c82c9eecb749d00f242682d445
@@ -388,7 +388,7 @@ struct ScreenInfo
     short NoRaiseMove;         /* don't raise window following move */
     short NoRaiseResize;       /* don't raise window following resize */
     short NoRaiseDeicon;       /* don't raise window on deiconify */
-    short NoRaiseWarp;         /* don't raise window on warp */
+    short RaiseOnWarp;         /* do raise window on warp */
     short DontMoveOff;         /* don't allow windows to be moved off */
     int MoveOffResistance;     /* nb of pixel before moveOff gives up */
     int MovePackResistance;    /* nb of pixel before f.movepack gives up */
============================================================
--- workmgr.c   ea9dbcb2897548e5721e6a6cd2da57223c2dfaad
+++ workmgr.c   e15ade89451967b36f052fba572ac2552f4ba90b
@@ -626,12 +626,13 @@ void GotoWorkSpace (virtualScreen *vs, W
 
     /* If SaveWorkspaceFocus is on, try to restore the focus to the last
        window which was focused when we left this workspace. */
-    if ( Scr->SaveWorkspaceFocus && newws->save_focus) {
-        for (twmWin = &(Scr->TwmRoot); twmWin != NULL; twmWin = twmWin->next) {
-            if (twmWin == newws->save_focus) {
-                WarpToWindow(twmWin);
-            }
-        }
+    if (Scr->SaveWorkspaceFocus && newws->save_focus) {
+       twmWin = newws->save_focus;
+       if (OCCUPY(twmWin, newws)) {    /* check should not even be needed 
anymore */
+           WarpToWindow(twmWin, 0);
+       } else {
+           newws->save_focus = NULL;
+       }
     }
 
     /* keep track of the order of the workspaces across restarts */
@@ -1502,10 +1503,14 @@ void ChangeOccupation (TwmWindow *tmp_wi
     for (ws = Scr->workSpaceMgr.workSpaceList; ws != NULL; ws = ws->next) {
        int mask = 1 << ws->number;
        if (changedoccupation & mask) {
-           if (newoccupation & mask)
+           if (newoccupation & mask) {
                WMapAddToList (tmp_win, ws);
-           else
+           } else {
                WMapRemoveFromList (tmp_win, ws);
+                if (Scr->SaveWorkspaceFocus && ws->save_focus == tmp_win) {
+                    ws->save_focus = NULL;
+                }
+           }
        }
     }
 
@@ -1585,8 +1590,8 @@ void WMgrAddToCurrentWorkSpaceAndWarp (v
     }
 
     if (! tw->mapped) DeIconify (tw);
-    if (! Scr->NoRaiseWarp) RaiseWindow (tw);
-    WarpToWindow (tw);
+    //if (! Scr->RaiseOnWarp) RaiseWindow (tw);
+    WarpToWindow (tw, Scr->RaiseOnWarp);
 }
 
 static void CreateWorkSpaceManagerWindow (virtualScreen *vs)
@@ -2900,7 +2905,7 @@ move:             XMoveWindow (dpy, w, newX - XW, n
        XMapWindow (dpy, sw);
        XDestroyWindow (dpy, w);
        GotoWorkSpace (vs, ws);
-       if (!Scr->DontWarpCursorInWMap) WarpToWindow (win);
+       if (!Scr->DontWarpCursorInWMap) WarpToWindow (win, Scr->RaiseOnWarp);
        control_L_sym  = XStringToKeysym  ("Control_L");
        control_R_sym  = XStringToKeysym  ("Control_R");
        control_L_code = XKeysymToKeycode (dpy, control_L_sym);

-Olaf.
-- 
___ Olaf 'Rhialto' Seibert  -- The Doctor: No, 'eureka' is Greek for
\X/ rhialto/at/xs4all.nl    -- 'this bath is too hot.'

Reply via email to