JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
In the destroy path do not use a previously unmanaged window focus
[spectrwm.git] / scrotwm.c
index 61f3dda..4ef1088 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
@@ -52,7 +52,7 @@
 
 static const char      *cvstag = "$scrotwm$";
 
-#define        SWM_VERSION     "0.9.14"
+#define        SWM_VERSION     "0.9.15"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -94,6 +94,7 @@ static const char     *cvstag = "$scrotwm$";
 #endif
 #endif
 
+#define SWM_DEBUG
 /* #define SWM_DEBUG */
 #ifdef SWM_DEBUG
 #define DPRINTF(x...)          do { if (swm_debug) fprintf(stderr, x); } while (0)
@@ -337,7 +338,7 @@ struct layout {
        { horizontal_stack,     horizontal_config,      0,      "[-]" },
        { max_stack,            NULL,
          SWM_L_FOCUSPREV | SWM_L_MAPONFOCUS,                   "[ ]"},
-       { NULL,                 NULL,                   0},
+       { NULL,                 NULL,                   0,      NULL },
 };
 
 #define SWM_H_SLICE            (32)
@@ -369,9 +370,9 @@ enum        { SWM_S_COLOR_BAR, SWM_S_COLOR_BAR_BORDER, SWM_S_COLOR_BAR_FONT,
          SWM_S_COLOR_FOCUS, SWM_S_COLOR_UNFOCUS, SWM_S_COLOR_MAX };
 
 /* physical screen mapping */
-#define SWM_WS_MAX             (10)            /* XXX Too small? */
+#define SWM_WS_MAX             (10)
 struct swm_screen {
-       int                     idx;            /* screen index */
+       int                     idx;    /* screen index */
        struct swm_region_list  rl;     /* list of regions on this screen */
        struct swm_region_list  orl;    /* list of old regions */
        Window                  root;
@@ -1708,18 +1709,21 @@ stack_floater(struct ws_win *win, struct swm_region *r)
        }
 
        /* adjust for region */
-       wc.x += r->g.x;
-       wc.y += r->g.y;
+       if (wc.x < r->g.x)
+               wc.x += r->g.x;
+       if (wc.y < r->g.y)
+               wc.y += r->g.y;
 
        win->g.x = wc.x;
        win->g.y = wc.y;
        win->g.w = wc.width;
        win->g.h = wc.height;
 
-       DNPRINTF(SWM_D_STACK, "stack_floater: win %lu x %d y %d w %d h %d\n",
+       DNPRINTF(SWM_D_MISC, "stack_floater: win %lu x %d y %d w %d h %d\n",
            win->id, wc.x, wc.y, wc.width, wc.height);
 
        XConfigureWindow(display, win->id, mask, &wc);
+       configreq_win(win);
 }
 
 /*
@@ -2186,7 +2190,7 @@ resize_window(struct ws_win *win, int center)
            win->id, wc.x, wc.y, wc.width, wc.height);
 
        XConfigureWindow(display, win->id, mask, &wc);
-       config_win(win);
+       configreq_win(win);
 }
 
 void
@@ -2194,6 +2198,7 @@ resize(struct ws_win *win, union arg *args)
 {
        XEvent                  ev;
        Time                    time = 0;
+       struct swm_region       *r = win->ws->r;
 
        DNPRINTF(SWM_D_MOUSE, "resize: win %lu floating %d trans %d\n",
            win->id, win->floating, win->transient);
@@ -2215,6 +2220,14 @@ resize(struct ws_win *win, union arg *args)
                        handler[ev.type](&ev);
                        break;
                case MotionNotify:
+                       /* do not allow resize outside of region */
+                       if (ev.xmotion.y_root < r->g.y ||
+                           ev.xmotion.y_root >= r->g.y + r->g.h - 1)
+                               continue;
+                       if (ev.xmotion.x_root < r->g.x ||
+                           ev.xmotion.x_root >= r->g.x + r->g.w - 1)
+                               continue;
+
                        if (ev.xmotion.x <= 1)
                                ev.xmotion.x = 1;
                        if (ev.xmotion.y <= 1)
