Some checks failed
CI Code / Check spelling (pull_request) Successful in 18s
CI Code / Check coding style (pull_request) Successful in 30s
CI Code / Code Coverage (pull_request) Successful in 3m24s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m54s
CI Code / Linux (debian) (pull_request) Successful in 6m58s
CI Code / Linux (arch) (pull_request) Successful in 7m7s
CI Code / Check spelling (push) Successful in 16s
CI Code / Check coding style (push) Successful in 32s
CI Code / Code Coverage (push) Failing after 3m24s
CI Code / Linux (debian) (push) Failing after 5m38s
CI Code / Linux (ubuntu) (push) Failing after 5m51s
CI Code / Linux (arch) (push) Failing after 7m38s
A tall multi-line message printed near the bottom of the ncurses pad was clipped because _win_print_internal grew the pad from the current cursor only (_win_ensure_pad_capacity(getcury)), not the height of the message about to be printed. The clipped message's captured height (e.g. 1 row for a 49-row message) was wrong while win_redraw later rendered it in full; the resulting buffer->lines / y_start_pos mismatch desynced the page-up scroll anchor, producing a ~one-page jump when scrolling past such messages from history.
Estimate the rendered height (hard newlines + soft-wrap over the usable width) and reserve that many rows before printing, so the message is never clipped and its captured height matches the redraw. All print paths go through _win_print_internal, so incoming/outgoing/history are covered.
Regression from the upstream sync (72f4f186d), which replaced the fixed-size pad with the dynamic _win_ensure_pad_capacity model.