X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=spectrwm.c;h=eff0c5d301e83b4302ca7b102563cc9fe0b7d4c6;hb=f9609966f0d40cccd8e67ce5d871f1eab55b676a;hp=786deae95a627aeaedc3821e0ee0de63304b5e51;hpb=bedad617e4f77af0f54d47ca9dcafddb32b3cc35;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 786deae..eff0c5d 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -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[] = { @@ -7140,13 +7158,46 @@ void buttonpress(xcb_button_press_event_t *e) { struct ws_win *win; + 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); + + /* Clear bar since empty. */ + bar_update(); + + handled = 1; + goto out; + } + } + } else { + win = find_window(e->event); + } - if ((win = find_window(e->event)) == NULL) + 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();