module/dwl: allow specify the name of tags

This commit is contained in:
Leonardo Hernández Hernández 2023-01-16 19:53:21 -06:00
parent 134ae847dc
commit 5da51210de
No known key found for this signature in database
GPG key ID: E538897EE11B9624
3 changed files with 75 additions and 19 deletions

View file

@ -15,8 +15,10 @@
* Field width tag format option ([#246][246]) * Field width tag format option ([#246][246])
* river: support for layout events. * river: support for layout events.
* dwl: support for specifying name of tags ([#256][256])
[246]: https://codeberg.org/dnkl/yambar/issues/246 [246]: https://codeberg.org/dnkl/yambar/issues/246
[256]: https://codeberg.org/dnkl/yambar/pulls/256
### Changed ### Changed

View file

@ -7,7 +7,7 @@ dwl - This module provides information about dwl tags, and information.
This module provides a map of each tags present in dwl. This module provides a map of each tags present in dwl.
Each tags has its _id_, its status (_selected_, _empty_, _urgent_) Each tags has its _id_, its _name_, its status (_selected_, _empty_, _urgent_)
and the global data like _title_, _fullscreen_, _floating_, and the global data like _title_, _fullscreen_, _floating_,
_selmon_, and _layout_). The tags start a 1. For needs where _selmon_, and _layout_). The tags start a 1. For needs where
you only want information about the global data and not the _tags_, you only want information about the global data and not the _tags_,
@ -29,6 +29,9 @@ Running multiple instances at the same time may result in
| id | id
: int : int
: Dwl tag id. : Dwl tag id.
| name
: string
: The name of the tag (defaults to _id_ if not set).
| selected | selected
: bool : bool
: True if the tag is currently selected. : True if the tag is currently selected.
@ -64,6 +67,10 @@ Running multiple instances at the same time may result in
: int : int
: yes : yes
: The number of defined tags in the dwl `config.def.h`. : The number of defined tags in the dwl `config.def.h`.
| name-of-tags
: list
: false
: The name of the tags (must have the same length that _number-of-tags_).
| dwl-info-filename | dwl-info-filename
: string : string
: yes : yes
@ -77,16 +84,18 @@ bar:
- dwl: - dwl:
number-of-tags: 9 number-of-tags: 9
dwl-info-filename: "/home/ogromny/dwl_info" dwl-info-filename: "/home/ogromny/dwl_info"
name-of-tags: [ , , , , , , , ,  ]
content: content:
list: list:
items: items:
- map: - map:
conditions: conditions:
selected: {string: {text: "-> {id}"}}
~empty: {string: {text: "{id}"}}
urgent: {string: {text: "=> {id} <="}}
# default tag # default tag
id == 0: {string: {text: "{layout} {title}"}} id == 0: {string: {text: "{layout} {title}"}}
selected: {string: {text: "-> {name}"}}
~empty: {string: {text: "{name}"}}
urgent: {string: {text: "=> {name} <="}}
``` ```
# SEE ALSO # SEE ALSO

View file

@ -18,6 +18,7 @@
struct dwl_tag { struct dwl_tag {
int id; int id;
char *name;
bool selected; bool selected;
bool empty; bool empty;
bool urgent; bool urgent;
@ -51,13 +52,20 @@ enum LINE_MODE {
LINE_MODE_LAYOUT, LINE_MODE_LAYOUT,
}; };
static void
free_dwl_tag(struct dwl_tag *tag)
{
free(tag->name);
free(tag);
}
static void static void
destroy(struct module *module) destroy(struct module *module)
{ {
struct private *private = module->private; struct private *private = module->private;
private->label->destroy(private->label); private->label->destroy(private->label);
tll_free_and_free(private->tags, free); tll_free_and_free(private->tags, free_dwl_tag);
free(private->dwl_info_filename); free(private->dwl_info_filename);
free(private->title); free(private->title);
free(private->layout); free(private->layout);
@ -91,11 +99,12 @@ content(struct module *module)
tag_new_bool(module, "selmon", private->selmon), tag_new_bool(module, "selmon", private->selmon),
tag_new_string(module, "layout", private->layout), tag_new_string(module, "layout", private->layout),
tag_new_int(module, "id", it->item->id), tag_new_int(module, "id", it->item->id),
tag_new_string(module, "name", it->item->name),
tag_new_bool(module, "selected", it->item->selected), tag_new_bool(module, "selected", it->item->selected),
tag_new_bool(module, "empty", it->item->empty), tag_new_bool(module, "empty", it->item->empty),
tag_new_bool(module, "urgent", it->item->urgent), tag_new_bool(module, "urgent", it->item->urgent),
}, },
.count = 9, .count = 10,
}; };
exposable[i++] = private->label->instantiate(private->label, &tags); exposable[i++] = private->label->instantiate(private->label, &tags);
tag_set_destroy(&tags); tag_set_destroy(&tags);
@ -110,11 +119,12 @@ content(struct module *module)
tag_new_bool(module, "selmon", private->selmon), tag_new_bool(module, "selmon", private->selmon),
tag_new_string(module, "layout", private->layout), tag_new_string(module, "layout", private->layout),
tag_new_int(module, "id", 0), tag_new_int(module, "id", 0),
tag_new_string(module, "name", "0"),
tag_new_bool(module, "selected", false), tag_new_bool(module, "selected", false),
tag_new_bool(module, "empty", true), tag_new_bool(module, "empty", true),
tag_new_bool(module, "urgent", false), tag_new_bool(module, "urgent", false),
}, },
.count = 9, .count = 10,
}; };
exposable[i++] = private->label->instantiate(private->label, &tags); exposable[i++] = private->label->instantiate(private->label, &tags);
tag_set_destroy(&tags); tag_set_destroy(&tags);
@ -124,7 +134,7 @@ content(struct module *module)
} }
static struct dwl_tag * static struct dwl_tag *
dwl_tag_find_or_create(struct private *private, uint32_t id) dwl_tag_from_id(struct private *private, uint32_t id)
{ {
tll_foreach(private->tags, it) tll_foreach(private->tags, it)
{ {
@ -132,11 +142,8 @@ dwl_tag_find_or_create(struct private *private, uint32_t id)
return it->item; return it->item;
} }
/* No need to order the tag, `print_status` from dwl already orders tags */ assert(false); /* unreachable */
struct dwl_tag *dwl_tag = calloc(1, sizeof(struct dwl_tag)); return NULL;
dwl_tag->id = id;
tll_push_back(private->tags, dwl_tag);
return dwl_tag;
} }
static void static void
@ -219,7 +226,7 @@ process_line(char *line, struct module *module)
for (size_t id = 1; id <= private->number_of_tags; ++id) { for (size_t id = 1; id <= private->number_of_tags; ++id) {
uint32_t mask = 1 << (id - 1); uint32_t mask = 1 << (id - 1);
struct dwl_tag *dwl_tag = dwl_tag_find_or_create(private, id); struct dwl_tag *dwl_tag = dwl_tag_from_id(private, id);
dwl_tag->selected = mask & selected; dwl_tag->selected = mask & selected;
dwl_tag->empty = !(mask & occupied); dwl_tag->empty = !(mask & occupied);
dwl_tag->urgent = mask & urgent; dwl_tag->urgent = mask & urgent;
@ -420,13 +427,30 @@ run(struct module *module)
} }
static struct module * static struct module *
dwl_new(struct particle *label, int number_of_tags, char const *dwl_info_filename) dwl_new(struct particle *label, int number_of_tags,
struct yml_node const *name_of_tags, char const *dwl_info_filename)
{ {
struct private *private = calloc(1, sizeof(struct private)); struct private *private = calloc(1, sizeof(struct private));
private->label = label; private->label = label;
private->number_of_tags = number_of_tags; private->number_of_tags = number_of_tags;
private->dwl_info_filename = strdup(dwl_info_filename); private->dwl_info_filename = strdup(dwl_info_filename);
struct yml_list_iter list = {0};
if (name_of_tags)
list = yml_list_iter(name_of_tags);
for (int i = 1; i <= number_of_tags; i++) {
struct dwl_tag *dwl_tag = calloc(1, sizeof(struct dwl_tag));
dwl_tag->id = i;
if (list.node) {
dwl_tag->name = strdup(yml_value_as_string(list.node));
yml_list_next(&list);
} else if (asprintf(&dwl_tag->name, "%d", i) < 0) {
LOG_ERRNO("asprintf");
}
tll_push_back(private->tags, dwl_tag);
}
struct module *module = module_common_new(); struct module *module = module_common_new();
module->private = private; module->private = private;
module->run = &run; module->run = &run;
@ -442,10 +466,21 @@ from_conf(struct yml_node const *node, struct conf_inherit inherited)
{ {
struct yml_node const *content = yml_get_value(node, "content"); struct yml_node const *content = yml_get_value(node, "content");
struct yml_node const *number_of_tags = yml_get_value(node, "number-of-tags"); struct yml_node const *number_of_tags = yml_get_value(node, "number-of-tags");
struct yml_node const *name_of_tags = yml_get_value(node, "name-of-tags");
struct yml_node const *dwl_info_filename = yml_get_value(node, "dwl-info-filename"); struct yml_node const *dwl_info_filename = yml_get_value(node, "dwl-info-filename");
return dwl_new(conf_to_particle(content, inherited), yml_value_as_int(number_of_tags), return dwl_new(conf_to_particle(content, inherited), yml_value_as_int(number_of_tags),
yml_value_as_string(dwl_info_filename)); name_of_tags, yml_value_as_string(dwl_info_filename));
}
static bool
verify_names(keychain_t *keychain, const struct yml_node *node)
{
if (!yml_is_list(node)) {
LOG_ERR("%s: %s is not a list", conf_err_prefix(keychain, node), yml_value_as_string(node));
return false;
}
return conf_verify_list(keychain, node, &conf_verify_string);
} }
static bool static bool
@ -454,6 +489,7 @@ verify_conf(keychain_t *keychain, struct yml_node const *node)
static struct attr_info const attrs[] = { static struct attr_info const attrs[] = {
{"number-of-tags", true, &conf_verify_unsigned}, {"number-of-tags", true, &conf_verify_unsigned},
{"name-of-tags", false, &verify_names},
{"dwl-info-filename", true, &conf_verify_string}, {"dwl-info-filename", true, &conf_verify_string},
MODULE_COMMON_ATTRS, MODULE_COMMON_ATTRS,
}; };
@ -463,10 +499,19 @@ verify_conf(keychain_t *keychain, struct yml_node const *node)
/* No need to check whether is `number_of_tags` is a int /* No need to check whether is `number_of_tags` is a int
* because `conf_verify_unsigned` already did it */ * because `conf_verify_unsigned` already did it */
struct yml_node const *key = yml_get_key(node, "number-of-tags"); struct yml_node const *ntags_key = yml_get_key(node, "number-of-tags");
struct yml_node const *value = yml_get_value(node, "number-of-tags"); struct yml_node const *value = yml_get_value(node, "number-of-tags");
if (yml_value_as_int(value) == 0) { int number_of_tags = yml_value_as_int(value);
LOG_ERR("%s: %s must not be 0", conf_err_prefix(keychain, key), yml_value_as_string(key)); if (number_of_tags == 0) {
LOG_ERR("%s: %s must not be 0", conf_err_prefix(keychain, ntags_key), yml_value_as_string(ntags_key));
return false;
}
struct yml_node const *key = yml_get_key(node, "name-of-tags");
value = yml_get_value(node, "name-of-tags");
if (value && yml_list_length(value) != number_of_tags) {
LOG_ERR("%s: %s must have the same number of elements that %s", conf_err_prefix(keychain, key),
yml_value_as_string(key), yml_value_as_string(ntags_key));
return false; return false;
} }