JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
shuffle some stuff around to make more sense
[spectrwm.git] / scrotwm.c
index f865183..edcd339 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
@@ -1193,14 +1193,14 @@ unfocus_win(struct ws_win *win)
        if (win->ws->r == NULL)
                return;
 
-       grabbuttons(win, 0);
-       XSetWindowBorder(display, win->id,
-           win->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color);
-
        if (win->ws->focus == win) {
                win->ws->focus = NULL;
                win->ws->focus_prev = win;
        }
+
+       grabbuttons(win, 0);
+       XSetWindowBorder(display, win->id,
+           win->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color);
 }
 
 void
@@ -1233,12 +1233,11 @@ focus_win(struct ws_win *win)
        if (win->ws->r != NULL) {
                XSetWindowBorder(display, win->id,
                    win->ws->r->s->c[SWM_S_COLOR_FOCUS].color);
-               grabbuttons(win, 1);
                if (win->ws->cur_layout->flags & SWM_L_MAPONFOCUS)
                        XMapRaised(display, win->id);
                XSetInputFocus(display, win->id,
                    RevertToPointerRoot, CurrentTime);
-               XSync(display, False);
+               grabbuttons(win, 1);
        }
 }
 
@@ -1247,7 +1246,7 @@ switchws(struct swm_region *r, union arg *args)
 {
        int                     wsid = args->id;
        struct swm_region       *this_r, *other_r;
-       struct ws_win           *win, *winfocus = NULL;
+       struct ws_win           *win, *winfocus = NULL, *parent = NULL;
        struct workspace        *new_ws, *old_ws;
 
        this_r = r;
@@ -1283,7 +1282,9 @@ switchws(struct swm_region *r, union arg *args)
                 */
                if (new_ws->old_r == this_r)
                        TAILQ_FOREACH(win, &new_ws->winlist, entry)
-                               XMapRaised(display, win->id);
+                               if (!(win->ws->cur_layout->flags &
+                                   SWM_L_MAPONFOCUS))
+                                       XMapRaised(display, win->id);
 
                TAILQ_FOREACH(win, &old_ws->winlist, entry)
                        unmap_window(win);
@@ -1296,7 +1297,17 @@ switchws(struct swm_region *r, union arg *args)
 
        ignore_enter = 1;
        stack();
-       focus_win(winfocus);
+       if (winfocus) {
+               /* make sure we see the parent window */
+               if (winfocus->transient) {
+                       parent = find_window(winfocus->transient);
+                       if (parent)
+                               focus_win(parent);
+               }
+
+               focus_win(winfocus);
+       }
+       ignore_enter = 0;
        bar_update();
 }
 
@@ -1341,8 +1352,10 @@ cyclews(struct swm_region *r, union arg *args)
 void
 cyclescr(struct swm_region *r, union arg *args)
 {
-       struct swm_region       *rr;
-       int                     i;
+       struct swm_region       *rr = NULL;
+       struct workspace        *ws = NULL;
+       struct ws_win           *winfocus = NULL;
+       int                     i, x, y;
 
        /* do nothing if we don't have more than one screen */
        if (!(ScreenCount(display) > 1 || outputs > 1))
@@ -1363,10 +1376,28 @@ cyclescr(struct swm_region *r, union arg *args)
        default:
                return;
        };
+       if (rr == NULL)
+               return;
+
+       ws = rr->ws;
+       winfocus = ws->focus;
+       if (winfocus == NULL)
+               winfocus = ws->focus_prev;
+       if (winfocus) {
+               /* use window coordinates */
+               x = winfocus->g.x + 1;
+               y = winfocus->g.y + 1;
+       } else {
+               /* use region coordinates */
+               x = rr->g.x + 1;
+               y = rr->g.y + 1 + bar_enabled ? bar_height : 0;
+       }
+
        unfocus_all();
        XSetInputFocus(display, PointerRoot, RevertToPointerRoot, CurrentTime);
