From 9f828800fbf9005a0f73904f3d58f7b1828513db Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Sat, 4 Sep 2021 14:36:01 +0200 Subject: [PATCH] fix(xworkspaces): Fix scrolling (#2492) The scroll handler had two issues: * It did not respect the order the desktops where displayed in * It would not wrap around on the first desktop because of an integer underflow Fixes #2491 --- CHANGELOG.md | 3 +++ src/modules/xworkspaces.cpp | 39 +++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ad80fba..db65179c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -132,6 +132,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([`#2371`](https://github.com/polybar/polybar/issues/2371)) - `polybar -m` used to show both physical outputs and randr monitors, even if the outputs were covered by monitors. ([`#2481`](https://github.com/polybar/polybar/issues/2481)) +- `internal/xworkspaces`: Broken scroll-wrapping and order of workspaces when scrolling + ([`#2491`](https://github.com/polybar/polybar/issues/2491)) + ## [3.5.6] - 2021-05-24 ### Build diff --git a/src/modules/xworkspaces.cpp b/src/modules/xworkspaces.cpp index e6c3cee4..1e4e8796 100644 --- a/src/modules/xworkspaces.cpp +++ b/src/modules/xworkspaces.cpp @@ -391,27 +391,42 @@ namespace modules { focus_direction(false); } + /** + * Focuses either the next or previous desktop. + * + * Will wrap around at the ends and go in the order the desktops are displayed. + */ void xworkspaces_module::focus_direction(bool next) { std::lock_guard lock(m_workspace_mutex); - vector indexes; + + unsigned int current_desktop{ewmh_util::get_current_desktop()}; + int current_index = -1; + + /* + * Desktop indices in the order they are displayed. + */ + vector indices; + for (auto&& viewport : m_viewports) { for (auto&& desktop : viewport->desktops) { - indexes.emplace_back(desktop->index); + + if (current_desktop == desktop->index) { + current_index = indices.size(); + } + + indices.emplace_back(desktop->index); } } - unsigned new_desktop; - unsigned int current_desktop{ewmh_util::get_current_desktop()}; - - if (next) { - new_desktop = math_util::min(indexes.back(), current_desktop + 1); - new_desktop = new_desktop == current_desktop ? indexes.front() : new_desktop; - } else { - new_desktop = math_util::max(indexes.front(), current_desktop - 1); - new_desktop = new_desktop == current_desktop ? indexes.back() : new_desktop; + if (current_index == -1) { + m_log.err("%s: Current desktop (%u) not found in list of desktops", name(), current_desktop); + return; } - focus_desktop(new_desktop); + int offset = next? 1 : -1; + + int new_index = (current_index + offset + indices.size()) % indices.size(); + focus_desktop(indices.at(new_index)); } void xworkspaces_module::focus_desktop(unsigned new_desktop) {