From 6fe764540c431657b37b575cf3ac103cf369d315 Mon Sep 17 00:00:00 2001 From: Michael Rodler Date: Tue, 5 May 2020 09:08:05 +0200 Subject: [PATCH] sway/workspaces: sort by the "num" property provided by sway, configurable whether numeric workspace names come first Sway provides the workspace "num" property which is an integer number of the workspace, i.e., workspace "3" -> 3 and also "3dev" -> "3". This commit uses this property to sort the workspaces, which makes sense when persistent workspaces or all-output is specified. This commit also adds a new configuration option, whether the numeric workspaces come in front or after workspaces that have non-numeric name. --- man/waybar-sway-workspaces.5.scd | 5 ++++ src/modules/sway/workspaces.cpp | 44 ++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/man/waybar-sway-workspaces.5.scd b/man/waybar-sway-workspaces.5.scd index 9c9c214..56b703a 100644 --- a/man/waybar-sway-workspaces.5.scd +++ b/man/waybar-sway-workspaces.5.scd @@ -64,6 +64,10 @@ Addressed by *sway/workspaces* typeof: string ++ Command to execute when the module is updated. +*numeric-first*: ++ + typeof: bool ++ + Whether to put workspaces starting with numbers before workspaces that do not start with a number. + # FORMAT REPLACEMENTS *{value}*: Name of the workspace, as defined by sway. @@ -107,6 +111,7 @@ n.b.: the list of outputs can be obtained from command line using *swaymsg -t ge "sway/workspaces": { "disable-scroll": true, "all-outputs": true, + "numeric-first": false, "format": "{name}: {icon}", "format-icons": { "1": "", diff --git a/src/modules/sway/workspaces.cpp b/src/modules/sway/workspaces.cpp index bd003cb..60d9887 100644 --- a/src/modules/sway/workspaces.cpp +++ b/src/modules/sway/workspaces.cpp @@ -1,4 +1,5 @@ #include "modules/sway/workspaces.hpp" + #include namespace waybar::modules::sway { @@ -90,16 +91,38 @@ 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) { - if (lhs["name"].isInt() && rhs["name"].isInt()) { - return lhs["name"].asInt() < rhs["name"].asInt(); - } - return lhs["name"].asString() < rhs["name"].asString(); - }); } + + // config option to sort numeric workspace names before others + bool config_numeric_first = config_["numeric-first"].asBool(); + + std::sort(workspaces_.begin(), + workspaces_.end(), + [config_numeric_first](const Json::Value &lhs, const Json::Value &rhs) { + // 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(); + 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(); + } + + // one of the workspaces doesn't begin with a number, so + // num is -1. + if (l < 0 || r < 0) { + if (config_numeric_first) { + return r < 0; + } + return l < 0; + } + + // both workspaces have a "num" so let's just compare those + return l < r; + }); } dp.emit(); } catch (const std::exception &e) { @@ -217,7 +240,8 @@ std::string Workspaces::getIcon(const std::string &name, const Json::Value &node if (config_["format-icons"][key].isString() && node[key].asBool()) { return config_["format-icons"][key].asString(); } - } else if (config_["format_icons"]["persistent"].isString() && node["target_output"].isString()) { + } else if (config_["format_icons"]["persistent"].isString() && + node["target_output"].isString()) { return config_["format-icons"]["persistent"].asString(); } else if (config_["format-icons"][key].isString()) { return config_["format-icons"][key].asString();