• src/doors/syncconquer/door/door_input.c src/doors/syncdoom/syncdoom.c

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Mon Jul 13 21:37:59 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/a6db70e358aa19e785fb7553
    Modified Files:
    src/doors/syncconquer/door/door_input.c src/doors/syncdoom/syncdoom.c Log Message:
    syncdoom,syncconquer: resolve a lone ESC on a timer, not on the next key

    Pressing Escape in xterm did nothing until another key was pressed -- and if that key was Escape too, both arrived at once and the menu opened and
    instantly closed again.

    ESC is ambiguous: the Escape key and the first byte of every escape sequence (arrows are ESC[A) are the same 0x1b. The parser cannot classify it until it sees whether a byte follows, so it parks in the ESC state -- and neither door ever left that state on its own. The pending ESC was only flushed when the
    NEXT byte arrived, which is exactly the reported behavior.

    A real escape sequence arrives in one burst, so a follow-up byte is either there immediately or it is never coming. Deliver the pending ESC once that window (50ms) has elapsed, on a pump that reads nothing.

    SyncTERM hid this: it reports Escape as an evdev/kitty key event, never a bare 0x1b, so the byte path is never entered. A legacy-key terminal like xterm
    takes the byte path every time.

    SyncDuke (SYNCDUKE_ESC_MS) and SyncMOO1 (SM_ESC_MS) already did this; SyncDOOM and SyncConquer never got it. SyncRetro needs nothing -- a lone ESC is not a key on a RetroPad, and it says so.

    Not live-verified: the doors exit within a second without a real door socket, so the pty harness cannot hold one open long enough to drive a keystroke through it. The mechanism is a direct port of the one shipping in SyncDuke and SyncMOO1.
    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net