From e33874e6b591f88cb1d9287e1663376df2fd583e Mon Sep 17 00:00:00 2001 From: "jabber.developer2" Date: Tue, 9 Jun 2026 14:24:35 +0300 Subject: [PATCH 1/2] fix(ui): reclaim pad by dead space instead of absolute height MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Variant A (PAD_THRESHOLD=12000) bounds the pad but still re-enters win_redraw() from the print path on every message once the *live* buffer renders >= the threshold — reachable with a single oversized message (huge paste, narrow terminal, crafted incoming), reintroducing the per-message redraw storm. Trigger the reclaim redraw on dead space (getcury - buffer->lines) instead of absolute pad height. After a redraw the cursor equals buffer->lines, so dead space is 0 regardless of buffer size: the reclaim can never fire while scrolling, and an oversized message no longer storms (and is shown in full rather than clipped). Dead space only accrues in a long append-only session that trimmed old entries — exactly when reclaiming is wanted. --- src/ui/window.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ui/window.c b/src/ui/window.c index 0f6e2780..a9a99f85 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -43,7 +43,7 @@ #include "ai/ai_client.h" static const int PAD_MIN_HEIGHT = 100; -static const int PAD_THRESHOLD = 12000; // above buffer cap (~9000): reclaims dead pad space, never fires while scrolling +static const int PAD_DEAD_SPACE_LIMIT = 2000; // reclaim once the pad holds this much dead space (cursor past live buffer); size-independent, so it never fires while scrolling static gboolean _in_redraw = FALSE; static void @@ -56,9 +56,10 @@ _win_ensure_pad_capacity(ProfWin* window, WINDOW* win, int lines_needed) int cur_height = getmaxy(win); int cur_width = getmaxx(win); if (lines_needed >= cur_height - 1) { - // If we are getting too large, trigger a redraw to clean up old lines - // but only if we are not already in a redraw process. - if (window && cur_height >= PAD_THRESHOLD && !_in_redraw) { + // redraw to reclaim dead pad space (cursor far past live buffer, e.g. a long + // append-only session); dead space never accrues while scrolling, only here + int dead = window ? lines_needed - window->layout->buffer->lines : 0; + if (window && dead > PAD_DEAD_SPACE_LIMIT && !_in_redraw) { win_redraw(window); } else { // resize to required lines + some buffer for next messages -- 2.49.1 From 36512d9ddef4cbb250f3409c588168b5b109ca66 Mon Sep 17 00:00:00 2001 From: "jabber.developer2" Date: Tue, 23 Jun 2026 14:18:37 +0300 Subject: [PATCH 2/2] fix(ui): measure dead pad space from the cursor, not the requested lines _win_print_internal now calls _win_ensure_pad_capacity() with getcury() plus the estimated message height, so deriving 'dead' from lines_needed counted that lookahead reservation as dead space. Compute it from getcury(win) directly so the reclaim keys off the real cursor-vs-buffer gap. --- src/ui/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/window.c b/src/ui/window.c index a9a99f85..4cbbbb71 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -58,7 +58,7 @@ _win_ensure_pad_capacity(ProfWin* window, WINDOW* win, int lines_needed) if (lines_needed >= cur_height - 1) { // redraw to reclaim dead pad space (cursor far past live buffer, e.g. a long // append-only session); dead space never accrues while scrolling, only here - int dead = window ? lines_needed - window->layout->buffer->lines : 0; + int dead = window ? getcury(win) - window->layout->buffer->lines : 0; if (window && dead > PAD_DEAD_SPACE_LIMIT && !_in_redraw) { win_redraw(window); } else { -- 2.49.1