mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
Add 'effective utf8' field to ncinput struct. This field will contain the utf8 emitted by a key with all modifiers taken into account.
This commit is contained in:
parent
eac79ee680
commit
d8cb625b9a
@ -37,6 +37,7 @@ 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
|
||||
} ncinput;
|
||||
|
||||
|
||||
@ -242,6 +243,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,
|
||||
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.
|
||||
|
||||
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
|
||||
sometimes can be if the event occurs prior to a window resize.
|
||||
|
@ -1214,6 +1214,7 @@ 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
|
||||
} ncinput;
|
||||
|
||||
static inline bool
|
||||
|
97
src/lib/in.c
97
src/lib/in.c
@ -797,7 +797,7 @@ kitty_functional(uint32_t val){
|
||||
}
|
||||
|
||||
static void
|
||||
kitty_kbd(inputctx* ictx, int val, int mods, int evtype){
|
||||
kitty_kbd_txt(inputctx* ictx, int val, int mods, unsigned *txt, int evtype){
|
||||
assert(evtype >= 0);
|
||||
assert(mods >= 0);
|
||||
assert(val > 0);
|
||||
@ -830,9 +830,33 @@ kitty_kbd(inputctx* ictx, int val, int mods, 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){
|
||||
for(int i=0 ; i<4 ; i++){
|
||||
tni.utf8_eff[i] = (char)txt[i];
|
||||
}
|
||||
}
|
||||
load_ncinput(ictx, &tni);
|
||||
}
|
||||
|
||||
static void
|
||||
kitty_kbd(inputctx* ictx, int val, int mods, int evtype){
|
||||
kitty_kbd_txt(ictx, val, mods, NULL, evtype);
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_simple(inputctx* ictx){
|
||||
unsigned val = amata_next_numeric(&ictx->amata, "\x1b[", 'u');
|
||||
@ -849,6 +873,66 @@ kitty_cb(inputctx* ictx){
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_atxtn(inputctx* ictx, int n, int with_event){
|
||||
unsigned txt[5]={0};
|
||||
unsigned val = amata_next_numeric(&ictx->amata, "\x1b[", ';');
|
||||
unsigned ev = 0;
|
||||
unsigned mods = 0;
|
||||
if (with_event) {
|
||||
mods = amata_next_numeric(&ictx->amata, "", ':');
|
||||
ev = amata_next_numeric(&ictx->amata, "", ';');
|
||||
} else {
|
||||
mods = amata_next_numeric(&ictx->amata, "", ';');
|
||||
}
|
||||
for (int i = 0; i<n; i++) {
|
||||
txt[i] = amata_next_numeric(&ictx->amata, "", (i==n-1)?'u':';');
|
||||
}
|
||||
kitty_kbd_txt(ictx, val, mods, txt, ev);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_atxt1(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 1, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_atxt2(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 2, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_atxt3(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 3, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_atxt4(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 4, 0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
kitty_cb_complex_atxt1(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 1, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_complex_atxt2(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 2, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_complex_atxt3(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 3, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
kitty_cb_complex_atxt4(inputctx* ictx){
|
||||
return kitty_cb_atxtn(ictx, 4, 1);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
legacy_functional(uint32_t id){
|
||||
switch(id){
|
||||
@ -1702,7 +1786,15 @@ build_cflow_automaton(inputctx* ictx){
|
||||
{ "[\\Nu", kitty_cb_simple, },
|
||||
{ "[\\N;\\N~", wezterm_cb, },
|
||||
{ "[\\N;\\Nu", kitty_cb, },
|
||||
{ "[\\N;\\N;\\Nu", kitty_cb_atxt1, },
|
||||
{ "[\\N;\\N;\\N;\\Nu", kitty_cb_atxt2, },
|
||||
{ "[\\N;\\N;\\N;\\N;\\Nu", kitty_cb_atxt3, },
|
||||
{ "[\\N;\\N;\\N;\\N;\\N;\\Nu", kitty_cb_atxt4, },
|
||||
{ "[\\N;\\N:\\Nu", kitty_cb_complex, },
|
||||
{ "[\\N;\\N:\\N;\\Nu", kitty_cb_complex_atxt1, },
|
||||
{ "[\\N;\\N:\\N;\\N;\\Nu", kitty_cb_complex_atxt2, },
|
||||
{ "[\\N;\\N:\\N;\\N;\\N;\\Nu", kitty_cb_complex_atxt3, },
|
||||
{ "[\\N;\\N:\\N;\\N;\\N;\\N;\\Nu", kitty_cb_complex_atxt4, },
|
||||
{ "[\\N;\\N;\\N~", xtmodkey_cb, },
|
||||
{ "[\\N;\\N:\\N~", kitty_cb_functional, },
|
||||
{ "[1;\\NP", legacy_cb_f1, },
|
||||
@ -2617,6 +2709,9 @@ 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(++ictx->iread == ictx->isize){
|
||||
ictx->iread = 0;
|
||||
|
@ -400,12 +400,8 @@ bool ncreader_offer_input(ncreader* n, const ncinput* ni){
|
||||
}else if(nckey_synthesized_p(ni->id)){
|
||||
return false;
|
||||
}
|
||||
// FIXME need to collect full EGCs
|
||||
char wbuf[WCHAR_MAX_UTF8BYTES + 1];
|
||||
// FIXME breaks for wint_t < 32bits
|
||||
if(snprintf(wbuf, sizeof(wbuf), "%lc", (wint_t)ni->id) < (int)sizeof(wbuf)){
|
||||
ncreader_write_egc(n, wbuf);
|
||||
}
|
||||
|
||||
ncreader_write_egc(n, ni->utf8_eff);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -351,9 +351,9 @@ init_terminfo_esc(tinfo* ti, const char* name, escape_e idx,
|
||||
#define KITTYQUERY
|
||||
#endif
|
||||
|
||||
// request kitty keyboard protocol features 1, 2, and 8, first pushing current.
|
||||
// request kitty keyboard protocol features 1, 2, 8 and 16, first pushing current.
|
||||
// see https://sw.kovidgoyal.net/kitty/keyboard-protocol/#progressive-enhancement
|
||||
#define KKBDSUPPORT "\x1b[=11u"
|
||||
#define KKBDSUPPORT "\x1b[=27u"
|
||||
|
||||
// the kitty keyboard protocol allows unambiguous, complete identification of
|
||||
// input events. this queries for the level of support. we want to do this
|
||||
|
Loading…
x
Reference in New Issue
Block a user