Subj : src/conio/curs_cio.c To : Git commit to main/sbbs/master From : Rob Swindell (on Debian Linux) Date : Mon Aug 10 2026 21:30:27 https://gitlab.synchro.net/main/sbbs/-/commit/826514e72339ef2036c76d26 Modified Files: src/conio/curs_cio.c Log Message: Account for curses' own input queue in curs_kbhit() (#1223) Completing an escape sequence makes curses read ahead: on receiving ESC it consumes further bytes for up to ESCDELAY (uifc sets 25 ms) trying to match a key sequence, and holds whatever it swallowed but did not return in its own input queue. curs_kbhit() answered "is a key waiting?" with a zero-timeout select() on stdin, which cannot see that queue, and the uifc menu loop only calls getch() when kbhit says yes. A byte parked in the queue was therefore never fetched until unrelated input arrived on the descriptor, leaving the application one keystroke behind for the rest of the session. Typing ESC with anything close behind it is enough to trigger this, so it shows up readily over ssh and inside screen, where the network coalesces two quick keystrokes into a single burst. The visible symptom in SCFG is an ESC that does nothing until the next key is pressed. Every ciolib curses-mode program is affected, not just SCFG. Ask curses as well when select() comes up empty, and push back whatever it hands over. The suspended check is needed because curs_kbhit(), unlike curs_getch(), never calls curs_resume(), so it can be reached after endwin(). Co-Authored-By: Claude Opus 5 (1M context) --- SBBSecho 3.37-Linux * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705) .