mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-20 03:35:41 +02:00
particle: on-click: tilde expansion
We now do tilde expansion of the *first* argument in on-click handlers. That is: ~/bin/foobar.sh ~/arg1 is expanded to $HOME/bin/foobar.sh ~/arg1 (meaning, the handler will most likely *not* do what you’d expect) Related to #307
This commit is contained in:
parent
f948b9f8f9
commit
d6e7710a7e
6 changed files with 77 additions and 21 deletions
|
@ -19,10 +19,12 @@
|
||||||
* i3/sway: extend option `sort`; use `native` to sort numbered workspaces only.
|
* i3/sway: extend option `sort`; use `native` to sort numbered workspaces only.
|
||||||
* modules/dwl: handle the appid status ([#284][284])
|
* modules/dwl: handle the appid status ([#284][284])
|
||||||
* battery: also show estimation for time to full ([#303][303]).
|
* battery: also show estimation for time to full ([#303][303]).
|
||||||
|
* on-click: tilde expansion ([#307][307])
|
||||||
|
|
||||||
[246]: https://codeberg.org/dnkl/yambar/issues/246
|
[246]: https://codeberg.org/dnkl/yambar/issues/246
|
||||||
[256]: https://codeberg.org/dnkl/yambar/pulls/256
|
[256]: https://codeberg.org/dnkl/yambar/pulls/256
|
||||||
[284]: https://codeberg.org/dnkl/yambar/pulls/284
|
[284]: https://codeberg.org/dnkl/yambar/pulls/284
|
||||||
|
[307]: https://codeberg.org/dnkl/yambar/issues/307
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -174,22 +174,47 @@ conf_verify_dict(keychain_t *chain, const struct yml_node *node,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
verify_on_click_path(keychain_t *chain, const struct yml_node *node)
|
||||||
|
{
|
||||||
|
if (!conf_verify_string(chain, node))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* We allow non-absolute paths in on-click handlers */
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
const char *path = yml_value_as_string(node);
|
||||||
|
|
||||||
|
const bool is_absolute = path[0] == '/';
|
||||||
|
const bool is_tilde = path[0] == '~' && path[1] == '/';
|
||||||
|
|
||||||
|
if (!is_absolute && !is_tilde) {
|
||||||
|
LOG_ERR("%s: path must be either absolute, or begin with '~/",
|
||||||
|
conf_err_prefix(chain, node));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
conf_verify_on_click(keychain_t *chain, const struct yml_node *node)
|
conf_verify_on_click(keychain_t *chain, const struct yml_node *node)
|
||||||
{
|
{
|
||||||
/* on-click: <command> */
|
/* on-click: <command> */
|
||||||
const char *s = yml_value_as_string(node);
|
const char *s = yml_value_as_string(node);
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
return true;
|
return verify_on_click_path(chain, node);
|
||||||
|
|
||||||
static const struct attr_info info[] = {
|
static const struct attr_info info[] = {
|
||||||
{"left", false, &conf_verify_string},
|
{"left", false, &verify_on_click_path},
|
||||||
{"middle", false, &conf_verify_string},
|
{"middle", false, &verify_on_click_path},
|
||||||
{"right", false, &conf_verify_string},
|
{"right", false, &verify_on_click_path},
|
||||||
{"wheel-up", false, &conf_verify_string},
|
{"wheel-up", false, &verify_on_click_path},
|
||||||
{"wheel-down", false, &conf_verify_string},
|
{"wheel-down", false, &verify_on_click_path},
|
||||||
{"previous", false, &conf_verify_string},
|
{"previous", false, &verify_on_click_path},
|
||||||
{"next", false, &conf_verify_string},
|
{"next", false, &verify_on_click_path},
|
||||||
{NULL, false, NULL},
|
{NULL, false, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -306,7 +331,8 @@ conf_verify_particle_dictionary(keychain_t *chain, const struct yml_node *node)
|
||||||
|
|
||||||
const char *particle_name = yml_value_as_string(particle);
|
const char *particle_name = yml_value_as_string(particle);
|
||||||
if (particle_name == NULL) {
|
if (particle_name == NULL) {
|
||||||
LOG_ERR("%s: particle name must be a string", conf_err_prefix(chain, particle));
|
LOG_ERR("%s: particle name must be a string",
|
||||||
|
conf_err_prefix(chain, particle));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
37
config.c
37
config.c
|
@ -211,20 +211,47 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited)
|
||||||
int right = margin != NULL ? yml_value_as_int(margin) :
|
int right = margin != NULL ? yml_value_as_int(margin) :
|
||||||
right_margin != NULL ? yml_value_as_int(right_margin) : 0;
|
right_margin != NULL ? yml_value_as_int(right_margin) : 0;
|
||||||
|
|
||||||
const char *on_click_templates[MOUSE_BTN_COUNT] = {NULL};
|
char *on_click_templates[MOUSE_BTN_COUNT] = {NULL};
|
||||||
if (on_click != NULL) {
|
if (on_click != NULL) {
|
||||||
const char *legacy = yml_value_as_string(on_click);
|
const char *yml_legacy = yml_value_as_string(on_click);
|
||||||
|
|
||||||
|
if (yml_legacy != NULL) {
|
||||||
|
char *legacy = NULL;
|
||||||
|
|
||||||
|
if (yml_legacy[0] == '~' && yml_legacy[1] == '/') {
|
||||||
|
const char *home_dir = getenv("HOME");
|
||||||
|
|
||||||
|
if (home_dir != NULL)
|
||||||
|
asprintf(&legacy, "%s/%s", home_dir, yml_legacy + 2);
|
||||||
|
|
||||||
|
if (legacy == NULL)
|
||||||
|
legacy = strdup(yml_legacy);
|
||||||
|
} else
|
||||||
|
legacy = strdup(yml_legacy);
|
||||||
|
|
||||||
if (legacy != NULL)
|
|
||||||
on_click_templates[MOUSE_BTN_LEFT] = legacy;
|
on_click_templates[MOUSE_BTN_LEFT] = legacy;
|
||||||
|
}
|
||||||
|
|
||||||
if (yml_is_dict(on_click)) {
|
else if (yml_is_dict(on_click)) {
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(on_click);
|
for (struct yml_dict_iter it = yml_dict_iter(on_click);
|
||||||
it.key != NULL;
|
it.key != NULL;
|
||||||
yml_dict_next(&it))
|
yml_dict_next(&it))
|
||||||
{
|
{
|
||||||
const char *key = yml_value_as_string(it.key);
|
const char *key = yml_value_as_string(it.key);
|
||||||
const char *template = yml_value_as_string(it.value);
|
const char *yml_template = yml_value_as_string(it.value);
|
||||||
|
|
||||||
|
char *template = NULL;
|
||||||
|
|
||||||
|
if (yml_template[0] == '~' && yml_template[1] == '/') {
|
||||||
|
const char *home_dir = getenv("HOME");
|
||||||
|
|
||||||
|
if (home_dir != NULL)
|
||||||
|
asprintf(&template, "%s/%s", home_dir, yml_template + 2);
|
||||||
|
|
||||||
|
if (template == NULL)
|
||||||
|
template = strdup(yml_template);
|
||||||
|
} else
|
||||||
|
template = strdup(yml_template);
|
||||||
|
|
||||||
if (strcmp(key, "left") == 0)
|
if (strcmp(key, "left") == 0)
|
||||||
on_click_templates[MOUSE_BTN_LEFT] = template;
|
on_click_templates[MOUSE_BTN_LEFT] = template;
|
||||||
|
|
|
@ -44,10 +44,11 @@ following attributes are supported by all particles:
|
||||||
| on-click
|
| on-click
|
||||||
: associative array/string
|
: associative array/string
|
||||||
: no
|
: no
|
||||||
: When set to a string, executes the string as a command when the particle
|
: When set to a string, executes the string as a command when the
|
||||||
is left-clicked. Tags can be used. Note that the string is *not*
|
particle is left-clicked. Tags can be used. Note that the string is
|
||||||
executed in a shell. The same applies to all attributes associated with
|
*not* executed in a shell. Environment variables are not expanded.
|
||||||
it, below.
|
*~/* is expanded, but only in the first argument. The same applies
|
||||||
|
to all attributes associated with it, below.
|
||||||
| on-click.left
|
| on-click.left
|
||||||
: string
|
: string
|
||||||
: no
|
: no
|
||||||
|
|
|
@ -30,7 +30,7 @@ particle_default_destroy(struct particle *particle)
|
||||||
|
|
||||||
struct particle *
|
struct particle *
|
||||||
particle_common_new(int left_margin, int right_margin,
|
particle_common_new(int left_margin, int right_margin,
|
||||||
const char **on_click_templates,
|
char **on_click_templates,
|
||||||
struct fcft_font *font, enum font_shaping font_shaping,
|
struct fcft_font *font, enum font_shaping font_shaping,
|
||||||
pixman_color_t foreground, struct deco *deco)
|
pixman_color_t foreground, struct deco *deco)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ particle_common_new(int left_margin, int right_margin,
|
||||||
for (size_t i = 0; i < MOUSE_BTN_COUNT; i++) {
|
for (size_t i = 0; i < MOUSE_BTN_COUNT; i++) {
|
||||||
if (on_click_templates[i] != NULL) {
|
if (on_click_templates[i] != NULL) {
|
||||||
p->have_on_click_template = true;
|
p->have_on_click_template = true;
|
||||||
p->on_click_templates[i] = strdup(on_click_templates[i]);
|
p->on_click_templates[i] = on_click_templates[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ struct exposable {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct particle *particle_common_new(
|
struct particle *particle_common_new(
|
||||||
int left_margin, int right_margin, const char *on_click_templates[],
|
int left_margin, int right_margin, char *on_click_templates[],
|
||||||
struct fcft_font *font, enum font_shaping font_shaping,
|
struct fcft_font *font, enum font_shaping font_shaping,
|
||||||
pixman_color_t foreground, struct deco *deco);
|
pixman_color_t foreground, struct deco *deco);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue