From 4ca21ccb464c8bf8405c3ecbbe018a05a3fbd132 Mon Sep 17 00:00:00 2001 From: Bastien Dejean Date: Wed, 23 Dec 2015 22:21:43 +0100 Subject: [PATCH] Handle preselection feedbacks in query_pointer Fixes #341. --- bspwm.h | 10 ++++++---- helpers.c | 6 ++++++ helpers.h | 1 + monitor.c | 4 +--- tree.c | 2 +- window.c | 23 +++++++++++++++++++++++ window.h | 1 + 7 files changed, 39 insertions(+), 8 deletions(-) diff --git a/bspwm.h b/bspwm.h index c3c304af..7ee0db3c 100644 --- a/bspwm.h +++ b/bspwm.h @@ -29,10 +29,12 @@ #define ROOT_EVENT_MASK (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY) #define CLIENT_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE) -#define META_WINDOW_IC "wm\0Bspwm" -#define ROOT_WINDOW_IC "root\0Bspwm" -#define PRESEL_FEEDBACK_IC "presel_feedback\0Bspwm" -#define MOTION_RECORDER_IC "motion_recorder\0Bspwm" +#define BSPWM_CLASS_NAME "Bspwm" +#define META_WINDOW_IC "wm\0" BSPWM_CLASS_NAME +#define ROOT_WINDOW_IC "root\0" BSPWM_CLASS_NAME +#define PRESEL_FEEDBACK_I "presel_feedback" +#define PRESEL_FEEDBACK_IC PRESEL_FEEDBACK_I "\0" BSPWM_CLASS_NAME +#define MOTION_RECORDER_IC "motion_recorder\0" BSPWM_CLASS_NAME xcb_connection_t *dpy; int default_screen, screen_width, screen_height; diff --git a/helpers.c b/helpers.c index 1b2ef330..a1dbce4d 100644 --- a/helpers.c +++ b/helpers.c @@ -131,6 +131,12 @@ bool is_hex_color(const char *color) return true; } +bool is_inside(xcb_point_t p, xcb_rectangle_t r) +{ + return (p.x >= r.x && p.x < (r.x + r.width) && + p.y >= r.y && p.y < (r.y + r.height)); +} + double distance(xcb_point_t a, xcb_point_t b) { return hypot(a.x - b.x, a.y - b.y); diff --git a/helpers.h b/helpers.h index 40050cf8..52d179d9 100644 --- a/helpers.h +++ b/helpers.h @@ -65,6 +65,7 @@ void err(char *fmt, ...); char *read_string(const char *file_path, size_t *tlen); uint32_t get_color_pixel(const char *color); bool is_hex_color(const char *color); +bool is_inside(xcb_point_t p, xcb_rectangle_t r); double distance(xcb_point_t a, xcb_point_t b); #endif diff --git a/monitor.c b/monitor.c index a5d8b22b..659eef16 100644 --- a/monitor.c +++ b/monitor.c @@ -324,9 +324,7 @@ monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, monitor_select_t sel) bool is_inside_monitor(monitor_t *m, xcb_point_t pt) { - xcb_rectangle_t r = m->rectangle; - return (r.x <= pt.x && pt.x < (r.x + r.width) - && r.y <= pt.y && pt.y < (r.y + r.height)); + return is_inside(pt, m->rectangle); } monitor_t *monitor_from_point(xcb_point_t pt) diff --git a/tree.c b/tree.c index 15cccb0f..6b82e648 100644 --- a/tree.c +++ b/tree.c @@ -1687,7 +1687,7 @@ xcb_rectangle_t get_rectangle(monitor_t *m, desktop_t *d, node_t *n) break; } } else { - int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap); + int wg = (d == NULL ? 0 : (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap)); xcb_rectangle_t rect = n->rectangle; rect.width -= wg; rect.height -= wg; diff --git a/window.c b/window.c index 16e03604..e2b9ff58 100644 --- a/window.c +++ b/window.c @@ -226,6 +226,19 @@ void unmanage_window(xcb_window_t win) } } +bool is_presel_window(xcb_window_t win) +{ + xcb_icccm_get_wm_class_reply_t reply; + bool ret = false; + if (xcb_icccm_get_wm_class_reply(dpy, xcb_icccm_get_wm_class(dpy, win), &reply, NULL) == 1) { + if (streq(BSPWM_CLASS_NAME, reply.class_name) && streq(PRESEL_FEEDBACK_I, reply.instance_name)) { + ret = true; + } + xcb_icccm_get_wm_class_reply_wipe(&reply); + } + return ret; +} + void initialize_presel_feedback(node_t *n) { if (n == NULL || n->presel == NULL || n->presel->feedback != XCB_NONE) { @@ -483,6 +496,16 @@ void query_pointer(xcb_window_t *win, xcb_point_t *pt) if (qpr != NULL) { if (win != NULL) { *win = qpr->child; + xcb_point_t pt = {qpr->root_x, qpr->root_y}; + for (stacking_list_t *s = stack_tail; s != NULL; s = s->prev) { + xcb_rectangle_t rect = get_rectangle(NULL, NULL, s->node); + if (is_inside(pt, rect)) { + if (s->node->id == qpr->child || is_presel_window(qpr->child)) { + *win = s->node->id; + } + break; + } + } } if (pt != NULL) { *pt = (xcb_point_t) {qpr->root_x, qpr->root_y}; diff --git a/window.h b/window.h index ee2c36ee..8e0d6293 100644 --- a/window.h +++ b/window.h @@ -50,6 +50,7 @@ void update_floating_rectangle(node_t *n); void restrain_floating_width(client_t *c, int *width); void restrain_floating_height(client_t *c, int *height); void restrain_floating_size(client_t *c, int *width, int *height); +bool is_presel_window(xcb_window_t win); void query_pointer(xcb_window_t *win, xcb_point_t *pt); void window_border_width(xcb_window_t win, uint32_t bw); void window_move(xcb_window_t win, int16_t x, int16_t y);