diff options
author | 2021-09-18 22:21:22 +0200 | |
---|---|---|
committer | 2022-11-26 10:29:59 +0100 | |
commit | 0a9b468540d4be7dbea3b63515b64eaa5c187f0f (patch) | |
tree | 0ad85957876211c887654dd2d8a55fc4d7abbaf8 | |
parent | swaybar: Prioritize hotspot events to bar bindings (diff) | |
download | sway-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.h | 2 | ||||
-rw-r--r-- | include/swaybar/input.h | 2 | ||||
-rw-r--r-- | swaybar/i3bar.c | 7 | ||||
-rw-r--r-- | swaybar/input.c | 17 | ||||
-rw-r--r-- | swaybar/render.c | 11 | ||||
-rw-r--r-- | swaybar/tray/item.c | 7 |
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); | |||
30 | bool i3bar_handle_readable(struct status_line *status); | 30 | bool i3bar_handle_readable(struct status_line *status); |
31 | enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, | 31 | enum 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 | ||
270 | enum hotspot_event_handling i3bar_block_send_click(struct status_line *status, | 270 | enum 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 | ||
143 | static bool process_hotspots(struct swaybar_output *output, | 143 | static 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 | ||
161 | static enum hotspot_event_handling block_hotspot_callback( | 161 | static 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 | ||
174 | static void i3bar_block_unref_callback(void *data) { | 174 | static void i3bar_block_unref_callback(void *data) { |
@@ -599,10 +599,15 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx, | |||
599 | 599 | ||
600 | static enum hotspot_event_handling workspace_hotspot_callback( | 600 | static 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 | ||
386 | static enum hotspot_event_handling icon_hotspot_callback( | 386 | static 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; |