mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-08 10:06:22 -05:00
Merge branch 'reduce-tllist-usage'
This commit is contained in:
commit
b77dbc341b
5 changed files with 380 additions and 276 deletions
523
config.c
523
config.c
|
|
@ -744,26 +744,40 @@ parse_section_main(const char *key, const char *value, struct config *conf,
|
|||
strcmp(key, "font-bold") == 0 ? 1 :
|
||||
strcmp(key, "font-italic") == 0 ? 2 : 3;
|
||||
|
||||
tll_foreach(conf->fonts[idx], it)
|
||||
config_font_destroy(&it->item);
|
||||
tll_free(conf->fonts[idx]);
|
||||
config_font_list_destroy(&conf->fonts[idx]);
|
||||
|
||||
size_t count = 0;
|
||||
size_t size = 0;
|
||||
struct config_font *fonts = NULL;
|
||||
|
||||
char *copy = xstrdup(value);
|
||||
for (const char *font = strtok(copy, ","); font != NULL; font = strtok(NULL, ",")) {
|
||||
/* Trim spaces, strictly speaking not necessary, but looks nice :) */
|
||||
while (*font != '\0' && isspace(*font))
|
||||
font++;
|
||||
if (*font != '\0') {
|
||||
struct config_font font_data;
|
||||
if (!config_font_parse(font, &font_data)) {
|
||||
LOG_ERR("%s:%d: [default]: %s: invalid font specification",
|
||||
path, lineno, key);
|
||||
free(copy);
|
||||
return false;
|
||||
}
|
||||
tll_push_back(conf->fonts[idx], font_data);
|
||||
|
||||
if (font[0] == '\0')
|
||||
continue;
|
||||
|
||||
struct config_font font_data;
|
||||
if (!config_font_parse(font, &font_data)) {
|
||||
LOG_ERR("%s:%d: [default]: %s: invalid font specification",
|
||||
path, lineno, key);
|
||||
free(copy);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count + 1 > size) {
|
||||
size += 4;
|
||||
fonts = xrealloc(fonts, size * sizeof(fonts[0]));
|
||||
}
|
||||
|
||||
xassert(count + 1 <= size);
|
||||
fonts[count++] = font_data;
|
||||
}
|
||||
|
||||
conf->fonts[idx].count = count;
|
||||
conf->fonts[idx].arr = fonts;
|
||||
free(copy);
|
||||
}
|
||||
|
||||
|
|
@ -1356,14 +1370,20 @@ struct key_combo {
|
|||
} m;
|
||||
};
|
||||
};
|
||||
typedef tll(struct key_combo) key_combo_list_t;
|
||||
|
||||
static void
|
||||
free_key_combo_list(key_combo_list_t *key_combos)
|
||||
struct key_combo_list {
|
||||
size_t count;
|
||||
struct key_combo *combos;
|
||||
};
|
||||
|
||||
static void NOINLINE
|
||||
free_key_combo_list(struct key_combo_list *key_combos)
|
||||
{
|
||||
tll_foreach(*key_combos, it)
|
||||
free(it->item.text);
|
||||
tll_free(*key_combos);
|
||||
for (size_t i = 0; i < key_combos->count; i++)
|
||||
free(key_combos->combos[i].text);
|
||||
free(key_combos->combos);
|
||||
key_combos->count = 0;
|
||||
key_combos->combos = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1402,11 +1422,15 @@ out:
|
|||
}
|
||||
|
||||
static bool
|
||||
parse_key_combos(struct config *conf, const char *combos, key_combo_list_t *key_combos,
|
||||
parse_key_combos(struct config *conf, const char *combos,
|
||||
struct key_combo_list *key_combos,
|
||||
const char *section, const char *option,
|
||||
const char *path, unsigned lineno)
|
||||
{
|
||||
xassert(tll_length(*key_combos) == 0);
|
||||
xassert(key_combos != NULL);
|
||||
xassert(key_combos->count == 0 && key_combos->combos == NULL);
|
||||
|
||||
size_t size = 0; /* Size of ‘combos’ array in the key-combo list */
|
||||
|
||||
char *copy = xstrdup(combos);
|
||||
|
||||
|
|
@ -1450,18 +1474,25 @@ parse_key_combos(struct config *conf, const char *combos, key_combo_list_t *key_
|
|||
goto err;
|
||||
}
|
||||
|
||||
tll_push_back(
|
||||
*key_combos,
|
||||
((struct key_combo){.text = xstrdup(combo), .modifiers = modifiers, .sym = sym}));
|
||||
if (key_combos->count + 1 > size) {
|
||||
size += 4;
|
||||
key_combos->combos = xrealloc(
|
||||
key_combos->combos, size * sizeof(key_combos->combos[0]));
|
||||
}
|
||||
|
||||
xassert(key_combos->count + 1 <= size);
|
||||
key_combos->combos[key_combos->count++] = (struct key_combo){
|
||||
.text = xstrdup(combo),
|
||||
.modifiers = modifiers,
|
||||
.sym = sym,
|
||||
};
|
||||
}
|
||||
|
||||
free(copy);
|
||||
return true;
|
||||
|
||||
err:
|
||||
tll_foreach(*key_combos, it)
|
||||
free(it->item.text);
|
||||
tll_free(*key_combos);
|
||||
free_key_combo_list(key_combos);
|
||||
free(copy);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1469,31 +1500,38 @@ err:
|
|||
static bool
|
||||
has_key_binding_collisions(struct config *conf,
|
||||
int action, const char *const action_map[],
|
||||
config_key_binding_list_t *bindings,
|
||||
const key_combo_list_t *key_combos,
|
||||
const struct config_key_binding_list *bindings,
|
||||
const struct key_combo_list *key_combos,
|
||||
const char *path, unsigned lineno)
|
||||
{
|
||||
tll_foreach(*bindings, it) {
|
||||
if (it->item.action == action)
|
||||
for (size_t j = 0; j < bindings->count; j++) {
|
||||
const struct config_key_binding *combo1 = &bindings->arr[j];
|
||||
|
||||
if (combo1->action == BIND_ACTION_NONE)
|
||||
continue;
|
||||
|
||||
tll_foreach(*key_combos, it2) {
|
||||
const struct config_key_modifiers *mods1 = &it->item.modifiers;
|
||||
const struct config_key_modifiers *mods2 = &it2->item.modifiers;
|
||||
if (combo1->action == action)
|
||||
continue;
|
||||
|
||||
for (size_t i = 0; i < key_combos->count; i++) {
|
||||
const struct key_combo *combo2 = &key_combos->combos[i];
|
||||
|
||||
const struct config_key_modifiers *mods1 = &combo1->modifiers;
|
||||
const struct config_key_modifiers *mods2 = &combo2->modifiers;
|
||||
|
||||
bool shift = mods1->shift == mods2->shift;
|
||||
bool alt = mods1->alt == mods2->alt;
|
||||
bool ctrl = mods1->ctrl == mods2->ctrl;
|
||||
bool meta = mods1->meta == mods2->meta;
|
||||
bool sym = it->item.sym == it2->item.sym;
|
||||
bool sym = combo1->sym == combo2->sym;
|
||||
|
||||
if (shift && alt && ctrl && meta && sym) {
|
||||
bool has_pipe = it->item.pipe.cmd != NULL;
|
||||
bool has_pipe = combo1->pipe.cmd != NULL;
|
||||
LOG_AND_NOTIFY_ERR("%s:%d: %s already mapped to '%s%s%s%s'",
|
||||
path, lineno, it2->item.text,
|
||||
action_map[it->item.action],
|
||||
path, lineno, combo2->text,
|
||||
action_map[combo1->action],
|
||||
has_pipe ? " [" : "",
|
||||
has_pipe ? it->item.pipe.cmd : "",
|
||||
has_pipe ? combo1->pipe.cmd : "",
|
||||
has_pipe ? "]" : "");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1587,7 +1625,7 @@ static bool NOINLINE
|
|||
parse_key_binding_section(
|
||||
const char *section, const char *key, const char *value,
|
||||
int action_count, const char *const action_map[static action_count],
|
||||
config_key_binding_list_t *bindings,
|
||||
struct config_key_binding_list *bindings,
|
||||
struct config *conf, const char *path, unsigned lineno)
|
||||
{
|
||||
char *pipe_cmd;
|
||||
|
|
@ -1610,21 +1648,27 @@ parse_key_binding_section(
|
|||
|
||||
/* Unset binding */
|
||||
if (strcasecmp(value, "none") == 0) {
|
||||
tll_foreach(*bindings, it) {
|
||||
if (it->item.action == action) {
|
||||
if (it->item.pipe.master_copy) {
|
||||
free(it->item.pipe.cmd);
|
||||
free(it->item.pipe.argv);
|
||||
}
|
||||
tll_remove(*bindings, it);
|
||||
for (size_t i = 0; i < bindings->count; i++) {
|
||||
struct config_key_binding *binding = &bindings->arr[i];
|
||||
|
||||
if (binding->action != action)
|
||||
continue;
|
||||
|
||||
if (binding->pipe.master_copy) {
|
||||
free(binding->pipe.cmd);
|
||||
free(binding->pipe.argv);
|
||||
}
|
||||
binding->action = BIND_ACTION_NONE;
|
||||
binding->pipe.cmd = NULL;
|
||||
binding->pipe.argv = NULL;
|
||||
}
|
||||
|
||||
free(pipe_argv);
|
||||
free(pipe_cmd);
|
||||
return true;
|
||||
}
|
||||
|
||||
key_combo_list_t key_combos = tll_init();
|
||||
struct key_combo_list key_combos = {0};
|
||||
if (!parse_key_combos(
|
||||
conf, value, &key_combos, section, key, path, lineno) ||
|
||||
has_key_binding_collisions(
|
||||
|
|
@ -1638,28 +1682,38 @@ parse_key_binding_section(
|
|||
}
|
||||
|
||||
/* Remove existing bindings for this action+pipe */
|
||||
tll_foreach(*bindings, it) {
|
||||
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)))
|
||||
for (size_t i = 0; i < bindings->count; i++) {
|
||||
struct config_key_binding *binding = &bindings->arr[i];
|
||||
|
||||
if (binding->action == action &&
|
||||
((binding->pipe.argv == NULL && pipe_argv == NULL) ||
|
||||
(binding->pipe.argv != NULL && pipe_argv != NULL &&
|
||||
argv_compare(binding->pipe.argv, pipe_argv) == 0)))
|
||||
{
|
||||
|
||||
if (it->item.pipe.master_copy) {
|
||||
free(it->item.pipe.cmd);
|
||||
free(it->item.pipe.argv);
|
||||
if (binding->pipe.master_copy) {
|
||||
free(binding->pipe.cmd);
|
||||
free(binding->pipe.argv);
|
||||
}
|
||||
tll_remove(*bindings, it);
|
||||
binding->action = BIND_ACTION_NONE;
|
||||
binding->pipe.cmd = NULL;
|
||||
binding->pipe.argv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit key bindings */
|
||||
size_t ofs = bindings->count;
|
||||
bindings->count += key_combos.count;
|
||||
bindings->arr = xrealloc(
|
||||
bindings->arr, bindings->count * sizeof(bindings->arr[0]));
|
||||
|
||||
bool first = true;
|
||||
tll_foreach(key_combos, it) {
|
||||
for (size_t i = 0; i < key_combos.count; i++) {
|
||||
const struct key_combo *combo = &key_combos.combos[i];
|
||||
struct config_key_binding binding = {
|
||||
.action = action,
|
||||
.modifiers = it->item.modifiers,
|
||||
.sym = it->item.sym,
|
||||
.modifiers = combo->modifiers,
|
||||
.sym = combo->sym,
|
||||
.pipe = {
|
||||
.cmd = pipe_cmd,
|
||||
.argv = pipe_argv,
|
||||
|
|
@ -1667,7 +1721,8 @@ parse_key_binding_section(
|
|||
},
|
||||
};
|
||||
|
||||
tll_push_back(*bindings, binding);
|
||||
/* TODO: we could re-use free:d slots */
|
||||
bindings->arr[ofs + i] = binding;
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
|
@ -1747,10 +1802,14 @@ parse_section_url_bindings(
|
|||
}
|
||||
|
||||
static bool
|
||||
parse_mouse_combos(struct config *conf, const char *combos, key_combo_list_t *key_combos,
|
||||
parse_mouse_combos(struct config *conf, const char *combos,
|
||||
struct key_combo_list *key_combos,
|
||||
const char *path, unsigned lineno)
|
||||
{
|
||||
xassert(tll_length(*key_combos) == 0);
|
||||
xassert(key_combos != NULL);
|
||||
xassert(key_combos->count == 0 && key_combos->combos == NULL);
|
||||
|
||||
size_t size = 0; /* Size of the ‘combos’ array in key_combos */
|
||||
|
||||
char *copy = xstrdup(combos);
|
||||
|
||||
|
|
@ -1835,44 +1894,55 @@ parse_mouse_combos(struct config *conf, const char *combos, key_combo_list_t *ke
|
|||
.count = count,
|
||||
},
|
||||
};
|
||||
tll_push_back(*key_combos, new);
|
||||
|
||||
if (key_combos->count + 1 > size) {
|
||||
size += 4;
|
||||
key_combos->combos = xrealloc(
|
||||
key_combos->combos, size * sizeof(key_combos->combos[0]));
|
||||
}
|
||||
|
||||
xassert(key_combos->count + 1 <= size);
|
||||
key_combos->combos[key_combos->count++] = new;
|
||||
}
|
||||
|
||||
free(copy);
|
||||
return true;
|
||||
|
||||
err:
|
||||
tll_foreach(*key_combos, it) {
|
||||
free(it->item.text);
|
||||
tll_remove(*key_combos, it);
|
||||
}
|
||||
free_key_combo_list(key_combos);
|
||||
free(copy);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_mouse_binding_collisions(struct config *conf, const key_combo_list_t *key_combos,
|
||||
has_mouse_binding_collisions(struct config *conf, const struct key_combo_list *key_combos,
|
||||
const char *path, unsigned lineno)
|
||||
{
|
||||
tll_foreach(conf->bindings.mouse, it) {
|
||||
tll_foreach(*key_combos, it2) {
|
||||
const struct config_key_modifiers *mods1 = &it->item.modifiers;
|
||||
const struct config_key_modifiers *mods2 = &it2->item.modifiers;
|
||||
for (size_t j = 0; j < conf->bindings.mouse.count; j++) {
|
||||
const struct config_mouse_binding *combo1 = &conf->bindings.mouse.arr[j];
|
||||
if (combo1->action == BIND_ACTION_NONE)
|
||||
continue;
|
||||
|
||||
for (size_t i = 0; i < key_combos->count; i++) {
|
||||
const struct key_combo *combo2 = &key_combos->combos[i];
|
||||
|
||||
const struct config_key_modifiers *mods1 = &combo1->modifiers;
|
||||
const struct config_key_modifiers *mods2 = &combo2->modifiers;
|
||||
|
||||
bool shift = mods1->shift == mods2->shift;
|
||||
bool alt = mods1->alt == mods2->alt;
|
||||
bool ctrl = mods1->ctrl == mods2->ctrl;
|
||||
bool meta = mods1->meta == mods2->meta;
|
||||
bool button = it->item.button == it2->item.m.button;
|
||||
bool count = it->item.count == it2->item.m.count;
|
||||
bool button = combo1->button == combo2->m.button;
|
||||
bool count = combo1->count == combo2->m.count;
|
||||
|
||||
if (shift && alt && ctrl && meta && button && count) {
|
||||
bool has_pipe = it->item.pipe.cmd != NULL;
|
||||
bool has_pipe = combo1->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],
|
||||
path, lineno, combo2->text,
|
||||
binding_action_map[combo1->action],
|
||||
has_pipe ? " [" : "",
|
||||
has_pipe ? it->item.pipe.cmd : "",
|
||||
has_pipe ? combo1->pipe.cmd : "",
|
||||
has_pipe ? "]" : "");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1911,13 +1981,18 @@ 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.pipe.master_copy) {
|
||||
free(it->item.pipe.cmd);
|
||||
free(it->item.pipe.argv);
|
||||
for (size_t i = 0; i < conf->bindings.mouse.count; i++) {
|
||||
struct config_mouse_binding *binding =
|
||||
&conf->bindings.mouse.arr[i];
|
||||
|
||||
if (binding->action == action) {
|
||||
if (binding->pipe.master_copy) {
|
||||
free(binding->pipe.cmd);
|
||||
free(binding->pipe.argv);
|
||||
}
|
||||
tll_remove(conf->bindings.mouse, it);
|
||||
binding->action = BIND_ACTION_NONE;
|
||||
binding->pipe.cmd = NULL;
|
||||
binding->pipe.argv = NULL;
|
||||
}
|
||||
}
|
||||
free(pipe_argv);
|
||||
|
|
@ -1925,7 +2000,7 @@ parse_section_mouse_bindings(
|
|||
return true;
|
||||
}
|
||||
|
||||
key_combo_list_t key_combos = tll_init();
|
||||
struct key_combo_list key_combos = {0};
|
||||
if (!parse_mouse_combos(conf, value, &key_combos, path, lineno) ||
|
||||
has_mouse_binding_collisions(conf, &key_combos, path, lineno))
|
||||
{
|
||||
|
|
@ -1936,35 +2011,47 @@ parse_section_mouse_bindings(
|
|||
}
|
||||
|
||||
/* Remove existing bindings for this action */
|
||||
tll_foreach(conf->bindings.mouse, it) {
|
||||
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)))
|
||||
for (size_t i = 0; i < conf->bindings.mouse.count; i++) {
|
||||
struct config_mouse_binding *binding = &conf->bindings.mouse.arr[i];
|
||||
|
||||
if (binding->action == action &&
|
||||
((binding->pipe.argv == NULL && pipe_argv == NULL) ||
|
||||
(binding->pipe.argv != NULL && pipe_argv != NULL &&
|
||||
argv_compare(binding->pipe.argv, pipe_argv) == 0)))
|
||||
{
|
||||
if (it->item.pipe.master_copy) {
|
||||
free(it->item.pipe.cmd);
|
||||
free(it->item.pipe.argv);
|
||||
if (binding->pipe.master_copy) {
|
||||
free(binding->pipe.cmd);
|
||||
free(binding->pipe.argv);
|
||||
}
|
||||
tll_remove(conf->bindings.mouse, it);
|
||||
binding->action = BIND_ACTION_NONE;
|
||||
binding->pipe.cmd = NULL;
|
||||
binding->pipe.argv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Emit mouse bindings */
|
||||
size_t ofs = conf->bindings.mouse.count;
|
||||
conf->bindings.mouse.count += key_combos.count;
|
||||
conf->bindings.mouse.arr = xrealloc(
|
||||
conf->bindings.mouse.arr,
|
||||
conf->bindings.mouse.count * sizeof(conf->bindings.mouse.arr[0]));
|
||||
|
||||
bool first = true;
|
||||
tll_foreach(key_combos, it) {
|
||||
for (size_t i = 0; i < key_combos.count; i++) {
|
||||
const struct key_combo *combo = &key_combos.combos[i];
|
||||
struct config_mouse_binding binding = {
|
||||
.action = action,
|
||||
.modifiers = it->item.modifiers,
|
||||
.button = it->item.m.button,
|
||||
.count = it->item.m.count,
|
||||
.modifiers = combo->modifiers,
|
||||
.button = combo->m.button,
|
||||
.count = combo->m.count,
|
||||
.pipe = {
|
||||
.cmd = pipe_cmd,
|
||||
.argv = pipe_argv,
|
||||
.master_copy = first,
|
||||
},
|
||||
};
|
||||
tll_push_back(conf->bindings.mouse, binding);
|
||||
|
||||
conf->bindings.mouse.arr[ofs + i] = binding;
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
|
@ -2362,137 +2449,112 @@ get_server_socket_path(void)
|
|||
return xasprintf("%s/foot-%s.sock", xdg_runtime, wayland_display);
|
||||
}
|
||||
|
||||
static void NOINLINE
|
||||
add_key_binding(config_key_binding_list_t *list, int action,
|
||||
const struct config_key_modifiers *mods, xkb_keysym_t sym)
|
||||
{
|
||||
tll_push_back(
|
||||
*list,
|
||||
((struct config_key_binding){action, *mods, sym}));
|
||||
}
|
||||
#define m_none {0}
|
||||
#define m_alt {.alt = true}
|
||||
#define m_ctrl {.ctrl = true}
|
||||
#define m_shift {.shift = true}
|
||||
#define m_ctrl_shift {.ctrl = true, .shift = true}
|
||||
|
||||
static void
|
||||
add_default_key_bindings(struct config *conf)
|
||||
{
|
||||
#define add_binding(action, mods, sym) \
|
||||
add_key_binding(&conf->bindings.key, action, &mods, sym)
|
||||
static const struct config_key_binding bindings[] = {
|
||||
{BIND_ACTION_SCROLLBACK_UP_PAGE, m_shift, XKB_KEY_Page_Up},
|
||||
{BIND_ACTION_SCROLLBACK_DOWN_PAGE, m_shift, XKB_KEY_Page_Down},
|
||||
{BIND_ACTION_CLIPBOARD_COPY, m_ctrl_shift, XKB_KEY_c},
|
||||
{BIND_ACTION_CLIPBOARD_PASTE, m_ctrl_shift, XKB_KEY_v},
|
||||
{BIND_ACTION_PRIMARY_PASTE, m_shift, XKB_KEY_Insert},
|
||||
{BIND_ACTION_SEARCH_START, m_ctrl_shift, XKB_KEY_r},
|
||||
{BIND_ACTION_FONT_SIZE_UP, m_ctrl, XKB_KEY_plus},
|
||||
{BIND_ACTION_FONT_SIZE_UP, m_ctrl, XKB_KEY_equal},
|
||||
{BIND_ACTION_FONT_SIZE_UP, m_ctrl, XKB_KEY_KP_Add},
|
||||
{BIND_ACTION_FONT_SIZE_DOWN, m_ctrl, XKB_KEY_minus},
|
||||
{BIND_ACTION_FONT_SIZE_DOWN, m_ctrl, XKB_KEY_KP_Subtract},
|
||||
{BIND_ACTION_FONT_SIZE_RESET, m_ctrl, XKB_KEY_0},
|
||||
{BIND_ACTION_FONT_SIZE_RESET, m_ctrl, XKB_KEY_KP_0},
|
||||
{BIND_ACTION_SPAWN_TERMINAL, m_ctrl_shift, XKB_KEY_n},
|
||||
{BIND_ACTION_SHOW_URLS_LAUNCH, m_ctrl_shift, XKB_KEY_u},
|
||||
};
|
||||
|
||||
const struct config_key_modifiers shift = {.shift = true};
|
||||
const struct config_key_modifiers ctrl = {.ctrl = true};
|
||||
const struct config_key_modifiers ctrl_shift = {.ctrl = true, .shift = true};
|
||||
|
||||
add_binding(BIND_ACTION_SCROLLBACK_UP_PAGE, shift, XKB_KEY_Page_Up);
|
||||
add_binding(BIND_ACTION_SCROLLBACK_DOWN_PAGE, shift, XKB_KEY_Page_Down);
|
||||
add_binding(BIND_ACTION_CLIPBOARD_COPY, ctrl_shift, XKB_KEY_c);
|
||||
add_binding(BIND_ACTION_CLIPBOARD_PASTE, ctrl_shift, XKB_KEY_v);
|
||||
add_binding(BIND_ACTION_PRIMARY_PASTE, shift, XKB_KEY_Insert);
|
||||
add_binding(BIND_ACTION_SEARCH_START, ctrl_shift, XKB_KEY_r);
|
||||
add_binding(BIND_ACTION_FONT_SIZE_UP, ctrl, XKB_KEY_plus);
|
||||
add_binding(BIND_ACTION_FONT_SIZE_UP, ctrl, XKB_KEY_equal);
|
||||
add_binding(BIND_ACTION_FONT_SIZE_UP, ctrl, XKB_KEY_KP_Add);
|
||||
add_binding(BIND_ACTION_FONT_SIZE_DOWN, ctrl, XKB_KEY_minus);
|
||||
add_binding(BIND_ACTION_FONT_SIZE_DOWN, ctrl, XKB_KEY_KP_Subtract);
|
||||
add_binding(BIND_ACTION_FONT_SIZE_RESET, ctrl, XKB_KEY_0);
|
||||
add_binding(BIND_ACTION_FONT_SIZE_RESET, ctrl, XKB_KEY_KP_0);
|
||||
add_binding(BIND_ACTION_SPAWN_TERMINAL, ctrl_shift, XKB_KEY_n);
|
||||
add_binding(BIND_ACTION_SHOW_URLS_LAUNCH, ctrl_shift, XKB_KEY_u);
|
||||
|
||||
#undef add_binding
|
||||
conf->bindings.key.count = ALEN(bindings);
|
||||
conf->bindings.key.arr = xmalloc(sizeof(bindings));
|
||||
memcpy(conf->bindings.key.arr, bindings, sizeof(bindings));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_default_search_bindings(struct config *conf)
|
||||
{
|
||||
#define add_binding(action, mods, sym) \
|
||||
add_key_binding(&conf->bindings.search, action, &mods, sym)
|
||||
static const struct config_key_binding bindings[] = {
|
||||
{BIND_ACTION_SEARCH_CANCEL, m_ctrl, XKB_KEY_c},
|
||||
{BIND_ACTION_SEARCH_CANCEL, m_ctrl, XKB_KEY_g},
|
||||
{BIND_ACTION_SEARCH_CANCEL, m_none, XKB_KEY_Escape},
|
||||
{BIND_ACTION_SEARCH_COMMIT, m_none, XKB_KEY_Return},
|
||||
{BIND_ACTION_SEARCH_FIND_PREV, m_ctrl, XKB_KEY_r},
|
||||
{BIND_ACTION_SEARCH_FIND_NEXT, m_ctrl, XKB_KEY_s},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT, m_none, XKB_KEY_Left},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT, m_ctrl, XKB_KEY_b},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT_WORD, m_ctrl, XKB_KEY_Left},
|
||||
{BIND_ACTION_SEARCH_EDIT_LEFT_WORD, m_alt, XKB_KEY_b},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT, m_none, XKB_KEY_Right},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT, m_ctrl, XKB_KEY_f},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT_WORD, m_ctrl, XKB_KEY_Right},
|
||||
{BIND_ACTION_SEARCH_EDIT_RIGHT_WORD, m_alt, XKB_KEY_f},
|
||||
{BIND_ACTION_SEARCH_EDIT_HOME, m_none, XKB_KEY_Home},
|
||||
{BIND_ACTION_SEARCH_EDIT_HOME, m_ctrl, XKB_KEY_a},
|
||||
{BIND_ACTION_SEARCH_EDIT_END, m_none, XKB_KEY_End},
|
||||
{BIND_ACTION_SEARCH_EDIT_END, m_ctrl, XKB_KEY_e},
|
||||
{BIND_ACTION_SEARCH_DELETE_PREV, m_none, XKB_KEY_BackSpace},
|
||||
{BIND_ACTION_SEARCH_DELETE_PREV_WORD, m_ctrl, XKB_KEY_BackSpace},
|
||||
{BIND_ACTION_SEARCH_DELETE_PREV_WORD, m_alt, XKB_KEY_BackSpace},
|
||||
{BIND_ACTION_SEARCH_DELETE_NEXT, m_none, XKB_KEY_Delete},
|
||||
{BIND_ACTION_SEARCH_DELETE_NEXT_WORD, m_ctrl, XKB_KEY_Delete},
|
||||
{BIND_ACTION_SEARCH_DELETE_NEXT_WORD, m_alt, XKB_KEY_d},
|
||||
{BIND_ACTION_SEARCH_EXTEND_WORD, m_ctrl, XKB_KEY_w},
|
||||
{BIND_ACTION_SEARCH_EXTEND_WORD_WS, m_ctrl_shift, XKB_KEY_w},
|
||||
{BIND_ACTION_SEARCH_CLIPBOARD_PASTE, m_ctrl, XKB_KEY_v},
|
||||
{BIND_ACTION_SEARCH_CLIPBOARD_PASTE, m_ctrl, XKB_KEY_y},
|
||||
{BIND_ACTION_SEARCH_PRIMARY_PASTE, m_shift, XKB_KEY_Insert},
|
||||
};
|
||||
|
||||
const struct config_key_modifiers none = {0};
|
||||
const struct config_key_modifiers alt = {.alt = true};
|
||||
const struct config_key_modifiers ctrl = {.ctrl = true};
|
||||
const struct config_key_modifiers shift = {.shift = true};
|
||||
const struct config_key_modifiers ctrl_shift = {.ctrl = true, .shift = true};
|
||||
|
||||
add_binding(BIND_ACTION_SEARCH_CANCEL, ctrl, XKB_KEY_c);
|
||||
add_binding(BIND_ACTION_SEARCH_CANCEL, ctrl, XKB_KEY_g);
|
||||
add_binding(BIND_ACTION_SEARCH_CANCEL, none, XKB_KEY_Escape);
|
||||
add_binding(BIND_ACTION_SEARCH_COMMIT, none, XKB_KEY_Return);
|
||||
add_binding(BIND_ACTION_SEARCH_FIND_PREV, ctrl, XKB_KEY_r);
|
||||
add_binding(BIND_ACTION_SEARCH_FIND_NEXT, ctrl, XKB_KEY_s);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_LEFT, none, XKB_KEY_Left);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_LEFT, ctrl, XKB_KEY_b);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_LEFT_WORD, ctrl, XKB_KEY_Left);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_LEFT_WORD, alt, XKB_KEY_b);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_RIGHT, none, XKB_KEY_Right);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_RIGHT, ctrl, XKB_KEY_f);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_RIGHT_WORD, ctrl, XKB_KEY_Right);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_RIGHT_WORD, alt, XKB_KEY_f);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_HOME, none, XKB_KEY_Home);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_HOME, ctrl, XKB_KEY_a);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_END, none, XKB_KEY_End);
|
||||
add_binding(BIND_ACTION_SEARCH_EDIT_END, ctrl, XKB_KEY_e);
|
||||
add_binding(BIND_ACTION_SEARCH_DELETE_PREV, none, XKB_KEY_BackSpace);
|
||||
add_binding(BIND_ACTION_SEARCH_DELETE_PREV_WORD, ctrl, XKB_KEY_BackSpace);
|
||||
add_binding(BIND_ACTION_SEARCH_DELETE_PREV_WORD, alt, XKB_KEY_BackSpace);
|
||||
add_binding(BIND_ACTION_SEARCH_DELETE_NEXT, none, XKB_KEY_Delete);
|
||||
add_binding(BIND_ACTION_SEARCH_DELETE_NEXT_WORD, ctrl, XKB_KEY_Delete);
|
||||
add_binding(BIND_ACTION_SEARCH_DELETE_NEXT_WORD, alt, XKB_KEY_d);
|
||||
add_binding(BIND_ACTION_SEARCH_EXTEND_WORD, ctrl, XKB_KEY_w);
|
||||
add_binding(BIND_ACTION_SEARCH_EXTEND_WORD_WS, ctrl_shift, XKB_KEY_w);
|
||||
add_binding(BIND_ACTION_SEARCH_CLIPBOARD_PASTE, ctrl, XKB_KEY_v);
|
||||
add_binding(BIND_ACTION_SEARCH_CLIPBOARD_PASTE, ctrl, XKB_KEY_y);
|
||||
add_binding(BIND_ACTION_SEARCH_PRIMARY_PASTE, shift, XKB_KEY_Insert);
|
||||
|
||||
#undef add_binding
|
||||
conf->bindings.search.count = ALEN(bindings);
|
||||
conf->bindings.search.arr = xmalloc(sizeof(bindings));
|
||||
memcpy(conf->bindings.search.arr, bindings, sizeof(bindings));
|
||||
}
|
||||
|
||||
static void
|
||||
add_default_url_bindings(struct config *conf)
|
||||
{
|
||||
#define add_binding(action, mods, sym) \
|
||||
add_key_binding(&conf->bindings.url, action, &mods, sym)
|
||||
static const struct config_key_binding bindings[] = {
|
||||
{BIND_ACTION_URL_CANCEL, m_ctrl, XKB_KEY_c},
|
||||
{BIND_ACTION_URL_CANCEL, m_ctrl, XKB_KEY_g},
|
||||
{BIND_ACTION_URL_CANCEL, m_ctrl, XKB_KEY_d},
|
||||
{BIND_ACTION_URL_CANCEL, m_none, XKB_KEY_Escape},
|
||||
{BIND_ACTION_URL_TOGGLE_URL_ON_JUMP_LABEL, m_none, XKB_KEY_t},
|
||||
};
|
||||
|
||||
const struct config_key_modifiers none = {0};
|
||||
const struct config_key_modifiers ctrl = {.ctrl = true};
|
||||
|
||||
add_binding(BIND_ACTION_URL_CANCEL, ctrl, XKB_KEY_c);
|
||||
add_binding(BIND_ACTION_URL_CANCEL, ctrl, XKB_KEY_g);
|
||||
add_binding(BIND_ACTION_URL_CANCEL, ctrl, XKB_KEY_d);
|
||||
add_binding(BIND_ACTION_URL_CANCEL, none, XKB_KEY_Escape);
|
||||
add_binding(BIND_ACTION_URL_TOGGLE_URL_ON_JUMP_LABEL, none, XKB_KEY_t);
|
||||
|
||||
#undef add_binding
|
||||
}
|
||||
|
||||
static void NOINLINE
|
||||
add_mouse_binding(config_mouse_binding_list_t *list, int action,
|
||||
const struct config_key_modifiers *mods,
|
||||
int button, int count)
|
||||
{
|
||||
tll_push_back(
|
||||
*list,
|
||||
((struct config_mouse_binding){action, *mods, button, count, {0}}));
|
||||
conf->bindings.url.count = ALEN(bindings);
|
||||
conf->bindings.url.arr = xmalloc(sizeof(bindings));
|
||||
memcpy(conf->bindings.url.arr, bindings, sizeof(bindings));
|
||||
}
|
||||
|
||||
static void
|
||||
add_default_mouse_bindings(struct config *conf)
|
||||
{
|
||||
#define add_binding(action, mods, btn, count) \
|
||||
add_mouse_binding(&conf->bindings.mouse, action, &mods, btn, count)
|
||||
static const struct config_mouse_binding bindings[] = {
|
||||
{BIND_ACTION_PRIMARY_PASTE, m_none, BTN_MIDDLE, 1},
|
||||
{BIND_ACTION_SELECT_BEGIN, m_none, BTN_LEFT, 1},
|
||||
{BIND_ACTION_SELECT_BEGIN_BLOCK, m_ctrl, BTN_LEFT, 1},
|
||||
{BIND_ACTION_SELECT_EXTEND, m_none, BTN_RIGHT, 1},
|
||||
{BIND_ACTION_SELECT_EXTEND_CHAR_WISE, m_ctrl, BTN_RIGHT, 1},
|
||||
{BIND_ACTION_SELECT_WORD, m_none, BTN_LEFT, 2},
|
||||
{BIND_ACTION_SELECT_WORD_WS, m_ctrl, BTN_LEFT, 2},
|
||||
{BIND_ACTION_SELECT_ROW, m_none, BTN_LEFT, 3},
|
||||
};
|
||||
|
||||
const struct config_key_modifiers none = {0};
|
||||
const struct config_key_modifiers ctrl = {.ctrl = true};
|
||||
|
||||
add_binding(BIND_ACTION_PRIMARY_PASTE, none, BTN_MIDDLE, 1);
|
||||
add_binding(BIND_ACTION_SELECT_BEGIN, none, BTN_LEFT, 1);
|
||||
add_binding(BIND_ACTION_SELECT_BEGIN_BLOCK, ctrl, BTN_LEFT, 1);
|
||||
add_binding(BIND_ACTION_SELECT_EXTEND, none, BTN_RIGHT, 1);
|
||||
add_binding(BIND_ACTION_SELECT_EXTEND_CHAR_WISE, ctrl, BTN_RIGHT, 1);
|
||||
add_binding(BIND_ACTION_SELECT_WORD, none, BTN_LEFT, 2);
|
||||
add_binding(BIND_ACTION_SELECT_WORD_WS, ctrl, BTN_LEFT, 2);
|
||||
add_binding(BIND_ACTION_SELECT_ROW, none, BTN_LEFT, 3);
|
||||
|
||||
#undef add_binding
|
||||
conf->bindings.mouse.count = ALEN(bindings);
|
||||
conf->bindings.mouse.arr = xmalloc(sizeof(bindings));
|
||||
memcpy(conf->bindings.mouse.arr, bindings, sizeof(bindings));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -2521,7 +2583,7 @@ config_load(struct config *conf, const char *conf_path,
|
|||
.palette_based = false,
|
||||
},
|
||||
.startup_mode = STARTUP_WINDOWED,
|
||||
.fonts = {tll_init(), tll_init(), tll_init(), tll_init()},
|
||||
.fonts = {{0}},
|
||||
.line_height = {.pt = 0, .px = -1},
|
||||
.letter_spacing = {.pt = 0, .px = 0},
|
||||
.horizontal_letter_offset = {.pt = 0, .px = 0},
|
||||
|
|
@ -2734,13 +2796,16 @@ config_load(struct config *conf, const char *conf_path,
|
|||
conf->colors.selection_bg >> 24 == 0;
|
||||
|
||||
out:
|
||||
if (ret && tll_length(conf->fonts[0]) == 0) {
|
||||
if (ret && conf->fonts[0].count == 0) {
|
||||
struct config_font font;
|
||||
if (!config_font_parse("monospace", &font)) {
|
||||
LOG_ERR("failed to load font 'monospace' - no fonts installed?");
|
||||
ret = false;
|
||||
} else
|
||||
tll_push_back(conf->fonts[0], font);
|
||||
} else {
|
||||
conf->fonts[0].count = 1;
|
||||
conf->fonts[0].arr = malloc(sizeof(font));
|
||||
conf->fonts[0].arr[0] = font;
|
||||
}
|
||||
}
|
||||
|
||||
free(conf_file.path);
|
||||
|
|
@ -2783,14 +2848,14 @@ config_override_apply(struct config *conf, config_override_t *overrides, bool er
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
static void NOINLINE
|
||||
free_spawn_template(struct config_spawn_template *template)
|
||||
{
|
||||
free(template->raw_cmd);
|
||||
free(template->argv);
|
||||
}
|
||||
|
||||
static void
|
||||
static void NOINLINE
|
||||
binding_pipe_free(struct config_binding_pipe *pipe)
|
||||
{
|
||||
if (pipe->master_copy) {
|
||||
|
|
@ -2806,12 +2871,11 @@ key_binding_free(struct config_key_binding *binding)
|
|||
}
|
||||
|
||||
static void
|
||||
key_binding_list_free(config_key_binding_list_t *bindings)
|
||||
key_binding_list_free(struct config_key_binding_list *bindings)
|
||||
{
|
||||
tll_foreach(*bindings, it) {
|
||||
key_binding_free(&it->item);
|
||||
tll_remove(*bindings, it);
|
||||
}
|
||||
for (size_t i = 0; i < bindings->count; i++)
|
||||
key_binding_free(&bindings->arr[i]);
|
||||
free(bindings->arr);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2825,12 +2889,8 @@ config_free(struct config conf)
|
|||
free_spawn_template(&conf.bell.command);
|
||||
free(conf.scrollback.indicator.text);
|
||||
free_spawn_template(&conf.notify);
|
||||
for (size_t i = 0; i < ALEN(conf.fonts); i++) {
|
||||
tll_foreach(conf.fonts[i], it) {
|
||||
config_font_destroy(&it->item);
|
||||
tll_remove(conf.fonts[i], it);
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < ALEN(conf.fonts); i++)
|
||||
config_font_list_destroy(&conf.fonts[i]);
|
||||
free(conf.server_socket_path);
|
||||
|
||||
free(conf.url.label_letters);
|
||||
|
|
@ -2843,10 +2903,9 @@ config_free(struct config conf)
|
|||
key_binding_list_free(&conf.bindings.search);
|
||||
key_binding_list_free(&conf.bindings.url);
|
||||
|
||||
tll_foreach(conf.bindings.mouse, it) {
|
||||
binding_pipe_free(&it->item.pipe);
|
||||
tll_remove(conf.bindings.mouse, it);
|
||||
}
|
||||
for (size_t i = 0; i < conf.bindings.mouse.count; i++)
|
||||
binding_pipe_free(&conf.bindings.mouse.arr[i].pipe);
|
||||
free(conf.bindings.mouse.arr);
|
||||
|
||||
user_notifications_free(&conf.notifications);
|
||||
}
|
||||
|
|
@ -2881,9 +2940,11 @@ config_font_parse(const char *pattern, struct config_font *font)
|
|||
}
|
||||
|
||||
void
|
||||
config_font_destroy(struct config_font *font)
|
||||
config_font_list_destroy(struct config_font_list *font_list)
|
||||
{
|
||||
if (font == NULL)
|
||||
return;
|
||||
free(font->pattern);
|
||||
for (size_t i = 0; i < font_list->count; i++)
|
||||
free(font_list->arr[i].pattern);
|
||||
free(font_list->arr);
|
||||
font_list->count = 0;
|
||||
font_list->arr = NULL;
|
||||
}
|
||||
|
|
|
|||
24
config.h
24
config.h
|
|
@ -15,6 +15,12 @@
|
|||
#define DEFAULT_TERM "xterm-256color"
|
||||
#endif
|
||||
|
||||
#define DEFINE_LIST(type) \
|
||||
type##_list { \
|
||||
size_t count; \
|
||||
type *arr; \
|
||||
}
|
||||
|
||||
enum conf_size_type {CONF_SIZE_PX, CONF_SIZE_CELLS};
|
||||
|
||||
struct config_font {
|
||||
|
|
@ -22,7 +28,7 @@ struct config_font {
|
|||
double pt_size;
|
||||
int px_size;
|
||||
};
|
||||
typedef tll(struct config_font) config_font_list_t;
|
||||
DEFINE_LIST(struct config_font);
|
||||
|
||||
struct config_key_modifiers {
|
||||
bool shift;
|
||||
|
|
@ -43,7 +49,7 @@ struct config_key_binding {
|
|||
xkb_keysym_t sym;
|
||||
struct config_binding_pipe pipe;
|
||||
};
|
||||
typedef tll(struct config_key_binding) config_key_binding_list_t;
|
||||
DEFINE_LIST(struct config_key_binding);
|
||||
|
||||
struct config_mouse_binding {
|
||||
enum bind_action_normal action;
|
||||
|
|
@ -52,7 +58,7 @@ struct config_mouse_binding {
|
|||
int count;
|
||||
struct config_binding_pipe pipe;
|
||||
};
|
||||
typedef tll(struct config_mouse_binding) config_mouse_binding_list_t;
|
||||
DEFINE_LIST(struct config_mouse_binding);
|
||||
|
||||
typedef tll(char *) config_override_t;
|
||||
|
||||
|
|
@ -89,7 +95,7 @@ struct config {
|
|||
enum { STARTUP_WINDOWED, STARTUP_MAXIMIZED, STARTUP_FULLSCREEN } startup_mode;
|
||||
|
||||
enum {DPI_AWARE_AUTO, DPI_AWARE_YES, DPI_AWARE_NO} dpi_aware;
|
||||
config_font_list_t fonts[4];
|
||||
struct config_font_list fonts[4];
|
||||
|
||||
/* Custom font metrics (-1 = use real font metrics) */
|
||||
struct pt_or_px line_height;
|
||||
|
|
@ -184,8 +190,8 @@ struct config {
|
|||
|
||||
struct {
|
||||
/* Bindings for "normal" mode */
|
||||
config_key_binding_list_t key;
|
||||
config_mouse_binding_list_t mouse;
|
||||
struct config_key_binding_list key;
|
||||
struct config_mouse_binding_list mouse;
|
||||
|
||||
/*
|
||||
* Special modes
|
||||
|
|
@ -193,10 +199,10 @@ struct config {
|
|||
|
||||
/* While searching (not - action to *start* a search is in the
|
||||
* 'key' bindings above */
|
||||
config_key_binding_list_t search;
|
||||
struct config_key_binding_list search;
|
||||
|
||||
/* While showing URL jump labels */
|
||||
config_key_binding_list_t url;
|
||||
struct config_key_binding_list url;
|
||||
} bindings;
|
||||
|
||||
struct {
|
||||
|
|
@ -257,4 +263,4 @@ bool config_load(
|
|||
void config_free(struct config conf);
|
||||
|
||||
bool config_font_parse(const char *pattern, struct config_font *font);
|
||||
void config_font_destroy(struct config_font *font);
|
||||
void config_font_list_destroy(struct config_font_list *font_list);
|
||||
|
|
|
|||
40
input.c
40
input.c
|
|
@ -527,22 +527,36 @@ convert_key_binding(const struct seat *seat,
|
|||
static void
|
||||
convert_key_bindings(const struct config *conf, struct seat *seat)
|
||||
{
|
||||
tll_foreach(conf->bindings.key, it)
|
||||
convert_key_binding(seat, &it->item, &seat->kbd.bindings.key);
|
||||
for (size_t i = 0; i < conf->bindings.key.count; i++) {
|
||||
const struct config_key_binding *binding = &conf->bindings.key.arr[i];
|
||||
if (binding->action == BIND_ACTION_NONE)
|
||||
continue;
|
||||
convert_key_binding(seat, binding, &seat->kbd.bindings.key);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_search_bindings(const struct config *conf, struct seat *seat)
|
||||
{
|
||||
tll_foreach(conf->bindings.search, it)
|
||||
convert_key_binding(seat, &it->item, &seat->kbd.bindings.search);
|
||||
for (size_t i = 0; i < conf->bindings.search.count; i++) {
|
||||
const struct config_key_binding *binding = &conf->bindings.search.arr[i];
|
||||
if (binding->action == BIND_ACTION_SEARCH_NONE)
|
||||
continue;
|
||||
convert_key_binding(seat, binding, &seat->kbd.bindings.search);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
convert_url_bindings(const struct config *conf, struct seat *seat)
|
||||
{
|
||||
tll_foreach(conf->bindings.url, it)
|
||||
convert_key_binding(seat, &it->item, &seat->kbd.bindings.url);
|
||||
for (size_t i = 0; i < conf->bindings.url.count; i++) {
|
||||
const struct config_key_binding *binding = &conf->bindings.url.arr[i];
|
||||
#if 0
|
||||
if (binding->action == BIND_ACTION_URL_NONE)
|
||||
continue;
|
||||
#endif
|
||||
convert_key_binding(seat, binding, &seat->kbd.bindings.url);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -562,8 +576,12 @@ convert_mouse_binding(struct seat *seat,
|
|||
static void
|
||||
convert_mouse_bindings(const struct config *conf, struct seat *seat)
|
||||
{
|
||||
tll_foreach(conf->bindings.mouse, it)
|
||||
convert_mouse_binding(seat, &it->item);
|
||||
for (size_t i = 0; i < conf->bindings.mouse.count; i++) {
|
||||
const struct config_mouse_binding *binding = &conf->bindings.mouse.arr[i];
|
||||
if (binding->action == BIND_ACTION_NONE)
|
||||
continue;
|
||||
convert_mouse_binding(seat, binding);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1924,9 +1942,11 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
|||
else {
|
||||
/* Seat does NOT have a keyboard - use mouse bindings *without* modifiers */
|
||||
const struct config_mouse_binding *match = NULL;
|
||||
const struct config *conf = seat->wayl->conf;
|
||||
|
||||
tll_foreach(seat->wayl->conf->bindings.mouse, it) {
|
||||
const struct config_mouse_binding *binding = &it->item;
|
||||
for (size_t i = 0; i < conf->bindings.mouse.count; i++) {
|
||||
const struct config_mouse_binding *binding =
|
||||
&conf->bindings.mouse.arr[i];
|
||||
|
||||
if (binding->button != button) {
|
||||
/* Wrong button */
|
||||
|
|
|
|||
17
main.c
17
main.c
|
|
@ -441,17 +441,22 @@ main(int argc, char *const *argv)
|
|||
if (login_shell)
|
||||
conf.login_shell = true;
|
||||
if (tll_length(conf_fonts) > 0) {
|
||||
for (size_t i = 0; i < ALEN(conf.fonts); i++) {
|
||||
tll_foreach(conf.fonts[i], it)
|
||||
config_font_destroy(&it->item);
|
||||
tll_free(conf.fonts[i]);
|
||||
}
|
||||
for (size_t i = 0; i < ALEN(conf.fonts); i++)
|
||||
config_font_list_destroy(&conf.fonts[i]);
|
||||
|
||||
struct config_font_list *font_list = &conf.fonts[0];
|
||||
xassert(font_list->count == 0);
|
||||
xassert(font_list->arr == NULL);
|
||||
|
||||
font_list->arr = xmalloc(
|
||||
tll_length(conf_fonts) * sizeof(font_list->arr[0]));
|
||||
|
||||
tll_foreach(conf_fonts, it) {
|
||||
struct config_font font;
|
||||
if (!config_font_parse(it->item, &font)) {
|
||||
LOG_ERR("%s: invalid font specification", it->item);
|
||||
} else
|
||||
tll_push_back(conf.fonts[0], font);
|
||||
font_list->arr[font_list->count++] = font;
|
||||
}
|
||||
tll_free(conf_fonts);
|
||||
}
|
||||
|
|
|
|||
52
terminal.c
52
terminal.c
|
|
@ -808,11 +808,13 @@ font_loader_thread(void *_data)
|
|||
static bool
|
||||
reload_fonts(struct terminal *term)
|
||||
{
|
||||
const struct config *conf = term->conf;
|
||||
|
||||
const size_t counts[4] = {
|
||||
tll_length(term->conf->fonts[0]),
|
||||
tll_length(term->conf->fonts[1]),
|
||||
tll_length(term->conf->fonts[2]),
|
||||
tll_length(term->conf->fonts[3]),
|
||||
conf->fonts[0].count,
|
||||
conf->fonts[1].count,
|
||||
conf->fonts[2].count,
|
||||
conf->fonts[3].count,
|
||||
};
|
||||
|
||||
/* Configure size (which may have been changed run-time) */
|
||||
|
|
@ -820,8 +822,10 @@ reload_fonts(struct terminal *term)
|
|||
for (size_t i = 0; i < 4; i++) {
|
||||
names[i] = xmalloc(counts[i] * sizeof(names[i][0]));
|
||||
|
||||
size_t j = 0;
|
||||
tll_foreach(term->conf->fonts[i], it) {
|
||||
const struct config_font_list *font_list = &conf->fonts[i];
|
||||
|
||||
for (size_t j = 0; j < font_list->count; j++) {
|
||||
const struct config_font *font = &font_list->arr[j];
|
||||
bool use_px_size = term->font_sizes[i][j].px_size > 0;
|
||||
char size[64];
|
||||
|
||||
|
|
@ -835,12 +839,11 @@ reload_fonts(struct terminal *term)
|
|||
snprintf(size, sizeof(size), ":size=%.2f",
|
||||
term->font_sizes[i][j].pt_size * (double)scale);
|
||||
|
||||
size_t len = strlen(it->item.pattern) + strlen(size) + 1;
|
||||
size_t len = strlen(font->pattern) + strlen(size) + 1;
|
||||
names[i][j] = xmalloc(len);
|
||||
|
||||
strcpy(names[i][j], it->item.pattern);
|
||||
strcpy(names[i][j], font->pattern);
|
||||
strcat(names[i][j], size);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -937,11 +940,15 @@ reload_fonts(struct terminal *term)
|
|||
static bool
|
||||
load_fonts_from_conf(struct terminal *term)
|
||||
{
|
||||
const struct config *conf = term->conf;
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
size_t j = 0;
|
||||
tll_foreach(term->conf->fonts[i], it) {
|
||||
const struct config_font_list *font_list = &conf->fonts[i];
|
||||
|
||||
for (size_t j = 0; i < font_list->count; j++) {
|
||||
const struct config_font *font = &font_list->arr[j];
|
||||
term->font_sizes[i][j++] = (struct config_font){
|
||||
.pt_size = it->item.pt_size, .px_size = it->item.px_size};
|
||||
.pt_size = font->pt_size, .px_size = font->px_size};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1039,10 +1046,10 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
|||
.ptmx_buffers = tll_init(),
|
||||
.ptmx_paste_buffers = tll_init(),
|
||||
.font_sizes = {
|
||||
xmalloc(sizeof(term->font_sizes[0][0]) * tll_length(conf->fonts[0])),
|
||||
xmalloc(sizeof(term->font_sizes[1][0]) * tll_length(conf->fonts[1])),
|
||||
xmalloc(sizeof(term->font_sizes[2][0]) * tll_length(conf->fonts[2])),
|
||||
xmalloc(sizeof(term->font_sizes[3][0]) * tll_length(conf->fonts[3])),
|
||||
xmalloc(sizeof(term->font_sizes[0][0]) * conf->fonts[0].count),
|
||||
xmalloc(sizeof(term->font_sizes[1][0]) * conf->fonts[1].count),
|
||||
xmalloc(sizeof(term->font_sizes[2][0]) * conf->fonts[2].count),
|
||||
xmalloc(sizeof(term->font_sizes[3][0]) * conf->fonts[3].count),
|
||||
},
|
||||
.font_dpi = 0.,
|
||||
.font_subpixel = (conf->colors.alpha == 0xffff /* Can't do subpixel rendering on transparent background */
|
||||
|
|
@ -1136,10 +1143,11 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
|||
term_update_ascii_printer(term);
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
size_t j = 0;
|
||||
tll_foreach(conf->fonts[i], it) {
|
||||
const struct config_font_list *font_list = &conf->fonts[i];
|
||||
for (size_t j = 0; j < font_list->count; j++) {
|
||||
const struct config_font *font = &font_list->arr[j];
|
||||
term->font_sizes[i][j++] = (struct config_font){
|
||||
.pt_size = it->item.pt_size, .px_size = it->item.px_size};
|
||||
.pt_size = font->pt_size, .px_size = font->px_size};
|
||||
}
|
||||
}
|
||||
term->font_line_height = conf->line_height;
|
||||
|
|
@ -1716,8 +1724,12 @@ term_reset(struct terminal *term, bool hard)
|
|||
static bool
|
||||
term_font_size_adjust(struct terminal *term, double amount)
|
||||
{
|
||||
const struct config *conf = term->conf;
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
for (size_t j = 0; j < tll_length(term->conf->fonts[i]); j++) {
|
||||
const struct config_font_list *font_list = &conf->fonts[i];
|
||||
|
||||
for (size_t j = 0; j < font_list->count; j++) {
|
||||
double old_pt_size = term->font_sizes[i][j].pt_size;
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue