From dd724d1bc284dc42ebae1e3625c5be5c8985c4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 21 Jun 2021 21:00:07 +0200 Subject: [PATCH 01/14] =?UTF-8?q?exposable:=20add=20=E2=80=98btn=E2=80=99?= =?UTF-8?q?=20argument=20to=20on=5Fmouse()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bar/backend.h | 2 +- bar/bar.c | 9 +++++---- bar/wayland.c | 23 +++++++++++++++++++---- bar/xcb.c | 13 ++++++++++--- particle.c | 7 ++++--- particle.h | 11 +++++++++-- particles/dynlist.c | 8 ++++---- particles/list.c | 8 ++++---- particles/map.c | 8 ++++---- particles/progress-bar.c | 10 +++++----- particles/ramp.c | 8 ++++---- 11 files changed, 69 insertions(+), 38 deletions(-) diff --git a/bar/backend.h b/bar/backend.h index f2681a8..d365da6 100644 --- a/bar/backend.h +++ b/bar/backend.h @@ -10,7 +10,7 @@ struct backend { void (*loop)(struct bar *bar, void (*expose)(const struct bar *bar), void (*on_mouse)(struct bar *bar, enum mouse_event event, - int x, int y)); + enum mouse_button btn, int x, int y)); void (*commit)(const struct bar *bar); void (*refresh)(const struct bar *bar); void (*set_cursor)(struct bar *bar, const char *cursor); diff --git a/bar/bar.c b/bar/bar.c index 0e51608..b7557fd 100644 --- a/bar/bar.c +++ b/bar/bar.c @@ -151,7 +151,8 @@ set_cursor(struct bar *bar, const char *cursor) } static void -on_mouse(struct bar *_bar, enum mouse_event event, int x, int y) +on_mouse(struct bar *_bar, enum mouse_event event, enum mouse_button btn, + int x, int y) { struct private *bar = _bar->private; @@ -173,7 +174,7 @@ on_mouse(struct bar *_bar, enum mouse_event event, int x, int y) mx += bar->left_spacing; if (x >= mx && x < mx + e->width) { if (e->on_mouse != NULL) - e->on_mouse(e, _bar, event, x - mx, y); + e->on_mouse(e, _bar, event, btn, x - mx, y); return; } @@ -187,7 +188,7 @@ on_mouse(struct bar *_bar, enum mouse_event event, int x, int y) mx += bar->left_spacing; if (x >= mx && x < mx + e->width) { if (e->on_mouse != NULL) - e->on_mouse(e, _bar, event, x - mx, y); + e->on_mouse(e, _bar, event, btn, x - mx, y); return; } @@ -205,7 +206,7 @@ on_mouse(struct bar *_bar, enum mouse_event event, int x, int y) mx += bar->left_spacing; if (x >= mx && x < mx + e->width) { if (e->on_mouse != NULL) - e->on_mouse(e, _bar, event, x - mx, y); + e->on_mouse(e, _bar, event, btn, x - mx, y); return; } diff --git a/bar/wayland.c b/bar/wayland.c index 1a72577..05a12a9 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -113,7 +114,8 @@ struct wayland_backend { struct buffer *pending_buffer; /* Finished, but not yet rendered */ void (*bar_expose)(const struct bar *bar); - void (*bar_on_mouse)(struct bar *bar, enum mouse_event event, int x, int y); + void (*bar_on_mouse)(struct bar *bar, enum mouse_event event, + enum mouse_button btn, int x, int y); }; static void @@ -262,7 +264,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, backend->active_seat = seat; backend->bar_on_mouse( - backend->bar, ON_MOUSE_MOTION, seat->pointer.x, seat->pointer.y); + backend->bar, ON_MOUSE_MOTION, MOUSE_BTN_NONE, + seat->pointer.x, seat->pointer.y); } static void @@ -276,8 +279,19 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, struct wayland_backend *backend = seat->backend; backend->active_seat = seat; + + enum mouse_button btn; + + switch (button) { + case BTN_LEFT: btn = MOUSE_BTN_LEFT; break; + case BTN_MIDDLE: btn = MOUSE_BTN_MIDDLE; break; + case BTN_RIGHT: btn = MOUSE_BTN_RIGHT; break; + default: + return; + } + backend->bar_on_mouse( - backend->bar, ON_MOUSE_CLICK, seat->pointer.x, seat->pointer.y); + backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); } static void @@ -1011,7 +1025,8 @@ cleanup(struct bar *_bar) static void loop(struct bar *_bar, void (*expose)(const struct bar *bar), - void (*on_mouse)(struct bar *bar, enum mouse_event event, int x, int y)) + void (*on_mouse)(struct bar *bar, enum mouse_event event, + enum mouse_button btn, int x, int y)) { struct private *bar = _bar->private; struct wayland_backend *backend = bar->backend.data; diff --git a/bar/xcb.c b/bar/xcb.c index 99b787d..6229bc5 100644 --- a/bar/xcb.c +++ b/bar/xcb.c @@ -312,7 +312,8 @@ cleanup(struct bar *_bar) static void loop(struct bar *_bar, void (*expose)(const struct bar *bar), - void (*on_mouse)(struct bar *bar, enum mouse_event event, int x, int y)) + void (*on_mouse)(struct bar *bar, enum mouse_event event, + enum mouse_button btn, int x, int y)) { struct private *bar = _bar->private; struct xcb_backend *backend = bar->backend.data; @@ -357,7 +358,7 @@ loop(struct bar *_bar, case XCB_MOTION_NOTIFY: { const xcb_motion_notify_event_t *evt = (void *)e; - on_mouse(_bar, ON_MOUSE_MOTION, evt->event_x, evt->event_y); + on_mouse(_bar, ON_MOUSE_MOTION, MOUSE_BTN_NONE, evt->event_x, evt->event_y); break; } @@ -366,7 +367,13 @@ loop(struct bar *_bar, case XCB_BUTTON_RELEASE: { const xcb_button_release_event_t *evt = (void *)e; - on_mouse(_bar, ON_MOUSE_CLICK, evt->event_x, evt->event_y); + + switch (evt->detail) { + case 1: case 2: case 3: + on_mouse(_bar, ON_MOUSE_CLICK, + evt->detail, evt->event_x, evt->event_y); + break; + } break; } diff --git a/particle.c b/particle.c index ffe330f..2ce4800 100644 --- a/particle.c +++ b/particle.c @@ -141,10 +141,11 @@ err: void exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, - enum mouse_event event, int x, int y) + enum mouse_event event, enum mouse_button btn, + int x, int y) { - LOG_DBG("on_mouse: exposable=%p, event=%s, x=%d, y=%d (on-click=%s)", - exposable, event == ON_MOUSE_MOTION ? "motion" : "click", x, y, + LOG_DBG("on_mouse: exposable=%p, event=%s, btn=%d, x=%d, y=%d (on-click=%s)", + exposable, event == ON_MOUSE_MOTION ? "motion" : "click", btn, x, y, exposable->on_click); /* If we have a handler, change cursor to a hand */ diff --git a/particle.h b/particle.h index e89b9c4..1fc582a 100644 --- a/particle.h +++ b/particle.h @@ -29,6 +29,13 @@ enum mouse_event { ON_MOUSE_CLICK, }; +enum mouse_button { + MOUSE_BTN_NONE, + MOUSE_BTN_LEFT, + MOUSE_BTN_MIDDLE, + MOUSE_BTN_RIGHT, +}; + struct exposable { const struct particle *particle; void *private; @@ -42,7 +49,7 @@ struct exposable { int x, int y, int height); void (*on_mouse)(struct exposable *exposable, struct bar *bar, - enum mouse_event event, int x, int y); + enum mouse_event event, enum mouse_button btn, int x, int y); }; struct particle *particle_common_new( @@ -59,7 +66,7 @@ void exposable_render_deco( void exposable_default_on_mouse( struct exposable *exposable, struct bar *bar, - enum mouse_event event, int x, int y); + enum mouse_event event, enum mouse_button btn, int x, int y); /* List of attributes *all* particles implement */ #define PARTICLE_COMMON_ATTRS \ diff --git a/particles/dynlist.c b/particles/dynlist.c index c04d610..00bb41f 100644 --- a/particles/dynlist.c +++ b/particles/dynlist.c @@ -67,13 +67,13 @@ dynlist_expose(const struct exposable *exposable, pixman_image_t *pix, int x, in static void on_mouse(struct exposable *exposable, struct bar *bar, - enum mouse_event event, int x, int y) + enum mouse_event event, enum mouse_button btn, int x, int y) { //const struct particle *p = exposable->particle; const struct private *e = exposable->private; if (exposable->on_click != NULL) { - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; } @@ -82,7 +82,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, if (x >= px && x < px + e->exposables[i]->width) { if (e->exposables[i]->on_mouse != NULL) { e->exposables[i]->on_mouse( - e->exposables[i], bar, event, x - px, y); + e->exposables[i], bar, event, btn, x - px, y); } return; } @@ -91,7 +91,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, } LOG_DBG("on_mouse missed all sub-particles"); - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); } struct exposable * diff --git a/particles/list.c b/particles/list.c index 6f51152..f9e61f6 100644 --- a/particles/list.c +++ b/particles/list.c @@ -75,14 +75,14 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int static void on_mouse(struct exposable *exposable, struct bar *bar, - enum mouse_event event, int x, int y) + enum mouse_event event, enum mouse_button btn, int x, int y) { const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; if (exposable->on_click != NULL) { /* We have our own handler */ - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; } @@ -91,7 +91,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, if (x >= px && x < px + e->exposables[i]->width) { if (e->exposables[i]->on_mouse != NULL) { e->exposables[i]->on_mouse( - e->exposables[i], bar, event, x - px, y); + e->exposables[i], bar, event, btn, x - px, y); } return; } @@ -100,7 +100,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, } /* We're between sub-particles (or in the left/right margin) */ - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); } static struct exposable * diff --git a/particles/map.c b/particles/map.c index 57bb0fb..cc26f77 100644 --- a/particles/map.c +++ b/particles/map.c @@ -61,26 +61,26 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int static void on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, - int x, int y) + enum mouse_button btn, int x, int y) { const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; if (exposable->on_click != NULL) { /* We have our own handler */ - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; } int px = p->left_margin; if (x >= px && x < px + e->exposable->width) { if (e->exposable->on_mouse != NULL) - e->exposable->on_mouse(e->exposable, bar, event, x - px, y); + e->exposable->on_mouse(e->exposable, bar, event, btn, x - px, y); return; } /* In the left- or right margin */ - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); } static struct exposable * diff --git a/particles/progress-bar.c b/particles/progress-bar.c index ad5c4cd..62a58b9 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -85,10 +85,10 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int static void on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, - int x, int y) + enum mouse_button btn, int x, int y) { if (exposable->on_click == NULL) { - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; } @@ -120,7 +120,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, /* Mouse is over the start-marker */ struct exposable *start = e->exposables[0]; if (start->on_mouse != NULL) - start->on_mouse(start, bar, event, x - p->left_margin, y); + start->on_mouse(start, bar, event, btn, x - p->left_margin, y); } else { /* Mouse if over left margin */ bar->set_cursor(bar, "left_ptr"); @@ -139,7 +139,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, /* Mouse is over the end-marker */ struct exposable *end = e->exposables[e->count - 1]; if (end->on_mouse != NULL) - end->on_mouse(end, bar, event, x - x_offset - clickable_width, y); + end->on_mouse(end, bar, event, btn, x - x_offset - clickable_width, y); } else { /* Mouse is over the right margin */ bar->set_cursor(bar, "left_ptr"); @@ -165,7 +165,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, } /* Call default implementation, which will execute our handler */ - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); if (event == ON_MOUSE_CLICK) { /* Reset handler string */ diff --git a/particles/ramp.c b/particles/ramp.c index 9a7f06e..8087217 100644 --- a/particles/ramp.c +++ b/particles/ramp.c @@ -57,26 +57,26 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int static void on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, - int x, int y) + enum mouse_button btn, int x, int y) { const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; if (exposable->on_click != NULL) { /* We have our own handler */ - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; } int px = p->left_margin; if (x >= px && x < px + e->exposable->width) { if (e->exposable->on_mouse != NULL) - e->exposable->on_mouse(e->exposable, bar, event, x - px, y); + e->exposable->on_mouse(e->exposable, bar, event, btn, x - px, y); return; } /* In the left- or right margin */ - exposable_default_on_mouse(exposable, bar, event, x, y); + exposable_default_on_mouse(exposable, bar, event, btn, x, y); } static void From af163d3f77667b5eb1589c2ec84bea5172777d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 21 Jun 2021 21:02:31 +0200 Subject: [PATCH 02/14] exposable: log button name in debug log --- particle.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/particle.c b/particle.c index 2ce4800..ad76965 100644 --- a/particle.c +++ b/particle.c @@ -144,9 +144,10 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { - LOG_DBG("on_mouse: exposable=%p, event=%s, btn=%d, x=%d, y=%d (on-click=%s)", - exposable, event == ON_MOUSE_MOTION ? "motion" : "click", btn, x, y, - exposable->on_click); + LOG_DBG("on_mouse: exposable=%p, event=%s, btn=%s, x=%d, y=%d (on-click=%s)", + exposable, event == ON_MOUSE_MOTION ? "motion" : "click", + btn == MOUSE_BTN_NONE ? "none" : btn == MOUSE_BTN_LEFT ? "left" : btn == MOUSE_BTN_MIDDLE ? "middle" : "right", + x, y, exposable->on_click); /* If we have a handler, change cursor to a hand */ bar->set_cursor(bar, exposable->on_click == NULL ? "left_ptr" : "hand2"); From c79ffbe057f8d9d664f960e262185cc64e9ec195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 22 Jun 2021 19:04:13 +0200 Subject: [PATCH 03/14] Add support binding on-click handlers to other buttons than LEFT One can now bind the left/middle/right mouse buttons to on-click. In fact, you can have all three buttons bound to different handlers for the same particle. The new syntax is on-click: left: middle: right: Leaving one out is the same thing as not mapping it at all. Furthermore, on-click: is still valid, and is a shorthand for on-click: left: --- bar/wayland.c | 27 +++++++++-------- config-verify.c | 18 ++++++++++++ config-verify.h | 1 + config.c | 31 ++++++++++++++++++-- particle.c | 63 +++++++++++++++++++++++++++++----------- particle.h | 47 ++++++++++++++++-------------- particles/dynlist.c | 2 +- particles/empty.c | 6 +--- particles/list.c | 8 ++--- particles/map.c | 7 ++--- particles/progress-bar.c | 19 +++++++----- particles/ramp.c | 7 ++--- particles/string.c | 6 +--- tag.c | 8 +++++ tag.h | 3 ++ 15 files changed, 163 insertions(+), 90 deletions(-) diff --git a/bar/wayland.c b/bar/wayland.c index 05a12a9..1124ab2 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -272,26 +272,25 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { - if (state != WL_POINTER_BUTTON_STATE_PRESSED) - return; - struct seat *seat = data; struct wayland_backend *backend = seat->backend; - backend->active_seat = seat; + if (state == WL_POINTER_BUTTON_STATE_PRESSED) + backend->active_seat = seat; + else { + enum mouse_button btn; - enum mouse_button btn; + switch (button) { + case BTN_LEFT: btn = MOUSE_BTN_LEFT; break; + case BTN_MIDDLE: btn = MOUSE_BTN_MIDDLE; break; + case BTN_RIGHT: btn = MOUSE_BTN_RIGHT; break; + default: + return; + } - switch (button) { - case BTN_LEFT: btn = MOUSE_BTN_LEFT; break; - case BTN_MIDDLE: btn = MOUSE_BTN_MIDDLE; break; - case BTN_RIGHT: btn = MOUSE_BTN_RIGHT; break; - default: - return; + backend->bar_on_mouse( + backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); } - - backend->bar_on_mouse( - backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); } static void diff --git a/config-verify.c b/config-verify.c index 7e87d42..6a5278b 100644 --- a/config-verify.c +++ b/config-verify.c @@ -152,6 +152,24 @@ conf_verify_dict(keychain_t *chain, const struct yml_node *node, return true; } +bool +conf_verify_on_click(keychain_t *chain, const struct yml_node *node) +{ + /* on-click: */ + const char *s = yml_value_as_string(node); + if (s != NULL) + return true; + + static const struct attr_info info[] = { + {"left", false, &conf_verify_string}, + {"middle", false, &conf_verify_string}, + {"right", false, &conf_verify_string}, + {NULL, false, NULL}, + }; + + return conf_verify_dict(chain, node, info); +} + bool conf_verify_color(keychain_t *chain, const struct yml_node *node) { diff --git a/config-verify.h b/config-verify.h index 44a6a66..dccaf5f 100644 --- a/config-verify.h +++ b/config-verify.h @@ -40,6 +40,7 @@ bool conf_verify_list(keychain_t *chain, const struct yml_node *node, bool conf_verify_dict(keychain_t *chain, const struct yml_node *node, const struct attr_info info[]); /* NULL-terminated list */ +bool conf_verify_on_click(keychain_t *chain, const struct yml_node *node); bool conf_verify_color(keychain_t *chain, const struct yml_node *node); bool conf_verify_font(keychain_t *chain, const struct yml_node *node); diff --git a/config.c b/config.c index aaa62f9..b2e131c 100644 --- a/config.c +++ b/config.c @@ -139,8 +139,33 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) int right = margin != NULL ? yml_value_as_int(margin) : right_margin != NULL ? yml_value_as_int(right_margin) : 0; - const char *on_click_template - = on_click != NULL ? yml_value_as_string(on_click) : NULL; + const char *on_click_templates[MOUSE_BTN_COUNT] = {NULL}; + if (on_click != NULL) { + const char *legacy = yml_value_as_string(on_click); + + if (legacy != NULL) + on_click_templates[MOUSE_BTN_LEFT] = legacy; + + if (yml_is_dict(on_click)) { + for (struct yml_dict_iter it = yml_dict_iter(on_click); + it.key != NULL; + yml_dict_next(&it)) + { + const char *key = yml_value_as_string(it.key); + const char *template = yml_value_as_string(it.value); + + if (strcmp(key, "left") == 0) + on_click_templates[MOUSE_BTN_LEFT] = template; + else if (strcmp(key, "middle") == 0) + on_click_templates[MOUSE_BTN_MIDDLE] = template; + else if (strcmp(key, "right") == 0) + on_click_templates[MOUSE_BTN_RIGHT] = template; + else + assert(false); + } + } + } + struct deco *deco = deco_node != NULL ? conf_to_deco(deco_node) : NULL; /* @@ -159,7 +184,7 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) /* Instantiate base/common particle */ struct particle *common = particle_common_new( - left, right, on_click_template, font, foreground, deco); + left, right, on_click_templates, font, foreground, deco); const struct particle_iface *iface = plugin_load_particle(type); diff --git a/particle.c b/particle.c index ad76965..ea4bb62 100644 --- a/particle.c +++ b/particle.c @@ -22,31 +22,41 @@ particle_default_destroy(struct particle *particle) if (particle->deco != NULL) particle->deco->destroy(particle->deco); fcft_destroy(particle->font); - free(particle->on_click_template); + for (size_t i = 0; i < MOUSE_BTN_COUNT; i++) + free(particle->on_click_templates[i]); free(particle); } struct particle * particle_common_new(int left_margin, int right_margin, - const char *on_click_template, + const char **on_click_templates, struct fcft_font *font, pixman_color_t foreground, struct deco *deco) { struct particle *p = calloc(1, sizeof(*p)); p->left_margin = left_margin; p->right_margin = right_margin; - p->on_click_template = - on_click_template != NULL ? strdup(on_click_template) : NULL; p->foreground = foreground; p->font = font; p->deco = deco; + + if (on_click_templates != NULL) { + for (size_t i = 0; i < MOUSE_BTN_COUNT; i++) { + if (on_click_templates[i] != NULL) { + p->have_on_click_template = true; + p->on_click_templates[i] = strdup(on_click_templates[i]); + } + } + } + return p; } void exposable_default_destroy(struct exposable *exposable) { - free(exposable->on_click); + for (size_t i = 0; i < MOUSE_BTN_COUNT; i++) + free(exposable->on_click[i]); free(exposable); } @@ -144,19 +154,32 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { +#if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG + static const char *button_name[] = { + [MOUSE_BTN_NONE] = "none", + [MOUSE_BTN_LEFT] = "left", + [MOUSE_BTN_MIDDLE] = "middle", + [MOUSE_BTN_RIGHT] = "right", + [MOUSE_BTN_COUNT] = "count", + }; LOG_DBG("on_mouse: exposable=%p, event=%s, btn=%s, x=%d, y=%d (on-click=%s)", exposable, event == ON_MOUSE_MOTION ? "motion" : "click", - btn == MOUSE_BTN_NONE ? "none" : btn == MOUSE_BTN_LEFT ? "left" : btn == MOUSE_BTN_MIDDLE ? "middle" : "right", - x, y, exposable->on_click); + button_name[btn], x, y, exposable->on_click[btn]); +#endif /* If we have a handler, change cursor to a hand */ - bar->set_cursor(bar, exposable->on_click == NULL ? "left_ptr" : "hand2"); + const char *cursor = + (exposable->particle != NULL && + exposable->particle->have_on_click_template) + ? "hand2" + : "left_ptr"; + bar->set_cursor(bar, cursor); /* If this is a mouse click, and we have a handler, execute it */ - if (exposable->on_click != NULL && event == ON_MOUSE_CLICK) { + if (exposable->on_click[btn] != NULL && event == ON_MOUSE_CLICK) { /* Need a writeable copy, whose scope *we* control */ - char *cmd = strdup(exposable->on_click); - LOG_DBG("cmd = \"%s\"", exposable->on_click); + char *cmd = strdup(exposable->on_click[btn]); + LOG_DBG("cmd = \"%s\"", exposable->on_click[btn]); char **argv; if (!tokenize_cmdline(cmd, &argv)) { @@ -174,15 +197,15 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, int wstatus; if (waitpid(pid, &wstatus, 0) == -1) - LOG_ERRNO("%s: failed to wait for on_click handler", exposable->on_click); + LOG_ERRNO("%s: failed to wait for on_click handler", exposable->on_click[btn]); if (WIFEXITED(wstatus)) { if (WEXITSTATUS(wstatus) != 0) - LOG_ERRNO_P("%s: failed to execute", WEXITSTATUS(wstatus), exposable->on_click); + LOG_ERRNO_P("%s: failed to execute", WEXITSTATUS(wstatus), exposable->on_click[btn]); } else - LOG_ERR("%s: did not exit normally", exposable->on_click); + LOG_ERR("%s: did not exit normally", exposable->on_click[btn]); - LOG_DBG("%s: launched", exposable->on_click); + LOG_DBG("%s: launched", exposable->on_click[btn]); } else { /* * Use a pipe with O_CLOEXEC to communicate exec() failure @@ -283,11 +306,17 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, } struct exposable * -exposable_common_new(const struct particle *particle, const char *on_click) +exposable_common_new(const struct particle *particle, const struct tag_set *tags) { struct exposable *exposable = calloc(1, sizeof(*exposable)); exposable->particle = particle; - exposable->on_click = on_click != NULL ? strdup(on_click) : NULL; + + if (particle != NULL && particle->have_on_click_template) { + tags_expand_templates( + exposable->on_click, + (const char **)particle->on_click_templates, + MOUSE_BTN_COUNT, tags); + } exposable->destroy = &exposable_default_destroy; exposable->on_mouse = &exposable_default_on_mouse; return exposable; diff --git a/particle.h b/particle.h index 1fc582a..4e449f3 100644 --- a/particle.h +++ b/particle.h @@ -7,23 +7,6 @@ #include "decoration.h" #include "tag.h" -struct bar; - -struct particle { - void *private; - - int left_margin, right_margin; - char *on_click_template; - - pixman_color_t foreground; - struct fcft_font *font; - struct deco *deco; - - void (*destroy)(struct particle *particle); - struct exposable *(*instantiate)(const struct particle *particle, - const struct tag_set *tags); -}; - enum mouse_event { ON_MOUSE_MOTION, ON_MOUSE_CLICK, @@ -34,14 +17,36 @@ enum mouse_button { MOUSE_BTN_LEFT, MOUSE_BTN_MIDDLE, MOUSE_BTN_RIGHT, + + MOUSE_BTN_COUNT, }; +struct bar; + +struct particle { + void *private; + + int left_margin, right_margin; + + bool have_on_click_template; + char *on_click_templates[MOUSE_BTN_COUNT]; + + pixman_color_t foreground; + struct fcft_font *font; + struct deco *deco; + + void (*destroy)(struct particle *particle); + struct exposable *(*instantiate)(const struct particle *particle, + const struct tag_set *tags); +}; + + struct exposable { const struct particle *particle; void *private; int width; /* Should be set by begin_expose(), at latest */ - char *on_click; + char *on_click[MOUSE_BTN_COUNT]; void (*destroy)(struct exposable *exposable); int (*begin_expose)(struct exposable *exposable); @@ -53,13 +58,13 @@ struct exposable { }; struct particle *particle_common_new( - int left_margin, int right_margin, const char *on_click_template, + int left_margin, int right_margin, const char *on_click_templates[], struct fcft_font *font, pixman_color_t foreground, struct deco *deco); void particle_default_destroy(struct particle *particle); struct exposable *exposable_common_new( - const struct particle *particle, const char *on_click); + const struct particle *particle, const struct tag_set *tags); void exposable_default_destroy(struct exposable *exposable); void exposable_render_deco( const struct exposable *exposable, pixman_image_t *pix, int x, int y, int height); @@ -73,7 +78,7 @@ void exposable_default_on_mouse( {"margin", false, &conf_verify_int}, \ {"left-margin", false, &conf_verify_int}, \ {"right-margin", false, &conf_verify_int}, \ - {"on-click", false, &conf_verify_string}, \ + {"on-click", false, &conf_verify_on_click}, \ {"font", false, &conf_verify_font}, \ {"foreground", false, &conf_verify_color}, \ {"deco", false, &conf_verify_decoration}, \ diff --git a/particles/dynlist.c b/particles/dynlist.c index 00bb41f..bd002d1 100644 --- a/particles/dynlist.c +++ b/particles/dynlist.c @@ -72,7 +72,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, //const struct particle *p = exposable->particle; const struct private *e = exposable->private; - if (exposable->on_click != NULL) { + if (exposable->on_click[btn] != NULL) { exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; } diff --git a/particles/empty.c b/particles/empty.c index e97f929..5c0be16 100644 --- a/particles/empty.c +++ b/particles/empty.c @@ -22,13 +22,9 @@ expose(const struct exposable *exposable, pixman_image_t *pix, int x, int y, int static struct exposable * instantiate(const struct particle *particle, const struct tag_set *tags) { - char *on_click = tags_expand_template(particle->on_click_template, tags); - - struct exposable *exposable = exposable_common_new(particle, on_click); + struct exposable *exposable = exposable_common_new(particle, tags); exposable->begin_expose = &begin_expose; exposable->expose = &expose; - - free(on_click); return exposable; } diff --git a/particles/list.c b/particles/list.c index f9e61f6..43bd3be 100644 --- a/particles/list.c +++ b/particles/list.c @@ -80,7 +80,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if (exposable->on_click != NULL) { + if (exposable->on_click[btn] != NULL) { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; @@ -121,16 +121,12 @@ instantiate(const struct particle *particle, const struct tag_set *tags) assert(e->exposables[i] != NULL); } - char *on_click = tags_expand_template(particle->on_click_template, tags); - - struct exposable *exposable = exposable_common_new(particle, on_click); + struct exposable *exposable = exposable_common_new(particle, tags); exposable->private = e; exposable->destroy = &exposable_destroy; exposable->begin_expose = &begin_expose; exposable->expose = &expose; exposable->on_mouse = &on_mouse; - - free(on_click); return exposable; } diff --git a/particles/map.c b/particles/map.c index cc26f77..3710f72 100644 --- a/particles/map.c +++ b/particles/map.c @@ -66,7 +66,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if (exposable->on_click != NULL) { + if (exposable->on_click[btn] != NULL) { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; @@ -119,15 +119,12 @@ instantiate(const struct particle *particle, const struct tag_set *tags) assert(e->exposable != NULL); - char *on_click = tags_expand_template(particle->on_click_template, tags); - struct exposable *exposable = exposable_common_new(particle, on_click); + struct exposable *exposable = exposable_common_new(particle, tags); exposable->private = e; exposable->destroy = &exposable_destroy; exposable->begin_expose = &begin_expose; exposable->expose = &expose; exposable->on_mouse = &on_mouse; - - free(on_click); return exposable; } diff --git a/particles/progress-bar.c b/particles/progress-bar.c index 62a58b9..74c8ebe 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -148,7 +148,9 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, } /* Remember the original handler, so that we can restore it */ - char *original = exposable->on_click; + char *original[MOUSE_BTN_COUNT]; + for (size_t i = 0; i < MOUSE_BTN_COUNT; i++) + original[i] = exposable->on_click[i]; if (event == ON_MOUSE_CLICK) { long where = clickable_width > 0 @@ -160,7 +162,9 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, .count = 1, }; - exposable->on_click = tags_expand_template(exposable->on_click, &tags); + tags_expand_templates( + exposable->on_click, (const char **)exposable->on_click, + MOUSE_BTN_COUNT, &tags); tag_set_destroy(&tags); } @@ -169,8 +173,10 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, if (event == ON_MOUSE_CLICK) { /* Reset handler string */ - free(exposable->on_click); - exposable->on_click = original; + for (size_t i = 0; i < MOUSE_BTN_COUNT; i++) { + free(exposable->on_click[i]); + exposable->on_click[i] = original[i]; + } } } @@ -213,10 +219,7 @@ instantiate(const struct particle *particle, const struct tag_set *tags) for (size_t i = 0; i < epriv->count; i++) assert(epriv->exposables[i] != NULL); - char *on_click = tags_expand_template(particle->on_click_template, tags); - - struct exposable *exposable = exposable_common_new(particle, on_click); - free(on_click); + struct exposable *exposable = exposable_common_new(particle, tags); exposable->private = epriv; exposable->destroy = &exposable_destroy; diff --git a/particles/ramp.c b/particles/ramp.c index 8087217..14594a2 100644 --- a/particles/ramp.c +++ b/particles/ramp.c @@ -62,7 +62,7 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if (exposable->on_click != NULL) { + if (exposable->on_click[btn] != NULL) { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; @@ -146,15 +146,12 @@ instantiate(const struct particle *particle, const struct tag_set *tags) e->exposable = pp->instantiate(pp, tags); assert(e->exposable != NULL); - char *on_click = tags_expand_template(particle->on_click_template, tags); - struct exposable *exposable = exposable_common_new(particle, on_click); + struct exposable *exposable = exposable_common_new(particle, tags); exposable->private = e; exposable->destroy = &exposable_destroy; exposable->begin_expose = &begin_expose; exposable->expose = &expose; exposable->on_mouse = &on_mouse; - - free(on_click); return exposable; } diff --git a/particles/string.c b/particles/string.c index 653c8ef..fbed826 100644 --- a/particles/string.c +++ b/particles/string.c @@ -269,15 +269,11 @@ instantiate(const struct particle *particle, const struct tag_set *tags) } } - char *on_click = tags_expand_template(particle->on_click_template, tags); - - struct exposable *exposable = exposable_common_new(particle, on_click); + struct exposable *exposable = exposable_common_new(particle, tags); exposable->private = e; exposable->destroy = &exposable_destroy; exposable->begin_expose = &begin_expose; exposable->expose = &expose; - - free(on_click); return exposable; } diff --git a/tag.c b/tag.c index 5b00218..8ca7e52 100644 --- a/tag.c +++ b/tag.c @@ -533,3 +533,11 @@ tags_expand_template(const char *template, const struct tag_set *tags) return formatted.s; } + +void +tags_expand_templates(char *expanded[], const char *template[], size_t nmemb, + const struct tag_set *tags) +{ + for (size_t i = 0; i < nmemb; i++) + expanded[i] = tags_expand_template(template[i], tags); +} diff --git a/tag.h b/tag.h index 2c629c5..d6bfe6a 100644 --- a/tag.h +++ b/tag.h @@ -50,3 +50,6 @@ void tag_set_destroy(struct tag_set *set); /* Utility functions */ char *tags_expand_template(const char *template, const struct tag_set *tags); +void tags_expand_templates( + char *expanded[], const char *template[], size_t nmemb, + const struct tag_set *tags); From 34d832cd220f477ca0cb9f15bd6ff7f571cd7d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 22 Jun 2021 19:30:41 +0200 Subject: [PATCH 04/14] config+particle: add support for mouse wheel up/down --- config-verify.c | 2 ++ config.c | 4 ++++ particle.c | 2 ++ particle.h | 2 ++ 4 files changed, 10 insertions(+) diff --git a/config-verify.c b/config-verify.c index 6a5278b..ae6e41d 100644 --- a/config-verify.c +++ b/config-verify.c @@ -164,6 +164,8 @@ conf_verify_on_click(keychain_t *chain, const struct yml_node *node) {"left", false, &conf_verify_string}, {"middle", false, &conf_verify_string}, {"right", false, &conf_verify_string}, + {"wheel-up", false, &conf_verify_string}, + {"wheel-down", false, &conf_verify_string}, {NULL, false, NULL}, }; diff --git a/config.c b/config.c index b2e131c..956eba9 100644 --- a/config.c +++ b/config.c @@ -160,6 +160,10 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) on_click_templates[MOUSE_BTN_MIDDLE] = template; else if (strcmp(key, "right") == 0) on_click_templates[MOUSE_BTN_RIGHT] = template; + else if (strcmp(key, "wheel-up") == 0) + on_click_templates[MOUSE_BTN_WHEEL_UP] = template; + else if (strcmp(key, "wheel-down") == 0) + on_click_templates[MOUSE_BTN_WHEEL_DOWN] = template; else assert(false); } diff --git a/particle.c b/particle.c index ea4bb62..16eb738 100644 --- a/particle.c +++ b/particle.c @@ -161,6 +161,8 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, [MOUSE_BTN_MIDDLE] = "middle", [MOUSE_BTN_RIGHT] = "right", [MOUSE_BTN_COUNT] = "count", + [MOUSE_BTN_WHEEL_UP] = "wheel-up", + [MOUSE_BTN_WHEEL_DOWN] = "wheel-down", }; LOG_DBG("on_mouse: exposable=%p, event=%s, btn=%s, x=%d, y=%d (on-click=%s)", exposable, event == ON_MOUSE_MOTION ? "motion" : "click", diff --git a/particle.h b/particle.h index 4e449f3..4ca520f 100644 --- a/particle.h +++ b/particle.h @@ -17,6 +17,8 @@ enum mouse_button { MOUSE_BTN_LEFT, MOUSE_BTN_MIDDLE, MOUSE_BTN_RIGHT, + MOUSE_BTN_WHEEL_UP, + MOUSE_BTN_WHEEL_DOWN, MOUSE_BTN_COUNT, }; From 13ef977eebd1350226c5d0374b873f941bef57bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 22 Jun 2021 20:17:58 +0200 Subject: [PATCH 05/14] =?UTF-8?q?particle:=20on-mouse:=20don=E2=80=99t=20c?= =?UTF-8?q?lose=20our=20own=20pipe=20FD=20before=20the=20execvp()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- particle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/particle.c b/particle.c index 16eb738..5748cce 100644 --- a/particle.c +++ b/particle.c @@ -277,7 +277,8 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, /* Close *all* other FDs (e.g. script modules' FDs) */ for (int i = STDERR_FILENO + 1; i < 65536; i++) - close(i); + if (i != pipe_fds[1]) + close(i); execvp(argv[0], argv); From 4e2c4e1e3a304cc48bdcbcd673fe2daa73b6381a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 22 Jun 2021 20:18:23 +0200 Subject: [PATCH 06/14] particle: on-mouse: close the read pipe after reading from it, in parent --- particle.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/particle.c b/particle.c index 5748cce..a1e2b2c 100644 --- a/particle.c +++ b/particle.c @@ -295,6 +295,8 @@ exposable_default_on_mouse(struct exposable *exposable, struct bar *bar, int _errno = 0; ssize_t ret = read(pipe_fds[0], &_errno, sizeof(_errno)); + close(pipe_fds[0]); + if (ret == 0) { /* Pipe was closed - child succeeded with exec() */ _exit(0); From 5e6e9e189b5a7f731292fef6e066a1af02bd3ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 22 Jun 2021 20:18:50 +0200 Subject: [PATCH 07/14] bar: xcb: add support for mouse wheel up/down --- bar/xcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar/xcb.c b/bar/xcb.c index 6229bc5..9c452da 100644 --- a/bar/xcb.c +++ b/bar/xcb.c @@ -369,7 +369,7 @@ loop(struct bar *_bar, const xcb_button_release_event_t *evt = (void *)e; switch (evt->detail) { - case 1: case 2: case 3: + case 1: case 2: case 3: case 4: case 5: on_mouse(_bar, ON_MOUSE_CLICK, evt->detail, evt->event_x, evt->event_y); break; From 93a5bbb4a4ff94137eb10447de4242c9013f3b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 22 Jun 2021 20:19:07 +0200 Subject: [PATCH 08/14] bar: wayland: require seat version 5, to get discrete axis events --- bar/wayland.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar/wayland.c b/bar/wayland.c index 1124ab2..7fb9d29 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -574,7 +574,7 @@ handle_global(void *data, struct wl_registry *registry, } else if (strcmp(interface, wl_seat_interface.name) == 0) { - const uint32_t required = 3; + const uint32_t required = 5; if (!verify_iface_version(interface, version, required)) return; From 530afe6cf56a51126f6ec62282110eebdd3bf558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 22 Jun 2021 20:20:06 +0200 Subject: [PATCH 09/14] bar: wayland: initial support for mouse wheel up/down --- bar/wayland.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/bar/wayland.c b/bar/wayland.c index 7fb9d29..77474eb 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -113,6 +113,9 @@ struct wayland_backend { struct buffer *next_buffer; /* Bar is rendering to this one */ struct buffer *pending_buffer; /* Finished, but not yet rendered */ + double aggregated_scroll; + bool have_discrete; + void (*bar_expose)(const struct bar *bar); void (*bar_on_mouse)(struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y); @@ -248,6 +251,8 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, struct seat *seat = data; struct wayland_backend *backend = seat->backend; + backend->have_discrete = false; + if (backend->active_seat == seat) backend->active_seat = NULL; } @@ -297,11 +302,46 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { + if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) + return; + + struct seat *seat = data; + struct wayland_backend *backend = seat->backend; + backend->active_seat = seat; + + if (backend->have_discrete) + return; + + const double amount = wl_fixed_to_double(value); + + if ((backend->aggregated_scroll > 0 && amount < 0) || + (backend->aggregated_scroll < 0 && amount > 0)) + { + backend->aggregated_scroll = amount; + } else + backend->aggregated_scroll += amount; + + enum mouse_button btn = backend->aggregated_scroll > 0 + ? MOUSE_BTN_WHEEL_DOWN + : MOUSE_BTN_WHEEL_UP; + + const double step = 20.; + const double adjust = backend->aggregated_scroll > 0 ? -step : step; + + while (fabs(backend->aggregated_scroll) >= step) { + backend->bar_on_mouse( + backend->bar, ON_MOUSE_CLICK, btn, + seat->pointer.x, seat->pointer.y); + backend->aggregated_scroll += adjust; + } } static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { + struct seat *seat = data; + struct wayland_backend *backend = seat->backend; + backend->have_discrete = false; } static void @@ -314,12 +354,34 @@ static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) { + if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) + return; + + struct seat *seat = data; + struct wayland_backend *backend = seat->backend; + backend->aggregated_scroll = 0.; } static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) { + if (axis != WL_POINTER_AXIS_VERTICAL_SCROLL) + return; + + struct seat *seat = data; + struct wayland_backend *backend = seat->backend; + backend->have_discrete = true; + + enum mouse_button btn = discrete > 0 + ? MOUSE_BTN_WHEEL_DOWN + : MOUSE_BTN_WHEEL_UP; + + for (int32_t i = 0; i < discrete; i++) { + backend->bar_on_mouse( + backend->bar, ON_MOUSE_CLICK, btn, + seat->pointer.x, seat->pointer.y); + } } static const struct wl_pointer_listener pointer_listener = { From 46e6539b1ad81743b30b0fc9984d29e99b46b791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 23 Jun 2021 10:58:28 +0200 Subject: [PATCH 10/14] particle/list: call default handler on motion events if we a have click handler This ensures the cursor changes shape correctly --- particles/list.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/particles/list.c b/particles/list.c index 43bd3be..9f03231 100644 --- a/particles/list.c +++ b/particles/list.c @@ -80,7 +80,10 @@ on_mouse(struct exposable *exposable, struct bar *bar, const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if (exposable->on_click[btn] != NULL) { + if ((event == ON_MOUSE_MOTION && + exposable->particle->have_on_click_template) || + exposable->on_click[btn] != NULL) + { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; From 4ce3fe22858ed86480cead7302afa40c7a2a40fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 23 Jun 2021 11:21:26 +0200 Subject: [PATCH 11/14] bar/wayland: fix mouse wheel up not being emitted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We emit mouse wheel up events when the ‘discrete’ counter is negative. Thus, when looping, we need to loop to its *absolute* value. --- bar/wayland.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bar/wayland.c b/bar/wayland.c index 77474eb..19470fc 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -377,7 +377,9 @@ wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, ? MOUSE_BTN_WHEEL_DOWN : MOUSE_BTN_WHEEL_UP; - for (int32_t i = 0; i < discrete; i++) { + int count = abs(discrete); + + for (int32_t i = 0; i < count; i++) { backend->bar_on_mouse( backend->bar, ON_MOUSE_CLICK, btn, seat->pointer.x, seat->pointer.y); From 0aef2f85ee93fdd8fbf43f959bc15ffb6159701f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 23 Jun 2021 11:28:59 +0200 Subject: [PATCH 12/14] config: add bar.trackpad-sensitivity This is an integer that specifies the amount of scrolling that needs to be accumulated before a wheel-up/down event is emitted. A higher value means you need to drag your fingers a longer distance before the event is emitted. The default is 30. --- bar/bar.c | 1 + bar/bar.h | 1 + bar/private.h | 1 + bar/wayland.c | 4 +++- config-verify.c | 2 ++ config.c | 6 ++++++ doc/yambar.5.scd | 6 ++++++ 7 files changed, 20 insertions(+), 1 deletion(-) diff --git a/bar/bar.c b/bar/bar.c index b7557fd..9806f44 100644 --- a/bar/bar.c +++ b/bar/bar.c @@ -408,6 +408,7 @@ bar_new(const struct bar_config *config) priv->right_spacing = config->right_spacing; priv->left_margin = config->left_margin; priv->right_margin = config->right_margin; + priv->trackpad_sensitivity = config->trackpad_sensitivity; priv->border.width = config->border.width; priv->border.color = config->border.color; priv->border.left_margin = config->border.left_margin; diff --git a/bar/bar.h b/bar/bar.h index 78e2414..4e82534 100644 --- a/bar/bar.h +++ b/bar/bar.h @@ -25,6 +25,7 @@ struct bar_config { int height; int left_spacing, right_spacing; int left_margin, right_margin; + int trackpad_sensitivity; pixman_color_t background; diff --git a/bar/private.h b/bar/private.h index b5d888f..eed532b 100644 --- a/bar/private.h +++ b/bar/private.h @@ -10,6 +10,7 @@ struct private { int height; int left_spacing, right_spacing; int left_margin, right_margin; + int trackpad_sensitivity; pixman_color_t background; diff --git a/bar/wayland.c b/bar/wayland.c index 19470fc..7e63cf0 100644 --- a/bar/wayland.c +++ b/bar/wayland.c @@ -307,6 +307,8 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, struct seat *seat = data; struct wayland_backend *backend = seat->backend; + struct private *bar = backend->bar->private; + backend->active_seat = seat; if (backend->have_discrete) @@ -325,7 +327,7 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, ? MOUSE_BTN_WHEEL_DOWN : MOUSE_BTN_WHEEL_UP; - const double step = 20.; + const double step = bar->trackpad_sensitivity; const double adjust = backend->aggregated_scroll > 0 ? -step : step; while (fabs(backend->aggregated_scroll) >= step) { diff --git a/config-verify.c b/config-verify.c index ae6e41d..6c09a4a 100644 --- a/config-verify.c +++ b/config-verify.c @@ -423,6 +423,8 @@ conf_verify_bar(const struct yml_node *bar) {"center", false, &verify_module_list}, {"right", false, &verify_module_list}, + {"trackpad-sensitivity", false, &conf_verify_int}, + {NULL, false, NULL}, }; diff --git a/config.c b/config.c index 956eba9..bc6d7a7 100644 --- a/config.c +++ b/config.c @@ -252,6 +252,12 @@ conf_to_bar(const struct yml_node *bar, enum bar_backend backend) if (right_margin != NULL) conf.right_margin = yml_value_as_int(right_margin); + const struct yml_node *trackpad_sensitivity = + yml_get_value(bar, "trackpad-sensitivity"); + conf.trackpad_sensitivity = trackpad_sensitivity != NULL + ? yml_value_as_int(trackpad_sensitivity) + : 30; + const struct yml_node *border = yml_get_value(bar, "border"); if (border != NULL) { const struct yml_node *width = yml_get_value(border, "width"); diff --git a/doc/yambar.5.scd b/doc/yambar.5.scd index 6b4a5ff..d352e0e 100644 --- a/doc/yambar.5.scd +++ b/doc/yambar.5.scd @@ -109,6 +109,12 @@ types that are frequently used: : color : no : Default foreground (text) color to use +| trackpad-sensitivity +: int +: no +: How easy it is to trigger wheel-up and wheel-down on-click + handlers. Higher values means you need to drag your finger a longer + distance. The default is 30. | left : list : no From e11fe12c98aed71ce7b720cca6f78c77fbdb7c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 2 Jul 2021 16:36:09 +0200 Subject: [PATCH 13/14] particles: fix mouse hover on non-primitive particles If a ramp, map or progress-bar has an on-click handler, then the mouse should _always_ reflect this. --- particles/dynlist.c | 1 - particles/map.c | 5 ++++- particles/progress-bar.c | 5 ++++- particles/ramp.c | 5 ++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/particles/dynlist.c b/particles/dynlist.c index bd002d1..8c6319c 100644 --- a/particles/dynlist.c +++ b/particles/dynlist.c @@ -69,7 +69,6 @@ static void on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { - //const struct particle *p = exposable->particle; const struct private *e = exposable->private; if (exposable->on_click[btn] != NULL) { diff --git a/particles/map.c b/particles/map.c index 3710f72..e2d8c03 100644 --- a/particles/map.c +++ b/particles/map.c @@ -66,7 +66,10 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if (exposable->on_click[btn] != NULL) { + if ((event == ON_MOUSE_MOTION && + exposable->particle->have_on_click_template) || + exposable->on_click[btn] != NULL) + { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; diff --git a/particles/progress-bar.c b/particles/progress-bar.c index 74c8ebe..a825117 100644 --- a/particles/progress-bar.c +++ b/particles/progress-bar.c @@ -87,7 +87,10 @@ static void on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, enum mouse_button btn, int x, int y) { - if (exposable->on_click == NULL) { + if ((event == ON_MOUSE_MOTION && + exposable->particle->have_on_click_template) || + exposable->on_click[btn] != NULL) + { exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; } diff --git a/particles/ramp.c b/particles/ramp.c index 14594a2..3fa2fc8 100644 --- a/particles/ramp.c +++ b/particles/ramp.c @@ -62,7 +62,10 @@ on_mouse(struct exposable *exposable, struct bar *bar, enum mouse_event event, const struct particle *p = exposable->particle; const struct eprivate *e = exposable->private; - if (exposable->on_click[btn] != NULL) { + if ((event == ON_MOUSE_MOTION && + exposable->particle->have_on_click_template) || + exposable->on_click[btn] != NULL) + { /* We have our own handler */ exposable_default_on_mouse(exposable, bar, event, btn, x, y); return; From fc9c3ebbb82abfe07b556ff84ee7b47030d8833f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 4 Jul 2021 19:50:15 +0200 Subject: [PATCH 14/14] changelog: mouse buttons + scrolling --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78a2a2..850a307 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ ### Added * Text shaping support. +* Support for middle and right mouse buttons, mouse wheel and trackpad + scrolling (https://codeberg.org/dnkl/yambar/issues/39). ### Changed