From 15fe73a2520e1ca84fbf5fd783cfe0c4bfebe79c Mon Sep 17 00:00:00 2001 From: Michael Rodler Date: Wed, 22 Jul 2020 16:13:24 +0200 Subject: [PATCH 1/2] duplicate the logic to assign numbers to workspaces from sway into waybar to handle perisstent workspaces --- src/modules/sway/workspaces.cpp | 39 ++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index 5f7c3f61..fd2ad43d 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -1,9 +1,28 @@ #include "modules/sway/workspaces.hpp" +#include +#include #include + namespace waybar::modules::sway { +// this is the code that sway uses to assign a number to a workspace. This is +// taken quite verbatim from `sway/ipc-json.c`. +int sway_wsname_to_num(std::string name) { + if (isdigit(name[0])) { + errno = 0; + char * endptr = NULL; + long long parsed_num = strtoll(name.c_str(), &endptr, 10); + if (errno != 0 || parsed_num > INT32_MAX || parsed_num < 0 || endptr == name.c_str()) { + return -1; + } else { + return (int)parsed_num; + } + } + return -1; +} + Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config) : AModule(config, "workspaces", id, false, !config["disable-scroll"].asBool()), bar_(bar), @@ -102,13 +121,27 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { // the "num" property (integer type): // The workspace number or -1 for workspaces that do // not start with a number. - auto l = lhs["num"].asInt(); - auto r = rhs["num"].asInt(); + //auto l = lhs["num"].asInt(); + //auto r = rhs["num"].asInt(); + + // We cannot rely on the "num" property as provided by sway + // via IPC, because persistent workspace might not exist in + // sway's view. However, we need this property also for + // not-yet created persistent workspace. As such, we simply + // duplicate sway's logic of assigning the "num" property + // into waybar (see sway_wsname_to_num). This way the + // sorting should work out even when we include workspaces + // that do not currently exist. + auto lname = lhs["name"].asString(); + auto rname = rhs["name"].asString(); + auto l = sway_wsname_to_num(lname); + auto r = sway_wsname_to_num(rname); + if (l == r) { // in case both integers are the same, lexicographical // sort. This also covers the case when both don't have a // number (i.e., l == r == -1). - return lhs["name"].asString() < rhs["name"].asString(); + return lname < rname; } // one of the workspaces doesn't begin with a number, so From 006850ea5e77419fb857a791d23040bc29d8b182 Mon Sep 17 00:00:00 2001 From: Michael Rodler Date: Mon, 27 Jul 2020 10:56:49 +0200 Subject: [PATCH 2/2] Changed helper function for workspace->num assignment to a static method of Workspaces class and adapted comments/method name to be consistent with the rest --- include/modules/sway/workspaces.hpp | 2 ++ src/modules/sway/workspaces.cpp | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/modules/sway/workspaces.hpp b/include/modules/sway/workspaces.hpp index 228c71c7..92ec0516 100644 --- a/include/modules/sway/workspaces.hpp +++ b/include/modules/sway/workspaces.hpp @@ -22,6 +22,8 @@ class Workspaces : public AModule, public sigc::trackable { private: static inline const std::string workspace_switch_cmd_ = "workspace --no-auto-back-and-forth \"{}\""; + static int convertWorkspaceNameToNum(std::string name); + void onCmd(const struct Ipc::ipc_response&); void onEvent(const struct Ipc::ipc_response&); bool filterButtons(); diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index fd2ad43d..fc6d5eb8 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -1,15 +1,15 @@ #include "modules/sway/workspaces.hpp" -#include -#include #include +#include +#include namespace waybar::modules::sway { -// this is the code that sway uses to assign a number to a workspace. This is -// taken quite verbatim from `sway/ipc-json.c`. -int sway_wsname_to_num(std::string name) { +// Helper function to to assign a number to a workspace, just like sway. In fact +// this is taken quite verbatim from `sway/ipc-json.c`. +int Workspaces::convertWorkspaceNameToNum(std::string name) { if (isdigit(name[0])) { errno = 0; char * endptr = NULL; @@ -121,21 +121,23 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) { // the "num" property (integer type): // The workspace number or -1 for workspaces that do // not start with a number. - //auto l = lhs["num"].asInt(); - //auto r = rhs["num"].asInt(); - + // We could rely on sway providing this property: + // + // auto l = lhs["num"].asInt(); + // auto r = rhs["num"].asInt(); + // // We cannot rely on the "num" property as provided by sway // via IPC, because persistent workspace might not exist in // sway's view. However, we need this property also for // not-yet created persistent workspace. As such, we simply // duplicate sway's logic of assigning the "num" property - // into waybar (see sway_wsname_to_num). This way the + // into waybar (see convertWorkspaceNameToNum). This way the // sorting should work out even when we include workspaces // that do not currently exist. auto lname = lhs["name"].asString(); auto rname = rhs["name"].asString(); - auto l = sway_wsname_to_num(lname); - auto r = sway_wsname_to_num(rname); + int l = convertWorkspaceNameToNum(lname); + int r = convertWorkspaceNameToNum(rname); if (l == r) { // in case both integers are the same, lexicographical