diff --git a/docs/keyboard-protocol.rst b/docs/keyboard-protocol.rst index d613a6295..190ee7302 100644 --- a/docs/keyboard-protocol.rst +++ b/docs/keyboard-protocol.rst @@ -260,6 +260,11 @@ and alternate screens. If a pop request is received that empties the stack, all flags are reset. If a push request is received and the stack is full, the oldest entry from the stack must be evicted. +.. note:: In the interests of interoperation, the XTerm specific sequences + `CSI > 4; 1 m` and `CSI > 4; 0 m` are treated as `CSI > 1 u` and `CSI < 1 u`. + These codes cause XTerm to use the CSI u encoding for more keys and are therefore + treated as similar to the disambiguate progressive enhancement. + .. _disambiguate: Disambiguate escape codes diff --git a/kitty/parser.c b/kitty/parser.c index 3edd534f0..ed6ce0a03 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -943,7 +943,7 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) { break; case 'm': if (start_modifier == '>' && !end_modifier) { - REPORT_ERROR("Ignoring xterm specific key modifier resource options (CSI > m)"); + CALL_CSI_HANDLER2(screen_xtmodkeys, 0, 0); break; } /* fallthrough */ diff --git a/kitty/screen.c b/kitty/screen.c index 226de7ec2..673d9debe 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -886,6 +886,16 @@ screen_pop_key_encoding_flags(Screen *self, uint32_t num) { } } +void +screen_xtmodkeys(Screen *self, uint32_t p1, uint32_t p2) { + // this is the legacy XTerm escape code for modify keys + // https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Functions-using-CSI-_-ordered-by-the-final-character-lparen-s-rparen:CSI-gt-Pp-m.1DB2 + // we handle them as being equivalent to push and pop 1 onto the keyboard stack + if ((!p1 && !p2) || (p1 == 4 && p2 == 0)) screen_pop_key_encoding_flags(self, 1); + else if (p1 == 4 && p2 == 1) screen_push_key_encoding_flags(self, 1); +} + + // }}} // Cursor {{{ diff --git a/kitty/screen.h b/kitty/screen.h index aeb26888b..8f6b62e6d 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -229,6 +229,7 @@ void screen_push_key_encoding_flags(Screen *self, uint32_t val); void screen_pop_key_encoding_flags(Screen *self, uint32_t num); uint8_t screen_current_key_encoding_flags(Screen *self); void screen_report_key_encoding_flags(Screen *self); +void screen_xtmodkeys(Screen *self, uint32_t p1, uint32_t p2); #define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen); DECLARE_CH_SCREEN_HANDLER(bell) DECLARE_CH_SCREEN_HANDLER(backspace)