• src/doors/termgfx/focus.c focus.h src/doors/termgfx/test/test_focus.cs

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Mon Aug 10 21:30:27 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/61e0fc1b44d9b0fe71ec050f
    Added Files:
    src/doors/termgfx/focus.c focus.h src/doors/termgfx/test/test_focus.c Modified Files:
    src/doors/termgfx/CMakeLists.txt src/doors/termgfx/test/CMakeLists.txt Log Message:
    termgfx: track terminal focus, so an unfocused window stops turning

    A terminal reports pointer motion whether or not its window has focus.
    A door reading motion as look-around therefore turns the view while the
    pointer is being moved for some other window, and the player comes back
    facing somewhere new.

    DECSET 1004 is the only way to know: the terminal sends CSI I on focus
    gained and CSI O on focus lost. focus.c wraps the two escape strings and
    the state machine, and offers a latched focus-out edge -- a release edge
    that falls while the window is unfocused never arrives, so a door has to
    let go of every held key when it hears about the gap, not when the next
    report happens to land.

    SyncTERM does not implement mode 1004 (src/conio/cterm.adoc), so nothing
    here may depend on the events arriving. What is stored is therefore the NEGATIVE, "focus has been lost", so that a zeroed struct means focused:
    doors memset their terminal state, and a `focused` field would start
    false and silently disable mouse look on every terminal that never
    answers.

    Only a bare, unparameterised final counts. Anything carrying parameters
    is somebody else's sequence -- claiming CSI S for F4 turned SyncTERM's XTSMGRAPHICS reply into a keypress that dropped the player back to the
    BBS, and CSI I and CSI O sit one letter away from the same trap.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net