From 85f177a2134230c5c07a68c9f03766fc58999f7b Mon Sep 17 00:00:00 2001 From: Lucas Lazare Date: Sat, 18 May 2019 10:58:55 -0400 Subject: [PATCH 1/8] Adding sway/workspaces:persistant_workspaces in config file c.f. https://github.com/Alexays/Waybar/issues/210 --- src/modules/sway/workspaces.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 231b3363..0266a546 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -47,6 +47,38 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { ? workspace["output"].asString() == bar_.output->name : true; }); + + // adding persistant workspaces (as per the config file) + const Json::Value& p_workspaces = config_["persistant_workspaces"]; + const std::vector p_workspaces_names = p_workspaces.getMemberNames(); + for (const std::string& p_w_name : p_workspaces_names) { + const Json::Value& p_w = p_workspaces[p_w_name]; + auto it = std::find_if(payload.begin(), payload.end(), [&p_w_name](const Json::Value& node) { + return node["name"].asString() == p_w_name; + }); + if (it != payload.end()) { + continue; // already displayed by some bar + } + + if (p_w.isArray() && !p_w.empty()) { + for (const Json::Value& output : p_w) { + if (output.asString() == bar_.output->name) { + Json::Value v; + v["name"] = p_w_name; + workspaces_.emplace_back(std::move(v)); + break; + } + } + } else { + Json::Value v; + v["name"] = p_w_name; + workspaces_.emplace_back(std::move(v)); + } + } + std::sort(workspaces_.begin(), workspaces_.end(), [](const Json::Value& lhs, const Json::Value& rhs) { + return lhs["name"].asString() < rhs["name"].asString(); + }); + dp.emit(); } } catch (const std::exception &e) { From 1a76aa0c8c4cb38f2cf71cedc7068025245b5124 Mon Sep 17 00:00:00 2001 From: Lucas Lazare Date: Sat, 18 May 2019 11:58:01 -0400 Subject: [PATCH 2/8] Improving ordering --- include/modules/sway/workspaces.hpp | 1 + src/modules/sway/workspaces.cpp | 30 ++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/include/modules/sway/workspaces.hpp b/include/modules/sway/workspaces.hpp index 8c7875cc..d6244c42 100644 --- a/include/modules/sway/workspaces.hpp +++ b/include/modules/sway/workspaces.hpp @@ -35,6 +35,7 @@ class Workspaces : public IModule, public sigc::trackable { const Bar& bar_; const Json::Value& config_; std::vector workspaces_; + std::vector workspaces_order_; waybar::util::SleeperThread thread_; std::mutex mutex_; Gtk::Box box_; diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 0266a546..09950adc 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -75,9 +75,33 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { workspaces_.emplace_back(std::move(v)); } } - std::sort(workspaces_.begin(), workspaces_.end(), [](const Json::Value& lhs, const Json::Value& rhs) { - return lhs["name"].asString() < rhs["name"].asString(); - }); + + if (workspaces_order_.empty()) { + workspaces_order_.reserve(workspaces_.size()); + for (const Json::Value& workspace : workspaces_) { + workspaces_order_.emplace_back(workspace["name"].asString()); + } + } else { + std::vector sorted_workspaces; + sorted_workspaces.reserve(workspaces_.size()); + auto ws_end = workspaces_.end(); + for (const std::string& name_by_order : workspaces_order_) { + auto it = std::find_if(workspaces_.begin(), ws_end, [&name_by_order](const Json::Value& ws) { + return ws["name"].asString() == name_by_order; + }); + if (it != ws_end) { + sorted_workspaces.emplace_back(*it); + --ws_end; + ws_end->swap(*it); + } + } + + for (int i = 0 ; workspaces_.size() > sorted_workspaces.size() ; ++i) { + workspaces_order_.emplace_back(workspaces_[i]["name"].asString()); + sorted_workspaces.emplace_back(workspaces_[i]); + } + workspaces_.swap(sorted_workspaces); + } dp.emit(); } From 8ba3052dd117b7c837ddba60de58cb9b2eaa97ad Mon Sep 17 00:00:00 2001 From: Lucas Lazare Date: Sat, 18 May 2019 12:04:09 -0400 Subject: [PATCH 3/8] Adding comments & fixing code style --- src/modules/sway/workspaces.cpp | 68 ++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 09950adc..055be22c 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -49,19 +49,22 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { }); // adding persistant workspaces (as per the config file) - const Json::Value& p_workspaces = config_["persistant_workspaces"]; + const Json::Value &p_workspaces = config_["persistant_workspaces"]; const std::vector p_workspaces_names = p_workspaces.getMemberNames(); - for (const std::string& p_w_name : p_workspaces_names) { - const Json::Value& p_w = p_workspaces[p_w_name]; - auto it = std::find_if(payload.begin(), payload.end(), [&p_w_name](const Json::Value& node) { - return node["name"].asString() == p_w_name; - }); + for (const std::string &p_w_name : p_workspaces_names) { + const Json::Value &p_w = p_workspaces[p_w_name]; + auto it = + std::find_if(payload.begin(), payload.end(), [&p_w_name](const Json::Value &node) { + return node["name"].asString() == p_w_name; + }); + if (it != payload.end()) { - continue; // already displayed by some bar + continue; // already displayed by some bar } if (p_w.isArray() && !p_w.empty()) { - for (const Json::Value& output : p_w) { + // Adding to target outputs + for (const Json::Value &output : p_w) { if (output.asString() == bar_.output->name) { Json::Value v; v["name"] = p_w_name; @@ -70,6 +73,7 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { } } } else { + // Adding to all outputs Json::Value v; v["name"] = p_w_name; workspaces_.emplace_back(std::move(v)); @@ -77,30 +81,34 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { } if (workspaces_order_.empty()) { - workspaces_order_.reserve(workspaces_.size()); - for (const Json::Value& workspace : workspaces_) { - workspaces_order_.emplace_back(workspace["name"].asString()); - } + // Saving starting order + workspaces_order_.reserve(workspaces_.size()); + for (const Json::Value &workspace : workspaces_) { + workspaces_order_.emplace_back(workspace["name"].asString()); + } } else { - std::vector sorted_workspaces; - sorted_workspaces.reserve(workspaces_.size()); - auto ws_end = workspaces_.end(); - for (const std::string& name_by_order : workspaces_order_) { - auto it = std::find_if(workspaces_.begin(), ws_end, [&name_by_order](const Json::Value& ws) { - return ws["name"].asString() == name_by_order; - }); - if (it != ws_end) { - sorted_workspaces.emplace_back(*it); - --ws_end; - ws_end->swap(*it); - } - } + // Ordering workspaces as it was before for current output + std::vector sorted_workspaces; + sorted_workspaces.reserve(workspaces_.size()); + auto ws_end = workspaces_.end(); + for (const std::string &name_by_order : workspaces_order_) { + auto it = + std::find_if(workspaces_.begin(), ws_end, [&name_by_order](const Json::Value &ws) { + return ws["name"].asString() == name_by_order; + }); + if (it != ws_end) { + sorted_workspaces.emplace_back(*it); + --ws_end; + ws_end->swap(*it); + } + } - for (int i = 0 ; workspaces_.size() > sorted_workspaces.size() ; ++i) { - workspaces_order_.emplace_back(workspaces_[i]["name"].asString()); - sorted_workspaces.emplace_back(workspaces_[i]); - } - workspaces_.swap(sorted_workspaces); + // Adding new workspaces to the output (those where never showed in this output before) + for (int i = 0; workspaces_.size() > sorted_workspaces.size(); ++i) { + workspaces_order_.emplace_back(workspaces_[i]["name"].asString()); + sorted_workspaces.emplace_back(workspaces_[i]); + } + workspaces_.swap(sorted_workspaces); } dp.emit(); From 863e0babd8316a4c1b88da1a0a1197ccaf8e6ec6 Mon Sep 17 00:00:00 2001 From: Lucas Lazare Date: Sat, 18 May 2019 12:09:30 -0400 Subject: [PATCH 4/8] Adding break when sorted_workspaces is filled --- src/modules/sway/workspaces.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 055be22c..6ec8fa87 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -99,6 +99,9 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { if (it != ws_end) { sorted_workspaces.emplace_back(*it); --ws_end; + if (ws_end == workspaces_.begin()) { // we've extracted everything + break; + } ws_end->swap(*it); } } From a00f812cd19afc7fcd042066ff64aae0d476e8ff Mon Sep 17 00:00:00 2001 From: Lucas Lazare Date: Sat, 18 May 2019 18:21:01 -0400 Subject: [PATCH 5/8] Typo --- src/modules/sway/workspaces.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 6ec8fa87..28310b0a 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -106,7 +106,7 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { } } - // Adding new workspaces to the output (those where never showed in this output before) + // Adding new workspaces to the output (those were never showed in this output before) for (int i = 0; workspaces_.size() > sorted_workspaces.size(); ++i) { workspaces_order_.emplace_back(workspaces_[i]["name"].asString()); sorted_workspaces.emplace_back(workspaces_[i]); From 7c4d75d428aaf70a80f12b4fa960710caa8cd4fc Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 20 May 2019 13:21:22 +0200 Subject: [PATCH 6/8] feat: create new workspace on the wanted output --- src/modules/sway/workspaces.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 28310b0a..37f17280 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -16,7 +16,7 @@ Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value ipc_.signal_cmd.connect(sigc::mem_fun(*this, &Workspaces::onCmd)); ipc_.sendCmd(IPC_GET_WORKSPACES); if (!config["disable-bar-scroll"].asBool()) { - auto &window = const_cast(bar_).window; + 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)); } @@ -49,11 +49,11 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { }); // adding persistant workspaces (as per the config file) - const Json::Value &p_workspaces = config_["persistant_workspaces"]; + const Json::Value & p_workspaces = config_["persistant_workspaces"]; const std::vector p_workspaces_names = p_workspaces.getMemberNames(); for (const std::string &p_w_name : p_workspaces_names) { const Json::Value &p_w = p_workspaces[p_w_name]; - auto it = + auto it = std::find_if(payload.begin(), payload.end(), [&p_w_name](const Json::Value &node) { return node["name"].asString() == p_w_name; }); @@ -68,6 +68,7 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { if (output.asString() == bar_.output->name) { Json::Value v; v["name"] = p_w_name; + v["target_output"] = bar_.output->name; workspaces_.emplace_back(std::move(v)); break; } @@ -99,7 +100,7 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { if (it != ws_end) { sorted_workspaces.emplace_back(*it); --ws_end; - if (ws_end == workspaces_.begin()) { // we've extracted everything + if (ws_end == workspaces_.begin()) { // we've extracted everything break; } ws_end->swap(*it); @@ -202,9 +203,18 @@ Gtk::Button &Workspaces::addButton(const Json::Value &node) { auto &button = pair.first->second; box_.pack_start(button, false, false, 0); button.set_relief(Gtk::RELIEF_NONE); - button.signal_clicked().connect([this, pair] { + button.signal_clicked().connect([this, node] { try { - ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", pair.first->first)); + if (node["target_output"].isString()) { + ipc_.sendCmd( + IPC_COMMAND, + fmt::format("workspace \"{}\"; move workspace to output \"{}\"; workspace \"{}\"", + node["name"].asString(), + node["target_output"].asString(), + node["name"].asString())); + } else { + ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"")); + } } catch (const std::exception &e) { std::cerr << e.what() << std::endl; } From 071b4928dcc0154a73cf156f0464c33db9b1ed99 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 20 May 2019 13:31:02 +0200 Subject: [PATCH 7/8] fix(workspaces): order --- src/modules/sway/workspaces.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 37f17280..81e62974 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -83,8 +83,8 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { if (workspaces_order_.empty()) { // Saving starting order - workspaces_order_.reserve(workspaces_.size()); - for (const Json::Value &workspace : workspaces_) { + workspaces_order_.reserve(payload.size()); + for (const Json::Value &workspace : payload) { workspaces_order_.emplace_back(workspace["name"].asString()); } } else { From 0ec8774a08d7c80fa6d64f6ffa5ac410182cc73b Mon Sep 17 00:00:00 2001 From: Lucas Lazare Date: Mon, 20 May 2019 08:23:42 -0400 Subject: [PATCH 8/8] Fixing: missing argument for fmt, workspace order Persistant workspaces would reorder upon their first creation --- src/modules/sway/workspaces.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 81e62974..08082ac9 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -51,6 +51,8 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { // adding persistant workspaces (as per the config file) const Json::Value & p_workspaces = config_["persistant_workspaces"]; const std::vector p_workspaces_names = p_workspaces.getMemberNames(); + + auto first_persistant_ws_idx = workspaces_.size(); for (const std::string &p_w_name : p_workspaces_names) { const Json::Value &p_w = p_workspaces[p_w_name]; auto it = @@ -83,10 +85,13 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { if (workspaces_order_.empty()) { // Saving starting order - workspaces_order_.reserve(payload.size()); + workspaces_order_.reserve(payload.size() + workspaces_.size() - first_persistant_ws_idx); for (const Json::Value &workspace : payload) { workspaces_order_.emplace_back(workspace["name"].asString()); } + for (auto i = first_persistant_ws_idx; i < workspaces_.size() ; ++i) { + workspaces_order_.emplace_back(workspaces_[i]["name"].asString()); + } } else { // Ordering workspaces as it was before for current output std::vector sorted_workspaces; @@ -213,7 +218,7 @@ Gtk::Button &Workspaces::addButton(const Json::Value &node) { node["target_output"].asString(), node["name"].asString())); } else { - ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"")); + ipc_.sendCmd(IPC_COMMAND, fmt::format("workspace \"{}\"", node["name"].asString())); } } catch (const std::exception &e) { std::cerr << e.what() << std::endl;