This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository terminology.
View the commit online.
commit 9084ef0da2dea525e395dc3c70c1d914e27faa9f
Author: Boris Faure <[email protected]>
AuthorDate: Sat Sep 12 16:06:51 2026 +0200
keyin: implement modifyOtherKeys
xmod[] was write-only, so a client asking for level 2 still got the
legacy encoding. Emit CSI 27 ; Pm ; Pc ~ for the keys that qualify.
---
src/bin/keyin.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 106 insertions(+), 17 deletions(-)
diff --git a/src/bin/keyin.c b/src/bin/keyin.c
index 9236bc61..fc065d0a 100644
--- a/src/bin/keyin.c
+++ b/src/bin/keyin.c
@@ -57,6 +57,69 @@ static Eina_Hash *_key_bindings = NULL;
/* {{{ Keys to TTY */
+/* {{{ modifyOtherKeys */
+
+static Eina_Bool
+_xmod_other_keys(const Termpty *ty)
+{
+ return ty->termstate.xmod[XMOD_OTHER] == 2;
+}
+
+static void
+_xmod_write(Termpty *ty, int code, int alt, int shift, int ctrl)
+{
+ char buf[32];
+ int param = 1 + (shift ? 1 : 0) + (alt ? 2 : 0) + (ctrl ? 4 : 0);
+ int len = snprintf(buf, sizeof(buf), "\033[27;%d;%d~", param, code);
+
+ termpty_write(ty, buf, len);
+}
+
+/* xterm's ModifyOtherKeys(), modifyOtherKeys=2, for an ordinary key */
+static Eina_Bool
+_xmod_wants_other(int code, int alt, int shift, int ctrl)
+{
+ if (!alt && !shift && !ctrl)
+ return EINA_FALSE;
+ if ((code >= 0x40) && (code <= 0x7f))
+ return EINA_TRUE;
+ if (alt || ctrl)
+ return EINA_TRUE;
+ return (code == ' ');
+}
+
+/* Keysym name -> the character xterm would report for it, or -1 */
+static int
+_xmod_key_code(const char *key)
+{
+ static const struct {
+ const char *name;
+ char code;
+ } named[] = {
+ { "space", ' ' }, { "exclam", '!' }, { "quotedbl", '"' },
+ { "numbersign", '#' }, { "dollar", '$' }, { "percent", '%' },
+ { "ampersand", '&' }, { "apostrophe", '\'' }, { "parenleft", '(' },
+ { "parenright", ')' }, { "asterisk", '*' }, { "plus", '+' },
+ { "comma", ',' }, { "minus", '-' }, { "period", '.' },
+ { "slash", '/' }, { "colon", ':' }, { "semicolon", ';' },
+ { "less", '<' }, { "equal", '=' }, { "greater", '>' },
+ { "question", '?' }, { "at", '@' }, { "bracketleft", '[' },
+ { "backslash", '\\' }, { "bracketright", ']' }, { "asciicircum", '^' },
+ { "underscore", '_' }, { "grave", '`' }, { "braceleft", '{' },
+ { "bar", '|' }, { "braceright", '}' }, { "asciitilde", '~' },
+ };
+ unsigned int i;
+
+ if (key[0] && !key[1] && (key[0] >= 0x20) && (key[0] < 0x7f))
+ return key[0];
+ for (i = 0; i < sizeof(named)/sizeof(named[0]); i++)
+ if (!strcmp(key, named[i].name))
+ return named[i].code;
+ return -1;
+}
+
+/* }}} */
+
static Eina_Bool
_key_try(Termpty *ty, const Tty_Key *map, int len, const Evas_Event_Key_Down *ev,
int alt, int shift, int ctrl)
@@ -112,25 +175,21 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
if (!strcmp(ev->key, "BackSpace"))
{
+ const Config *cfg = ty->config;
+ char code = '\b';
+
+ if (!ty->termstate.send_bs && cfg->erase_is_del && !ctrl)
+ code = '\177';
+
+ /* xterm strips Control here, as per IsBackarrowToggle() */
+ if (_xmod_other_keys(ty) && (alt || shift))
+ {
+ _xmod_write(ty, code, alt, shift, ctrl);
+ return;
+ }
if (alt)
termpty_write(ty, "\033", 1);
- if (ty->termstate.send_bs)
- {
- termpty_write(ty, "\b", 1);
- }
- else
- {
- const Config *cfg = ty->config;
-
- if (cfg->erase_is_del && !ctrl)
- {
- termpty_write(ty, "\177", sizeof("\177") - 1);
- }
- else
- {
- termpty_write(ty, "\b", sizeof("\b") - 1);
- }
- }
+ termpty_write(ty, &code, 1);
return;
}
if (!strcmp(ev->key, "Escape"))
@@ -143,6 +202,10 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
{
TERMPTY_WRITE_STR("\034");
}
+ else if (_xmod_other_keys(ty) && (alt || shift || ctrl))
+ {
+ _xmod_write(ty, '\033', alt, shift, ctrl);
+ }
else
{
if (alt)
@@ -158,6 +221,11 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
}
if (!strcmp(ev->key, "Return"))
{
+ if (_xmod_other_keys(ty) && (alt || shift || ctrl))
+ {
+ _xmod_write(ty, '\r', alt, shift, ctrl);
+ return;
+ }
if (alt)
termpty_write(ty, "\033", 1);
if (ty->termstate.crlf)
@@ -171,6 +239,27 @@ keyin_handle_key_to_pty(Termpty *ty, const Evas_Event_Key_Down *ev,
return;
}
}
+ if (_xmod_other_keys(ty))
+ {
+ if (!strcmp(ev->key, "Tab") || !strcmp(ev->key, "ISO_Left_Tab"))
+ {
+ if (alt || shift || ctrl)
+ {
+ _xmod_write(ty, '\t', alt, shift, ctrl);
+ return;
+ }
+ }
+ else
+ {
+ int code = _xmod_key_code(ev->key);
+
+ if ((code >= 0) && _xmod_wants_other(code, alt, shift, ctrl))
+ {
+ _xmod_write(ty, code, alt, shift, ctrl);
+ return;
+ }
+ }
+ }
if (ev->key[0] == 'K' && (ev->key[1] == 'k' || ev->key[1] == 'P'))
{
if (!evas_key_lock_is_set(ev->locks, "Num_Lock"))
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.