-       XWarpPointer(display, None, rr->s[i].root, 0, 0, 0, 0, rr->g.x,
-           rr->g.y + bar_enabled ? bar_height : 0);
+       XWarpPointer(display, None, rr->s[i].root, 0, 0, 0, 0, x, y);
+
+       focus_win(winfocus);
 }
 
 void
@@ -1482,7 +1513,7 @@ void
 cycle_layout(struct swm_region *r, union arg *args)
 {
        struct workspace        *ws = r->ws;
-       struct ws_win           *winfocus;
+       struct ws_win           *winfocus, *parent = NULL;
 
        DNPRINTF(SWM_D_EVENT, "cycle_layout: workspace: %d\n", ws->idx);
 
@@ -1494,7 +1525,14 @@ cycle_layout(struct swm_region *r, union arg *args)
 
        ignore_enter = 1;
        stack();
-       focus_win(winfocus);
+       /* make sure we see the parent window */
+       if (winfocus) {
+               if (winfocus->transient)
+                       parent = find_window(winfocus->transient);
+               if (parent)
+                       focus_win(parent);
+               focus_win(winfocus);
+       }
        ignore_enter = 0;
 }
 
@@ -1542,7 +1580,6 @@ stack(void) {
        }
        if (font_adjusted)
                font_adjusted--;
-       XSync(display, False);
 }
 
 void
@@ -1957,7 +1994,6 @@ send_to_ws(struct swm_region *r, union arg *args)
                if (ScreenCount(display) > 1 || outputs > 1)
                        winfocus = win;
 
-
        unmap_window(win);
        TAILQ_REMOVE(&ws->winlist, win, entry);
        TAILQ_INSERT_TAIL(&nws->winlist, win, entry);
@@ -3560,11 +3596,12 @@ destroynotify(XEvent *e)
                                }
                        }
                }
-
+               ignore_enter = 1;
                unmanage_window(win);
                stack();
                if (winfocus)
                        focus_win(winfocus);
+               ignore_enter = 0;
        }
 
        SWM_EV_EPILOGUE(display);
@@ -3590,8 +3627,11 @@ enternotify(XEvent *e)
        if (QLength(display))
                return;
 
-       if ((win = find_window(ev->window)) != NULL)
+       if ((win = find_window(ev->window)) != NULL) {
+               if (win->ws->focus == win)
+                       return;
                focus_win(win);
+       }
 }
 
 void
@@ -3710,8 +3750,6 @@ unmapnotify(XEvent *e)
        win = find_window(e->xunmap.window);
        if (win == NULL)
                goto done;
-       if (win->transient)
-               goto done;
 
        if (getstate(e->xunmap.window) == NormalState) {
                /*
@@ -3721,9 +3759,12 @@ unmapnotify(XEvent *e)
 
                ws = win->ws;
                /* if we are max_stack try harder to focus on something */
-               if (ws->cur_layout->flags & SWM_L_FOCUSPREV)
-                       if (win != ws->focus && win != ws->focus_prev)
+               if (ws->cur_layout->flags & SWM_L_FOCUSPREV) {
+                       if (win->transient)
+                               winfocus = find_window(win->transient);
+                       else if (win != ws->focus && win != ws->focus_prev)
                                winfocus = ws->focus_prev;
+               }
 
                /* normal and fallback if haven't found anything to focus on */
                if (winfocus == NULL) {
@@ -3731,8 +3772,9 @@ unmapnotify(XEvent *e)
                        if (TAILQ_FIRST(&ws->winlist) == win)
                                winfocus = TAILQ_NEXT(win, entry);
                        else {
-                               winfocus = TAILQ_PREV(ws->focus, ws_win_list,
-                                   entry);
+                               if (ws->focus)
+                                       winfocus = TAILQ_PREV(ws->focus,
+                                           ws_win_list, entry);
                                if (winfocus == NULL)
                                        winfocus = TAILQ_LAST(&ws->winlist,
                                            ws_win_list);
@@ -3741,8 +3783,10 @@ unmapnotify(XEvent *e)
 
                /* trash window and refocus */
                unmanage_window(win);
+               ignore_enter = 1;
                stack();
                focus_win(winfocus);
+               ignore_enter = 0;
        }
 
 done: