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;
|
ncintype_e evtype;
|
||||||
unsigned modifiers;// bitmask over NCKEY_MOD_*
|
unsigned modifiers;// bitmask over NCKEY_MOD_*
|
||||||
int ypx, xpx; // pixel offsets within cell, -1 for undefined
|
int ypx, xpx; // pixel offsets within cell, -1 for undefined
|
||||||
|
char utf8_eff[5]; // Effective utf8 representation, taking modifier keys into account
|
||||||
} ncinput;
|
} 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
|
by examining the output of **notcurses-info(1)**. If the **kbd** property
|
||||||
is indicated, you're using the Kitty protocol.
|
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
|
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
|
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.
|
sometimes can be if the event occurs prior to a window resize.
|
||||||
|
@ -1214,6 +1214,7 @@ typedef struct ncinput {
|
|||||||
ncintype_e evtype;
|
ncintype_e evtype;
|
||||||
unsigned modifiers;// bitmask over NCKEY_MOD_*
|
unsigned modifiers;// bitmask over NCKEY_MOD_*
|
||||||
int ypx, xpx; // pixel offsets within cell, -1 for undefined
|
int ypx, xpx; // pixel offsets within cell, -1 for undefined
|
||||||
|
char utf8_eff[5]; // Effective utf8 representation, taking modifier keys into account
|
||||||
} ncinput;
|
} ncinput;
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
|
97
src/lib/in.c
97
src/lib/in.c
@ -797,7 +797,7 @@ kitty_functional(uint32_t val){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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(evtype >= 0);
|
||||||
assert(mods >= 0);
|
assert(mods >= 0);
|
||||||
assert(val > 0);
|
assert(val > 0);
|
||||||
@ -830,9 +830,33 @@ kitty_kbd(inputctx* ictx, int val, int mods, int evtype){
|
|||||||
tni.evtype = NCTYPE_UNKNOWN;
|
tni.evtype = NCTYPE_UNKNOWN;
|
||||||
break;
|
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);
|
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
|
static int
|
||||||
kitty_cb_simple(inputctx* ictx){
|
kitty_cb_simple(inputctx* ictx){
|
||||||
unsigned val = amata_next_numeric(&ictx->amata, "\x1b[", 'u');
|
unsigned val = amata_next_numeric(&ictx->amata, "\x1b[", 'u');
|
||||||
@ -849,6 +873,66 @@ kitty_cb(inputctx* ictx){
|
|||||||
return 2;
|
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
|
static uint32_t
|
||||||
legacy_functional(uint32_t id){
|
legacy_functional(uint32_t id){
|
||||||
switch(id){
|
switch(id){
|
||||||
@ -1702,7 +1786,15 @@ build_cflow_automaton(inputctx* ictx){
|
|||||||
{ "[\\Nu", kitty_cb_simple, },
|
{ "[\\Nu", kitty_cb_simple, },
|
||||||
{ "[\\N;\\N~", wezterm_cb, },
|
{ "[\\N;\\N~", wezterm_cb, },
|
||||||
{ "[\\N;\\Nu", kitty_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:\\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~", xtmodkey_cb, },
|
||||||
{ "[\\N;\\N:\\N~", kitty_cb_functional, },
|
{ "[\\N;\\N:\\N~", kitty_cb_functional, },
|
||||||
{ "[1;\\NP", legacy_cb_f1, },
|
{ "[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){
|
if(notcurses_ucs32_to_utf8(&ni->id, 1, (unsigned char*)ni->utf8, sizeof(ni->utf8)) < 0){
|
||||||
ni->utf8[0] = 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){
|
if(++ictx->iread == ictx->isize){
|
||||||
ictx->iread = 0;
|
ictx->iread = 0;
|
||||||
|
@ -400,12 +400,8 @@ bool ncreader_offer_input(ncreader* n, const ncinput* ni){
|
|||||||
}else if(nckey_synthesized_p(ni->id)){
|
}else if(nckey_synthesized_p(ni->id)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// FIXME need to collect full EGCs
|
|
||||||
char wbuf[WCHAR_MAX_UTF8BYTES + 1];
|
ncreader_write_egc(n, ni->utf8_eff);
|
||||||
// FIXME breaks for wint_t < 32bits
|
|
||||||
if(snprintf(wbuf, sizeof(wbuf), "%lc", (wint_t)ni->id) < (int)sizeof(wbuf)){
|
|
||||||
ncreader_write_egc(n, wbuf);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,9 +351,9 @@ init_terminfo_esc(tinfo* ti, const char* name, escape_e idx,
|
|||||||
#define KITTYQUERY
|
#define KITTYQUERY
|
||||||
#endif
|
#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
|
// 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
|
// the kitty keyboard protocol allows unambiguous, complete identification of
|
||||||
// input events. this queries for the level of support. we want to do this
|
// input events. this queries for the level of support. we want to do this
|
||||||
|
Loading…
x
Reference in New Issue
Block a user