diff --git a/include/modules/niri/workspaces.hpp b/include/modules/niri/workspaces.hpp index 08986412..01840b33 100644 --- a/include/modules/niri/workspaces.hpp +++ b/include/modules/niri/workspaces.hpp @@ -20,6 +20,7 @@ class Workspaces : public AModule, public EventHandler { void doUpdate(); Gtk::Button& addButton(const Json::Value& ws); std::string getIcon(const std::string& value, const Json::Value& ws); + bool handleScroll(GdkEventScroll* /*unused*/) override; const Bar& bar_; Gtk::Box box_; diff --git a/man/waybar-niri-workspaces.5.scd b/man/waybar-niri-workspaces.5.scd index 4be85eb3..ec329404 100644 --- a/man/waybar-niri-workspaces.5.scd +++ b/man/waybar-niri-workspaces.5.scd @@ -31,6 +31,11 @@ Addressed by *niri/workspaces* default: false ++ If set to false, you can click to change workspace. If set to true this behaviour is disabled. +*enable-bar-scroll*: ++ + typeof: bool ++ + default: false ++ + If set to false, you can't scroll to cycle throughout workspaces from the entire bar. If set to true this behaviour is enabled. + *disable-markup*: ++ typeof: bool ++ default: false ++ diff --git a/src/modules/niri/workspaces.cpp b/src/modules/niri/workspaces.cpp index 97d15215..97472260 100644 --- a/src/modules/niri/workspaces.cpp +++ b/src/modules/niri/workspaces.cpp @@ -22,6 +22,12 @@ Workspaces::Workspaces(const std::string& id, const Bar& bar, const Json::Value& gIPC->registerForIPC("WorkspaceActiveWindowChanged", this); gIPC->registerForIPC("WorkspaceUrgencyChanged", this); + if (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, &Workspaces::handleScroll)); + } + dp.emit(); } @@ -198,4 +204,43 @@ std::string Workspaces::getIcon(const std::string& value, const Json::Value& ws) return value; } +bool Workspaces::handleScroll(GdkEventScroll* e) { + if (gdk_event_get_pointer_emulated((GdkEvent*)e) != 0) { + /** + * Ignore emulated scroll events on window + */ + return false; + } + + auto dir = AModule::getScrollDir(e); + if (dir == SCROLL_DIR::NONE) { + return true; + } + + try { + Json::Value request(Json::objectValue); + auto& action = (request["Action"] = Json::Value(Json::objectValue)); + + std::string action_name; + + if (dir == SCROLL_DIR::DOWN || dir == SCROLL_DIR::RIGHT) { + action_name = "FocusWorkspaceDown"; + } else if (dir == SCROLL_DIR::UP || dir == SCROLL_DIR::LEFT) { + action_name = "FocusWorkspaceUp"; + } else { + return true; + } + + action[action_name] = Json::Value(Json::objectValue); + + IPC::send(request); + + } catch (const std::exception& e) { + spdlog::error("Workspaces: {}", e.what()); + return false; + } + + return true; +} + } // namespace waybar::modules::niri