From ff2ffd0f2098f0c42e1f01216e30676aeb43a681 Mon Sep 17 00:00:00 2001 From: Michael Grant Date: Sun, 20 Sep 2026 15:23:04 +0100 Subject: [PATCH] Bugfix: OSC133 tracking can lose the C marker (start-of-output) for whatever was on screen at the time when screen and copy buffer gets cleared. --- regress/output-commands.sh | 1 + window-copy.c | 35 ++++++++++++++++++----------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/regress/output-commands.sh b/regress/output-commands.sh index caf2d5b80..089bc25d5 100755 --- a/regress/output-commands.sh +++ b/regress/output-commands.sh @@ -120,6 +120,7 @@ $TMUX send-keys -t :same.0 -X copy-selection || exit 1 [ "$($TMUX show-buffer)" = one ] || exit 1 $TMUX send-keys -t :same.0 -X cancel || exit 1 +$TMUX set-option -g scroll-on-clear off || exit 1 $TMUX new-window -d -n clear "printf 'old1\\nold2\\nold3\\nold4\\nold5\\nold6\\n\\033]133;A\\007p\\$ \\033]133;B\\007echo 1; clear; ps\\n\\033]133;C\\0071\\n\\033[H\\033[2JPID TTY\\n1 pts/0\\n\\033]133;D;0\\007separator\\n\\033]133;A\\007p\\$ \\033]133;B\\007'; exec sleep 100" || exit 1 sleep 1 $TMUX copy-mode -t :clear || exit 1 diff --git a/window-copy.c b/window-copy.c index 0a4e4e984..19e262b1a 100644 --- a/window-copy.c +++ b/window-copy.c @@ -7345,6 +7345,12 @@ window_copy_find_output_range(struct window_mode_entry *wme, u_int *sx, } window_copy_output_end(data->source, ex, ey); } + if (*sx == *ex && *sy == *ey) { + log_debug("%s: output at cursor is empty, look for previous", + __func__); + return (window_copy_find_previous_output_range(data->source, + cursor_x, cursor_y, sx, sy, ex, ey)); + } log_debug("%s: output from %u,%u to %u,%u", __func__, *sx, *sy, *ex, *ey); return (1); @@ -7357,21 +7363,21 @@ window_copy_find_previous_output_range(struct screen *s, u_int cursor_x, { struct grid *gd = s->grid; struct grid_line *gl; - void *buf; - u_int start_x, start_y, end_x, end_y; + u_int start_x, start_y; u_int y, total; - size_t len; int found = 0, have_prompt = 0; - int pending = 0; + int pending = 0, started_here; total = gd->hsize + gd->sy; for (y = 0; y < total && y <= cursor_y; y++) { gl = grid_get_line(gd, y); + started_here = 0; if (gl->flags & GRID_LINE_START_OUTPUT && (y != cursor_y || gl->osc133_data.out_start_col <= cursor_x)) { start_x = gl->osc133_data.out_start_col; start_y = y; pending = 1; + started_here = 1; } /* The output may have cleared its C marker from the screen. */ if (!pending && !have_prompt && @@ -7380,26 +7386,21 @@ window_copy_find_previous_output_range(struct screen *s, u_int cursor_x, gl->osc133_data.out_end_col <= gl->osc133_data.prompt_col)) { start_x = start_y = 0; pending = 1; + started_here = 1; } if (pending && gl->flags & GRID_LINE_END_OUTPUT && (y != cursor_y || gl->osc133_data.out_end_col <= cursor_x)) { - end_x = gl->osc133_data.out_end_col; - end_y = y; - buf = window_copy_get_grid_range(gd, start_x, start_y, - end_x, end_y, &len); - if (buf != NULL) { - free(buf); - *sx = start_x; - *sy = start_y; - *ex = end_x; - *ey = end_y; - found = 1; - } + *sx = start_x; + *sy = start_y; + *ex = gl->osc133_data.out_end_col; + *ey = y; + found = 1; pending = 0; } if (gl->flags & GRID_LINE_START_PROMPT) { - pending = 0; have_prompt = 1; + if (!started_here) + pending = 0; } } return (found);