forked from external/yambar
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.
|
||||
* modules/dwl: handle the appid status ([#284][284])
|
||||
* battery: also show estimation for time to full ([#303][303]).
|
||||
* on-click: tilde expansion ([#307][307])
|
||||
|
||||
[246]: https://codeberg.org/dnkl/yambar/issues/246
|
||||
[256]: https://codeberg.org/dnkl/yambar/pulls/256
|
||||
[284]: https://codeberg.org/dnkl/yambar/pulls/284
|
||||
[307]: https://codeberg.org/dnkl/yambar/issues/307
|
||||
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -174,22 +174,47 @@ conf_verify_dict(keychain_t *chain, const struct yml_node *node,
|
|||
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
|
||||
conf_verify_on_click(keychain_t *chain, const struct yml_node *node)
|
||||
{
|
||||
/* on-click: <command> */
|
||||
const char *s = yml_value_as_string(node);
|
||||
if (s != NULL)
|
||||
return true;
|
||||
return verify_on_click_path(chain, node);
|
||||
|
||||
static const struct attr_info info[] = {
|
||||
{"left", false, &conf_verify_string},
|
||||
{"middle", false, &conf_verify_string},
|
||||
{"right", false, &conf_verify_string},
|
||||
{"wheel-up", false, &conf_verify_string},
|
||||
{"wheel-down", false, &conf_verify_string},
|
||||
{"previous", false, &conf_verify_string},
|
||||
{"next", false, &conf_verify_string},
|
||||
{"left", false, &verify_on_click_path},
|
||||
{"middle", false, &verify_on_click_path},
|
||||
{"right", false, &verify_on_click_path},
|
||||
{"wheel-up", false, &verify_on_click_path},
|
||||
{"wheel-down", false, &verify_on_click_path},
|
||||
{"previous", false, &verify_on_click_path},
|
||||
{"next", false, &verify_on_click_path},
|
||||
{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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
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) :
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (yml_is_dict(on_click)) {
|
||||
else if (yml_is_dict(on_click)) {
|
||||
for (struct yml_dict_iter it = yml_dict_iter(on_click);
|
||||
it.key != NULL;
|
||||
yml_dict_next(&it))
|
||||
{
|
||||
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)
|
||||
on_click_templates[MOUSE_BTN_LEFT] = template;
|
||||
|
|
|
@ -44,10 +44,11 @@ following attributes are supported by all particles:
|
|||
| on-click
|
||||
: associative array/string
|
||||
: no
|
||||
: When set to a string, executes the string as a command when the particle
|
||||
is left-clicked. Tags can be used. Note that the string is *not*
|
||||
executed in a shell. The same applies to all attributes associated with
|
||||
it, below.
|
||||
: When set to a string, executes the string as a command when the
|
||||
particle is left-clicked. Tags can be used. Note that the string is
|
||||
*not* executed in a shell. Environment variables are not expanded.
|
||||
*~/* is expanded, but only in the first argument. The same applies
|
||||
to all attributes associated with it, below.
|
||||
| on-click.left
|
||||
: string
|
||||
: no
|
||||
|
|
|
@ -30,7 +30,7 @@ particle_default_destroy(struct particle *particle)
|
|||
|
||||
struct particle *
|
||||
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,
|
||||
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++) {
|
||||
if (on_click_templates[i] != NULL) {
|
||||
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(
|
||||
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,
|
||||
pixman_color_t foreground, struct deco *deco);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue