|
2 | 2 |
|
3 | 3 | #include <spdlog/spdlog.h>
|
4 | 4 |
|
| 5 | +#include <cctype> |
| 6 | +#include <string> |
| 7 | + |
5 | 8 | namespace waybar::modules::sway {
|
6 | 9 |
|
| 10 | +// Helper function to to assign a number to a workspace, just like sway. In fact |
| 11 | +// this is taken quite verbatim from `sway/ipc-json.c`. |
| 12 | +int Workspaces::convertWorkspaceNameToNum(std::string name) { |
| 13 | + if (isdigit(name[0])) { |
| 14 | + errno = 0; |
| 15 | + char * endptr = NULL; |
| 16 | + long long parsed_num = strtoll(name.c_str(), &endptr, 10); |
| 17 | + if (errno != 0 || parsed_num > INT32_MAX || parsed_num < 0 || endptr == name.c_str()) { |
| 18 | + return -1; |
| 19 | + } else { |
| 20 | + return (int)parsed_num; |
| 21 | + } |
| 22 | + } |
| 23 | + return -1; |
| 24 | +} |
| 25 | + |
7 | 26 | Workspaces::Workspaces(const std::string &id, const Bar &bar, const Json::Value &config)
|
8 | 27 | : AModule(config, "workspaces", id, false, !config["disable-scroll"].asBool()),
|
9 | 28 | bar_(bar),
|
@@ -102,13 +121,29 @@ void Workspaces::onCmd(const struct Ipc::ipc_response &res) {
|
102 | 121 | // the "num" property (integer type):
|
103 | 122 | // The workspace number or -1 for workspaces that do
|
104 | 123 | // not start with a number.
|
105 |
| - auto l = lhs["num"].asInt(); |
106 |
| - auto r = rhs["num"].asInt(); |
| 124 | + // We could rely on sway providing this property: |
| 125 | + // |
| 126 | + // auto l = lhs["num"].asInt(); |
| 127 | + // auto r = rhs["num"].asInt(); |
| 128 | + // |
| 129 | + // We cannot rely on the "num" property as provided by sway |
| 130 | + // via IPC, because persistent workspace might not exist in |
| 131 | + // sway's view. However, we need this property also for |
| 132 | + // not-yet created persistent workspace. As such, we simply |
| 133 | + // duplicate sway's logic of assigning the "num" property |
| 134 | + // into waybar (see convertWorkspaceNameToNum). This way the |
| 135 | + // sorting should work out even when we include workspaces |
| 136 | + // that do not currently exist. |
| 137 | + auto lname = lhs["name"].asString(); |
| 138 | + auto rname = rhs["name"].asString(); |
| 139 | + int l = convertWorkspaceNameToNum(lname); |
| 140 | + int r = convertWorkspaceNameToNum(rname); |
| 141 | + |
107 | 142 | if (l == r) {
|
108 | 143 | // in case both integers are the same, lexicographical
|
109 | 144 | // sort. This also covers the case when both don't have a
|
110 | 145 | // number (i.e., l == r == -1).
|
111 |
| - return lhs["name"].asString() < rhs["name"].asString(); |
| 146 | + return lname < rname; |
112 | 147 | }
|
113 | 148 |
|
114 | 149 | // one of the workspaces doesn't begin with a number, so
|
|
0 commit comments