mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
Merge branch 'refactor-key-bindings'
This commit is contained in:
commit
ee840a308a
11 changed files with 224 additions and 172 deletions
132
config.c
132
config.c
|
|
@ -1451,7 +1451,7 @@ parse_section_csd(struct context *ctx)
|
|||
}
|
||||
|
||||
else if (strcmp(key, "button-close-color") == 0) {
|
||||
if (!value_to_color(ctx, &conf->csd.color.close, true))
|
||||
if (!value_to_color(ctx, &conf->csd.color.quit, true))
|
||||
return false;
|
||||
|
||||
conf->csd.color.close_set = true;
|
||||
|
|
@ -1476,16 +1476,18 @@ parse_section_csd(struct context *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
free_binding_pipe(struct config_binding_pipe *pipe)
|
||||
free_binding_aux(struct binding_aux *aux)
|
||||
{
|
||||
if (pipe->master_copy)
|
||||
free_argv(&pipe->argv);
|
||||
switch (aux->type) {
|
||||
case BINDING_AUX_NONE: break;
|
||||
case BINDING_AUX_PIPE: free_argv(&aux->pipe);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_key_binding(struct config_key_binding *binding)
|
||||
{
|
||||
free_binding_pipe(&binding->pipe);
|
||||
free_binding_aux(&binding->aux);
|
||||
}
|
||||
|
||||
static void NOINLINE
|
||||
|
|
@ -1568,9 +1570,25 @@ argv_compare(const struct argv *argv1, const struct argv *argv2)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static bool NOINLINE
|
||||
binding_aux_equal(const struct binding_aux *a,
|
||||
const struct binding_aux *b)
|
||||
{
|
||||
if (a->type != b->type)
|
||||
return false;
|
||||
|
||||
switch (a->type) {
|
||||
case BINDING_AUX_NONE: return true;
|
||||
case BINDING_AUX_PIPE: return argv_compare(&a->pipe, &b->pipe) == 0;
|
||||
}
|
||||
|
||||
BUG("invalid AUX type: %d", a->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void NOINLINE
|
||||
remove_from_key_bindings_list(struct config_key_binding_list *bindings,
|
||||
int action, const struct argv *pipe_argv)
|
||||
int action, const struct binding_aux *aux)
|
||||
{
|
||||
size_t remove_first_idx = 0;
|
||||
size_t remove_count = 0;
|
||||
|
|
@ -1581,7 +1599,7 @@ remove_from_key_bindings_list(struct config_key_binding_list *bindings,
|
|||
if (binding->action != action)
|
||||
continue;
|
||||
|
||||
if (argv_compare(&binding->pipe.argv, pipe_argv) == 0) {
|
||||
if (binding_aux_equal(&binding->aux, aux)) {
|
||||
if (remove_count++ == 0)
|
||||
remove_first_idx = i;
|
||||
|
||||
|
|
@ -1638,12 +1656,13 @@ mouse_button_code_to_name(int code)
|
|||
}
|
||||
|
||||
static bool NOINLINE
|
||||
value_to_key_combos(struct context *ctx, int action, struct argv *argv,
|
||||
value_to_key_combos(struct context *ctx, int action,
|
||||
struct binding_aux *aux,
|
||||
struct config_key_binding_list *bindings,
|
||||
enum config_key_binding_type type)
|
||||
enum key_binding_type type)
|
||||
{
|
||||
if (strcasecmp(ctx->value, "none") == 0) {
|
||||
remove_from_key_bindings_list(bindings, action, argv);
|
||||
remove_from_key_bindings_list(bindings, action, aux);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1668,8 +1687,13 @@ value_to_key_combos(struct context *ctx, int action, struct argv *argv,
|
|||
{
|
||||
struct config_key_binding *new_combo = &new_combos[idx];
|
||||
new_combo->action = action;
|
||||
new_combo->pipe.master_copy = idx == 0;
|
||||
new_combo->pipe.argv = *argv;
|
||||
new_combo->aux = *aux;
|
||||
new_combo->aux.master_copy = idx == 0;
|
||||
#if 0
|
||||
new_combo->aux.type = BINDING_AUX_PIPE;
|
||||
new_combo->aux.master_copy = idx == 0;
|
||||
new_combo->aux.pipe = *argv;
|
||||
#endif
|
||||
new_combo->path = ctx->path;
|
||||
new_combo->lineno = ctx->lineno;
|
||||
|
||||
|
|
@ -1736,7 +1760,7 @@ value_to_key_combos(struct context *ctx, int action, struct argv *argv,
|
|||
goto err;
|
||||
}
|
||||
|
||||
remove_from_key_bindings_list(bindings, action, argv);
|
||||
remove_from_key_bindings_list(bindings, action, aux);
|
||||
|
||||
bindings->arr = xrealloc(
|
||||
bindings->arr,
|
||||
|
|
@ -1850,12 +1874,15 @@ parse_key_binding_section(struct context *ctx,
|
|||
const char *const action_map[static action_count],
|
||||
struct config_key_binding_list *bindings)
|
||||
{
|
||||
struct argv pipe_argv;
|
||||
struct binding_aux aux;
|
||||
|
||||
ssize_t pipe_remove_len = pipe_argv_from_value(ctx, &pipe_argv);
|
||||
ssize_t pipe_remove_len = pipe_argv_from_value(ctx, &aux.pipe);
|
||||
if (pipe_remove_len < 0)
|
||||
return false;
|
||||
|
||||
aux.type = pipe_remove_len == 0 ? BINDING_AUX_NONE : BINDING_AUX_PIPE;
|
||||
aux.master_copy = true;
|
||||
|
||||
for (int action = 0; action < action_count; action++) {
|
||||
if (action_map[action] == NULL)
|
||||
continue;
|
||||
|
|
@ -1863,10 +1890,8 @@ parse_key_binding_section(struct context *ctx,
|
|||
if (strcmp(ctx->key, action_map[action]) != 0)
|
||||
continue;
|
||||
|
||||
if (!value_to_key_combos(
|
||||
ctx, action, &pipe_argv, bindings, KEY_BINDING))
|
||||
{
|
||||
free_argv(&pipe_argv);
|
||||
if (!value_to_key_combos(ctx, action, &aux, bindings, KEY_BINDING)) {
|
||||
free_binding_aux(&aux);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1874,7 +1899,7 @@ parse_key_binding_section(struct context *ctx,
|
|||
}
|
||||
|
||||
LOG_CONTEXTUAL_ERR("not a valid action: %s", ctx->key);
|
||||
free_argv(&pipe_argv);
|
||||
free_binding_aux(&aux);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2002,7 +2027,7 @@ static bool NOINLINE
|
|||
resolve_key_binding_collisions(struct config *conf, const char *section_name,
|
||||
const char *const action_map[],
|
||||
struct config_key_binding_list *bindings,
|
||||
enum config_key_binding_type type)
|
||||
enum key_binding_type type)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
|
|
@ -2033,12 +2058,10 @@ resolve_key_binding_collisions(struct config *conf, const char *section_name,
|
|||
const struct config_key_binding *binding2 = &bindings->arr[j];
|
||||
xassert(binding2->action != BIND_ACTION_NONE);
|
||||
|
||||
if (binding2->action == binding1->action) {
|
||||
if (argv_compare(
|
||||
&binding1->pipe.argv, &binding2->pipe.argv) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (binding2->action == binding1->action &&
|
||||
binding_aux_equal(&binding1->aux, &binding2->aux))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const struct config_key_modifiers *mods2 = &binding2->modifiers;
|
||||
|
|
@ -2092,7 +2115,7 @@ resolve_key_binding_collisions(struct config *conf, const char *section_name,
|
|||
break;
|
||||
|
||||
case COLLISION_BINDING: {
|
||||
bool has_pipe = collision_binding->pipe.argv.args != NULL;
|
||||
bool has_pipe = collision_binding->aux.type == BINDING_AUX_PIPE;
|
||||
LOG_AND_NOTIFY_ERR(
|
||||
"%s:%d: [%s].%s: %s%s already mapped to '%s%s%s%s'",
|
||||
binding1->path, binding1->lineno, section_name,
|
||||
|
|
@ -2100,7 +2123,7 @@ resolve_key_binding_collisions(struct config *conf, const char *section_name,
|
|||
modifier_names, sym_name,
|
||||
action_map[collision_binding->action],
|
||||
has_pipe ? " [" : "",
|
||||
has_pipe ? collision_binding->pipe.argv.args[0] : "",
|
||||
has_pipe ? collision_binding->aux.pipe.args[0] : "",
|
||||
has_pipe ? "]" : "");
|
||||
ret = false;
|
||||
break;
|
||||
|
|
@ -2128,15 +2151,15 @@ resolve_key_binding_collisions(struct config *conf, const char *section_name,
|
|||
|
||||
free(modifier_names);
|
||||
|
||||
if (binding1->pipe.master_copy && i + 1 < bindings->count) {
|
||||
if (binding1->aux.master_copy && i + 1 < bindings->count) {
|
||||
struct config_key_binding *next = &bindings->arr[i + 1];
|
||||
|
||||
if (next->action == binding1->action &&
|
||||
argv_compare(&binding1->pipe.argv, &next->pipe.argv) == 0)
|
||||
binding_aux_equal(&binding1->aux, &next->aux))
|
||||
{
|
||||
/* Transfer ownership to next binding */
|
||||
next->pipe.master_copy = true;
|
||||
binding1->pipe.master_copy = false;
|
||||
next->aux.master_copy = true;
|
||||
binding1->aux.master_copy = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2150,7 +2173,6 @@ resolve_key_binding_collisions(struct config *conf, const char *section_name,
|
|||
|
||||
i--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -2174,12 +2196,15 @@ parse_section_mouse_bindings(struct context *ctx)
|
|||
return true;
|
||||
}
|
||||
|
||||
struct argv pipe_argv;
|
||||
struct binding_aux aux;
|
||||
|
||||
ssize_t pipe_remove_len = pipe_argv_from_value(ctx, &pipe_argv);
|
||||
ssize_t pipe_remove_len = pipe_argv_from_value(ctx, &aux.pipe);
|
||||
if (pipe_remove_len < 0)
|
||||
return false;
|
||||
|
||||
aux.type = pipe_remove_len == 0 ? BINDING_AUX_NONE : BINDING_AUX_PIPE;
|
||||
aux.master_copy = true;
|
||||
|
||||
for (enum bind_action_normal action = 0;
|
||||
action < BIND_ACTION_COUNT;
|
||||
action++)
|
||||
|
|
@ -2191,9 +2216,9 @@ parse_section_mouse_bindings(struct context *ctx)
|
|||
continue;
|
||||
|
||||
if (!value_to_key_combos(
|
||||
ctx, action, &pipe_argv, &conf->bindings.mouse, MOUSE_BINDING))
|
||||
ctx, action, &aux, &conf->bindings.mouse, MOUSE_BINDING))
|
||||
{
|
||||
free_argv(&pipe_argv);
|
||||
free_binding_aux(&aux);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2201,7 +2226,7 @@ parse_section_mouse_bindings(struct context *ctx)
|
|||
}
|
||||
|
||||
LOG_CONTEXTUAL_ERR("not a valid option: %s", key);
|
||||
free_argv(&pipe_argv);
|
||||
free_binding_aux(&aux);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3055,14 +3080,6 @@ config_override_apply(struct config *conf, config_override_t *overrides,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
binding_pipe_clone(struct config_binding_pipe *dst,
|
||||
const struct config_binding_pipe *src)
|
||||
{
|
||||
xassert(src->master_copy);
|
||||
clone_argv(&dst->argv, &src->argv);
|
||||
}
|
||||
|
||||
static void NOINLINE
|
||||
key_binding_list_clone(struct config_key_binding_list *dst,
|
||||
const struct config_key_binding_list *src)
|
||||
|
|
@ -3078,15 +3095,20 @@ key_binding_list_clone(struct config_key_binding_list *dst,
|
|||
|
||||
*new = *old;
|
||||
|
||||
if (old->pipe.argv.args == NULL)
|
||||
continue;
|
||||
switch (old->aux.type) {
|
||||
case BINDING_AUX_NONE:
|
||||
last_master_argv = NULL;
|
||||
break;
|
||||
|
||||
if (old->pipe.master_copy) {
|
||||
binding_pipe_clone(&new->pipe, &old->pipe);
|
||||
last_master_argv = &new->pipe.argv;
|
||||
} else {
|
||||
xassert(last_master_argv != NULL);
|
||||
new->pipe.argv = *last_master_argv;
|
||||
case BINDING_AUX_PIPE:
|
||||
if (old->aux.master_copy) {
|
||||
clone_argv(&new->aux.pipe, &old->aux.pipe);
|
||||
last_master_argv = &new->aux.pipe;
|
||||
} else {
|
||||
xassert(last_master_argv != NULL);
|
||||
new->aux.pipe = *last_master_argv;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
33
config.h
33
config.h
|
|
@ -4,11 +4,11 @@
|
|||
#include <stdbool.h>
|
||||
#include <uchar.h>
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <tllist.h>
|
||||
#include <fcft/fcft.h>
|
||||
|
||||
#include "terminal.h"
|
||||
#include "user-notification.h"
|
||||
#include "wayland.h"
|
||||
|
||||
#define DEFINE_LIST(type) \
|
||||
type##_list { \
|
||||
|
|
@ -16,6 +16,14 @@
|
|||
type *arr; \
|
||||
}
|
||||
|
||||
/* If px != 0 then px is valid, otherwise pt is valid */
|
||||
struct pt_or_px {
|
||||
int16_t px;
|
||||
float pt;
|
||||
};
|
||||
|
||||
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
|
||||
|
||||
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
|
||||
|
||||
struct config_font {
|
||||
|
|
@ -36,12 +44,21 @@ struct argv {
|
|||
char **args;
|
||||
};
|
||||
|
||||
struct config_binding_pipe {
|
||||
struct argv argv;
|
||||
bool master_copy;
|
||||
enum binding_aux_type {
|
||||
BINDING_AUX_NONE,
|
||||
BINDING_AUX_PIPE,
|
||||
};
|
||||
|
||||
enum config_key_binding_type {
|
||||
struct binding_aux {
|
||||
enum binding_aux_type type;
|
||||
bool master_copy;
|
||||
|
||||
union {
|
||||
struct argv pipe;
|
||||
};
|
||||
};
|
||||
|
||||
enum key_binding_type {
|
||||
KEY_BINDING,
|
||||
MOUSE_BINDING,
|
||||
};
|
||||
|
|
@ -62,7 +79,7 @@ struct config_key_binding {
|
|||
} m;
|
||||
};
|
||||
|
||||
struct config_binding_pipe pipe;
|
||||
struct binding_aux aux;
|
||||
|
||||
/* For error messages in collision handling */
|
||||
const char *path;
|
||||
|
|
@ -245,7 +262,7 @@ struct config {
|
|||
uint32_t buttons;
|
||||
uint32_t minimize;
|
||||
uint32_t maximize;
|
||||
uint32_t close;
|
||||
uint32_t quit; /* ‘close’ collides with #define in epoll-shim */
|
||||
uint32_t border;
|
||||
} color;
|
||||
|
||||
|
|
|
|||
80
input.c
80
input.c
|
|
@ -81,9 +81,10 @@ pipe_closed:
|
|||
|
||||
static bool
|
||||
execute_binding(struct seat *seat, struct terminal *term,
|
||||
enum bind_action_normal action, char *const *pipe_argv,
|
||||
uint32_t serial)
|
||||
const struct key_binding *binding, uint32_t serial)
|
||||
{
|
||||
const enum bind_action_normal action = binding->action;
|
||||
|
||||
switch (action) {
|
||||
case BIND_ACTION_NONE:
|
||||
return true;
|
||||
|
|
@ -193,7 +194,7 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
/* FALLTHROUGH */
|
||||
case BIND_ACTION_PIPE_VIEW:
|
||||
case BIND_ACTION_PIPE_SELECTED: {
|
||||
if (pipe_argv == NULL)
|
||||
if (binding->aux->type != BINDING_AUX_PIPE)
|
||||
return true;
|
||||
|
||||
struct pipe_context *ctx = NULL;
|
||||
|
|
@ -266,7 +267,7 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
}
|
||||
}
|
||||
|
||||
if (!spawn(term->reaper, NULL, pipe_argv, pipe_fd[0], stdout_fd, stderr_fd))
|
||||
if (!spawn(term->reaper, NULL, binding->aux->pipe.args, pipe_fd[0], stdout_fd, stderr_fd))
|
||||
goto pipe_err;
|
||||
|
||||
/* Close read end */
|
||||
|
|
@ -524,11 +525,14 @@ convert_key_binding(const struct seat *seat,
|
|||
xkb_keysym_t sym = maybe_repair_key_combo(seat, conf_binding->k.sym, mods);
|
||||
|
||||
struct key_binding binding = {
|
||||
.mods = mods,
|
||||
.sym = sym,
|
||||
.key_codes = key_codes_for_xkb_sym(seat->kbd.xkb_keymap, sym),
|
||||
.type = KEY_BINDING,
|
||||
.action = conf_binding->action,
|
||||
.pipe_argv = conf_binding->pipe.argv.args,
|
||||
.aux = &conf_binding->aux,
|
||||
.mods = mods,
|
||||
.k = {
|
||||
.sym = sym,
|
||||
.key_codes = key_codes_for_xkb_sym(seat->kbd.xkb_keymap, sym),
|
||||
},
|
||||
};
|
||||
tll_push_back(*bindings, binding);
|
||||
}
|
||||
|
|
@ -564,12 +568,15 @@ static void
|
|||
convert_mouse_binding(struct seat *seat,
|
||||
const struct config_key_binding *conf_binding)
|
||||
{
|
||||
struct mouse_binding binding = {
|
||||
struct key_binding binding = {
|
||||
.type = MOUSE_BINDING,
|
||||
.action = conf_binding->action,
|
||||
.aux = &conf_binding->aux,
|
||||
.mods = conf_modifiers_to_mask(seat, &conf_binding->modifiers),
|
||||
.button = conf_binding->m.button,
|
||||
.count = conf_binding->m.count,
|
||||
.pipe_argv = conf_binding->pipe.argv.args,
|
||||
.m = {
|
||||
.button = conf_binding->m.button,
|
||||
.count = conf_binding->m.count,
|
||||
},
|
||||
};
|
||||
tll_push_back(seat->mouse.bindings, binding);
|
||||
}
|
||||
|
|
@ -618,15 +625,7 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
seat->kbd.xkb = NULL;
|
||||
}
|
||||
|
||||
tll_foreach(seat->kbd.bindings.key, it)
|
||||
tll_free(it->item.key_codes);
|
||||
tll_free(seat->kbd.bindings.key);
|
||||
|
||||
tll_foreach(seat->kbd.bindings.search, it)
|
||||
tll_free(it->item.key_codes);
|
||||
tll_free(seat->kbd.bindings.search);
|
||||
|
||||
tll_free(seat->mouse.bindings);
|
||||
wayl_bindings_reset(seat);
|
||||
|
||||
/* Verify keymap is in a format we understand */
|
||||
switch ((enum wl_keyboard_keymap_format)format) {
|
||||
|
|
@ -1525,10 +1524,9 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
const struct key_binding *bind = &it->item;
|
||||
|
||||
/* Match translated symbol */
|
||||
if (bind->sym == sym &&
|
||||
if (bind->k.sym == sym &&
|
||||
bind->mods == (bind_mods & ~bind_consumed) &&
|
||||
execute_binding(
|
||||
seat, term, bind->action, bind->pipe_argv, serial))
|
||||
execute_binding(seat, term, bind, serial))
|
||||
{
|
||||
goto maybe_repeat;
|
||||
}
|
||||
|
|
@ -1538,17 +1536,17 @@ key_press_release(struct seat *seat, struct terminal *term, uint32_t serial,
|
|||
|
||||
/* Match untranslated symbols */
|
||||
for (size_t i = 0; i < raw_count; i++) {
|
||||
if (bind->sym == raw_syms[i] && execute_binding(
|
||||
seat, term, bind->action, bind->pipe_argv, serial))
|
||||
if (bind->k.sym == raw_syms[i] &&
|
||||
execute_binding(seat, term, bind, serial))
|
||||
{
|
||||
goto maybe_repeat;
|
||||
}
|
||||
}
|
||||
|
||||
/* Match raw key code */
|
||||
tll_foreach(bind->key_codes, code) {
|
||||
if (code->item == key && execute_binding(
|
||||
seat, term, bind->action, bind->pipe_argv, serial))
|
||||
tll_foreach(bind->k.key_codes, code) {
|
||||
if (code->item == key &&
|
||||
execute_binding(seat, term, bind, serial))
|
||||
{
|
||||
goto maybe_repeat;
|
||||
}
|
||||
|
|
@ -2411,12 +2409,12 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
|||
/* Ignore selection override modifiers when matching modifiers */
|
||||
mods &= ~seat->kbd.selection_override_modmask;
|
||||
|
||||
const struct mouse_binding *match = NULL;
|
||||
const struct key_binding *match = NULL;
|
||||
|
||||
tll_foreach(seat->mouse.bindings, it) {
|
||||
const struct mouse_binding *binding = &it->item;
|
||||
const struct key_binding *binding = &it->item;
|
||||
|
||||
if (binding->button != button) {
|
||||
if (binding->m.button != button) {
|
||||
/* Wrong button */
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2426,19 +2424,17 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (binding->count > seat->mouse.count) {
|
||||
if (binding->m.count > seat->mouse.count) {
|
||||
/* Not correct click count */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (match == NULL || binding->count > match->count)
|
||||
if (match == NULL || binding->m.count > match->m.count)
|
||||
match = binding;
|
||||
}
|
||||
|
||||
if (match != NULL) {
|
||||
consumed = execute_binding(
|
||||
seat, term, match->action, match->pipe_argv, serial);
|
||||
}
|
||||
if (match != NULL)
|
||||
consumed = execute_binding(seat, term, match, serial);
|
||||
}
|
||||
|
||||
else {
|
||||
|
|
@ -2471,9 +2467,11 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
|||
}
|
||||
|
||||
if (match != NULL) {
|
||||
consumed = execute_binding(
|
||||
seat, term, match->action, match->pipe.argv.args,
|
||||
serial);
|
||||
struct key_binding bind = {
|
||||
.action = match->action,
|
||||
.aux = &match->aux,
|
||||
};
|
||||
consumed = execute_binding(seat, term, &bind, serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
render.c
2
render.c
|
|
@ -2052,7 +2052,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx,
|
|||
case CSD_SURF_CLOSE:
|
||||
_color = term->conf->colors.table[1]; /* red */
|
||||
is_set = term->conf->csd.color.close_set;
|
||||
conf_color = &term->conf->csd.color.close;
|
||||
conf_color = &term->conf->csd.color.quit;
|
||||
is_active = term->active_surface == TERM_SURF_BUTTON_CLOSE;
|
||||
break;
|
||||
|
||||
|
|
|
|||
15
search.c
15
search.c
|
|
@ -604,10 +604,11 @@ from_clipboard_done(void *user)
|
|||
|
||||
static bool
|
||||
execute_binding(struct seat *seat, struct terminal *term,
|
||||
enum bind_action_search action, uint32_t serial,
|
||||
const struct key_binding *binding, uint32_t serial,
|
||||
bool *update_search_result, bool *redraw)
|
||||
{
|
||||
*update_search_result = *redraw = false;
|
||||
const enum bind_action_search action = binding->action;
|
||||
|
||||
switch (action) {
|
||||
case BIND_ACTION_SEARCH_NONE:
|
||||
|
|
@ -838,10 +839,10 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
|
|||
const struct key_binding *bind = &it->item;
|
||||
|
||||
/* Match translated symbol */
|
||||
if (bind->sym == sym &&
|
||||
if (bind->k.sym == sym &&
|
||||
bind->mods == (mods & ~consumed)) {
|
||||
|
||||
if (execute_binding(seat, term, bind->action, serial,
|
||||
if (execute_binding(seat, term, bind, serial,
|
||||
&update_search_result, &redraw))
|
||||
{
|
||||
goto update_search;
|
||||
|
|
@ -854,8 +855,8 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
|
|||
|
||||
/* Match untranslated symbols */
|
||||
for (size_t i = 0; i < raw_count; i++) {
|
||||
if (bind->sym == raw_syms[i]) {
|
||||
if (execute_binding(seat, term, bind->action, serial,
|
||||
if (bind->k.sym == raw_syms[i]) {
|
||||
if (execute_binding(seat, term, bind, serial,
|
||||
&update_search_result, &redraw))
|
||||
{
|
||||
goto update_search;
|
||||
|
|
@ -865,9 +866,9 @@ search_input(struct seat *seat, struct terminal *term, uint32_t key,
|
|||
}
|
||||
|
||||
/* Match raw key code */
|
||||
tll_foreach(bind->key_codes, code) {
|
||||
tll_foreach(bind->k.key_codes, code) {
|
||||
if (code->item == key) {
|
||||
if (execute_binding(seat, term, bind->action, serial,
|
||||
if (execute_binding(seat, term, bind, serial,
|
||||
&update_search_result, &redraw))
|
||||
{
|
||||
goto update_search;
|
||||
|
|
|
|||
1
server.h
1
server.h
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "fdm.h"
|
||||
#include "config.h"
|
||||
#include "reaper.h"
|
||||
#include "wayland.h"
|
||||
|
||||
struct server;
|
||||
|
|
|
|||
10
terminal.h
10
terminal.h
|
|
@ -14,7 +14,7 @@
|
|||
#include <tllist.h>
|
||||
#include <fcft/fcft.h>
|
||||
|
||||
//#include "config.h"
|
||||
#include "config.h"
|
||||
#include "composed.h"
|
||||
#include "debug.h"
|
||||
#include "fdm.h"
|
||||
|
|
@ -248,8 +248,6 @@ enum mouse_reporting {
|
|||
MOUSE_SGR_PIXELS, /* ?1016h */
|
||||
};
|
||||
|
||||
enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM };
|
||||
|
||||
enum selection_kind {
|
||||
SELECTION_NONE,
|
||||
SELECTION_CHAR_WISE,
|
||||
|
|
@ -299,12 +297,6 @@ struct url {
|
|||
};
|
||||
typedef tll(struct url) url_list_t;
|
||||
|
||||
/* If px != 0 then px is valid, otherwise pt is valid */
|
||||
struct pt_or_px {
|
||||
int16_t px;
|
||||
float pt;
|
||||
};
|
||||
|
||||
struct terminal {
|
||||
struct fdm *fdm;
|
||||
struct reaper *reaper;
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ test_section_csd(void)
|
|||
test_color(&ctx, &parse_section_csd, "button-maximize-color", true,
|
||||
&conf.csd.color.maximize);
|
||||
test_color(&ctx, &parse_section_csd, "button-close-color", true,
|
||||
&conf.csd.color.close);
|
||||
&conf.csd.color.quit);
|
||||
|
||||
/* TODO: verify the ‘set’ bit is actually set for colors */
|
||||
/* TODO: font */
|
||||
|
|
@ -677,7 +677,7 @@ static void
|
|||
test_key_binding(struct context *ctx, bool (*parse_fun)(struct context *ctx),
|
||||
int action, int max_action, const char *const *map,
|
||||
struct config_key_binding_list *bindings,
|
||||
enum config_key_binding_type type)
|
||||
enum key_binding_type type)
|
||||
{
|
||||
xassert(map[action] != NULL);
|
||||
xassert(bindings->count == 0);
|
||||
|
|
@ -756,30 +756,30 @@ test_key_binding(struct context *ctx, bool (*parse_fun)(struct context *ctx),
|
|||
&bindings->arr[bindings->count - 1];
|
||||
|
||||
if (argv) {
|
||||
if (binding->pipe.argv.args == NULL) {
|
||||
if (binding->aux.pipe.args == NULL) {
|
||||
BUG("[%s].%s=%s: pipe argv is NULL",
|
||||
ctx->section, ctx->key, ctx->value);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ALEN(args); i++) {
|
||||
if (binding->pipe.argv.args[i] == NULL ||
|
||||
strcmp(binding->pipe.argv.args[i], args[i]) != 0)
|
||||
if (binding->aux.pipe.args[i] == NULL ||
|
||||
strcmp(binding->aux.pipe.args[i], args[i]) != 0)
|
||||
{
|
||||
BUG("[%s].%s=%s: pipe argv not the expected one: "
|
||||
"mismatch of arg #%zu: expected=\"%s\", got=\"%s\"",
|
||||
ctx->section, ctx->key, ctx->value, i,
|
||||
args[i], binding->pipe.argv.args[i]);
|
||||
args[i], binding->aux.pipe.args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (binding->pipe.argv.args[ALEN(args)] != NULL) {
|
||||
if (binding->aux.pipe.args[ALEN(args)] != NULL) {
|
||||
BUG("[%s].%s=%s: pipe argv not the expected one: "
|
||||
"expected NULL terminator at arg #%zu, got=\"%s\"",
|
||||
ctx->section, ctx->key, ctx->value,
|
||||
ALEN(args), binding->pipe.argv.args[ALEN(args)]);
|
||||
ALEN(args), binding->aux.pipe.args[ALEN(args)]);
|
||||
}
|
||||
} else {
|
||||
if (binding->pipe.argv.args != NULL) {
|
||||
if (binding->aux.pipe.args != NULL) {
|
||||
BUG("[%s].%s=%s: pipe argv not NULL",
|
||||
ctx->section, ctx->key, ctx->value);
|
||||
}
|
||||
|
|
@ -840,7 +840,7 @@ enum collision_test_mode {
|
|||
static void
|
||||
_test_binding_collisions(struct context *ctx,
|
||||
int max_action, const char *const *map,
|
||||
enum config_key_binding_type type,
|
||||
enum key_binding_type type,
|
||||
enum collision_test_mode test_mode)
|
||||
{
|
||||
struct config_key_binding *bindings_array =
|
||||
|
|
@ -889,21 +889,23 @@ _test_binding_collisions(struct context *ctx,
|
|||
|
||||
case FAIL_DIFFERENT_ARGV:
|
||||
case SUCCED_SAME_ACTION_AND_ARGV:
|
||||
bindings.arr[0].pipe.master_copy = true;
|
||||
bindings.arr[0].pipe.argv.args = xcalloc(
|
||||
4, sizeof(bindings.arr[0].pipe.argv.args[0]));
|
||||
bindings.arr[0].pipe.argv.args[0] = xstrdup("/usr/bin/foobar");
|
||||
bindings.arr[0].pipe.argv.args[1] = xstrdup("hello");
|
||||
bindings.arr[0].pipe.argv.args[2] = xstrdup("world");
|
||||
bindings.arr[0].aux.type = BINDING_AUX_PIPE;
|
||||
bindings.arr[0].aux.master_copy = true;
|
||||
bindings.arr[0].aux.pipe.args = xcalloc(
|
||||
4, sizeof(bindings.arr[0].aux.pipe.args[0]));
|
||||
bindings.arr[0].aux.pipe.args[0] = xstrdup("/usr/bin/foobar");
|
||||
bindings.arr[0].aux.pipe.args[1] = xstrdup("hello");
|
||||
bindings.arr[0].aux.pipe.args[2] = xstrdup("world");
|
||||
|
||||
bindings.arr[1].pipe.master_copy = true;
|
||||
bindings.arr[1].pipe.argv.args = xcalloc(
|
||||
4, sizeof(bindings.arr[1].pipe.argv.args[0]));
|
||||
bindings.arr[1].pipe.argv.args[0] = xstrdup("/usr/bin/foobar");
|
||||
bindings.arr[1].pipe.argv.args[1] = xstrdup("hello");
|
||||
bindings.arr[1].aux.type = BINDING_AUX_PIPE;
|
||||
bindings.arr[1].aux.master_copy = true;
|
||||
bindings.arr[1].aux.pipe.args = xcalloc(
|
||||
4, sizeof(bindings.arr[1].aux.pipe.args[0]));
|
||||
bindings.arr[1].aux.pipe.args[0] = xstrdup("/usr/bin/foobar");
|
||||
bindings.arr[1].aux.pipe.args[1] = xstrdup("hello");
|
||||
|
||||
if (test_mode == SUCCED_SAME_ACTION_AND_ARGV)
|
||||
bindings.arr[1].pipe.argv.args[2] = xstrdup("world");
|
||||
bindings.arr[1].aux.pipe.args[2] = xstrdup("world");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -937,7 +939,7 @@ _test_binding_collisions(struct context *ctx,
|
|||
static void
|
||||
test_binding_collisions(struct context *ctx,
|
||||
int max_action, const char *const *map,
|
||||
enum config_key_binding_type type)
|
||||
enum key_binding_type type)
|
||||
{
|
||||
_test_binding_collisions(ctx, max_action, map, type, FAIL_DIFFERENT_ACTION);
|
||||
_test_binding_collisions(ctx, max_action, map, type, FAIL_DIFFERENT_ARGV);
|
||||
|
|
|
|||
16
url-mode.c
16
url-mode.c
|
|
@ -25,8 +25,10 @@ static void url_destroy(struct url *url);
|
|||
|
||||
static bool
|
||||
execute_binding(struct seat *seat, struct terminal *term,
|
||||
enum bind_action_url action, uint32_t serial)
|
||||
const struct key_binding *binding, uint32_t serial)
|
||||
{
|
||||
const enum bind_action_url action = binding->action;
|
||||
|
||||
switch (action) {
|
||||
case BIND_ACTION_URL_NONE:
|
||||
return false;
|
||||
|
|
@ -125,10 +127,10 @@ urls_input(struct seat *seat, struct terminal *term, uint32_t key,
|
|||
const struct key_binding *bind = &it->item;
|
||||
|
||||
/* Match translated symbol */
|
||||
if (bind->sym == sym &&
|
||||
if (bind->k.sym == sym &&
|
||||
bind->mods == (mods & ~consumed))
|
||||
{
|
||||
execute_binding(seat, term, bind->action, serial);
|
||||
execute_binding(seat, term, bind, serial);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -136,16 +138,16 @@ urls_input(struct seat *seat, struct terminal *term, uint32_t key,
|
|||
continue;
|
||||
|
||||
for (size_t i = 0; i < raw_count; i++) {
|
||||
if (bind->sym == raw_syms[i]) {
|
||||
execute_binding(seat, term, bind->action, serial);
|
||||
if (bind->k.sym == raw_syms[i]) {
|
||||
execute_binding(seat, term, bind, serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Match raw key code */
|
||||
tll_foreach(bind->key_codes, code) {
|
||||
tll_foreach(bind->k.key_codes, code) {
|
||||
if (code->item == key) {
|
||||
execute_binding(seat, term, bind->action, serial);
|
||||
execute_binding(seat, term, bind, serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
24
wayland.c
24
wayland.c
|
|
@ -158,11 +158,26 @@ static void
|
|||
key_bindings_destroy(key_binding_list_t *bindings)
|
||||
{
|
||||
tll_foreach(*bindings, it) {
|
||||
tll_free(it->item.key_codes);
|
||||
struct key_binding *bind = &it->item;
|
||||
switch (bind->type) {
|
||||
case KEY_BINDING: tll_free(it->item.k.key_codes); break;
|
||||
case MOUSE_BINDING: break;
|
||||
}
|
||||
|
||||
tll_remove(*bindings, it);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wayl_bindings_reset(struct seat *seat)
|
||||
{
|
||||
|
||||
key_bindings_destroy(&seat->kbd.bindings.key);
|
||||
key_bindings_destroy(&seat->kbd.bindings.search);
|
||||
key_bindings_destroy(&seat->kbd.bindings.url);
|
||||
key_bindings_destroy(&seat->mouse.bindings);
|
||||
}
|
||||
|
||||
static void
|
||||
seat_destroy(struct seat *seat)
|
||||
{
|
||||
|
|
@ -170,12 +185,7 @@ seat_destroy(struct seat *seat)
|
|||
return;
|
||||
|
||||
tll_free(seat->mouse.buttons);
|
||||
|
||||
key_bindings_destroy(&seat->kbd.bindings.key);
|
||||
key_bindings_destroy(&seat->kbd.bindings.search);
|
||||
key_bindings_destroy(&seat->kbd.bindings.url);
|
||||
|
||||
tll_free(seat->mouse.bindings);
|
||||
wayl_bindings_reset(seat);
|
||||
|
||||
if (seat->kbd.xkb_compose_state != NULL)
|
||||
xkb_compose_state_unref(seat->kbd.xkb_compose_state);
|
||||
|
|
|
|||
35
wayland.h
35
wayland.h
|
|
@ -23,6 +23,7 @@
|
|||
#include <fcft/fcft.h>
|
||||
#include <tllist.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "fdm.h"
|
||||
|
||||
/* Forward declarations */
|
||||
|
|
@ -100,24 +101,28 @@ enum bind_action_url {
|
|||
typedef tll(xkb_keycode_t) xkb_keycode_list_t;
|
||||
|
||||
struct key_binding {
|
||||
xkb_mod_mask_t mods;
|
||||
xkb_keysym_t sym;
|
||||
xkb_keycode_list_t key_codes;
|
||||
enum key_binding_type type;
|
||||
|
||||
int action; /* enum bind_action_* */
|
||||
char **pipe_argv;
|
||||
xkb_mod_mask_t mods;
|
||||
|
||||
union {
|
||||
struct {
|
||||
xkb_keysym_t sym;
|
||||
xkb_keycode_list_t key_codes;
|
||||
} k;
|
||||
|
||||
struct {
|
||||
uint32_t button;
|
||||
int count;
|
||||
} m;
|
||||
};
|
||||
|
||||
const struct binding_aux *aux;
|
||||
|
||||
};
|
||||
typedef tll(struct key_binding) key_binding_list_t;
|
||||
|
||||
struct mouse_binding {
|
||||
enum bind_action_normal action;
|
||||
xkb_mod_mask_t mods;
|
||||
uint32_t button;
|
||||
int count;
|
||||
char **pipe_argv;
|
||||
};
|
||||
typedef tll(struct mouse_binding) mouse_binding_list_t;
|
||||
|
||||
/* Mime-types we support when dealing with data offers (e.g. copy-paste, or DnD) */
|
||||
enum data_offer_mime_type {
|
||||
DATA_OFFER_MIME_UNSET,
|
||||
|
|
@ -253,7 +258,7 @@ struct seat {
|
|||
double aggregated[2];
|
||||
bool have_discrete;
|
||||
|
||||
mouse_binding_list_t bindings;
|
||||
key_binding_list_t bindings;
|
||||
} mouse;
|
||||
|
||||
/* Clipboard */
|
||||
|
|
@ -510,3 +515,5 @@ bool wayl_win_subsurface_new_with_custom_parent(
|
|||
struct wl_window *win, struct wl_surface *parent,
|
||||
struct wl_surf_subsurf *surf);
|
||||
void wayl_win_subsurface_destroy(struct wl_surf_subsurf *surf);
|
||||
|
||||
void wayl_bindings_reset(struct seat *seat);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue