JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Use cut instead of awk for some sort of mem saving.
[spectrwm.git] / scrotwm.c
index de6e2c7..0dda010 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
@@ -232,7 +232,6 @@ struct ws_win {
        TAILQ_ENTRY(ws_win)     entry;
        Window                  id;
        struct swm_geometry     g;
-       int                     got_focus;
        int                     floating;
        int                     transient;
        int                     manual;
@@ -1144,7 +1143,6 @@ unfocus_win(struct ws_win *win)
        grabbuttons(win, 0);
        XSetWindowBorder(display, win->id,
            win->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color);
-       win->got_focus = 0;
 
        if (win->ws->focus == win) {
                win->ws->focus = NULL;
@@ -1164,6 +1162,7 @@ unfocus_all(void)
                for (j = 0; j < SWM_WS_MAX; j++)
                        TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry)
                                unfocus_win(win);
+       XSync(display, False);
 }
 
 void
@@ -1179,14 +1178,12 @@ focus_win(struct ws_win *win)
        win->ws->focus = win;
 
        if (win->ws->r != NULL) {
-               if (win->got_focus == 0) {
-                       XSetWindowBorder(display, win->id,
-                           win->ws->r->s->c[SWM_S_COLOR_FOCUS].color);
-                       grabbuttons(win, 1);
-               }
-               win->got_focus = 1;
+               XSetWindowBorder(display, win->id,
+                   win->ws->r->s->c[SWM_S_COLOR_FOCUS].color);
+               grabbuttons(win, 1);
                XSetInputFocus(display, win->id,
                    RevertToPointerRoot, CurrentTime);
+               XSync(display, False);
        }
 }
 
@@ -3194,7 +3191,7 @@ manage_window(Window id)
 {
        Window                  trans;
        struct workspace        *ws;
-       struct ws_win           *win;
+       struct ws_win           *win, *ww;
        int                     format, i, ws_idx, n;
        unsigned long           nitems, bytes;
        Atom                    ws_idx_atom = 0, type;
@@ -3247,8 +3244,17 @@ manage_window(Window id)
                            errstr, prop);
                }
                ws = &r->s->ws[ws_idx];
-       } else
+       } else {
                ws = r->ws;
+               /* this should launch transients in the same ws as parent */
+               /* XXX doesn't work for intel xrandr */
+               if (id && trans) {
+                       if ((ww = find_window(trans)) != NULL) {
+                               ws = ww->ws;
+                               r = ws->r;
+                       }
+               }
+       }
 
        /* set up the window layout */
        win->id = id;
@@ -3321,9 +3327,6 @@ manage_window(Window id)
        if (win->floating && (ws->idx == r->ws->idx))
                XMapRaised(display, win->id);
 
-       /* make new win focused */
-       focus_win(win);
-
        return (win);
 }
 
@@ -3338,20 +3341,6 @@ unmanage_window(struct ws_win *win)
        DNPRINTF(SWM_D_MISC, "unmanage_window:  %lu\n", win->id);
 
        ws = win->ws;
-
-       /* find a window to focus */
-       if (ws->focus == win)
-               ws->focus = TAILQ_PREV(win, ws_win_list, entry);
-       if (ws->focus == NULL)
-               ws->focus = TAILQ_FIRST(&ws->winlist);
-       if (ws->focus == NULL || ws->focus == win) {
-               ws->focus = NULL;
-               unfocus_win(win);
-       } else
-               focus_win(ws->focus);
-       if (ws->focus_prev == win)
-               ws->focus_prev = NULL;
-
        TAILQ_REMOVE(&win->ws->winlist, win, entry);
        set_win_state(win, WithdrawnState);
        if (win->ch.res_class)
@@ -3443,14 +3432,32 @@ configurenotify(XEvent *e)
 void
 destroynotify(XEvent *e)
 {
-       struct ws_win           *win;
+       struct ws_win           *win, *winfocus = NULL;
+       struct workspace        *ws;
+       struct ws_win_list      *wl;
+
        XDestroyWindowEvent     *ev = &e->xdestroywindow;
 
        DNPRINTF(SWM_D_EVENT, "destroynotify: window %lu\n", ev->window);
 
        if ((win = find_window(ev->window)) != NULL) {
+               /* find a window to focus */
+               ws = win->ws;
+               wl = &ws->winlist;
+               if (ws->focus == win) {
+                       if (TAILQ_FIRST(wl) == win)
+                               winfocus = TAILQ_NEXT(win, entry);
+                       else {
+                               winfocus = TAILQ_PREV(ws->focus, ws_win_list, entry);
+                               if (winfocus == NULL)
+                                       winfocus = TAILQ_LAST(wl, ws_win_list);
+                       }
+               }
+
                unmanage_window(win);
                stack();
+               if (winfocus)
+                       focus_win(winfocus);
        }
 }
 
@@ -3467,6 +3474,12 @@ enternotify(XEvent *e)
                ignore_enter--;
                return;
        }
+       /*
+        * happens when a window is created or destroyed and the border
+        * crosses the mouse pointer
+        */
+       if (QLength(display))
+               return;
 
        if ((win = find_window(ev->window)) != NULL)
                focus_win(win);
@@ -3509,9 +3522,15 @@ maprequest(XEvent *e)
                return;
        if (wa.override_redirect)
                return;
+
        manage_window(e->xmaprequest.window);
 
        stack();
+
+       /* make new win focused */
+       struct ws_win           *win;
+       win = find_window(ev->window);
+       focus_win(win);
 }
 
 void