config: add support for pipe-* actions in mouse bindings

Closes #183
This commit is contained in:
Daniel Eklöf 2020-11-06 19:29:23 +01:00
parent 398f0b699a
commit 9ce79e2ef0
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 65 additions and 6 deletions

View file

@ -77,6 +77,10 @@
window (https://codeberg.org/dnkl/foot/issues/179).
* Character dropped from selection when "right-click-hold"-extending a
selection (https://codeberg.org/dnkl/foot/issues/180).
* Support for **pipe-\*** actions in mouse bindings. It was previously
not possible to add a command to these actions when used in mouse
bindings, making them useless
(https://codeberg.org/dnkl/foot/issues/183).
### Security

View file

@ -1470,8 +1470,13 @@ has_mouse_binding_collisions(struct config *conf, const key_combo_list_t *key_co
bool count = it->item.count == it2->item.m.count;
if (shift && alt && ctrl && meta && button && count) {
bool has_pipe = it->item.pipe.cmd != NULL;
LOG_AND_NOTIFY_ERR("%s:%d: %s already mapped to '%s%s%s%s'",
path, lineno, it2->item.text,
binding_action_map[it->item.action]);
binding_action_map[it->item.action],
has_pipe ? " [" : "",
has_pipe ? it->item.pipe.cmd : "",
has_pipe ? "]" : "");
return true;
}
}
@ -1486,6 +1491,17 @@ parse_section_mouse_bindings(
const char *key, const char *value, struct config *conf,
const char *path, unsigned lineno)
{
char *pipe_cmd;
char **pipe_argv;
ssize_t pipe_remove_len = pipe_argv_from_string(
value, &pipe_cmd, &pipe_argv, conf, path, lineno);
if (pipe_remove_len < 0)
return false;
value += pipe_remove_len;
for (enum bind_action_normal action = 0;
action < BIND_ACTION_COUNT;
action++)
@ -1502,9 +1518,16 @@ parse_section_mouse_bindings(
/* Unset binding */
if (strcasecmp(value, "none") == 0) {
tll_foreach(conf->bindings.mouse, it) {
if (it->item.action == action)
if (it->item.action == action) {
if (it->item.pipe.master_copy) {
free(it->item.pipe.cmd);
free(it->item.pipe.argv);
}
tll_remove(conf->bindings.mouse, it);
}
}
free(pipe_argv);
free(pipe_cmd);
return true;
}
@ -1512,26 +1535,43 @@ parse_section_mouse_bindings(
if (!parse_mouse_combos(conf, value, &key_combos, path, lineno) ||
has_mouse_binding_collisions(conf, &key_combos, path, lineno))
{
free(pipe_argv);
free(pipe_cmd);
free_key_combo_list(&key_combos);
return false;
}
/* Remove existing bindings for this action */
tll_foreach(conf->bindings.mouse, it) {
if (it->item.action == action) {
if (it->item.action == action &&
((it->item.pipe.argv == NULL && pipe_argv == NULL) ||
(it->item.pipe.argv != NULL && pipe_argv != NULL &&
argv_compare(it->item.pipe.argv, pipe_argv) == 0)))
{
if (it->item.pipe.master_copy) {
free(it->item.pipe.cmd);
free(it->item.pipe.argv);
}
tll_remove(conf->bindings.mouse, it);
}
}
/* Emit mouse bindings */
bool first = true;
tll_foreach(key_combos, it) {
struct config_mouse_binding binding = {
.action = action,
.modifiers = it->item.modifiers,
.button = it->item.m.button,
.count = it->item.m.count,
.pipe = {
.cmd = pipe_cmd,
.argv = pipe_argv,
.master_copy = first,
},
};
tll_push_back(conf->bindings.mouse, binding);
first = false;
}
free_key_combo_list(&key_combos);
@ -1539,6 +1579,8 @@ parse_section_mouse_bindings(
}
LOG_AND_NOTIFY_ERR("%s:%u: [mouse-bindings]: %s: invalid key", path, lineno, key);
free(pipe_argv);
free(pipe_cmd);
return false;
}
@ -1937,7 +1979,7 @@ add_default_mouse_bindings(struct config *conf)
do { \
tll_push_back( \
conf->bindings.mouse, \
((struct config_mouse_binding){action, mods, btn, count})); \
((struct config_mouse_binding){action, mods, btn, count, {0}})); \
} while (0)
const struct config_key_modifiers none = {0};
@ -2133,6 +2175,12 @@ config_free(struct config conf)
free(it->item.pipe.argv);
}
}
tll_foreach(conf.bindings.mouse, it) {
if (it->item.pipe.master_copy) {
free(it->item.pipe.cmd);
free(it->item.pipe.argv);
}
}
tll_free(conf.bindings.key);
tll_free(conf.bindings.mouse);

View file

@ -47,6 +47,11 @@ struct config_mouse_binding {
struct config_key_modifiers modifiers;
int button;
int count;
struct {
char *cmd;
char **argv;
bool master_copy;
} pipe;
};
struct config {

View file

@ -424,6 +424,7 @@ convert_mouse_binding(struct seat *seat,
.mods = conf_modifiers_to_mask(seat, &conf_binding->modifiers),
.button = conf_binding->button,
.count = conf_binding->count,
.pipe_argv = conf_binding->pipe.argv,
};
tll_push_back(seat->mouse.bindings, binding);
}
@ -1628,7 +1629,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
if (match != NULL) {
seat->mouse.consumed = execute_binding(
seat, term, match->action, NULL, serial);
seat, term, match->action, match->pipe_argv, serial);
}
}
@ -1661,7 +1662,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
if (match != NULL) {
seat->mouse.consumed = execute_binding(
seat, term, match->action, NULL, serial);
seat, term, match->action, match->pipe.argv, serial);
}
}

View file

@ -72,6 +72,7 @@ struct mouse_binding {
xkb_mod_mask_t mods;
uint32_t button;
int count;
char **pipe_argv;
};
typedef tll(struct mouse_binding) mouse_binding_list_t;