aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Joan Bruguera <joanbrugueram@gmail.com>2021-09-18 22:21:22 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2022-11-26 10:29:59 +0100
commit0a9b468540d4be7dbea3b63515b64eaa5c187f0f (patch)
tree0ad85957876211c887654dd2d8a55fc4d7abbaf8
parentswaybar: Prioritize hotspot events to bar bindings (diff)
downloadsway-0a9b468540d4be7dbea3b63515b64eaa5c187f0f.tar.gz
sway-0a9b468540d4be7dbea3b63515b64eaa5c187f0f.tar.zst
sway-0a9b468540d4be7dbea3b63515b64eaa5c187f0f.zip
swaybar: Make hotspots block bar release bindings
The previous commit prioritized hotspots before bar bindings for press events, which matches i3's behaviour. However, since hotspots don't need to do any processing on release events, those were not handled, and simply fell through to `bindsym --release` bar bindings (if any). This is counter-intuitive, and doesn't match i3's behaviour. Instead in case a hotspot handles the press event, it should also handle the release event, doing nothing, but blocking the event from triggering a --release bar binding. E.g., in Sway, without this commit, this config. shows a text on tray clicks: bar { # ... bindsym --release button1 exec swaynag -m I_got_the_release_event. } But the same configuration in i3 (with i3-nagbar) doesn't show the text. Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com> (cherry picked from commit 94b69acf0d7b26ee5af2172300cb18473508da76)
-rw-r--r--include/swaybar/i3bar.h2
-rw-r--r--include/swaybar/input.h2
-rw-r--r--swaybar/i3bar.c7
-rw-r--r--swaybar/input.c17
-rw-r--r--swaybar/render.c11
-rw-r--r--swaybar/tray/item.c7
6 files changed, 31 insertions, 15 deletions
diff --git a/include/swaybar/i3bar.h b/include/swaybar/i3bar.h
index 1aec6d6c..dced2a6c 100644
--- a/include/swaybar/i3bar.h
+++ b/include/swaybar/i3bar.h
@@ -30,6 +30,6 @@ void i3bar_block_unref(struct i3bar_block *block);
30bool i3bar_handle_readable(struct status_line *status); 30bool i3bar_handle_readable(struct status_line *status);
31enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, 31enum hotspot_event_handling i3bar_block_send_click(struct status_line *status,
32 struct i3bar_block *block, double x, double y, double rx, double ry, 32 struct i3bar_block *block, double x, double y, double rx, double ry,
33 double w, double h, int scale, uint32_t button); 33 double w, double h, int scale, uint32_t button, bool released);
34 34
35#endif 35#endif
diff --git a/include/swaybar/input.h b/include/swaybar/input.h
index e8735d88..8ea88a69 100644
--- a/include/swaybar/input.h
+++ b/include/swaybar/input.h
@@ -49,7 +49,7 @@ struct swaybar_hotspot {
49 int x, y, width, height; 49 int x, y, width, height;
50 enum hotspot_event_handling (*callback)(struct swaybar_output *output, 50 enum hotspot_event_handling (*callback)(struct swaybar_output *output,
51 struct swaybar_hotspot *hotspot, double x, double y, uint32_t button, 51 struct swaybar_hotspot *hotspot, double x, double y, uint32_t button,
52 void *data); 52 bool released, void *data);
53 void (*destroy)(void *data); 53 void (*destroy)(void *data);
54 void *data; 54 void *data;
55}; 55};
diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c
index 6d00befb..ccd5a076 100644
--- a/swaybar/i3bar.c
+++ b/swaybar/i3bar.c
@@ -269,11 +269,16 @@ bool i3bar_handle_readable(struct status_line *status) {
269 269
270enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, 270enum hotspot_event_handling i3bar_block_send_click(struct status_line *status,
271 struct i3bar_block *block, double x, double y, double rx, double ry, 271 struct i3bar_block *block, double x, double y, double rx, double ry,
272 double w, double h, int scale, uint32_t button) { 272 double w, double h, int scale, uint32_t button, bool released) {
273 sway_log(SWAY_DEBUG, "block %s clicked", block->name); 273 sway_log(SWAY_DEBUG, "block %s clicked", block->name);
274 if (!block->name || !status->click_events) { 274 if (!block->name || !status->click_events) {
275 return HOTSPOT_PROCESS; 275 return HOTSPOT_PROCESS;
276 } 276 }
277 if (released) {
278 // Since we handle the pressed event, also handle the released event
279 // to block it from falling through to a binding in the bar
280 return HOTSPOT_IGNORE;
281 }
277 282
278 struct json_object *event_json = json_object_new_object(); 283 struct json_object *event_json = json_object_new_object();
279 json_object_object_add(event_json, "name", 284 json_object_object_add(event_json, "name",
diff --git a/swaybar/input.c b/swaybar/input.c
index f12eed79..8eccf542 100644
--- a/swaybar/input.c
+++ b/swaybar/input.c
@@ -141,14 +141,15 @@ static bool check_bindings(struct swaybar *bar, uint32_t button,
141} 141}
142 142
143static bool process_hotspots(struct swaybar_output *output, 143static bool process_hotspots(struct swaybar_output *output,
144 double x, double y, uint32_t button) { 144 double x, double y, uint32_t button, uint32_t state) {
145 bool released = state == WL_POINTER_BUTTON_STATE_RELEASED;
145 struct swaybar_hotspot *hotspot; 146 struct swaybar_hotspot *hotspot;
146 wl_list_for_each(hotspot, &output->hotspots, link) { 147 wl_list_for_each(hotspot, &output->hotspots, link) {
147 if (x >= hotspot->x && y >= hotspot->y 148 if (x >= hotspot->x && y >= hotspot->y
148 && x < hotspot->x + hotspot->width 149 && x < hotspot->x + hotspot->width
149 && y < hotspot->y + hotspot->height) { 150 && y < hotspot->y + hotspot->height) {
150 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y, 151 if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot, x, y,
151 button, hotspot->data)) { 152 button, released, hotspot->data)) {
152 return true; 153 return true;
153 } 154 }
154 } 155 }
@@ -166,10 +167,8 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
166 return; 167 return;
167 } 168 }
168 169
169 if (state == WL_POINTER_BUTTON_STATE_PRESSED) { 170 if (process_hotspots(output, pointer->x, pointer->y, button, state)) {
170 if (process_hotspots(output, pointer->x, pointer->y, button)) { 171 return;
171 return;
172 }
173 } 172 }
174 173
175 check_bindings(seat->bar, button, state); 174 check_bindings(seat->bar, button, state);
@@ -222,7 +221,8 @@ static void process_discrete_scroll(struct swaybar_seat *seat,
222 struct swaybar_output *output, struct swaybar_pointer *pointer, 221 struct swaybar_output *output, struct swaybar_pointer *pointer,
223 uint32_t axis, wl_fixed_t value) { 222 uint32_t axis, wl_fixed_t value) {
224 uint32_t button = wl_axis_to_button(axis, value); 223 uint32_t button = wl_axis_to_button(axis, value);
225 if (process_hotspots(output, pointer->x, pointer->y, button)) { 224 if (process_hotspots(output, pointer->x, pointer->y, button, WL_POINTER_BUTTON_STATE_PRESSED)) {
225 // (Currently hotspots don't do anything on release events, so no need to emit one)
226 return; 226 return;
227 } 227 }
228 228
@@ -401,7 +401,8 @@ static void wl_touch_up(void *data, struct wl_touch *wl_touch,
401 } 401 }
402 if (time - slot->time < 500) { 402 if (time - slot->time < 500) {
403 // Tap, treat it like a pointer click 403 // Tap, treat it like a pointer click
404 process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT); 404 process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED);
405 // (Currently hotspots don't do anything on release events, so no need to emit one)
405 } 406 }
406 slot->output = NULL; 407 slot->output = NULL;
407} 408}
diff --git a/swaybar/render.c b/swaybar/render.c
index a878805e..95f6e5be 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -160,7 +160,7 @@ static void render_sharp_line(cairo_t *cairo, uint32_t color,
160 160
161static enum hotspot_event_handling block_hotspot_callback( 161static enum hotspot_event_handling block_hotspot_callback(
162 struct swaybar_output *output, struct swaybar_hotspot *hotspot, 162 struct swaybar_output *output, struct swaybar_hotspot *hotspot,
163 double x, double y, uint32_t button, void *data) { 163 double x, double y, uint32_t button, bool released, void *data) {
164 struct i3bar_block *block = data; 164 struct i3bar_block *block = data;
165 struct status_line *status = output->bar->status; 165 struct status_line *status = output->bar->status;
166 return i3bar_block_send_click(status, block, x, y, 166 return i3bar_block_send_click(status, block, x, y,
@@ -168,7 +168,7 @@ static enum hotspot_event_handling block_hotspot_callback(
168 y - (double)hotspot->y, 168 y - (double)hotspot->y,
169 (double)hotspot->width, 169 (double)hotspot->width,
170 (double)hotspot->height, 170 (double)hotspot->height,
171 output->scale, button); 171 output->scale, button, released);
172} 172}
173 173
174static void i3bar_block_unref_callback(void *data) { 174static void i3bar_block_unref_callback(void *data) {
@@ -599,10 +599,15 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx,
599 599
600static enum hotspot_event_handling workspace_hotspot_callback( 600static enum hotspot_event_handling workspace_hotspot_callback(
601 struct swaybar_output *output, struct swaybar_hotspot *hotspot, 601 struct swaybar_output *output, struct swaybar_hotspot *hotspot,
602 double x, double y, uint32_t button, void *data) { 602 double x, double y, uint32_t button, bool released, void *data) {
603 if (button != BTN_LEFT) { 603 if (button != BTN_LEFT) {
604 return HOTSPOT_PROCESS; 604 return HOTSPOT_PROCESS;
605 } 605 }
606 if (released) {
607 // Since we handle the pressed event, also handle the released event
608 // to block it from falling through to a binding in the bar
609 return HOTSPOT_IGNORE;
610 }
606 ipc_send_workspace_command(output->bar, (const char *)data); 611 ipc_send_workspace_command(output->bar, (const char *)data);
607 return HOTSPOT_IGNORE; 612 return HOTSPOT_IGNORE;
608} 613}
diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c
index 0cb5ee9d..1f18b8bb 100644
--- a/swaybar/tray/item.c
+++ b/swaybar/tray/item.c
@@ -385,13 +385,18 @@ static int cmp_sni_id(const void *item, const void *cmp_to) {
385 385
386static enum hotspot_event_handling icon_hotspot_callback( 386static enum hotspot_event_handling icon_hotspot_callback(
387 struct swaybar_output *output, struct swaybar_hotspot *hotspot, 387 struct swaybar_output *output, struct swaybar_hotspot *hotspot,
388 double x, double y, uint32_t button, void *data) { 388 double x, double y, uint32_t button, bool released, void *data) {
389 sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data); 389 sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data);
390 390
391 struct swaybar_tray *tray = output->bar->tray; 391 struct swaybar_tray *tray = output->bar->tray;
392 int idx = list_seq_find(tray->items, cmp_sni_id, data); 392 int idx = list_seq_find(tray->items, cmp_sni_id, data);
393 393
394 if (idx != -1) { 394 if (idx != -1) {
395 if (released) {
396 // Since we handle the pressed event, also handle the released event
397 // to block it from falling through to a binding in the bar
398 return HOTSPOT_IGNORE;
399 }
395 struct swaybar_sni *sni = tray->items->items[idx]; 400 struct swaybar_sni *sni = tray->items->items[idx];
396 // guess global position since wayland doesn't expose it 401 // guess global position since wayland doesn't expose it
397 struct swaybar_config *config = tray->bar->config; 402 struct swaybar_config *config = tray->bar->config;