• src/syncterm/scripts/auto/connected/capture_menu.wrensrc/syncterm/Wren

    From Deucе@VERT to Git commit to main/sbbs/master on Mon May 4 09:29:21 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/811f5588743a4178e8705abc
    Added Files:
    src/syncterm/scripts/auto/connected/capture_menu.wren
    Modified Files:
    src/syncterm/Wren.adoc src/syncterm/scripts/auto/connected/keys_default.wren status_default.wren src/syncterm/scripts/syncterm.wren ui_list.wren src/syncterm/term.c term.h wren_bind.c wren_bind_conn.c wren_bind_conn.h wren_bind_fs.c wren_bind_fs.h
    Log Message:
    SyncTERM: move capture / scrollback / paste keys to Wren + write-consent File

    Continues hollowing out doterm()'s key switch into Wren-driven Hook.onKey defaults. Adds the bindings the Wren handlers need, plus a write-consent flavour on the File class so we can ask the user to pick a save path
    without handing scripts open-ended write access to the local filesystem.

    Capture (streaming-log control):
    New foreign class — Capture.active / paused / start(file, raw) /
    stop / pause / resume. Replaces CTerm.logMode and CTerm.logPaused
    (those getters are gone; Capture.active and Capture.paused are
    bools and live where the verbs live). start(file, raw) consumes
    a write-consent File and transfers the FILE pointer into cterm's
    logfile.

    CTerm.saveScreenshot(file, withSauce):
    One-shot binary screen save (IBM-CGA / BinaryText), optionally with
    a SAUCE block populated from the active BBS. Snapshot is the cterm
    area only — status bar excluded. Consumes the File's write consent.

    Host.pickSavePath(initialDir, mask):
    uifc filepick wrapped with ALLOWENTRY + OVERPROMPT. Returns a
    write-consent File (or null on cancel). Open mode is determined
    by the picker outcome: WFC_CREATE ("wbx") for new paths,
    WFC_OVERWRITE ("wb") when the user confirmed overwrite.

    Write consent on File:
    New consent class on the File foreign — File.open() honors the
    authorized mode and consumes the consent on first close. Re-using
    the handle aborts the fiber. Token is intentionally null on
    write-consent Files (the read-side .token / Host.openLocalFile
    flow for upload resume is unaffected).

    Race-safety: WFC_CREATE uses fopen "wbx" (C11 exclusive create) so
    an attacker can't substitute a different file between the picker's
    existence check and our open().

    Capture menu (scripts/auto/connected/capture_menu.wren):
    Wren App that drives the Alt-C user flow. Three states based on
    Capture.active/paused: not-capturing → type list (ASCII / Raw /
    Binary [+SAUCE]) → save picker → start; paused → Unpause/Close;
    active → Pause/Close. Replaces the C-side capture_control() uifc
    dialog for the Alt-C path (the Alt-Z menu still calls the C version
    until we migrate that too).

    Trivial-key migrations (Hook.onKey in keys_default.wren):
    - Shift-Insert → Conn.paste() (wraps do_paste — codepage- and
    bracketed-paste-aware).
    - Alt-B → Conn.scrollback() (wraps viewscroll() with
    mouse-event disable / restore).
    - Alt-C → CaptureMenu.run() (described above).
    Corresponding cases removed from doterm()'s switch.

    ListView fix (drive-by):
    ui_list.wren onPaint_ row-highlight fill now spans the full widget
    width (excluding the scrollbar column when present), so the
    selected-row lightbar reads as a single edge-to-edge bar instead
    of leaving the padding cells in default style. Fixes the
    ListView.draw rows-rendered test that regressed when the inset
    padding was added.

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

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