[term] don't send keyboard upcodes if we're draining input #2374

This commit is contained in:
nick black 2021-11-25 13:57:01 -05:00 committed by nick black
parent 9b0f806d04
commit 0003165180
4 changed files with 44 additions and 19 deletions

View File

@ -829,9 +829,11 @@ ncdirect_stop_minimal(void* vnc){
ret |= fbuf_finalize(&f, stdout);
}
if(nc->tcache.ttyfd >= 0){
if(nc->tcache.kbdlevel){
if(tty_emit(KKEYBOARD_POP, nc->tcache.ttyfd)){
ret = -1;
if(!(nc->flags & NCDIRECT_OPTION_DRAIN_INPUT)){
if(nc->tcache.kbdlevel){
if(tty_emit(KKEYBOARD_POP, nc->tcache.ttyfd)){
ret = -1;
}
}
}
const char* cnorm = get_escape(&nc->tcache, ESCAPE_CNORM);

View File

@ -21,7 +21,7 @@
// without unbounded allocation, and also without losing data. We'd furthermore
// like to reliably differentiate escapes and regular input, even when that
// latter contains escapes. Unbounded input will hopefully only be present when
// redirected from a file (NCOPTION_TOSS_INPUT)
// redirected from a file.
static sig_atomic_t cont_seen;
static sig_atomic_t resize_seen;

View File

@ -101,14 +101,17 @@ notcurses_stop_minimal(void* vnc){
}
// don't use use leave_alternate_screen() here; we need pop the keyboard
// whether we're in regular or alternate screen, and we need it done
// before returning to the regular screen if we're in the alternate.
if(nc->tcache.kbdlevel){
if(tty_emit(KKEYBOARD_POP, nc->tcache.ttyfd)){
ret = -1;
}
}else{
if(tty_emit(XTMODKEYSUNDO, nc->tcache.ttyfd)){
ret = -1;
// before returning to the regular screen if we're in the alternate. if
// we drained input, we never sent a keyboard modifier; send none now.
if(!(nc->flags & NCOPTION_DRAIN_INPUT)){
if(nc->tcache.kbdlevel){
if(tty_emit(KKEYBOARD_POP, nc->tcache.ttyfd)){
ret = -1;
}
}else{
if(tty_emit(XTMODKEYSUNDO, nc->tcache.ttyfd)){
ret = -1;
}
}
}
if(nc->tcache.in_alt_screen){

View File

@ -416,21 +416,39 @@ init_terminfo_esc(tinfo* ti, const char* name, escape_e idx,
// and geometry. send XTGETTCAP for terminal name. if 'minimal' is set, don't
// send any identification queries (we've already identified the terminal).
// write DSRCPR as early as possible, so that it precedes any query material
// that's bled onto stdin and echoed.
// that's bled onto stdin and echoed. if 'noaltscreen' is set, do not send
// an smcup. if 'draininput' is set, do not send any keyboard modifiers.
static int
send_initial_queries(int fd, bool minimal, bool noaltscreen){
send_initial_queries(int fd, unsigned minimal, unsigned noaltscreen,
unsigned draininput){
const char *queries;
if(noaltscreen){
if(minimal){
queries = DSRCPR KKBDENTER DIRECTIVES;
if(draininput){
queries = DSRCPR DIRECTIVES;
}else{
queries = DSRCPR KKBDENTER DIRECTIVES;
}
}else{
queries = DSRCPR KKBDENTER IDQUERIES DIRECTIVES;
if(draininput){
queries = DSRCPR IDQUERIES DIRECTIVES;
}else{
queries = DSRCPR KKBDENTER IDQUERIES DIRECTIVES;
}
}
}else{
if(minimal){
queries = SMCUP DSRCPR KKBDENTER DIRECTIVES;
if(draininput){
queries = SMCUP DSRCPR DIRECTIVES;
}else{
queries = SMCUP DSRCPR KKBDENTER DIRECTIVES;
}
}else{
queries = SMCUP DSRCPR KKBDENTER IDQUERIES DIRECTIVES;
if(draininput){
queries = SMCUP DSRCPR IDQUERIES DIRECTIVES;
}else{
queries = SMCUP DSRCPR KKBDENTER IDQUERIES DIRECTIVES;
}
}
}
size_t len = strlen(queries);
@ -453,6 +471,7 @@ int enter_alternate_screen(FILE* fp, tinfo* ti, bool flush){
if(term_emit(smcup, fp, false) < 0){
return -1;
}
// probably don't want to send these if we've drained input...FIXME
if(ti->kbdlevel){
if(term_emit(KKBDENTER, fp, flush)){
return -1;
@ -475,6 +494,7 @@ int leave_alternate_screen(FILE* fp, tinfo* ti){
logerror("can't leave alternate screen");
return -1;
}
// probably don't want to send these if we've drained input...FIXME
if(ti->kbdlevel){
if(term_emit(KKEYBOARD_POP, fp, false) ||
term_emit(rmcup, fp, false) ||
@ -867,7 +887,7 @@ int interrogate_terminfo(tinfo* ti, FILE* out, unsigned utf8,
// if we already know our terminal (e.g. on the linux console), there's no
// need to send the identification queries. the controls are sufficient.
bool minimal = (ti->qterm != TERMINAL_UNKNOWN);
if(send_initial_queries(ti->ttyfd, minimal, noaltscreen)){
if(send_initial_queries(ti->ttyfd, minimal, noaltscreen, draininput)){
goto err;
}
}