From df7f1fffcf56bcbd54d92c6085692236dd7ab968 Mon Sep 17 00:00:00 2001 From: Tom Benham Date: Mon, 4 Mar 2024 13:17:30 +0100 Subject: [PATCH 1/2] feat(hyprland/workspaces): added options `move-to-monitor` and `active-per-monitor` --- include/modules/hyprland/workspaces.hpp | 4 ++ man/waybar-hyprland-workspaces.5.scd | 15 ++++++ src/modules/hyprland/workspaces.cpp | 61 ++++++++++++++++++++++--- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index 91ea1653..df72f343 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -126,6 +126,8 @@ class Workspaces : public AModule, public EventHandler { auto allOutputs() const -> bool { return m_allOutputs; } auto showSpecial() const -> bool { return m_showSpecial; } auto activeOnly() const -> bool { return m_activeOnly; } + auto moveToMonitor() const -> bool { return m_moveToMonitor; } + auto activePerMonitor() const -> bool { return m_activePerMonitor; } auto getBarOutput() const -> std::string { return m_bar.output->name; } @@ -182,6 +184,8 @@ class Workspaces : public AModule, public EventHandler { bool m_allOutputs = false; bool m_showSpecial = false; bool m_activeOnly = false; + bool m_moveToMonitor = false; + bool m_activePerMonitor = 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 12c1fe39..44218f9a 100644 --- a/man/waybar-hyprland-workspaces.5.scd +++ b/man/waybar-hyprland-workspaces.5.scd @@ -52,6 +52,21 @@ Addressed by *hyprland/workspaces* default: false ++ If set to true, only the active workspace will be shown. +*move-to-monitor*: ++ + typeof: bool ++ + default: false ++ + If set to true, open the workspace on the current monitor when clicking on a workspace button. + Otherwise, the workspace will open on the monitor where it was previously assigned. + Analog to using `focusworkspaceoncurrentmonitor` dispatcher instead of `workspace` in Hyprland. + +*active-per-monitor*: ++ + typeof: bool ++ + default: false ++ + If set to true, each bar on each monitor will show its separate active + workspace being the currently focused workspace on this monitor. + Otherwise, all bars on all monitors will show the same active workspace + being the currently focused workspace on the currently focused monitor. + *ignore-workspaces*: ++ typeof: array ++ default: [] ++ diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 882e3806..458da823 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -83,6 +83,16 @@ auto Workspaces::parseConfig(const Json::Value &config) -> void { m_activeOnly = configActiveOnly.asBool(); } + auto configMoveToMonitor = config_["move-to-monitor"]; + if (configMoveToMonitor.isBool()) { + m_moveToMonitor = configMoveToMonitor.asBool(); + } + + auto configActivePerMonitor = config_["active-per-monitor"]; + if (configActivePerMonitor.isBool()) { + m_activePerMonitor = configActivePerMonitor.asBool(); + } + auto configSortBy = config_["sort-by"]; if (configSortBy.isString()) { auto sortByStr = configSortBy.asString(); @@ -321,7 +331,14 @@ void Workspaces::onEvent(const std::string &ev) { } void Workspaces::onWorkspaceActivated(std::string const &payload) { - m_activeWorkspaceName = payload; + if (!m_activePerMonitor) { + m_activeWorkspaceName = payload; + return; + } + auto activeWorkspace = gIPC->getSocket1JsonReply("activeworkspace"); + if (m_bar.output->name == activeWorkspace["monitor"].asString()) { + m_activeWorkspaceName = payload; + } } void Workspaces::onSpecialWorkspaceActivated(std::string const &payload) { @@ -374,6 +391,16 @@ void Workspaces::onWorkspaceMoved(std::string const &payload) { if (m_bar.output->name == monitorName) { Json::Value clientsData = gIPC->getSocket1JsonReply("clients"); onWorkspaceCreated(workspaceName, clientsData); + if (m_activePerMonitor) { + for (Json::Value &monitor : gIPC->getSocket1JsonReply("monitors")) { + if (m_bar.output->name == monitor["name"].asString()) { + auto ws = monitor["activeWorkspace"]; + if (ws.isObject() && (ws["name"].isString())) { + m_activeWorkspaceName = ws["name"].asString(); + } + } + } + } } else { spdlog::debug("Removing workspace because it was moved to another monitor: {}"); onWorkspaceDestroyed(workspaceName); @@ -399,10 +426,13 @@ void Workspaces::onWorkspaceRenamed(std::string const &payload) { void Workspaces::onMonitorFocused(std::string const &payload) { spdlog::trace("Monitor focused: {}", payload); - m_activeWorkspaceName = payload.substr(payload.find(',') + 1); + auto monitorName = payload.substr(0, payload.find(',')); + if (!m_activePerMonitor || m_bar.output->name == monitorName) { + m_activeWorkspaceName = payload.substr(payload.find(',') + 1); + } for (Json::Value &monitor : gIPC->getSocket1JsonReply("monitors")) { - if (monitor["name"].asString() == payload.substr(0, payload.find(','))) { + if (monitor["name"].asString() == monitorName) { auto name = monitor["specialWorkspace"]["name"].asString(); m_activeSpecialWorkspaceName = !name.starts_with("special:") ? name : name.substr(8); } @@ -804,7 +834,18 @@ void Workspaces::extendOrphans(int workspaceId, Json::Value const &clientsJson) } void Workspaces::init() { - m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString(); + if (!m_activePerMonitor) { + m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString(); + } else { + for (Json::Value &monitor : gIPC->getSocket1JsonReply("monitors")) { + if (m_bar.output->name == monitor["name"].asString()) { + auto ws = monitor["activeWorkspace"]; + if (ws.isObject() && (ws["name"].isString())) { + m_activeWorkspaceName = ws["name"].asString(); + } + } + } + } initializeWorkspaces(); updateWindowCount(); @@ -1019,9 +1060,17 @@ bool Workspace::handleClicked(GdkEventButton *bt) const { if (bt->type == GDK_BUTTON_PRESS) { try { if (id() > 0) { // normal - gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id())); + if (m_workspaceManager.moveToMonitor()) { + gIPC->getSocket1Reply("dispatch focusworkspaceoncurrentmonitor " + std::to_string(id())); + } else { + gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id())); + } } else if (!isSpecial()) { // named (this includes persistent) - gIPC->getSocket1Reply("dispatch workspace name:" + name()); + if (m_workspaceManager.moveToMonitor()) { + gIPC->getSocket1Reply("dispatch focusworkspaceoncurrentmonitor name:" + name()); + } else { + gIPC->getSocket1Reply("dispatch workspace name:" + name()); + } } else if (id() != -99) { // named special gIPC->getSocket1Reply("dispatch togglespecialworkspace " + name()); } else { // special From 68889494d019705e87b519934b4625a2134336d7 Mon Sep 17 00:00:00 2001 From: Tom Benham Date: Tue, 5 Mar 2024 11:12:07 +0100 Subject: [PATCH 2/2] Removed option `active-per-monitor` --- include/modules/hyprland/workspaces.hpp | 2 -- man/waybar-hyprland-workspaces.5.scd | 8 ----- src/modules/hyprland/workspaces.cpp | 44 +++---------------------- 3 files changed, 4 insertions(+), 50 deletions(-) diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index df72f343..655bc460 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -127,7 +127,6 @@ class Workspaces : public AModule, public EventHandler { auto showSpecial() const -> bool { return m_showSpecial; } auto activeOnly() const -> bool { return m_activeOnly; } auto moveToMonitor() const -> bool { return m_moveToMonitor; } - auto activePerMonitor() const -> bool { return m_activePerMonitor; } auto getBarOutput() const -> std::string { return m_bar.output->name; } @@ -185,7 +184,6 @@ class Workspaces : public AModule, public EventHandler { bool m_showSpecial = false; bool m_activeOnly = false; bool m_moveToMonitor = false; - bool m_activePerMonitor = 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 44218f9a..584beac1 100644 --- a/man/waybar-hyprland-workspaces.5.scd +++ b/man/waybar-hyprland-workspaces.5.scd @@ -59,14 +59,6 @@ Addressed by *hyprland/workspaces* Otherwise, the workspace will open on the monitor where it was previously assigned. Analog to using `focusworkspaceoncurrentmonitor` dispatcher instead of `workspace` in Hyprland. -*active-per-monitor*: ++ - typeof: bool ++ - default: false ++ - If set to true, each bar on each monitor will show its separate active - workspace being the currently focused workspace on this monitor. - Otherwise, all bars on all monitors will show the same active workspace - being the currently focused workspace on the currently focused monitor. - *ignore-workspaces*: ++ typeof: array ++ default: [] ++ diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 458da823..3330fbc7 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -88,11 +88,6 @@ auto Workspaces::parseConfig(const Json::Value &config) -> void { m_moveToMonitor = configMoveToMonitor.asBool(); } - auto configActivePerMonitor = config_["active-per-monitor"]; - if (configActivePerMonitor.isBool()) { - m_activePerMonitor = configActivePerMonitor.asBool(); - } - auto configSortBy = config_["sort-by"]; if (configSortBy.isString()) { auto sortByStr = configSortBy.asString(); @@ -331,14 +326,7 @@ void Workspaces::onEvent(const std::string &ev) { } void Workspaces::onWorkspaceActivated(std::string const &payload) { - if (!m_activePerMonitor) { - m_activeWorkspaceName = payload; - return; - } - auto activeWorkspace = gIPC->getSocket1JsonReply("activeworkspace"); - if (m_bar.output->name == activeWorkspace["monitor"].asString()) { - m_activeWorkspaceName = payload; - } + m_activeWorkspaceName = payload; } void Workspaces::onSpecialWorkspaceActivated(std::string const &payload) { @@ -391,16 +379,6 @@ void Workspaces::onWorkspaceMoved(std::string const &payload) { if (m_bar.output->name == monitorName) { Json::Value clientsData = gIPC->getSocket1JsonReply("clients"); onWorkspaceCreated(workspaceName, clientsData); - if (m_activePerMonitor) { - for (Json::Value &monitor : gIPC->getSocket1JsonReply("monitors")) { - if (m_bar.output->name == monitor["name"].asString()) { - auto ws = monitor["activeWorkspace"]; - if (ws.isObject() && (ws["name"].isString())) { - m_activeWorkspaceName = ws["name"].asString(); - } - } - } - } } else { spdlog::debug("Removing workspace because it was moved to another monitor: {}"); onWorkspaceDestroyed(workspaceName); @@ -426,13 +404,10 @@ void Workspaces::onWorkspaceRenamed(std::string const &payload) { void Workspaces::onMonitorFocused(std::string const &payload) { spdlog::trace("Monitor focused: {}", payload); - auto monitorName = payload.substr(0, payload.find(',')); - if (!m_activePerMonitor || m_bar.output->name == monitorName) { - m_activeWorkspaceName = payload.substr(payload.find(',') + 1); - } + m_activeWorkspaceName = payload.substr(payload.find(',') + 1); for (Json::Value &monitor : gIPC->getSocket1JsonReply("monitors")) { - if (monitor["name"].asString() == monitorName) { + if (monitor["name"].asString() == payload.substr(0, payload.find(','))) { auto name = monitor["specialWorkspace"]["name"].asString(); m_activeSpecialWorkspaceName = !name.starts_with("special:") ? name : name.substr(8); } @@ -834,18 +809,7 @@ void Workspaces::extendOrphans(int workspaceId, Json::Value const &clientsJson) } void Workspaces::init() { - if (!m_activePerMonitor) { - m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString(); - } else { - for (Json::Value &monitor : gIPC->getSocket1JsonReply("monitors")) { - if (m_bar.output->name == monitor["name"].asString()) { - auto ws = monitor["activeWorkspace"]; - if (ws.isObject() && (ws["name"].isString())) { - m_activeWorkspaceName = ws["name"].asString(); - } - } - } - } + m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString(); initializeWorkspaces(); updateWindowCount();