diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b68f2c2..1ace3be1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -162,6 +162,8 @@ * Restore `SIGHUP` in spawned processes. * Text reflow performance (https://codeberg.org/dnkl/foot/issues/504). * IL+DL (`CSI Ps L` + `CSI Ps M`) now moves the cursor to column 0. +* SS2 and SS3 (single shift) escape sequences behaving like locking + shifts. ### Security diff --git a/terminal.c b/terminal.c index 3d6c20d4..5ba7b854 100644 --- a/terminal.c +++ b/terminal.c @@ -2839,6 +2839,14 @@ ascii_printer_fast(struct terminal *term, wchar_t wc) xassert(!term->grid->cursor.lcf); } +static void +ascii_printer_single_shift(struct terminal *term, wchar_t wc) +{ + ascii_printer_generic(term, wc); + term->charsets.selected = term->charsets.saved; + term_update_ascii_printer(term); +} + void term_update_ascii_printer(struct terminal *term) { @@ -2860,6 +2868,14 @@ term_update_ascii_printer(struct terminal *term) term->ascii_printer = new_printer; } +void +term_set_single_shift_ascii_printer(struct terminal *term, int selected) +{ + term->charsets.saved = term->charsets.selected; + term->charsets.selected = selected; + term->ascii_printer = &ascii_printer_single_shift; +} + enum term_surface term_surface_kind(const struct terminal *term, const struct wl_surface *surface) { diff --git a/terminal.h b/terminal.h index 1721a4c1..a54185e2 100644 --- a/terminal.h +++ b/terminal.h @@ -192,6 +192,7 @@ enum charset { CHARSET_ASCII, CHARSET_GRAPHIC }; struct charsets { int selected; + int saved; enum charset set[4]; /* G0-G3 */ }; @@ -605,6 +606,7 @@ bool term_shutdown(struct terminal *term); int term_destroy(struct terminal *term); void term_update_ascii_printer(struct terminal *term); +void term_set_single_shift_ascii_printer(struct terminal *term, int selected); void term_reset(struct terminal *term, bool hard); bool term_to_slave(struct terminal *term, const void *data, size_t len); diff --git a/vt.c b/vt.c index 97f45c48..26affcd2 100644 --- a/vt.c +++ b/vt.c @@ -426,14 +426,12 @@ action_esc_dispatch(struct terminal *term, uint8_t final) case 'N': /* SS2 - Single Shift 2 */ - term->charsets.selected = 2; /* G2 */ - term_update_ascii_printer(term); + term_set_single_shift_ascii_printer(term, 2); /* G2 */ break; case 'O': /* SS3 - Single Shift 3 */ - term->charsets.selected = 3; /* G3 */ - term_update_ascii_printer(term); + term_set_single_shift_ascii_printer(term, 3); /* G3 */ break; case '\\':