From a2cf05a64d00b14c0d5fbe001d6cb82aca59df81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 11 Feb 2022 21:44:43 +0100 Subject: [PATCH 1/2] =?UTF-8?q?module/i3:=20add=20=E2=80=98strip-workspace?= =?UTF-8?q?-numbers=E2=80=99=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a boolean option. When set, “N:” prefixes will be stripped from the workspaces’ name tag, *after* having been sorted (if the ‘sort’ option is being used). This makes it useful to arrange the workspaces in a fixed order, by prefixing the names with a number in the Sway config: set $ws1 “1:xyz” set $ws2 “2:abc” Then, in the yambar config: i3: sort: ascending strip-workspace-numbers: true --- CHANGELOG.md | 1 + doc/yambar-modules-i3.5.scd | 4 ++++ modules/i3.c | 34 +++++++++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f8113d..18ea8b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ (https://codeberg.org/dnkl/yambar/issues/153). * overline: new decoration (https://codeberg.org/dnkl/yambar/issues/153). +* i3/sway: boolean option `strip-workspace-numbers`. ### Changed diff --git a/doc/yambar-modules-i3.5.scd b/doc/yambar-modules-i3.5.scd index 2cae2f8..b2ba394 100644 --- a/doc/yambar-modules-i3.5.scd +++ b/doc/yambar-modules-i3.5.scd @@ -68,6 +68,10 @@ with the _application_ and _title_ tags to replace the X11-only : enum : no : How to sort the list of workspaces; one of _none_, _ascending_ or _descending_, defaults to _none_. +| strip-workspace-numbers +: bool +: no +: If true, *N:* prefixes will be stripped from workspace names. Useful together with *sort*, to have the workspace order fixed. | persistent : list of strings : no diff --git a/modules/i3.c b/modules/i3.c index 56dec4d..fcd9395 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -60,6 +60,7 @@ struct private { size_t count; } ws_content; + bool strip_workspace_numbers; enum sort_mode sort_mode; tll(struct workspace) workspaces; @@ -107,10 +108,11 @@ workspace_from_json(const struct json_object *json, struct workspace *ws) const size_t node_count = json_object_array_length(focus); const bool is_empty = node_count == 0; + int name_as_int = workspace_name_as_int(name_as_string); *ws = (struct workspace) { .name = strdup(name_as_string), - .name_as_int = workspace_name_as_int(name_as_string), + .name_as_int = name_as_int, .persistent = false, .output = strdup(json_object_get_string(output)), .visible = json_object_get_boolean(visible), @@ -615,9 +617,16 @@ run(struct module *mod) for (size_t i = 0; i < m->persistent_count; i++) { const char *name_as_string = m->persistent_workspaces[i]; + int name_as_int = workspace_name_as_int(name_as_string); + if (m->strip_workspace_numbers) { + const char *colon = strchr(name_as_string, ':'); + if (colon != NULL) + name_as_string = colon++; + } + struct workspace ws = { .name = strdup(name_as_string), - .name_as_int = workspace_name_as_int(name_as_string), + .name_as_int = name_as_int, .persistent = true, .empty = true, }; @@ -725,9 +734,17 @@ content(struct module *mod) ws->window.title, m->mode); + const char *name = ws->name; + + if (m->strip_workspace_numbers) { + const char *colon = strchr(name, ':'); + if (colon != NULL) + name = colon + 1; + } + struct tag_set tags = { .tags = (struct tag *[]){ - tag_new_string(mod, "name", ws->name), + tag_new_string(mod, "name", name), tag_new_bool(mod, "visible", ws->visible), tag_new_bool(mod, "focused", ws->focused), tag_new_bool(mod, "urgent", ws->urgent), @@ -778,7 +795,8 @@ static struct module * i3_new(struct i3_workspaces workspaces[], size_t workspace_count, int left_spacing, int right_spacing, enum sort_mode sort_mode, size_t persistent_count, - const char *persistent_workspaces[static persistent_count]) + const char *persistent_workspaces[static persistent_count], + bool strip_workspace_numbers) { struct private *m = calloc(1, sizeof(*m)); @@ -794,6 +812,7 @@ i3_new(struct i3_workspaces workspaces[], size_t workspace_count, m->ws_content.v[i].content = workspaces[i].content; } + m->strip_workspace_numbers = strip_workspace_numbers; m->sort_mode = sort_mode; m->persistent_count = persistent_count; @@ -821,6 +840,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) const struct yml_node *right_spacing = yml_get_value(node, "right-spacing"); const struct yml_node *sort = yml_get_value(node, "sort"); const struct yml_node *persistent = yml_get_value(node, "persistent"); + const struct yml_node *strip_workspace_number = yml_get_value( + node, "strip-workspace-numbers"); int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0; @@ -859,7 +880,9 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) } return i3_new(workspaces, yml_dict_length(c), left, right, sort_mode, - persistent_count, persistent_workspaces); + persistent_count, persistent_workspaces, + (strip_workspace_number != NULL + ? yml_value_as_bool(strip_workspace_number) : false)); } static bool @@ -914,6 +937,7 @@ verify_conf(keychain_t *chain, const struct yml_node *node) {"right-spacing", false, &conf_verify_unsigned}, {"sort", false, &verify_sort}, {"persistent", false, &verify_persistent}, + {"strip-workspace-numbers", false, &conf_verify_bool}, {"content", true, &verify_content}, {"anchors", false, NULL}, {NULL, false, NULL}, From ca407cd1669e6c871a25c86db92ea8e121fda46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 14 Feb 2022 18:33:14 +0100 Subject: [PATCH 2/2] module/i3: treat workspaces on the form N:name as numerical --- modules/i3.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/i3.c b/modules/i3.c index fcd9395..bb51794 100644 --- a/modules/i3.c +++ b/modules/i3.c @@ -72,6 +72,22 @@ static int workspace_name_as_int(const char *name) { int name_as_int = 0; + + /* First check for N:name pattern (set $ws1 “1:foobar”) */ + const char *colon = strchr(name, ':'); + if (colon != NULL) { + for (const char *p = name; p < colon; p++) { + if (!(*p >= '0' && *p < '9')) + return -1; + + name_as_int *= 10; + name_as_int += *p - '0'; + } + + return name_as_int; + } + + /* Then, if the name is a number *only* (set $ws1 1) */ for (const char *p = name; *p != '\0'; p++) { if (!(*p >= '0' && *p <= '9')) return -1;