• SCFG (curses mode): background shifts up by 1 row per scroll step in F

    From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Sun May 24 21:44:17 2026
    open https://gitlab.synchro.net/main/sbbs/-/issues/1147

    ## Summary

    In SCFG (and other UIFC-based TUIs) running in **curses output mode**
    (`-iC`), scrolling the F1 online help text causes the area of the
    screen *outside* the help window to shift up by one row per scroll
    keypress. The help window itself stays put and renders correctly;
    only the surrounding "background" (the few columns visible to the
    left/right of the centered 76-wide help frame, and any other rows
    ncurses doesn't repaint that step) walks upward.

    Symptom is consistent:

    - Reproduces on any menu — independent of which helpbuf is being
    displayed, as long as the help text is tall enough to scroll
    (i.e. taller than the visible help window).
    - Direction is **always up**, regardless of whether the user is
    scrolling the help content down or back up.
    - Exactly one row shift per scroll-key press (DOWN, PgDn, UP,
    PgUp).
    - Only the area outside the help window shifts; the help frame
    and inner text are fine.

    This is almost certainly a long-standing latent bug — likely been
    there as long as the curses backend has — that's only now being
    hit because of recent work to fill out SCFG's per-menu helpbufs
    with proper multi-paragraph descriptions tall enough to require
    scrolling. In the era of one-liner helpbufs nothing ever scrolled,
    so nobody noticed.

    ## Repro

    ```
    ~/sbbs/src/sbbs3/scfg/gcc.linux.x64.exe.debug/scfg -iC
    ```

    (Or any other curses-mode invocation: `-iI` ASCII curses, `-iF`
    IBM curses also expected to repro — only tested `-iC`.)

    Navigate to any menu whose helpbuf is taller than the help window
    (e.g. the top-level **System Configuration** menu after the recent
    `d448be457 scfg: rich helpbuf for System Configuration (System)
    root menu` commit). Press **F1**. Hit **DOWN** once. The columns
    of the screen visible *outside* the centered help window shift up
    by one row. Each additional scroll key shifts another row.

    ## Investigation so far (inconclusive)

    `showbuf()` in `src/uifc/uifc32.c` is called from `help()` with
    `WIN_MID | WIN_HLP`, width 76, height `api->scrn_len`. After the
    centering math, the help window covers `top+1 .. top+height` =
    rows `1 .. scrn_len` (in UIFC coords; `scrn_len` is one less than
    the real terminal height, accounting for the status line).

    Initial hypothesis was the help frame writing to the bottom row
    of stdscr — both `vmem_puttext` for the frame and the per-scroll `gotoxy`/`putch` for the up/down arrow indicators target row
    `top + height` (= `scrn_len`). On many ncurses/terminal combos,
    writing in or near the bottom-right cell can trigger a physical
    scroll that ncurses' diff layer doesn't fully clean up.

    Tested by editing `help()` to pass `WIN_L2R | WIN_HLP` (drop
    `WIN_T2B` so re-centering doesn't slide `top` back down) and
    `api->scrn_len - 1`, which puts the entire help window strictly
    above the bottom row. Rebuilt scfg, ran again — **background
    still shifts up** on each scroll step. So the bottom-row write
    theory is dead. Whatever's triggering the scroll is elsewhere.

    Other observations:

    - `scrollok(stdscr, FALSE)` is set in `curs_initciolib()`
    (`src/conio/curs_cio.c:868`) and never changed.
    - `idlok` is never called → defaults to FALSE → ncurses shouldn't
    emit insert-line/delete-line scroll commands as part of its
    refresh optimization.
    - `nonl()` is set; no `\n` translation.
    - The per-scroll write path inside `showbuf()`'s scroll loop is:
    `vmem_puttext` of the inner content area (rows `top+2+pad ..
    top+height-1-pad`, doesn't touch the bottom border row), then
    `gotoxy(SCROLL_UP_BUTTON_X, SCROLL_UP_BUTTON_Y)` and two
    `putch()` calls for the arrow indicators on the bottom border.
    Even with the help window forcibly shortened to leave the
    terminal bottom row alone, the symptom persists, so this path
    isn't the trigger either.

    ## Next step

    Capture the actual escape sequences emitted during one scroll
    step with `script(1)` and inspect — that'll show whether the
    shift comes from an explicit scroll/index sequence ncurses is
    emitting, or from a write that happens to advance the cursor
    past the screen edge:

    ```
    script -e -c "~/sbbs/src/sbbs3/scfg/gcc.linux.x64.exe.debug/scfg -iC" /tmp/scfg.script
    # F1, one DOWN, Esc Esc Esc to quit
    cat -v /tmp/scfg.script | less
    ```

    `TERM` value, presence of tmux/screen, and `infocmp $TERM | grep
    -E 'ind|scs|ri|csr'` may also matter — if the terminfo entry has
    unusual scroll-region or index capabilities, ncurses' optimizer
    behaves differently.

    — *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell@1:103/705 to GitLab note in main/sbbs on Sun May 24 21:45:40 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1147#note_9057

    **Clarification on the symptom** — the shift is **transient**, not persistent. On each scroll keypress the background cells appear to
    jump up by one row, then immediately snap back / get redrawn into
    place. So it's a one-frame visual flicker per scroll step, not a
    permanent drift of the background.

    That changes the diagnosis: this looks more like a refresh-order
    artifact — ncurses (or the terminal) momentarily shows a scrolled
    state before the next paint covers it — rather than a stuck
    off-by-one in the screen model. Consistent with the earlier
    finding that shrinking the help window to keep it off the bottom
    row didn't fix it.

    — *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Deucе@1:103/705 to GitLab note in main/sbbs on Sun May 24 21:50:09 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1147#note_9058

    One thing to check for is things directly poking stdout or stderr.
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Deucе@1:103/705 to GitLab note in main/sbbs on Sun May 24 22:04:13 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1147#note_9059

    Other important information to include is the value of `$TERM` and the terminal the issue was observed with.
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Deucе@1:103/705 to GitLab note in main/sbbs on Sun May 24 22:05:12 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1147#note_9060

    (Note, if TERM is syncterm, the termcap has recently been updated and fixed, so it should be verified that the installed termcap/terminfo matches the current entry, not a historical one)
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Rob Swindell@1:103/705 to GitLab note in main/sbbs on Sun May 24 22:18:53 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1147#note_9061

    **Environment for the report above:**

    - `TERM=xterm-256color`
    - Controlling terminal: Windows Terminal 1.24.11321.0

    — *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Deucе@1:103/705 to GitLab note in main/sbbs on Mon May 25 12:34:07 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1147#note_9062

    Another thing to check is that curses has the correct number of rows and columns.

    Testing with a broad selection of terminals (XFCE4 Terminal, kitty, ghostty, xterm, SyncTERM) on FreeBSD does not reproduce the issue, which suggests that Windows Terminal does not correctly match the behaviour described in the xterm-256color entry. Newer Curses come with an ms-terminal entry that may match better, but I'm not familiar with it, and Windows Terminal still seems to be a moving target.
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)
  • From Deucе@1:103/705 to GitLab note in main/sbbs on Mon May 25 12:38:14 2026
    https://gitlab.synchro.net/main/sbbs/-/issues/1147#note_9063

    Tested with alacritty and uxterm, still unable to reproduce.
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)