]> code.delx.au - spectrwm/blobdiff - spectrwm.c
Fix uninitialized variable warning.
[spectrwm] / spectrwm.c
index 786deae95a627aeaedc3821e0ee0de63304b5e51..6f250722a2fd97e7edd93375c06287e40dc03490 100644 (file)
@@ -703,6 +703,7 @@ char        *get_atom_name(xcb_atom_t);
 char   *get_notify_detail_label(uint8_t);
 char   *get_notify_mode_label(uint8_t);
 #endif
+struct ws_win  *get_pointer_win(xcb_window_t);
 struct ws_win  *get_region_focus(struct swm_region *);
 xcb_screen_t   *get_screen(int);
 char   *get_win_name(xcb_window_t);
@@ -2449,6 +2450,28 @@ restart(struct swm_region *r, union arg *args)
        quit(NULL, NULL);
 }
 
+struct ws_win *
+get_pointer_win(xcb_window_t root)
+{
+       struct ws_win                   *win = NULL;
+       xcb_query_pointer_reply_t       *r;
+
+       DNPRINTF(SWM_D_EVENT, "get_pointer_win: root: 0x%x.\n", root);
+
+       r = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, root), NULL);
+       if (r) {
+               win = find_window(r->child);
+               if (win) {
+                       DNPRINTF(SWM_D_EVENT, "get_pointer_win: 0x%x.\n",
+                           win->id);
+               } else {
+                       DNPRINTF(SWM_D_EVENT, "get_pointer_win: none.\n");
+               }
+       }
+
+       return win;
+}
+
 struct swm_region *
 root_to_region(xcb_window_t root, int check)
 {
@@ -5937,11 +5960,6 @@ grabbuttons(struct ws_win *win)
                            XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
                            XCB_WINDOW_NONE, XCB_CURSOR_NONE,
                            buttons[i].button, buttons[i].mask);
-
-       /* click to focus */
-       xcb_grab_button(conn, 0, win->id, BUTTONMASK, XCB_GRAB_MODE_SYNC,
-           XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE, XCB_CURSOR_NONE,
-           XCB_BUTTON_INDEX_1, XCB_BUTTON_MASK_ANY);
 }
 
 const char *quirkname[] = {
@@ -7139,14 +7157,47 @@ keypress(xcb_key_press_event_t *e)
 void
 buttonpress(xcb_button_press_event_t *e)
 {
-       struct ws_win           *win;
+       struct ws_win           *win = NULL;
+       struct swm_region       *r, *old_r;
        int                     i;
        int                     handled = 0;
 
-       DNPRINTF(SWM_D_EVENT, "buttonpress: window 0x%x, detail: %u\n",
-           e->event, e->detail);
+       DNPRINTF(SWM_D_EVENT, "buttonpress: win (x,y): 0x%x (%d,%d), "
+           "detail: %u, time: %u, root (x,y): 0x%x (%d,%d), child: 0x%x, "
+           "state: %u, same_screen: %s\n", e->event, e->event_x, e->event_y,
+           e->detail, e->time, e->root, e->root_x, e->root_y, e->child,
+           e->state, YESNO(e->same_screen));
+
+       if (e->event == e->root) {
+               if (e->child != 0) {
+                       win = find_window(e->child);
+                       /* Pass ButtonPress to window if it isn't managed. */
+                       if (win == NULL)
+                               goto out;
+               } else {
+                       /* Focus on empty region */
+                       /* If no windows on region if its empty. */
+                       r = root_to_region(e->root, SWM_CK_POINTER);
+                       if (TAILQ_EMPTY(&r->ws->winlist)) {
+                               old_r = root_to_region(e->root, SWM_CK_FOCUS);
+                               if (old_r && old_r != r)
+                                       unfocus_win(old_r->ws->focus);
+
+                               xcb_set_input_focus(conn,
+                                   XCB_INPUT_FOCUS_PARENT, e->root, e->time);
 
-       if ((win = find_window(e->event)) == NULL)
+                               /* Clear bar since empty. */
+                               bar_update();
+
+                               handled = 1;
+                               goto out;
+                       }
+               }
+       } else {
+               win = find_window(e->event);
+       }
+
+       if (win == NULL)
                return;
 
        last_event_time = e->time;
@@ -7161,11 +7212,15 @@ buttonpress(xcb_button_press_event_t *e)
                        handled = 1;
                }
 
+out:
        if (!handled) {
                DNPRINTF(SWM_D_EVENT, "buttonpress: passing to window.\n");
+               /* Replay event to event window */
                xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, e->time);
        } else {
                DNPRINTF(SWM_D_EVENT, "buttonpress: handled.\n");
+               /* Unfreeze grab events. */
+               xcb_allow_events(conn, XCB_ALLOW_SYNC_POINTER, e->time);
        }
 
        xcb_flush(conn);
@@ -7293,8 +7348,10 @@ configurerequest(xcb_configure_request_event_t *e)
                        wc[i++] = e->stack_mode;
                }
 
-               if (mask != 0)
+               if (mask != 0) {
                        xcb_configure_window(conn, e->window, mask, wc);
+                       xcb_flush(conn);
+               }
        } else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) &&
            !(win->ewmh_flags & EWMH_F_FULLSCREEN)) {
                if (win->ws->r)
@@ -7719,10 +7776,10 @@ unmapnotify(xcb_unmap_notify_event_t *e)
        if (win == NULL)
                return;
 
+       win->mapped = 0;
        ws = win->ws;
 
        if (getstate(e->window) == XCB_ICCCM_WM_STATE_NORMAL) {
-               win->mapped = 0;
                set_win_state(win, XCB_ICCCM_WM_STATE_ICONIC);
 
                /* If we were focused, make sure we focus on something else. */
@@ -7745,6 +7802,9 @@ unmapnotify(xcb_unmap_notify_event_t *e)
                }
 
                focus_flush();
+       } else if (focus_mode == SWM_FOCUS_FOLLOW) {
+               if (ws->r)
+                       focus_win(get_pointer_win(ws->r->s->root));
        }
 }
 
@@ -7885,6 +7945,11 @@ enable_wm(void)
                        free(error);
                        return 1;
                }
+
+               /* click to focus on empty region */
+               xcb_grab_button(conn, 1, sc->root, BUTTONMASK,
+                   XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE,
+                   XCB_CURSOR_NONE, XCB_BUTTON_INDEX_1, XCB_BUTTON_MASK_ANY);
        }
 
        return 0;
@@ -8556,11 +8621,6 @@ noconfig:
                                winfocus = NULL;
                                continue;
                        }
-                       /* move pointer to first screen if multi screen */
-                       if (num_screens > 1 || outputs > 1)
-                               xcb_warp_pointer(conn, XCB_WINDOW_NONE,
-                                   rr->s[0].root, 0, 0, 0, 0, X(rr),
-                                   Y(rr) + (bar_enabled ? bar_height : 0));
 
                        focus_win(get_region_focus(rr));
                        focus_flush();