JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Fix move_to_ws as fallout from killing cur_focus
[spectrwm.git] / scrotwm.c
index 716759d..adb386d 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
@@ -1203,22 +1203,19 @@ switchws(struct swm_region *r, union arg *args)
            "%d -> %d\n", r->s->idx, WIDTH(r), HEIGHT(r), X(r), Y(r),
            old_ws->idx, wsid);
 
-       /* get focus window */
-       if (new_ws->focus)
-               winfocus = new_ws->focus;
-       else if (new_ws->focus_prev)
-               winfocus = new_ws->focus_prev;
+       if (new_ws == old_ws)
+               return;
 
+       /* get focus window */
        if (new_ws->focus)
                winfocus = new_ws->focus;
        else if (new_ws->focus_prev)
                winfocus = new_ws->focus_prev;
-
-       if (new_ws == old_ws)
-               return;
+       else
+               winfocus = TAILQ_FIRST(&new_ws->winlist);
 
        other_r = new_ws->r;
-       if (!other_r) {
+       if (other_r == NULL) {
                /* if the other workspace is hidden, switch windows */
                /* map new window first to prevent ugly blinking */
                old_ws->r = NULL;
@@ -1860,7 +1857,7 @@ void
 send_to_ws(struct swm_region *r, union arg *args)
 {
        int                     wsid = args->id;
-       struct ws_win           *win = r->ws->focus;
+       struct ws_win           *win = r->ws->focus, *winfocus = NULL;
        struct workspace        *ws, *nws;
        Atom                    ws_idx_atom = 0;
        unsigned char           ws_idx_str[SWM_PROPLEN];
@@ -1873,14 +1870,20 @@ send_to_ws(struct swm_region *r, union arg *args)
        ws = win->ws;
        nws = &win->s->ws[wsid];
 
-       XUnmapWindow(display, win->id);
-
        /* find a window to focus */
-       ws->focus = TAILQ_PREV(win, ws_win_list, entry);
-       if (ws->focus == NULL)
-               ws->focus = TAILQ_FIRST(&ws->winlist);
-       if (ws->focus == win)
-               ws->focus = NULL;
+       winfocus = TAILQ_PREV(win, ws_win_list, entry);
+       if (TAILQ_FIRST(&ws->winlist) == win)
+               winfocus = TAILQ_NEXT(win, entry);
+       else {
+               winfocus = TAILQ_PREV(ws->focus, ws_win_list, entry);
+               if (winfocus == NULL)
+                       winfocus = TAILQ_LAST(&ws->winlist, ws_win_list);
+       }
+       /* out of windows in ws so focus on nws instead */
+       if (winfocus == NULL)
+               winfocus = win;
+
+       XUnmapWindow(display, win->id);
 
        TAILQ_REMOVE(&ws->winlist, win, entry);
 
@@ -1903,6 +1906,7 @@ send_to_ws(struct swm_region *r, union arg *args)
        nws->restack = 1;
 
        stack();
+       focus_win(winfocus);
 }
 
 void
@@ -4016,6 +4020,8 @@ main(int argc, char *argv[])
        while (running) {
                while (XPending(display)) {
                        XNextEvent(display, &e);
+                       if (running == 0)
+                               goto done;
                        if (e.type < LASTEvent) {
                                dumpevent(&e);
                                if (handler[e.type])
@@ -4041,7 +4047,7 @@ main(int argc, char *argv[])
                /* if we are being restarted go focus on first window */
                if (winfocus) {
                        rr = TAILQ_FIRST(&screens[0].rl);
-                       /* move pointer to first screen */
+                       /* move pointer to first screen if multi screen */
                        if (ScreenCount(display) > 1 || outputs > 1)
                                XWarpPointer(display, None, rr->s[0].root,
                                    0, 0, 0, 0, rr->g.x,
@@ -4056,13 +4062,15 @@ main(int argc, char *argv[])
                FD_SET(xfd, &rd);
                if (select(xfd + 1, &rd, NULL, NULL, NULL) == -1)
                        if (errno != EINTR)
-                               errx(1, "select failed");
+                               DNPRINTF(SWM_D_MISC, "select failed");
+               if (running == 0)
+                       goto done;
                if (bar_alarm) {
                        bar_alarm = 0;
                        bar_update();
                }
        }
-
+done:
        bar_extra_stop();
 
        XCloseDisplay(display);