From c0689ae4144ca1596a7f45034ea68bfb6b4cdef2 Mon Sep 17 00:00:00 2001 From: llyyr Date: Thu, 20 Aug 2026 09:28:28 +0000 Subject: [PATCH 1/2] ext/workspaces: support workspace switching with scroll --- include/modules/ext/workspace_manager.hpp | 2 + man/waybar-ext-workspaces.5.scd | 5 +++ src/modules/ext/workspace_manager.cpp | 45 ++++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/include/modules/ext/workspace_manager.hpp b/include/modules/ext/workspace_manager.hpp index f21ff26e73..d269c46f62 100644 --- a/include/modules/ext/workspace_manager.hpp +++ b/include/modules/ext/workspace_manager.hpp @@ -35,6 +35,7 @@ class WorkspaceManager final : public AModule { // wl requests void commit() const; + bool handleScroll(GdkEventScroll* e) override; private: void update() override; @@ -100,6 +101,7 @@ class Workspace { std::vector& coordinates() { return coordinates_; } Gtk::Button& button() { return button_; } void update(); + bool is_active() const { return has_state(EXT_WORKSPACE_HANDLE_V1_STATE_ACTIVE); } // wl events void handle_id(const std::string& id); diff --git a/man/waybar-ext-workspaces.5.scd b/man/waybar-ext-workspaces.5.scd index 15bf4760b3..80c345f753 100644 --- a/man/waybar-ext-workspaces.5.scd +++ b/man/waybar-ext-workspaces.5.scd @@ -54,6 +54,11 @@ Addressed by *ext/workspaces* default: false ++ If set to true only active or urgent workspaces will be shown. +*disable-scroll*: ++ + typeof: bool ++ + default: false ++ + If set to true, scrolling is disabled for this module. + *ignore-hidden*: ++ typeof: bool ++ default: true ++ diff --git a/src/modules/ext/workspace_manager.cpp b/src/modules/ext/workspace_manager.cpp index 477c50bf37..c8cb6dccda 100644 --- a/src/modules/ext/workspace_manager.cpp +++ b/src/modules/ext/workspace_manager.cpp @@ -22,7 +22,9 @@ std::map Workspace::icon_map_; WorkspaceManager::WorkspaceManager(const std::string& id, const waybar::Bar& bar, const Json::Value& config) - : waybar::AModule(config, "workspaces", id, false, false), bar_(bar), box_(bar.orientation, 0) { + : waybar::AModule(config, "workspaces", id, false, !config["disable-scroll"].asBool()), + bar_(bar), + box_(bar.orientation, 0) { add_registry_listener(this); // parse configuration @@ -147,6 +149,47 @@ void WorkspaceManager::commit() const { if (ext_manager_) ext_workspace_manager_v1_commit(ext_manager_); } +bool WorkspaceManager::handleScroll(GdkEventScroll* e) { + if (gdk_event_get_pointer_emulated(reinterpret_cast(e)) != 0) { + return false; + } + + const auto dir = getScrollDir(e); + if (dir == SCROLL_DIR::NONE) { + return true; + } + + auto active = std::find_if(workspaces_.begin(), workspaces_.end(), [](const auto& workspace) { + return workspace->is_active() && workspace->button().get_visible(); + }); + if (active == workspaces_.end()) { + return true; + } + + auto target = active; + do { + if (dir == SCROLL_DIR::DOWN || dir == SCROLL_DIR::RIGHT) { + ++target; + if (target == workspaces_.end()) { + target = workspaces_.begin(); + } + } else { + if (target == workspaces_.begin()) { + target = workspaces_.end(); + } + --target; + } + } while (target != active && + (!has_button(&(*target)->button()) || !(*target)->button().get_visible())); + + if (target != active) { + ext_workspace_handle_v1_activate((*target)->handle()); + commit(); + } + + return true; +} + void WorkspaceManager::update() { spdlog::debug("[ext/workspaces]: Updating state"); From e9a67daabdbfc3c8e3bde29d3cd60b24cca2339a Mon Sep 17 00:00:00 2001 From: llyyr Date: Thu, 20 Aug 2026 09:28:39 +0000 Subject: [PATCH 2/2] ext/workspaces: add option for scrolling anywhere on bar --- man/waybar-ext-workspaces.5.scd | 5 +++++ src/modules/ext/workspace_manager.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/man/waybar-ext-workspaces.5.scd b/man/waybar-ext-workspaces.5.scd index 80c345f753..627953ea4e 100644 --- a/man/waybar-ext-workspaces.5.scd +++ b/man/waybar-ext-workspaces.5.scd @@ -59,6 +59,11 @@ Addressed by *ext/workspaces* default: false ++ If set to true, scrolling is disabled for this module. +*enable-bar-scroll*: ++ + typeof: bool ++ + default: false ++ + If set to true, scrolling anywhere on the bar switches to the previous or next workspace. By default, scrolling only works when the pointer is over the workspaces module + *ignore-hidden*: ++ typeof: bool ++ default: true ++ diff --git a/src/modules/ext/workspace_manager.cpp b/src/modules/ext/workspace_manager.cpp index c8cb6dccda..d3aaa004cf 100644 --- a/src/modules/ext/workspace_manager.cpp +++ b/src/modules/ext/workspace_manager.cpp @@ -63,6 +63,11 @@ WorkspaceManager::WorkspaceManager(const std::string& id, const waybar::Bar& bar } box_.get_style_context()->add_class(MODULE_CLASS); event_box_.add(box_); + if (!config_["disable-scroll"].asBool() && config_["enable-bar-scroll"].asBool()) { + auto& window = const_cast(bar_).window; + window.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); + window.signal_scroll_event().connect(sigc::mem_fun(*this, &WorkspaceManager::handleScroll)); + } spdlog::debug("[ext/workspaces]: Workspace manager created"); }