From 39dc37c24392e224e78b9907e9fc9f582f422e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Bruguera=20Mic=C3=B3?= Date: Thu, 15 Aug 2024 11:17:16 +0000 Subject: [PATCH 1/2] swaybar: refactor workspace button handling logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the workspace pointer/touch button handling logic from render.c to input.c, and reorganize it so handling more buttons is more natural. No functional change intended. Signed-off-by: Joan Bruguera Micó --- include/swaybar/input.h | 3 +++ swaybar/input.c | 15 +++++++++++++++ swaybar/render.c | 12 ++---------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/include/swaybar/input.h b/include/swaybar/input.h index 8ea88a69..35360c96 100644 --- a/include/swaybar/input.h +++ b/include/swaybar/input.h @@ -78,6 +78,9 @@ uint32_t event_to_x11_button(uint32_t event); void free_hotspots(struct wl_list *list); +bool handle_workspace_button(struct swaybar_output *output, + uint32_t button, bool released, const char *ws); + void swaybar_seat_free(struct swaybar_seat *seat); #endif diff --git a/swaybar/input.c b/swaybar/input.c index ada4bc86..d5862832 100644 --- a/swaybar/input.c +++ b/swaybar/input.c @@ -236,6 +236,21 @@ static void workspace_next(struct swaybar *bar, struct swaybar_output *output, } } +bool handle_workspace_button(struct swaybar_output *output, + uint32_t button, bool released, const char *ws) { + if (button == BTN_LEFT) { + if (released) { + // Since we handle the pressed event, also handle the released event + // to block it from falling through to a binding in the bar + return true; + } + ipc_send_workspace_command(output->bar, ws); + return true; + } + + return false; +} + static void process_discrete_scroll(struct swaybar_seat *seat, struct swaybar_output *output, struct swaybar_pointer *pointer, uint32_t axis, wl_fixed_t value) { diff --git a/swaybar/render.c b/swaybar/render.c index 879a4e42..d0302eb6 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -599,16 +599,8 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx, static enum hotspot_event_handling workspace_hotspot_callback( struct swaybar_output *output, struct swaybar_hotspot *hotspot, double x, double y, uint32_t button, bool released, void *data) { - if (button != BTN_LEFT) { - return HOTSPOT_PROCESS; - } - if (released) { - // Since we handle the pressed event, also handle the released event - // to block it from falling through to a binding in the bar - return HOTSPOT_IGNORE; - } - ipc_send_workspace_command(output->bar, (const char *)data); - return HOTSPOT_IGNORE; + return handle_workspace_button(output, button, released, (const char *)data) + ? HOTSPOT_IGNORE : HOTSPOT_PROCESS; } static uint32_t render_workspace_button(struct render_context *ctx, From 9431d0603e8e6b5577ce21198d903eecdd006a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Bruguera=20Mic=C3=B3?= Date: Thu, 15 Aug 2024 14:41:30 +0000 Subject: [PATCH 2/2] swaybar: prioritize workspace scroll over bindsyms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds handling for scroll events (e.g. mouse wheel) to the hotspot callback equivalent to the fallback in `process_discrete_scroll`. While this may seem redundant (and in many cases, it is), it changes the priority when the user has Button4/Button5 bindsyms on the bar. Before this commit: * Scrolling on unused bar space calls the user's bindsyms. * Scrolling over the workspaces *still* calls the user's bindsyms. After this commit: * Scrolling on unused bar space calls the user's bindsyms. * Scrolling over the workspaces moves to the previous/next workspace. If the user has no bindsyms for Button4/Button5, there is no change. This is consistent with the idea that workspaces are hotspots, and hotspot event handlers take priority over the user's bindsyms, see 53f9dbd424dc ("swaybar: Prioritize hotspot events to bar bindings"). However, note that this strays further away from i3's behaviour. On i3, user bindsyms take precedence over workspaces, even for Button1. In fact, it's explicitly documented as such: https://web.archive.org/web/20240725173949/https://i3wm.org/docs/userguide.html#_mouse_button_commands Signed-off-by: Joan Bruguera Micó --- swaybar/input.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/swaybar/input.c b/swaybar/input.c index d5862832..4c79f962 100644 --- a/swaybar/input.c +++ b/swaybar/input.c @@ -246,6 +246,15 @@ bool handle_workspace_button(struct swaybar_output *output, } ipc_send_workspace_command(output->bar, ws); return true; + } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN || + button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) { + if (released) { + return true; + } + + workspace_next(output->bar, output, + button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT); + return true; } return false; @@ -266,6 +275,7 @@ static void process_discrete_scroll(struct swaybar_seat *seat, return; } + // If no hotspot nor binding handles the event, scroll through workspaces struct swaybar_config *config = seat->bar->config; double amt = wl_fixed_to_double(value); if (amt == 0.0 || !config->workspace_buttons) {