@@ -2260,7 +2273,7 @@ move_window(struct ws_win *win)
            win->id, wc.x, wc.y, wc.width, wc.height);
 
        XConfigureWindow(display, win->id, mask, &wc);
-       config_win(win);
+       configreq_win(win);
 }
 
 void
@@ -2269,6 +2282,7 @@ move(struct ws_win *win, union arg *args)
        XEvent                  ev;
        Time                    time = 0;
        int                     restack = 0;
+       struct swm_region       *r = win->ws->r;
 
        DNPRINTF(SWM_D_MOUSE, "move: win %lu floating %d trans %d\n",
            win->id, win->floating, win->transient);
@@ -2293,6 +2307,14 @@ move(struct ws_win *win, union arg *args)
                        handler[ev.type](&ev);
                        break;
                case MotionNotify:
+                       /* don't allow to move window out of region */
+                       if (ev.xmotion.y_root < r->g.y ||
+                           ev.xmotion.y_root + win->g.h >= r->g.y + r->g.h - 1)
+                               continue;
+                       if (ev.xmotion.x_root < r->g.x ||
+                           ev.xmotion.x_root + win->g.w >= r->g.x + r->g.w - 1)
+                               continue;
+
                        win->g.x = ev.xmotion.x_root;
                        win->g.y = ev.xmotion.y_root;
 
@@ -3712,27 +3734,8 @@ configurerequest(XEvent *e)
                                win->g.w = ev->width;
                        if (ev->value_mask & CWHeight)
                                win->g.h = ev->height;
-                       if (win->ws->r != NULL) {
-                               /* this seems to be full screen */
-                               if (win->g.w >= WIDTH(win->ws->r)) {
-                                       win->g.x = 0;
-                                       win->g.w = WIDTH(win->ws->r);
-                                       ev->value_mask |= CWX | CWWidth;
-                               }
-                               if (win->g.h >= HEIGHT(win->ws->r)) {
-                                       /* kill border */
-                                       win->g.y = 0;
-                                       win->g.h = HEIGHT(win->ws->r);
-                                       ev->value_mask |= CWY | CWHeight;
-                               }
-                       }
-                       XMoveResizeWindow(display, win->id,
-                           win->g.x, win->g.y, win->g.w, win->g.h);
-                       if ((ev->value_mask & (CWX | CWY)) &&
-                           !(ev->value_mask & (CWWidth | CWHeight)))
-                               config_win(win);
-               } else
-                       config_win(win);
+               }
+               config_win(win);
        }
 }
 
@@ -3761,21 +3764,22 @@ destroynotify(XEvent *e)
        struct workspace        *ws;
        struct ws_win_list      *wl;
        XDestroyWindowEvent     *ev = &e->xdestroywindow;
-       int                     unmanaged = 0;
 
        DNPRINTF(SWM_D_EVENT, "destroynotify: window %lu\n", ev->window);
 
        if ((win = find_window(ev->window)) == NULL) {
                if ((win = find_unmanaged_window(ev->window)) == NULL)
                        return;
-               unmanaged = 1;
+               free_window(win);
+               return;
        }
 
        /* find a window to focus */
        ws = win->ws;
        wl = &ws->winlist;
 
-       for (w = TAILQ_FIRST(&ws->winlist); w != TAILQ_END(&ws->winlist); w = wn) {
+       for (w = TAILQ_FIRST(&ws->winlist); w != TAILQ_END(&ws->winlist);
+           w = wn) {
                wn = TAILQ_NEXT(w, entry);
                if (win == w)
                        continue; /* can't happen but oh well */
@@ -3809,8 +3813,7 @@ destroynotify(XEvent *e)
                        }
                }
        }
-       if (unmanaged == 0)
-               unmanage_window(win);
+       unmanage_window(win);
        free_window(win);
 
        ignore_enter = 1;
@@ -4356,6 +4359,7 @@ main(int argc, char *argv[])
        int                     xfd, i;
        fd_set                  rd;
 
+swm_debug = 0;
        start_argv = argv;
        fprintf(stderr, "Welcome to scrotwm V%s cvs tag: %s\n",
            SWM_VERSION, cvstag);