From 3512f9e812ef30485a78229f885d31e6bb5a18bf Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Fri, 20 Jan 2023 21:16:33 +0800 Subject: [PATCH] Fix misunderstanding in Kitty kbd proto docs --- doc/man/man3/notcurses_input.3.md | 9 ++++++--- include/notcurses/notcurses.h | 4 +++- src/lib/in.c | 27 ++++++--------------------- src/lib/reader.c | 7 ++++++- 4 files changed, 21 insertions(+), 26 deletions(-) diff --git a/doc/man/man3/notcurses_input.3.md b/doc/man/man3/notcurses_input.3.md index b30833bb7..5fbead784 100644 --- a/doc/man/man3/notcurses_input.3.md +++ b/doc/man/man3/notcurses_input.3.md @@ -37,7 +37,9 @@ typedef struct ncinput { ncintype_e evtype; unsigned modifiers;// bitmask over NCKEY_MOD_* int ypx, xpx; // pixel offsets within cell, -1 for undefined - char utf8_eff[5]; // Effective utf8 representation, taking modifier keys into account + uint32_t eff_text[5]; // Effective utf32 representation, taking + // modifier keys into account. This can be multiple + // codepoints. Array is zero-terminated. } ncinput; @@ -243,11 +245,12 @@ issues are resolved. You can determine whether the protocol is in use by examining the output of **notcurses-info(1)**. If the **kbd** property is indicated, you're using the Kitty protocol. -Note that utf_eff will always return the effective text value of the key, +Note that eff_text will always return the effective text value of the key, taking into account any meta keys pressed. (So shift-a will always return 'A' in this field, regardless of if the Kitty keyboard disambiguation protocol is used.) This field generally only can be trusted on -**NCTYPE_PRESS** and **NCTYPE_REPEAT** events, however. +**NCTYPE_PRESS** and **NCTYPE_REPEAT** events, however. Also note that +this is a (zero-terminated) array as it can return multiple codepoints. Mouse events in the left margins will never be delivered to the application (as is intended), but mouse events in the bottom and right margins diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 34328591c..b148a7c88 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -1214,7 +1214,9 @@ typedef struct ncinput { ncintype_e evtype; unsigned modifiers;// bitmask over NCKEY_MOD_* int ypx, xpx; // pixel offsets within cell, -1 for undefined - char utf8_eff[5]; // Effective utf8 representation, taking modifier keys into account + uint32_t eff_text[5]; // Effective utf32 representation, taking + // modifier keys into account. This can be multiple + // codepoints. Array is zero-terminated. } ncinput; static inline bool diff --git a/src/lib/in.c b/src/lib/in.c index b60db5ac5..3be466db0 100644 --- a/src/lib/in.c +++ b/src/lib/in.c @@ -797,7 +797,7 @@ kitty_functional(uint32_t val){ } static void -kitty_kbd_txt(inputctx* ictx, int val, int mods, unsigned *txt, int evtype){ +kitty_kbd_txt(inputctx* ictx, int val, int mods, uint32_t *txt, int evtype){ assert(evtype >= 0); assert(mods >= 0); assert(val > 0); @@ -830,23 +830,10 @@ kitty_kbd_txt(inputctx* ictx, int val, int mods, unsigned *txt, int evtype){ tni.evtype = NCTYPE_UNKNOWN; break; } - // Validate the txt array. It needs to be a non-zero-length set of up to 4 bytes. - int txt_valid = 0; - if(txt){ - for (int i = 0 ; i<4 ; i++){ - if(txt[i]==0) break; - if(txt[i]>255){ - txt_valid = 0; - break; - } - txt_valid = 1; - } - } - //note: if we don't populate .utf8_eff here, it will be set to what becomes .utf8 in - //internal_get(). - if(txt_valid){ + //note: if we don't set eff_text here, it will be set to .id later. + if(txt && txt[0]!=0){ for(int i=0 ; i<4 ; i++){ - tni.utf8_eff[i] = (char)txt[i]; + tni.eff_text[i] = txt[i]; } } load_ncinput(ictx, &tni); @@ -875,7 +862,7 @@ kitty_cb(inputctx* ictx){ static int kitty_cb_atxtn(inputctx* ictx, int n, int with_event){ - unsigned txt[5]={0}; + uint32_t txt[5]={0}; unsigned val = amata_next_numeric(&ictx->amata, "\x1b[", ';'); unsigned ev = 0; unsigned mods = 0; @@ -2709,9 +2696,7 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){ if(notcurses_ucs32_to_utf8(&ni->id, 1, (unsigned char*)ni->utf8, sizeof(ni->utf8)) < 0){ ni->utf8[0] = 0; } - if(ni->utf8_eff[0] == 0){ - memcpy(ni->utf8_eff, ni->utf8, sizeof(ni->utf8_eff)); - } + if (ni->eff_text[0]==0) ni->eff_text[0]=ni->id; } if(++ictx->iread == ictx->isize){ ictx->iread = 0; diff --git a/src/lib/reader.c b/src/lib/reader.c index 7dedbe057..1de3e4b16 100644 --- a/src/lib/reader.c +++ b/src/lib/reader.c @@ -401,7 +401,12 @@ bool ncreader_offer_input(ncreader* n, const ncinput* ni){ return false; } - ncreader_write_egc(n, ni->utf8_eff); + for (int c=0; ni->eff_text[c]!=0; c++){ + unsigned char egc[5]={0}; + if(notcurses_ucs32_to_utf8(&ni->eff_text[c], 1, egc, 4)>=0){ + ncreader_write_egc(n, (char*)egc); + } + } return true; }