Please include the following data:
export | egrep 'LANG|LC_CTYPE|TERM':
declare -x LANG="en_US.UTF-8"
declare -x TERM="xterm-256color"
- notcurses version (available from
notcurses-demo i)
built from latest git master as of this issue report (but i can't actually open notcurses-demo i because of this problem)
- terminal name + version
Windows Terminal 1.24.11321.0
under Windows Terminal, talking to WSL2 Linux via ConPTY, notcurses_init() never returns. the program enters alternate screen and then gets stuck on a black screen
attaching a debugger revealed the main thread parked in inputlayer_get_responses() (src/lib/in.c) on pthread_cond_wait, waiting for a Primary Device Attributes (DA1) reply that never comes
i think it never arrives because the kitty graphics query APC that notcurses sends in DIRECTIVES immediately before the DA1 puts conpty's escape sequence parser into a state in which it just eats the DA1
notcurses already guards against this on native Windows builds:
// we do not send this query on Windows because it is bled through ConHost,
// and echoed onto the standard output.
#ifndef __MINGW32__
#define KITTYQUERY "\x1b_Gi=1,a=q;\x1b\\"
#else
#define KITTYQUERY
#endif
but of course, this does not trigger when it's running on real linux but being accessed through windows terminal.
repro example of the issue that causes this:
// this code dedicated to the public domain. no warranty
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <termios.h>
#include <ctype.h>
static struct termios g_orig;
static void raw_on(void){
struct termios t;
tcgetattr(STDIN_FILENO, &g_orig);
t = g_orig;
cfmakeraw(&t);
tcsetattr(STDIN_FILENO, TCSANOW, &t);
}
static void raw_off(void){ tcsetattr(STDIN_FILENO, TCSANOW, &g_orig); }
// write `query`, then collect everything that arrives within ~1.5s
static void run_case(const char *name, const char *query, size_t qlen){
// drain anything pending first
for(;;){
struct pollfd p = { .fd = STDIN_FILENO, .events = POLLIN, .revents = 0 };
char junk[256];
if(poll(&p, 1, 50) <= 0) break;
if(read(STDIN_FILENO, junk, sizeof junk) <= 0) break;
}
if(write(STDOUT_FILENO, query, qlen) < 0) return;
char buf[4096];
size_t n = 0;
for(;;){
struct pollfd p = { .fd = STDIN_FILENO, .events = POLLIN, .revents = 0 };
if(poll(&p, 1, 1500) <= 0) break; // timeout: terminal is done
ssize_t r = read(STDIN_FILENO, buf + n, sizeof(buf) - n - 1);
if(r <= 0) break;
n += (size_t)r;
if(n >= sizeof(buf) - 1) break;
}
int da1 = memmem(buf, n, "\x1b[?", 3) != NULL && n > 0 && buf[n-1] == 'c';
raw_off();
printf("=== %s ===\r\n sent:", name);
for(size_t i = 0; i < qlen; i++)
printf(isprint((unsigned char)query[i]) ? " %c" : " \\x%02x", (unsigned char)query[i]);
printf("\r\n got %zu bytes: ", n);
for(size_t i = 0; i < n; i++)
printf(isprint((unsigned char)buf[i]) ? "%c" : ".", (unsigned char)buf[i]);
printf("\r\n DA1 reply seen: %s\r\n\r\n", da1 ? "YES" : "no");
fflush(stdout);
raw_on();
}
int main(void){
raw_on();
run_case("1. DA1 alone",
"\x1b[c", 3);
run_case("2. DA2 alone (control)",
"\x1b[>c", 4);
run_case("3. kitty graphics APC, then DA1 (notcurses' DIRECTIVES order)",
"\x1b_Gi=1,a=q;\x1b\\" "\x1b[c", 11 + 3);
raw_off();
printf("if case 1 shows a DA1 reply but case 3 does not, the kitty graphics APC is consuming the DA1 that notcurses waits on as its init sentinel, which is why notcurses_init() never returns here.\r\n");
return 0;
}
Please include the following data:
export | egrep 'LANG|LC_CTYPE|TERM':notcurses-demo i)built from latest git master as of this issue report (but i can't actually open notcurses-demo i because of this problem)
Windows Terminal 1.24.11321.0
under Windows Terminal, talking to WSL2 Linux via ConPTY,notcurses_init()never returns. the program enters alternate screen and then gets stuck on a black screenattaching a debugger revealed the main thread parked ininputlayer_get_responses()(src/lib/in.c) onpthread_cond_wait, waiting for a Primary Device Attributes (DA1) reply that never comesi think it never arrives because the kitty graphics query APC that notcurses sends in DIRECTIVES immediately before the DA1 puts conpty's escape sequence parser into a state in which it just eats the DA1notcurses already guards against this on native Windows builds:but of course, this does not trigger when it's running on real linux but being accessed through windows terminal.repro example of the issue that causes this: