mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-08 08:20:59 -04:00
parent
398f0b699a
commit
9ce79e2ef0
5 changed files with 65 additions and 6 deletions
|
|
@ -77,6 +77,10 @@
|
||||||
window (https://codeberg.org/dnkl/foot/issues/179).
|
window (https://codeberg.org/dnkl/foot/issues/179).
|
||||||
* Character dropped from selection when "right-click-hold"-extending a
|
* Character dropped from selection when "right-click-hold"-extending a
|
||||||
selection (https://codeberg.org/dnkl/foot/issues/180).
|
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
|
### Security
|
||||||
|
|
|
||||||
56
config.c
56
config.c
|
|
@ -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;
|
bool count = it->item.count == it2->item.m.count;
|
||||||
|
|
||||||
if (shift && alt && ctrl && meta && button && 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,
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1486,6 +1491,17 @@ parse_section_mouse_bindings(
|
||||||
const char *key, const char *value, struct config *conf,
|
const char *key, const char *value, struct config *conf,
|
||||||
const char *path, unsigned lineno)
|
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;
|
for (enum bind_action_normal action = 0;
|
||||||
action < BIND_ACTION_COUNT;
|
action < BIND_ACTION_COUNT;
|
||||||
action++)
|
action++)
|
||||||
|
|
@ -1502,9 +1518,16 @@ parse_section_mouse_bindings(
|
||||||
/* Unset binding */
|
/* Unset binding */
|
||||||
if (strcasecmp(value, "none") == 0) {
|
if (strcasecmp(value, "none") == 0) {
|
||||||
tll_foreach(conf->bindings.mouse, it) {
|
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);
|
tll_remove(conf->bindings.mouse, it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
free(pipe_argv);
|
||||||
|
free(pipe_cmd);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1512,26 +1535,43 @@ parse_section_mouse_bindings(
|
||||||
if (!parse_mouse_combos(conf, value, &key_combos, path, lineno) ||
|
if (!parse_mouse_combos(conf, value, &key_combos, path, lineno) ||
|
||||||
has_mouse_binding_collisions(conf, &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);
|
free_key_combo_list(&key_combos);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove existing bindings for this action */
|
/* Remove existing bindings for this action */
|
||||||
tll_foreach(conf->bindings.mouse, it) {
|
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);
|
tll_remove(conf->bindings.mouse, it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit mouse bindings */
|
/* Emit mouse bindings */
|
||||||
|
bool first = true;
|
||||||
tll_foreach(key_combos, it) {
|
tll_foreach(key_combos, it) {
|
||||||
struct config_mouse_binding binding = {
|
struct config_mouse_binding binding = {
|
||||||
.action = action,
|
.action = action,
|
||||||
.modifiers = it->item.modifiers,
|
.modifiers = it->item.modifiers,
|
||||||
.button = it->item.m.button,
|
.button = it->item.m.button,
|
||||||
.count = it->item.m.count,
|
.count = it->item.m.count,
|
||||||
|
.pipe = {
|
||||||
|
.cmd = pipe_cmd,
|
||||||
|
.argv = pipe_argv,
|
||||||
|
.master_copy = first,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
tll_push_back(conf->bindings.mouse, binding);
|
tll_push_back(conf->bindings.mouse, binding);
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_key_combo_list(&key_combos);
|
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);
|
LOG_AND_NOTIFY_ERR("%s:%u: [mouse-bindings]: %s: invalid key", path, lineno, key);
|
||||||
|
free(pipe_argv);
|
||||||
|
free(pipe_cmd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1937,7 +1979,7 @@ add_default_mouse_bindings(struct config *conf)
|
||||||
do { \
|
do { \
|
||||||
tll_push_back( \
|
tll_push_back( \
|
||||||
conf->bindings.mouse, \
|
conf->bindings.mouse, \
|
||||||
((struct config_mouse_binding){action, mods, btn, count})); \
|
((struct config_mouse_binding){action, mods, btn, count, {0}})); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
const struct config_key_modifiers none = {0};
|
const struct config_key_modifiers none = {0};
|
||||||
|
|
@ -2133,6 +2175,12 @@ config_free(struct config conf)
|
||||||
free(it->item.pipe.argv);
|
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.key);
|
||||||
tll_free(conf.bindings.mouse);
|
tll_free(conf.bindings.mouse);
|
||||||
|
|
|
||||||
5
config.h
5
config.h
|
|
@ -47,6 +47,11 @@ struct config_mouse_binding {
|
||||||
struct config_key_modifiers modifiers;
|
struct config_key_modifiers modifiers;
|
||||||
int button;
|
int button;
|
||||||
int count;
|
int count;
|
||||||
|
struct {
|
||||||
|
char *cmd;
|
||||||
|
char **argv;
|
||||||
|
bool master_copy;
|
||||||
|
} pipe;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config {
|
struct config {
|
||||||
|
|
|
||||||
5
input.c
5
input.c
|
|
@ -424,6 +424,7 @@ convert_mouse_binding(struct seat *seat,
|
||||||
.mods = conf_modifiers_to_mask(seat, &conf_binding->modifiers),
|
.mods = conf_modifiers_to_mask(seat, &conf_binding->modifiers),
|
||||||
.button = conf_binding->button,
|
.button = conf_binding->button,
|
||||||
.count = conf_binding->count,
|
.count = conf_binding->count,
|
||||||
|
.pipe_argv = conf_binding->pipe.argv,
|
||||||
};
|
};
|
||||||
tll_push_back(seat->mouse.bindings, binding);
|
tll_push_back(seat->mouse.bindings, binding);
|
||||||
}
|
}
|
||||||
|
|
@ -1628,7 +1629,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
|
||||||
if (match != NULL) {
|
if (match != NULL) {
|
||||||
seat->mouse.consumed = execute_binding(
|
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) {
|
if (match != NULL) {
|
||||||
seat->mouse.consumed = execute_binding(
|
seat->mouse.consumed = execute_binding(
|
||||||
seat, term, match->action, NULL, serial);
|
seat, term, match->action, match->pipe.argv, serial);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ struct mouse_binding {
|
||||||
xkb_mod_mask_t mods;
|
xkb_mod_mask_t mods;
|
||||||
uint32_t button;
|
uint32_t button;
|
||||||
int count;
|
int count;
|
||||||
|
char **pipe_argv;
|
||||||
};
|
};
|
||||||
typedef tll(struct mouse_binding) mouse_binding_list_t;
|
typedef tll(struct mouse_binding) mouse_binding_list_t;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue