From 5b595a4dfe805f9059bbf2a34c3be415b9ba82c6 Mon Sep 17 00:00:00 2001 From: vawvaw Date: Tue, 13 Feb 2024 17:55:11 +0100 Subject: [PATCH] hyprland/workspaces: Add `enable-bar-scroll` option --- include/modules/hyprland/workspaces.hpp | 4 +++ man/waybar-hyprland-workspaces.5.scd | 5 ++++ src/modules/hyprland/workspaces.cpp | 35 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index a5d94bbf7d..8bf88888a1 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -43,6 +43,7 @@ class Workspaces : public AModule, public EventHandler { auto moveToMonitor() const -> bool { return m_moveToMonitor; } auto enableTaskbar() const -> bool { return m_enableTaskbar; } auto taskbarWithIcon() const -> bool { return m_taskbarWithIcon; } + auto barScroll() const -> bool { return m_barScroll; } auto getBarOutput() const -> std::string { return m_bar.output->name; } auto formatBefore() const -> std::string { return m_formatBefore; } @@ -122,6 +123,8 @@ class Workspaces : public AModule, public EventHandler { static std::pair splitDoublePayload(std::string const& payload); static std::tuple splitTriplePayload( std::string const& payload); + // scroll events + bool handleScroll(GdkEventScroll* e) override; // Update methods void doUpdate(); @@ -145,6 +148,7 @@ class Workspaces : public AModule, public EventHandler { bool m_specialVisibleOnly = false; bool m_persistentOnly = false; bool m_moveToMonitor = false; + bool m_barScroll = false; Json::Value m_persistentWorkspaceConfig; // Map for windows stored in workspaces not present in the current bar. diff --git a/man/waybar-hyprland-workspaces.5.scd b/man/waybar-hyprland-workspaces.5.scd index 1d04157b9e..5284ce991c 100644 --- a/man/waybar-hyprland-workspaces.5.scd +++ b/man/waybar-hyprland-workspaces.5.scd @@ -130,6 +130,11 @@ This setting is ignored if *workspace-taskbar.enable* is set to true. Otherwise, the workspace will open on the monitor where it was previously assigned. Analog to using `focusworkspaceoncurrentmonitor` dispatcher instead of `workspace` in Hyprland. +*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. + *ignore-workspaces*: ++ typeof: array ++ default: [] ++ diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 6fa382608c..8765d78b3d 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -43,6 +43,13 @@ void Workspaces::init() { m_activeWorkspaceId = m_ipc.getSocket1JsonReply("activeworkspace")["id"].asInt(); initializeWorkspaces(); + + if (barScroll()) { + auto &window = const_cast(m_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(); } @@ -636,6 +643,7 @@ auto Workspaces::parseConfig(const Json::Value& config) -> void { populateBoolConfig(config, "persistent-only", m_persistentOnly); populateBoolConfig(config, "active-only", m_activeOnly); populateBoolConfig(config, "move-to-monitor", m_moveToMonitor); + populateBoolConfig(config, "enable-bar-scroll", m_barScroll); m_persistentWorkspaceConfig = config.get("persistent-workspaces", Json::Value()); populateSortByConfig(config); @@ -1151,4 +1159,31 @@ std::optional Workspaces::parseWorkspaceId(std::string const& workspaceIdSt } } +bool Workspaces::handleScroll(GdkEventScroll *e) { + // Ignore emulated scroll events on window + if (gdk_event_get_pointer_emulated((GdkEvent *)e)) { + return false; + } + auto dir = AModule::getScrollDir(e); + if (dir == SCROLL_DIR::NONE) { + return true; + } + + if (dir == SCROLL_DIR::DOWN || dir == SCROLL_DIR::RIGHT) { + if (allOutputs()) { + m_ipc.getSocket1Reply("dispatch workspace e+1"); + } else { + m_ipc.getSocket1Reply("dispatch workspace m+1"); + } + } else if (dir == SCROLL_DIR::UP || dir == SCROLL_DIR::LEFT) { + if (allOutputs()) { + m_ipc.getSocket1Reply("dispatch workspace e-1"); + } else { + m_ipc.getSocket1Reply("dispatch workspace m-1"); + } + } + + return true; +} + } // namespace waybar::modules::hyprland