Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make waybar itself assign numbers to workspaces like sway #783

Merged
merged 2 commits into from
Jul 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/modules/sway/workspaces.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
41 changes: 38 additions & 3 deletions src/modules/sway/workspaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,27 @@

#include <spdlog/spdlog.h>

#include <cctype>
#include <string>

namespace waybar::modules::sway {

// 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;
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),
Expand Down Expand Up @@ -102,13 +121,29 @@ 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 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();
int l = convertWorkspaceNameToNum(lname);
int r = convertWorkspaceNameToNum(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
Expand Down