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);
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)
{
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[] = {
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);
- 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;
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);
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. */
}
focus_flush();
+ } else if (focus_mode == SWM_FOCUS_FOLLOW) {
+ if (ws->r)
+ focus_win(get_pointer_win(ws->r->s->root));
}
}
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;
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();