From 4dfbc3160c937b4fcee2b27d78d7e46a48cd68e9 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sun, 22 Apr 2018 17:13:52 +1200 Subject: [PATCH] Fix swaybar axis event logic Uses 'visible' instead of 'focused', since we may scroll on a bar which isn't the focused output. We can't use "next_on_output" or "prev_on_output" to implement this, because it only modify the focused output. So scrolling on an unfocused output will affect the incorrect one. We just use the "workspace name" command instead. --- swaybar/bar.c | 69 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/swaybar/bar.c b/swaybar/bar.c index 669cb11ac..d407db4fc 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -156,31 +156,56 @@ static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, if (!sway_assert(output, "axis with no active output")) { return; } + double amt = wl_fixed_to_double(value); - if (!bar->config->wrap_scroll) { - int i = 0; - struct swaybar_workspace *ws = NULL; - wl_list_for_each(ws, &output->workspaces, link) { - if (ws->focused) { - break; - } - ++i; - } - int len = wl_list_length(&output->workspaces); - if (!sway_assert(i != len, "axis with null workspace")) { - return; - } - if (i == 0 && amt > 0) { - return; // Do not wrap - } - if (i == len - 1 && amt < 0) { - return; // Do not wrap - } + if (amt == 0.0) { + return; } - const char *workspace_name = - amt < 0 ? "prev_on_output" : "next_on_output"; - ipc_send_workspace_command(bar, workspace_name); + struct swaybar_workspace *first = NULL; + struct swaybar_workspace *active = NULL; + struct swaybar_workspace *last; + + struct swaybar_workspace *iter; + wl_list_for_each(iter, &output->workspaces, link) { + if (!first) { + first = iter; + } + + if (iter->visible) { + active = iter; + } + + last = iter; + } + + if (!sway_assert(active, "axis with null workspace")) { + return; + } + + struct swaybar_workspace *new; + + if (amt > 0.0) { + if (active == first) { + if (!bar->config->wrap_scroll) { + return; + } + new = last; + } + + new = wl_container_of(active->link.prev, new, link); + } else { + if (active == last) { + if (!bar->config->wrap_scroll) { + return; + } + new = first; + } + + new = wl_container_of(active->link.next, new, link); + } + + ipc_send_workspace_command(bar, new->name); } static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) {