config: add tweak.grapheme-width-method=wcswidth|at-most-2

This commit is contained in:
Daniel Eklöf 2021-06-30 18:00:33 +02:00
parent 031e8f5987
commit 9817e44c32
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 46 additions and 5 deletions

View file

@ -36,6 +36,9 @@
terminfo entries. This should make 24-bit RGB colors work in tmux and terminfo entries. This should make 24-bit RGB colors work in tmux and
neovim, without the need for config hacks or detection heuristics neovim, without the need for config hacks or detection heuristics
(https://codeberg.org/dnkl/foot/issues/615). (https://codeberg.org/dnkl/foot/issues/615).
* `[tweak].grapheme-width-method=wcswidth|at-most-2` option to
`foot.ini`.
### Changed ### Changed
### Deprecated ### Deprecated

View file

@ -2255,6 +2255,15 @@ parse_section_tweak(
LOG_WARN("tweak: grapheme shaping"); LOG_WARN("tweak: grapheme shaping");
} }
else if (strcmp(key, "grapheme-width-method") == 0) {
if (strcmp(value, "at-most-2") == 0)
conf->tweak.grapheme_width_method = GRAPHEME_WIDTH_MAX_2;
else if (strcmp(value, "wcswidth") == 0)
conf->tweak.grapheme_width_method = GRAPHEME_WIDTH_WCSWIDTH;
LOG_WARN("%s:%d [tweak]: grapheme-width-method=%s", path, lineno, value);
}
else if (strcmp(key, "render-timer") == 0) { else if (strcmp(key, "render-timer") == 0) {
if (strcmp(value, "none") == 0) { if (strcmp(value, "none") == 0) {
conf->tweak.render_timer_osd = false; conf->tweak.render_timer_osd = false;
@ -2823,6 +2832,7 @@ config_load(struct config *conf, const char *conf_path,
.fcft_filter = FCFT_SCALING_FILTER_LANCZOS3, .fcft_filter = FCFT_SCALING_FILTER_LANCZOS3,
.allow_overflowing_double_width_glyphs = true, .allow_overflowing_double_width_glyphs = true,
.grapheme_shaping = false, .grapheme_shaping = false,
.grapheme_width_method = GRAPHEME_WIDTH_MAX_2,
.delayed_render_lower_ns = 500000, /* 0.5ms */ .delayed_render_lower_ns = 500000, /* 0.5ms */
.delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */ .delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */
.max_shm_pool_size = 512 * 1024 * 1024, .max_shm_pool_size = 512 * 1024 * 1024,

View file

@ -246,6 +246,7 @@ struct config {
enum fcft_scaling_filter fcft_filter; enum fcft_scaling_filter fcft_filter;
bool allow_overflowing_double_width_glyphs; bool allow_overflowing_double_width_glyphs;
bool grapheme_shaping; bool grapheme_shaping;
enum {GRAPHEME_WIDTH_WCSWIDTH, GRAPHEME_WIDTH_MAX_2} grapheme_width_method;
bool render_timer_osd; bool render_timer_osd;
bool render_timer_log; bool render_timer_log;
bool damage_whole_window; bool damage_whole_window;

View file

@ -997,8 +997,26 @@ any of these options.
but is necessary to not break cursor synchronization with the but is necessary to not break cursor synchronization with the
application running in foot. application running in foot.
See also: *grapheme-width-method*.
Default: _no_ Default: _no_
*grapheme-width-method*
Selects which method to use when calculating the width
(i.e. number of columns) of a grapheme cluster. One of *at-most-2*
and *wcswidth*.
*wcswidth* simply adds together the individual width of all
codepoints making up the cluster.
*at-most-2* does the same, but limits the maximum number of
columns to 2. This is more correct, but is likely to break
applications since applications typically use *wcswidth*(3)
internally to calculate the width. This results in cursor
de-synchronization issues.
Default: _at-most-2_
*max-shm-pool-size-mb* *max-shm-pool-size-mb*
This option controls the amount of virtual address space used by This option controls the amount of virtual address space used by
the pixmap memory to which the terminal screen content is the pixmap memory to which the terminal screen content is

19
vt.c
View file

@ -764,17 +764,26 @@ action_utf8_print(struct terminal *term, wchar_t wc)
(wanted_count - 2) * sizeof(new_cc->chars[0])); (wanted_count - 2) * sizeof(new_cc->chars[0]));
} }
int grapheme_width = composed != NULL ? composed->width : base_width; const int grapheme_width =
composed != NULL ? composed->width : base_width;
if (wc == 0xfe0f) switch (term->conf->tweak.grapheme_width_method) {
width = 2; case GRAPHEME_WIDTH_MAX_2:
new_cc->width = min(max(grapheme_width, width), 2); if (unlikely(wc == 0xfe0f))
width = 2;
new_cc->width = min(grapheme_width + width, 2);
break;
case GRAPHEME_WIDTH_WCSWIDTH:
new_cc->width = grapheme_width + width;
break;
}
term->composed_count++; term->composed_count++;
composed_insert(&term->composed, new_cc); composed_insert(&term->composed, new_cc);
wc = CELL_COMB_CHARS_LO + key; wc = CELL_COMB_CHARS_LO + key;
width = grapheme_width; width = new_cc->width;
xassert(wc >= CELL_COMB_CHARS_LO); xassert(wc >= CELL_COMB_CHARS_LO);
xassert(wc <= CELL_COMB_CHARS_HI); xassert(wc <= CELL_COMB_CHARS_HI);