JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
Fix focus issue when (un)mapping a window on an unfocused region.
[spectrwm.git] / spectrwm.c
index c49bcf0..f78f740 100644 (file)
@@ -244,6 +244,7 @@ u_int32_t           swm_debug = 0
 #define SH_INC_H(w)            (w)->sh.height_inc
 #define SWM_MAX_FONT_STEPS     (3)
 #define WINID(w)               ((w) ? (w)->id : XCB_WINDOW_NONE)
+#define WS_FOCUSED(ws)         ((ws)->r && (ws)->r->s->r_focus == (ws)->r)
 #define YESNO(x)               ((x) ? "yes" : "no")
 
 /* Constrain Window flags */
@@ -5306,16 +5307,12 @@ wkill(struct swm_region *r, union arg *args)
 int
 floating_toggle_win(struct ws_win *win)
 {
-       struct swm_region       *r;
-
        if (win == NULL)
                return (0);
 
        if (!win->ws->r)
                return (0);
 
-       r = win->ws->r;
-
        /* reject floating toggles in max stack mode */
        if (win->ws->cur_layout == &layouts[SWM_MAX_STACK])
                return (0);
@@ -5705,14 +5702,12 @@ move(struct ws_win *win, union arg *args)
 {
        xcb_timestamp_t         timestamp = 0;
        int                     move_stp = 0, moving;
-       struct swm_region       *r = NULL;
        xcb_query_pointer_reply_t       *qpr = NULL;
        xcb_generic_event_t             *evt;
        xcb_motion_notify_event_t       *mne;
 
        if (win == NULL)
                return;
-       r = win->ws->r;
 
        if (win->ewmh_flags & EWMH_F_FULLSCREEN)
                return;
@@ -8412,11 +8407,11 @@ destroynotify(xcb_destroy_notify_event_t *e)
        unmanage_window(win);
        stack();
 
-       if (focus_mode != SWM_FOCUS_FOLLOW) {
+       if (focus_mode != SWM_FOCUS_FOLLOW && WS_FOCUSED(win->ws)) {
                if (win->ws->focus_pending) {
                        focus_win(win->ws->focus_pending);
                        win->ws->focus_pending = NULL;
-               } else if (win == win->ws->focus && win->ws->r) {
+               } else if (win == win->ws->focus) {
                        xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT,
                            win->ws->r->id, XCB_CURRENT_TIME);
                }
@@ -8565,7 +8560,7 @@ mapnotify(xcb_map_notify_event_t *e)
        win->mapped = 1;
        set_win_state(win, XCB_ICCCM_WM_STATE_NORMAL);
 
-       if (focus_mode != SWM_FOCUS_FOLLOW) {
+       if (focus_mode != SWM_FOCUS_FOLLOW && WS_FOCUSED(win->ws)) {
                if (win->ws->focus_pending == win) {
                        focus_win(win);
                        win->ws->focus_pending = NULL;
@@ -8747,7 +8742,8 @@ propertynotify(xcb_property_notify_event_t *e)
                        if (ws->r) {
                                stack();
 
-                               if (focus_mode != SWM_FOCUS_FOLLOW) {
+                               if (focus_mode != SWM_FOCUS_FOLLOW &&
+                                   WS_FOCUSED(ws)) {
                                        if (ws->focus_pending) {
                                                focus_win(ws->focus_pending);
                                                ws->focus_pending = NULL;
@@ -8774,7 +8770,7 @@ propertynotify(xcb_property_notify_event_t *e)
        } else if (e->atom == a_state) {
                /* State just changed, make sure it gets focused if mapped. */
                if (e->state == XCB_PROPERTY_NEW_VALUE) {
-                       if (focus_mode != SWM_FOCUS_FOLLOW) {
+                       if (focus_mode != SWM_FOCUS_FOLLOW && WS_FOCUSED(ws)) {
                                if (win->mapped &&
                                    ws->focus_pending == win) {
                                        focus_win(ws->focus_pending);
@@ -8830,15 +8826,16 @@ unmapnotify(xcb_unmap_notify_event_t *e)
                if (ws->r)
                        stack();
 
-               if (focus_mode == SWM_FOCUS_FOLLOW) {
-                       if (ws->r)
+               if (WS_FOCUSED(ws)) {
+                       if (focus_mode == SWM_FOCUS_FOLLOW) {
                                focus_win(get_pointer_win(ws->r->s->root));
-               } else if (ws->focus_pending) {
-                       focus_win(ws->focus_pending);
-                       ws->focus_pending = NULL;
-               } else if (ws->focus == NULL && ws->r) {
-                       xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT,
-                           ws->r->id, XCB_CURRENT_TIME);
+                       } else if (ws->focus_pending) {
+                               focus_win(ws->focus_pending);
+                               ws->focus_pending = NULL;
+                       } else if (ws->focus == NULL) {
+                               xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT,
+                                   ws->r->id, XCB_CURRENT_TIME);
+                       }
                }
        }
 
@@ -8885,7 +8882,10 @@ clientmessage(xcb_client_message_event_t *e)
 
        if (e->type == ewmh[_NET_ACTIVE_WINDOW].atom) {
                DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_ACTIVE_WINDOW\n");
-               focus_win(win);
+               if (WS_FOCUSED(win->ws))
+                       focus_win(win);
+               else
+                       win->ws->focus_pending = win;
        }
        if (e->type == ewmh[_NET_CLOSE_WINDOW].atom) {
                DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_CLOSE_WINDOW\n");