This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch tmux-greenscroll
in repository terminology.
View the commit online.
commit d11383de93e7b29e7da035d73afd2cc351ecb1ce
Author: [email protected] <[email protected]>
AuthorDate: Fri Aug 21 11:47:57 2026 -0600
termptyops: fix scroll condition when cursor is below bottom margin
The scrolling region check incorrectly triggered a scroll even when the
cursor was already positioned below the bottom margin, where nothing
should happen.
With tmux's layout (e.g., pane rows 1..23, status line on row 24), a
line feed with cursor at row 24 would escape the boundary check and
trigger an unwanted scroll. This happened silently: tmux's own screen
model showed no change, so it never repaired the drift. Over long
sessions, pane content would shift further from the status line with
each occurrence.
The fix distinguishes two cases: when the cursor steps exactly onto the
bottom margin (cy == e), scroll the region and move cursor back up. When
it's already below (cy >= ty->h), don't scroll—just clamp the cursor to
the last row. This preserves the correct semantics: a line feed below
the region is a no-op.
Verified with differential harness (tmux byte stream rendered in tytest
vs. tmux-as-reference), minimal repro matching after fix. New regression
test added to tests/lf_below_bottom_margin.sh. Full suite: 153/156
passing (3 pre-existing failures on master).
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
src/bin/termptyops.c | 27 +++++++++++++++------------
tests/lf_below_bottom_margin.sh | 23 +++++++++++++++++++++++
tests/tests.results | 1 +
3 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/src/bin/termptyops.c b/src/bin/termptyops.c
index f1ceb0fc..5777458e 100644
--- a/src/bin/termptyops.c
+++ b/src/bin/termptyops.c
@@ -144,22 +144,25 @@ termpty_text_scroll_test(Termpty *ty, Eina_Bool clear)
int e = ty->h;
if (ty->termstate.bottom_margin != 0)
+ e = ty->termstate.bottom_margin;
+
+ if (ty->cursor_state.cy == e)
{
- e = ty->termstate.bottom_margin;
- if (ty->cursor_state.cy == e)
- {
- termpty_text_scroll(ty, clear);
- ty->cursor_state.cy = e - 1;
- TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
- return;
- }
- }
- if (ty->cursor_state.cy >= ty->h)
- {
+ /* Stepped off the bottom of the scrolling region: scroll it. */
termpty_text_scroll(ty, clear);
ty->cursor_state.cy = e - 1;
- TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
}
+ else if (ty->cursor_state.cy >= ty->h)
+ {
+ /* Below the region already (the cursor sits under the bottom margin):
+ * a line feed there just stays put, it does not scroll the region. */
+ ty->cursor_state.cy = ty->h - 1;
+ }
+ else
+ {
+ return;
+ }
+ TERMPTY_RESTRICT_FIELD(ty->cursor_state.cy, 0, ty->h);
}
void
diff --git a/tests/lf_below_bottom_margin.sh b/tests/lf_below_bottom_margin.sh
new file mode 100755
index 00000000..37cc48fe
--- /dev/null
+++ b/tests/lf_below_bottom_margin.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# A line feed with the cursor *below* the bottom margin must not scroll the
+# scrolling region: the cursor is already outside it, so it just stays put.
+# This is the layout tmux uses -- pane rows inside the region, status line on
+# the last row underneath it.
+
+# fill the screen so any stray scroll is visible
+printf '\033#8'
+
+# pane content
+printf '\033[1;1HTOP'
+printf '\033[23;1HBOTTOM_OF_REGION'
+
+# status line, below the region
+printf '\033[24;1HSTATUS'
+
+# tmux's pane scrolling region: rows 1..23
+printf '\033[1;23r'
+
+# park the cursor on the status row and feed lines there
+printf '\033[24;5H'
+printf '\n\n\n'
diff --git a/tests/tests.results b/tests/tests.results
index 8f6d270a..727f63a2 100644
--- a/tests/tests.results
+++ b/tests/tests.results
@@ -153,3 +153,4 @@ xterm-colors-rgbi.sh e03b6094b2e6ff60b519f132e9fc4433
xterm-set-cursor-color.sh 014a0027499b74ab705575c08005f438
csi-38-no-value.sh 70a432233cdbeeffb383c51be47979d4
osc_selection.sh ee9d9efb1f820ffd54de9465a9a90221
+lf_below_bottom_margin.sh 50502caece08a0c9b50d8c6a439a6fce
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.