From 7d2c7ab438afa5cde93969a1ade4fc8d39d2f1e1 Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 16 Jan 2015 01:37:45 +0200 Subject: [PATCH 1/6] Allow having clickable areas inside another Previously, if you started several areas, one inside another, only the inermost one would get registered and eventually triggered. This patch fixes that, allowing you to use multiple areas around text to respond to several different buttons, for example, both scroll-up and scroll-down. If you define two areas that respond to the same button, only the innermost one would get triggered. I think this makes sense. --- bar.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/bar.c b/bar.c index 90c2229..a4492e9 100644 --- a/bar.c +++ b/bar.c @@ -34,6 +34,7 @@ typedef struct monitor_t { } monitor_t; typedef struct area_t { + bool active; int begin, end, align, button; xcb_window_t window; char *cmd; @@ -219,11 +220,15 @@ set_attribute (const char modifier, const char attribute) area_t * -area_get (xcb_window_t win, const int x) +area_get (xcb_window_t win, const int btn, const int x) { - for (int i = 0; i < astack.pos; i++) - if (astack.slot[i].window == win && x >= astack.slot[i].begin && x < astack.slot[i].end) - return &astack.slot[i]; + /* Looping backwards ensures that we get the innermost area first */ + for (int i = astack.pos; i >= 0; i--) { + area_t *a = &astack.slot[i]; + if (a->window == win && a->button == btn + && x >= a->begin && x < a->end) + return a; + } return NULL; } @@ -248,17 +253,18 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x { char *p = str; char *trail; - area_t *a = &astack.slot[astack.pos]; - - if (astack.pos == N) { - fprintf(stderr, "astack overflow!\n"); - return false; - } + area_t *a; // A wild close area tag appeared! if (*p != ':') { *end = p; + /* Find most recent unclosed area. */ + int i; + for (i = astack.pos - 1; i >= 0 && !astack.slot[i].active; i--) + ; + a = &astack.slot[i]; + // Basic safety checks if (!a->cmd || a->align != align || a->window != mon->window) return false; @@ -280,11 +286,16 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x break; } - astack.pos++; - + a->active = false; return true; } + if (astack.pos >= N) { + fprintf(stderr, "astack overflow!\n"); + return false; + } + a = &astack.slot[astack.pos++]; + // Found the closing : and check if it's just an escaped one for (trail = strchr(++p, ':'); trail && trail[-1] == '\\'; trail = strchr(trail + 1, ':')) ; @@ -308,6 +319,7 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x // This is a pointer to the string buffer allocated in the main a->cmd = p; + a->active = true; a->align = align; a->begin = x; a->window = mon->window; @@ -1191,7 +1203,7 @@ main (int argc, char **argv) case XCB_BUTTON_PRESS: press_ev = (xcb_button_press_event_t *)ev; { - area_t *area = area_get(press_ev->event, press_ev->event_x); + area_t *area = area_get(press_ev->event, press_ev->detail, press_ev->event_x); // Respond to the click if (area && area->button == press_ev->detail) { write(STDOUT_FILENO, area->cmd, strlen(area->cmd)); From 3483f1b083e33d17cffb8842c12f9b7755eb3ddf Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 16 Jan 2015 01:40:04 +0200 Subject: [PATCH 2/6] typo, whitin -> within --- bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar.c b/bar.c index a4492e9..a6441fc 100644 --- a/bar.c +++ b/bar.c @@ -300,7 +300,7 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x for (trail = strchr(++p, ':'); trail && trail[-1] == '\\'; trail = strchr(trail + 1, ':')) ; - // Find the trailing : and make sure it's whitin the formatting block, also reject empty commands + // Find the trailing : and make sure it's within the formatting block, also reject empty commands if (!trail || p == trail || trail > optend) { *end = p; return false; From bb466a8c16b4110e5afc07849bfb56a45f7d611e Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 16 Jan 2015 01:41:56 +0200 Subject: [PATCH 3/6] area_add: Use str directly I don't why p was used, if there was a reason, please don't merge. --- bar.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/bar.c b/bar.c index a6441fc..5b6f18f 100644 --- a/bar.c +++ b/bar.c @@ -251,13 +251,12 @@ area_shift (xcb_window_t win, const int align, int delta) bool area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x, const int align, const int button) { - char *p = str; char *trail; area_t *a; // A wild close area tag appeared! - if (*p != ':') { - *end = p; + if (*str != ':') { + *end = str; /* Find most recent unclosed area. */ int i; @@ -297,19 +296,19 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x a = &astack.slot[astack.pos++]; // Found the closing : and check if it's just an escaped one - for (trail = strchr(++p, ':'); trail && trail[-1] == '\\'; trail = strchr(trail + 1, ':')) + for (trail = strchr(++str, ':'); trail && trail[-1] == '\\'; trail = strchr(trail + 1, ':')) ; // Find the trailing : and make sure it's within the formatting block, also reject empty commands - if (!trail || p == trail || trail > optend) { - *end = p; + if (!trail || str == trail || trail > optend) { + *end = str; return false; } *trail = '\0'; // Sanitize the user command by unescaping all the : - for (char *needle = p; *needle; needle++) { + for (char *needle = str; *needle; needle++) { int delta = trail - &needle[1]; if (needle[0] == '\\' && needle[1] == ':') { memmove(&needle[0], &needle[1], delta); @@ -318,7 +317,7 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x } // This is a pointer to the string buffer allocated in the main - a->cmd = p; + a->cmd = str; a->active = true; a->align = align; a->begin = x; From 4ad9cbd823e229b8af262ccf707889ce8b97eb03 Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 16 Jan 2015 23:15:00 +0200 Subject: [PATCH 4/6] remove duplicate test --- bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar.c b/bar.c index 5b6f18f..3da875d 100644 --- a/bar.c +++ b/bar.c @@ -1204,7 +1204,7 @@ main (int argc, char **argv) { area_t *area = area_get(press_ev->event, press_ev->detail, press_ev->event_x); // Respond to the click - if (area && area->button == press_ev->detail) { + if (area) { write(STDOUT_FILENO, area->cmd, strlen(area->cmd)); write(STDOUT_FILENO, "\n", 1); } From a313800686f3c6a24feb9646f646af6bfcc0d27d Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Fri, 16 Jan 2015 23:20:14 +0200 Subject: [PATCH 5/6] move a declaration to the top of the function --- bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bar.c b/bar.c index 3da875d..ccc18bd 100644 --- a/bar.c +++ b/bar.c @@ -251,6 +251,7 @@ area_shift (xcb_window_t win, const int align, int delta) bool area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x, const int align, const int button) { + int i; char *trail; area_t *a; @@ -259,7 +260,6 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x *end = str; /* Find most recent unclosed area. */ - int i; for (i = astack.pos - 1; i >= 0 && !astack.slot[i].active; i--) ; a = &astack.slot[i]; From 8492309a883ae8bc9cd667fa91b7682d9a47d1e8 Mon Sep 17 00:00:00 2001 From: Otto Modinos Date: Wed, 11 Feb 2015 14:54:47 +0200 Subject: [PATCH 6/6] change comment style --- bar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bar.c b/bar.c index ccc18bd..3733910 100644 --- a/bar.c +++ b/bar.c @@ -222,7 +222,7 @@ set_attribute (const char modifier, const char attribute) area_t * area_get (xcb_window_t win, const int btn, const int x) { - /* Looping backwards ensures that we get the innermost area first */ + // Looping backwards ensures that we get the innermost area first for (int i = astack.pos; i >= 0; i--) { area_t *a = &astack.slot[i]; if (a->window == win && a->button == btn @@ -259,7 +259,7 @@ area_add (char *str, const char *optend, char **end, monitor_t *mon, const int x if (*str != ':') { *end = str; - /* Find most recent unclosed area. */ + // Find most recent unclosed area. for (i = astack.pos - 1; i >= 0 && !astack.slot[i].active; i--) ; a = &astack.slot[i];