diff --git a/include/modules/hyprland/workspaces.hpp b/include/modules/hyprland/workspaces.hpp index d2006fcc4..827888b89 100644 --- a/include/modules/hyprland/workspaces.hpp +++ b/include/modules/hyprland/workspaces.hpp @@ -68,7 +68,7 @@ class Workspace { int id() const { return m_id; }; std::string name() const { return m_name; }; std::string output() const { return m_output; }; - bool isActive() const { return m_active; }; + bool isActive() const { return m_isActive; }; bool isSpecial() const { return m_isSpecial; }; bool isPersistent() const { return m_isPersistent; }; bool isVisible() const { return m_isVisible; }; @@ -76,7 +76,7 @@ class Workspace { bool isUrgent() const { return m_isUrgent; }; bool handleClicked(GdkEventButton* bt) const; - void setActive(bool value = true) { m_active = value; }; + void setActive(bool value = true) { m_isActive = value; }; void setPersistent(bool value = true) { m_isPersistent = value; }; void setUrgent(bool value = true) { m_isUrgent = value; }; void setVisible(bool value = true) { m_isVisible = value; }; @@ -99,7 +99,7 @@ class Workspace { std::string m_name; std::string m_output; uint m_windows; - bool m_active = false; + bool m_isActive = false; bool m_isSpecial = false; bool m_isPersistent = false; bool m_isUrgent = false; @@ -135,8 +135,8 @@ class Workspaces : public AModule, public EventHandler { void onEvent(const std::string& e) override; void updateWindowCount(); void sortWorkspaces(); - void createWorkspace(Json::Value const& workspace_data, - Json::Value const& clients_data = Json::Value::nullRef); + void createWorkspace(Json::Value const& workspaceData, + Json::Value const& clientsData = Json::Value::nullRef); void removeWorkspace(std::string const& name); void setUrgentWorkspace(std::string const& windowaddress); void parseConfig(const Json::Value& config); @@ -160,16 +160,24 @@ class Workspaces : public AModule, public EventHandler { void onWindowTitleEvent(std::string const& payload); + void onConfigReloaded(); + int windowRewritePriorityFunction(std::string const& window_rule); void doUpdate(); void extendOrphans(int workspaceId, Json::Value const& clientsJson); - void registerOrphanWindow(WindowCreationPayload create_window_paylod); + void registerOrphanWindow(WindowCreationPayload create_window_payload); + + void initializeWorkspaces(); + void setCurrentMonitorId(); + void loadPersistentWorkspacesFromConfig(Json::Value const& clientsJson); + void loadPersistentWorkspacesFromWorkspaceRules(const Json::Value& clientsJson); bool m_allOutputs = false; bool m_showSpecial = false; bool m_activeOnly = false; + Json::Value m_persistentWorkspaceConfig; // Map for windows stored in workspaces not present in the current bar. // This happens when the user has multiple monitors (hence, multiple bars) @@ -184,11 +192,6 @@ class Workspaces : public AModule, public EventHandler { {"NUMBER", SortMethod::NUMBER}, {"DEFAULT", SortMethod::DEFAULT}}; - void fillPersistentWorkspaces(); - void createPersistentWorkspaces(); - std::vector m_persistentWorkspacesToCreate; - bool m_persistentCreated = false; - std::string m_format; std::map m_iconsMap; diff --git a/src/modules/hyprland/workspaces.cpp b/src/modules/hyprland/workspaces.cpp index 88b5e135d..96893179f 100644 --- a/src/modules/hyprland/workspaces.cpp +++ b/src/modules/hyprland/workspaces.cpp @@ -49,6 +49,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value gIPC = std::make_unique(); } + setCurrentMonitorId(); init(); registerIpc(); } @@ -64,7 +65,6 @@ auto Workspaces::parseConfig(const Json::Value &config) -> void { for (std::string &name : formatIcons.getMemberNames()) { m_iconsMap.emplace(name, formatIcons[name].asString()); } - m_iconsMap.emplace("", ""); } @@ -112,11 +112,26 @@ auto Workspaces::parseConfig(const Json::Value &config) -> void { } } + if (config_["persistent_workspaces"].isObject()) { + spdlog::warn( + "persistent_workspaces is deprecated. Please change config to use persistent-workspaces."); + } + + if (config_["persistent-workspaces"].isObject() || config_["persistent_workspaces"].isObject()) { + m_persistentWorkspaceConfig = config_["persistent-workspaces"].isObject() + ? config_["persistent-workspaces"] + : config_["persistent_workspaces"]; + } + const Json::Value &formatWindowSeparator = config["format-window-separator"]; m_formatWindowSeparator = formatWindowSeparator.isString() ? formatWindowSeparator.asString() : " "; const Json::Value &windowRewrite = config["window-rewrite"]; + if (!windowRewrite.isObject()) { + spdlog::debug("window-rewrite is not defined or is not an object, using default rules."); + return; + } const Json::Value &windowRewriteDefaultConfig = config["window-rewrite-default"]; std::string windowRewriteDefault = @@ -127,9 +142,9 @@ auto Workspaces::parseConfig(const Json::Value &config) -> void { [this](std::string &window_rule) { return windowRewritePriorityFunction(window_rule); }); } -void Workspaces::registerOrphanWindow(WindowCreationPayload create_window_paylod) { - if (!create_window_paylod.isEmpty(*this)) { - m_orphanWindowMap[create_window_paylod.getAddress()] = create_window_paylod.repr(*this); +void Workspaces::registerOrphanWindow(WindowCreationPayload create_window_payload) { + if (!create_window_payload.isEmpty(*this)) { + m_orphanWindowMap[create_window_payload.getAddress()] = create_window_payload.repr(*this); } } @@ -144,6 +159,7 @@ auto Workspaces::registerIpc() -> void { gIPC->registerForIPC("closewindow", this); gIPC->registerForIPC("movewindow", this); gIPC->registerForIPC("urgent", this); + gIPC->registerForIPC("configreloaded", this); if (windowRewriteConfigUsesTitle()) { spdlog::info( @@ -175,6 +191,7 @@ void Workspaces::doUpdate() { m_workspacesToCreate.clear(); // get all active workspaces + spdlog::trace("Getting active workspaces"); auto monitors = gIPC->getSocket1JsonReply("monitors"); std::vector visibleWorkspaces; for (Json::Value &monitor : monitors) { @@ -184,6 +201,7 @@ void Workspaces::doUpdate() { } } + spdlog::trace("Updating workspace states"); for (auto &workspace : m_workspaces) { // active workspace->setActive(workspace->name() == m_activeWorkspaceName); @@ -204,6 +222,7 @@ void Workspaces::doUpdate() { workspace->update(m_format, workspaceIcon); } + spdlog::trace("Updating window count"); bool anyWindowCreated = false; std::vector notCreated; @@ -285,6 +304,8 @@ void Workspaces::onEvent(const std::string &ev) { onWorkspaceRenamed(payload); } else if (eventName == "windowtitle") { onWindowTitleEvent(payload); + } else if (eventName == "configreloaded") { + onConfigReloaded(); } dp.emit(); @@ -302,22 +323,37 @@ void Workspaces::onWorkspaceDestroyed(std::string const &payload) { void Workspaces::onWorkspaceCreated(std::string const &workspaceName, Json::Value const &clientsData) { - const Json::Value workspacesJson = gIPC->getSocket1JsonReply("workspaces"); + spdlog::debug("Workspace created: {}", workspaceName); + auto const workspacesJson = gIPC->getSocket1JsonReply("workspaces"); if (!isWorkspaceIgnored(workspaceName)) { + auto const workspaceRules = gIPC->getSocket1JsonReply("workspacerules"); for (Json::Value workspaceJson : workspacesJson) { std::string name = workspaceJson["name"].asString(); - if (name == workspaceName && - (allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) && - (showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(workspaceName)) { - m_workspacesToCreate.emplace_back(workspaceJson, clientsData); - break; + if (name == workspaceName) { + if ((allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) && + (showSpecial() || !name.starts_with("special")) && !isDoubleSpecial(workspaceName)) { + for (Json::Value const &rule : workspaceRules) { + if (rule["workspaceString"].asString() == workspaceName) { + workspaceJson["persistent"] = rule["persistent"].asBool(); + break; + } + } + + m_workspacesToCreate.emplace_back(workspaceJson, clientsData); + break; + } + } else { + extendOrphans(workspaceJson["id"].asInt(), clientsData); } } + } else { + spdlog::trace("Not creating workspace because it is ignored: {}", workspaceName); } } void Workspaces::onWorkspaceMoved(std::string const &payload) { + spdlog::debug("Workspace moved: {}", payload); std::string workspaceName = payload.substr(0, payload.find(',')); std::string monitorName = payload.substr(payload.find(',') + 1); @@ -325,11 +361,13 @@ void Workspaces::onWorkspaceMoved(std::string const &payload) { Json::Value clientsData = gIPC->getSocket1JsonReply("clients"); onWorkspaceCreated(workspaceName, clientsData); } else { + spdlog::debug("Removing workspace because it was moved to another monitor: {}"); onWorkspaceDestroyed(workspaceName); } } void Workspaces::onWorkspaceRenamed(std::string const &payload) { + spdlog::debug("Workspace renamed: {}", payload); std::string workspaceIdStr = payload.substr(0, payload.find(',')); int workspaceId = workspaceIdStr == "special" ? -99 : std::stoi(workspaceIdStr); std::string newName = payload.substr(payload.find(',') + 1); @@ -346,10 +384,12 @@ 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); } void Workspaces::onWindowOpened(std::string const &payload) { + spdlog::trace("Window opened: {}", payload); updateWindowCount(); size_t lastCommaIdx = 0; size_t nextCommaIdx = payload.find(','); @@ -369,6 +409,7 @@ void Workspaces::onWindowOpened(std::string const &payload) { } void Workspaces::onWindowClosed(std::string const &addr) { + spdlog::trace("Window closed: {}", addr); updateWindowCount(); for (auto &workspace : m_workspaces) { if (workspace->closeWindow(addr)) { @@ -378,6 +419,7 @@ void Workspaces::onWindowClosed(std::string const &addr) { } void Workspaces::onWindowMoved(std::string const &payload) { + spdlog::trace("Window moved: {}", payload); updateWindowCount(); size_t lastCommaIdx = 0; size_t nextCommaIdx = payload.find(','); @@ -416,6 +458,7 @@ void Workspaces::onWindowMoved(std::string const &payload) { } void Workspaces::onWindowTitleEvent(std::string const &payload) { + spdlog::trace("Window title changed: {}", payload); std::optional> inserter; // If the window was an orphan, rename it at the orphan's vector @@ -459,6 +502,11 @@ void Workspaces::onWindowTitleEvent(std::string const &payload) { } } +void Workspaces::onConfigReloaded() { + spdlog::info("Hyprland config reloaded, reinitializing hyprland/workspaces module..."); + init(); +} + void Workspaces::updateWindowCount() { const Json::Value workspacesJson = gIPC->getSocket1JsonReply("workspaces"); for (auto &workspace : m_workspaces) { @@ -515,8 +563,11 @@ std::optional Workspace::closeWindow(WindowAddress const &addr) { void Workspaces::createWorkspace(Json::Value const &workspace_data, Json::Value const &clients_data) { - // avoid recreating existing workspaces auto workspaceName = workspace_data["name"].asString(); + spdlog::debug("Creating workspace {}, persistent: {}", workspaceName, + workspace_data["persistent"].asBool() ? "true" : "false"); + + // avoid recreating existing workspaces auto workspace = std::find_if( m_workspaces.begin(), m_workspaces.end(), [workspaceName](std::unique_ptr const &w) { @@ -525,9 +576,8 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data, }); if (workspace != m_workspaces.end()) { - if (workspace_data["persistent"].asBool() and !(*workspace)->isPersistent()) { - (*workspace)->setPersistent(); - } + // don't recreate workspace, but update persistency if necessary + (*workspace)->setPersistent(workspace_data["persistent"].asBool()); return; } @@ -540,6 +590,7 @@ void Workspaces::createWorkspace(Json::Value const &workspace_data, } void Workspaces::removeWorkspace(std::string const &name) { + spdlog::debug("Removing workspace {}", name); auto workspace = std::find_if(m_workspaces.begin(), m_workspaces.end(), [&](std::unique_ptr &x) { return (name.starts_with("special:") && name.substr(8) == x->name()) || name == x->name(); @@ -551,7 +602,7 @@ void Workspaces::removeWorkspace(std::string const &name) { } if ((*workspace)->isPersistent()) { - // don't remove persistent workspaces, createWorkspace will take care of replacement + spdlog::trace("Not removing persistent workspace {}", name); return; } @@ -559,94 +610,106 @@ void Workspaces::removeWorkspace(std::string const &name) { m_workspaces.erase(workspace); } -void Workspaces::fillPersistentWorkspaces() { - if (config_["persistent_workspaces"].isObject()) { - spdlog::warn( - "persistent_workspaces is deprecated. Please change config to use persistent-workspaces."); - } +Json::Value createPersistentWorkspaceData(std::string const &name, std::string const &monitor) { + spdlog::trace("Creating persistent workspace: {} on monitor {}", name, monitor); + Json::Value workspaceData; + try { + // numbered persistent workspaces get the name as ID + workspaceData["id"] = name == "special" ? -99 : std::stoi(name); + } catch (const std::exception &e) { + // named persistent workspaces start with ID=0 + workspaceData["id"] = 0; + } + workspaceData["name"] = name; + workspaceData["monitor"] = monitor; + workspaceData["windows"] = 0; + workspaceData["persistent"] = true; + return workspaceData; +} - if (config_["persistent-workspaces"].isObject() || config_["persistent_workspaces"].isObject()) { - const Json::Value persistentWorkspaces = config_["persistent-workspaces"].isObject() - ? config_["persistent-workspaces"] - : config_["persistent_workspaces"]; - const std::vector keys = persistentWorkspaces.getMemberNames(); - - for (const std::string &key : keys) { - // only add if either: - // 1. key is "*" and this monitor is not already defined in the config - // 2. key is the current monitor name - bool canCreate = - (key == "*" && std::find(keys.begin(), keys.end(), m_bar.output->name) == keys.end()) || - key == m_bar.output->name; - const Json::Value &value = persistentWorkspaces[key]; - - if (value.isInt()) { - // value is a number => create that many workspaces for this monitor - if (canCreate) { - int amount = value.asInt(); - spdlog::debug("Creating {} persistent workspaces for monitor {}", amount, - m_bar.output->name); - for (int i = 0; i < amount; i++) { - m_persistentWorkspacesToCreate.emplace_back( - std::to_string(m_monitorId * amount + i + 1)); - } +void Workspaces::loadPersistentWorkspacesFromConfig(Json::Value const &clientsJson) { + spdlog::info("Loading persistent workspaces from Waybar config"); + const std::vector keys = m_persistentWorkspaceConfig.getMemberNames(); + std::vector persistentWorkspacesToCreate; + + const std::string currentMonitor = m_bar.output->name; + const bool monitorInConfig = std::find(keys.begin(), keys.end(), currentMonitor) != keys.end(); + for (const std::string &key : keys) { + // only add if either: + // 1. key is the current monitor name + // 2. key is "*" and this monitor is not already defined in the config + bool canCreate = key == currentMonitor || (key == "*" && !monitorInConfig); + const Json::Value &value = m_persistentWorkspaceConfig[key]; + spdlog::trace("Parsing persistent workspace config: {} => {}", key, value.toStyledString()); + + if (value.isInt()) { + // value is a number => create that many workspaces for this monitor + if (canCreate) { + int amount = value.asInt(); + spdlog::debug("Creating {} persistent workspaces for monitor {}", amount, currentMonitor); + for (int i = 0; i < amount; i++) { + persistentWorkspacesToCreate.emplace_back(std::to_string(m_monitorId * amount + i + 1)); } - } else if (value.isArray() && !value.empty()) { - // value is an array => create defined workspaces for this monitor - if (canCreate) { - for (const Json::Value &workspace : value) { - if (workspace.isInt()) { - spdlog::debug("Creating workspace {} on monitor {}", workspace, m_bar.output->name); - m_persistentWorkspacesToCreate.emplace_back(std::to_string(workspace.asInt())); - } - } - } else { - // key is the workspace and value is array of monitors to create on - for (const Json::Value &monitor : value) { - if (monitor.isString() && monitor.asString() == m_bar.output->name) { - m_persistentWorkspacesToCreate.emplace_back(key); - break; - } + } + } else if (value.isArray() && !value.empty()) { + // value is an array => create defined workspaces for this monitor + if (canCreate) { + for (const Json::Value &workspace : value) { + if (workspace.isInt()) { + spdlog::debug("Creating workspace {} on monitor {}", workspace, currentMonitor); + persistentWorkspacesToCreate.emplace_back(std::to_string(workspace.asInt())); } } } else { - // this workspace should be displayed on all monitors - m_persistentWorkspacesToCreate.emplace_back(key); + // key is the workspace and value is array of monitors to create on + for (const Json::Value &monitor : value) { + if (monitor.isString() && monitor.asString() == currentMonitor) { + persistentWorkspacesToCreate.emplace_back(currentMonitor); + break; + } + } } + } else { + // this workspace should be displayed on all monitors + persistentWorkspacesToCreate.emplace_back(key); } } -} -void Workspaces::createPersistentWorkspaces() { - for (const std::string &workspaceName : m_persistentWorkspacesToCreate) { - Json::Value newWorkspace; - try { - // numbered persistent workspaces get the name as ID - newWorkspace["id"] = workspaceName == "special" ? -99 : std::stoi(workspaceName); - } catch (const std::exception &e) { - // named persistent workspaces start with ID=0 - newWorkspace["id"] = 0; - } - newWorkspace["name"] = workspaceName; - newWorkspace["monitor"] = m_bar.output->name; - newWorkspace["windows"] = 0; - newWorkspace["persistent"] = true; - - createWorkspace(newWorkspace); + for (auto const &workspace : persistentWorkspacesToCreate) { + auto const workspaceData = createPersistentWorkspaceData(workspace, m_bar.output->name); + m_workspacesToCreate.emplace_back(workspaceData, clientsJson); } } -void Workspaces::extendOrphans(int workspaceId, Json::Value const &clientsJson) { - for (const auto &client : clientsJson) { - if (client["workspace"]["id"].asInt() == workspaceId) { - registerOrphanWindow({client}); +void Workspaces::loadPersistentWorkspacesFromWorkspaceRules(const Json::Value &clientsJson) { + spdlog::info("Loading persistent workspaces from Hyprland workspace rules"); + + auto const workspaceRules = gIPC->getSocket1JsonReply("workspacerules"); + for (Json::Value const &rule : workspaceRules) { + if (!rule["workspaceString"].isString()) { + spdlog::warn("Workspace rules: invalid workspaceString, skipping: {}", rule); + continue; + } + if (!rule["persistent"].asBool()) { + continue; + } + auto const &workspace = rule["workspaceString"].asString(); + auto const &monitor = rule["monitor"].asString(); + // create this workspace persistently if: + // 1. the allOutputs config option is enabled + // 2. the rule's monitor is the current monitor + // 3. no monitor is specified in the rule => assume it needs to be persistent on every monitor + if (allOutputs() || m_bar.output->name == monitor || monitor.empty()) { + // => persistent workspace should be shown on this monitor + auto workspaceData = createPersistentWorkspaceData(workspace, m_bar.output->name); + m_workspacesToCreate.emplace_back(workspaceData, clientsJson); + } else { + m_workspacesToRemove.emplace_back(workspace); } } } -void Workspaces::init() { - m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString(); - +void Workspaces::setCurrentMonitorId() { // get monitor ID from name (used by persistent workspaces) m_monitorId = 0; auto monitors = gIPC->getSocket1JsonReply("monitors"); @@ -657,29 +720,58 @@ void Workspaces::init() { spdlog::error("Monitor '{}' does not have an ID? Using 0", m_bar.output->name); } else { m_monitorId = (*currentMonitor)["id"].asInt(); + spdlog::trace("Current monitor ID: {}", m_monitorId); } +} - const Json::Value workspacesJson = gIPC->getSocket1JsonReply("workspaces"); - const Json::Value clientsJson = gIPC->getSocket1JsonReply("clients"); +void Workspaces::initializeWorkspaces() { + spdlog::debug("Initializing workspaces"); + + // if the workspace rules changed since last initialization, make sure we reset everything: + for (auto &workspace : m_workspaces) { + m_workspacesToRemove.push_back(workspace->name()); + } + + // get all current workspaces + auto const workspacesJson = gIPC->getSocket1JsonReply("workspaces"); + auto const clientsJson = gIPC->getSocket1JsonReply("clients"); for (Json::Value workspaceJson : workspacesJson) { std::string workspaceName = workspaceJson["name"].asString(); if ((allOutputs() || m_bar.output->name == workspaceJson["monitor"].asString()) && (!workspaceName.starts_with("special") || showSpecial()) && !isWorkspaceIgnored(workspaceName)) { - createWorkspace(workspaceJson, clientsJson); + m_workspacesToCreate.emplace_back(workspaceJson, clientsJson); } else { extendOrphans(workspaceJson["id"].asInt(), clientsJson); } } - fillPersistentWorkspaces(); - createPersistentWorkspaces(); + spdlog::debug("Initializing persistent workspaces"); + if (m_persistentWorkspaceConfig.isObject()) { + // a persistent workspace config is defined, so use that instead of workspace rules + loadPersistentWorkspacesFromConfig(clientsJson); + } else { + // no persistent workspaces config defined, use Hyprland's workspace rules + loadPersistentWorkspacesFromWorkspaceRules(clientsJson); + } +} - updateWindowCount(); +void Workspaces::extendOrphans(int workspaceId, Json::Value const &clientsJson) { + spdlog::trace("Extending orphans with workspace {}", workspaceId); + for (const auto &client : clientsJson) { + if (client["workspace"]["id"].asInt() == workspaceId) { + registerOrphanWindow({client}); + } + } +} - sortWorkspaces(); +void Workspaces::init() { + m_activeWorkspaceName = (gIPC->getSocket1JsonReply("activeworkspace"))["name"].asString(); + initializeWorkspaces(); + updateWindowCount(); + sortWorkspaces(); dp.emit(); } @@ -696,7 +788,8 @@ Workspace::Workspace(const Json::Value &workspace_data, Workspaces &workspace_ma m_name(workspace_data["name"].asString()), m_output(workspace_data["monitor"].asString()), // TODO:allow using monitor desc m_windows(workspace_data["windows"].asInt()), - m_active(true) { + m_isActive(true), + m_isPersistent(workspace_data["persistent"].asBool()) { if (m_name.starts_with("name:")) { m_name = m_name.substr(5); } else if (m_name.starts_with("special")) { @@ -704,10 +797,6 @@ Workspace::Workspace(const Json::Value &workspace_data, Workspaces &workspace_ma m_isSpecial = true; } - if (workspace_data.isMember("persistent")) { - m_isPersistent = workspace_data["persistent"].asBool(); - } - m_button.add_events(Gdk::BUTTON_PRESS_MASK); m_button.signal_button_press_event().connect(sigc::mem_fun(*this, &Workspace::handleClicked), false); @@ -813,8 +902,7 @@ void Workspaces::sortWorkspaces() { if (a->id() == -99 || b->id() == -99) { return b->id() == -99; } - // both are 0 (not yet named persistents) / both are named specials (-98 <= ID - // <=-1) + // both are 0 (not yet named persistents) / named specials (-98 <= ID <= -1) return isNameLess; } @@ -833,6 +921,7 @@ void Workspaces::sortWorkspaces() { } std::string &Workspace::selectIcon(std::map &icons_map) { + spdlog::trace("Selecting icon for workspace {}", name()); if (isUrgent()) { auto urgentIconIt = icons_map.find("urgent"); if (urgentIconIt != icons_map.end()) { @@ -889,21 +978,19 @@ std::string &Workspace::selectIcon(std::map &icons_map } bool Workspace::handleClicked(GdkEventButton *bt) const { - if (bt->type == GDK_BUTTON_PRESS) { - try { - if (id() > 0) { // normal or numbered persistent - gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id())); - } else if (!isSpecial()) { // named - gIPC->getSocket1Reply("dispatch workspace name:" + name()); - } else if (id() != -99) { // named special - gIPC->getSocket1Reply("dispatch togglespecialworkspace " + name()); - } else { // special - gIPC->getSocket1Reply("dispatch togglespecialworkspace"); - } - return true; - } catch (const std::exception &e) { - spdlog::error("Failed to dispatch workspace: {}", e.what()); + try { + if (id() > 0) { // normal + gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id())); + } else if (!isSpecial()) { // named (this includes persistent) + gIPC->getSocket1Reply("dispatch workspace name:" + name()); + } else if (id() != -99) { // named special + gIPC->getSocket1Reply("dispatch togglespecialworkspace " + name()); + } else { // special + gIPC->getSocket1Reply("dispatch togglespecialworkspace"); } + return true; + } catch (const std::exception &e) { + spdlog::error("Failed to dispatch workspace: {}", e.what()); } return false; } diff --git a/src/util/regex_collection.cpp b/src/util/regex_collection.cpp index df0879c18..704d65455 100644 --- a/src/util/regex_collection.cpp +++ b/src/util/regex_collection.cpp @@ -66,4 +66,4 @@ std::string& RegexCollection::get(std::string& value) { return get(value, matched_any); } -} // namespace waybar::util \ No newline at end of file +} // namespace waybar::util