mirror of
https://github.com/tmux/tmux.git
synced 2026-10-09 19:54:22 +00:00
Cleanup: moved the osc-133 marker save/restore into screen-write.c closer to where the issue existed.
This commit is contained in:
78
input.c
78
input.c
@@ -95,14 +95,6 @@ struct input_param {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Saved OSC 133 output marker. */
|
|
||||||
struct input_osc_133_ctx {
|
|
||||||
int running;
|
|
||||||
u_int start;
|
|
||||||
u_int col;
|
|
||||||
u_int collected;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Input parser context. */
|
/* Input parser context. */
|
||||||
struct input_ctx {
|
struct input_ctx {
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
@@ -181,9 +173,6 @@ static void input_osc_110(struct input_ctx *, const char *);
|
|||||||
static void input_osc_111(struct input_ctx *, const char *);
|
static void input_osc_111(struct input_ctx *, const char *);
|
||||||
static void input_osc_112(struct input_ctx *, const char *);
|
static void input_osc_112(struct input_ctx *, const char *);
|
||||||
static void input_osc_133(struct input_ctx *, const char *);
|
static void input_osc_133(struct input_ctx *, const char *);
|
||||||
static struct input_osc_133_ctx input_osc_133_save_marker(struct input_ctx *);
|
|
||||||
static void input_osc_133_restore_marker(struct input_ctx *,
|
|
||||||
const struct input_osc_133_ctx *);
|
|
||||||
|
|
||||||
/* Transition entry/exit handlers. */
|
/* Transition entry/exit handlers. */
|
||||||
static void input_clear(struct input_ctx *);
|
static void input_clear(struct input_ctx *);
|
||||||
@@ -947,6 +936,7 @@ input_reset(struct input_ctx *ictx, int clear)
|
|||||||
screen_write_start_pane(sctx, wp, &wp->base);
|
screen_write_start_pane(sctx, wp, &wp->base);
|
||||||
else
|
else
|
||||||
screen_write_start(sctx, &wp->base);
|
screen_write_start(sctx, &wp->base);
|
||||||
|
sctx->owner = wp;
|
||||||
screen_write_reset(sctx);
|
screen_write_reset(sctx);
|
||||||
screen_write_stop(sctx);
|
screen_write_stop(sctx);
|
||||||
}
|
}
|
||||||
@@ -1075,6 +1065,7 @@ input_parse_buffer(struct window_pane *wp, const u_char *buf, size_t len)
|
|||||||
screen_write_start_pane(sctx, wp, &wp->base);
|
screen_write_start_pane(sctx, wp, &wp->base);
|
||||||
else
|
else
|
||||||
screen_write_start(sctx, &wp->base);
|
screen_write_start(sctx, &wp->base);
|
||||||
|
sctx->owner = wp;
|
||||||
|
|
||||||
log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id,
|
log_debug("%s: %%%u %s, %zu bytes: %.*s", __func__, wp->id,
|
||||||
ictx->state->name, len, (int)len, buf);
|
ictx->state->name, len, (int)len, buf);
|
||||||
@@ -1094,6 +1085,7 @@ input_parse_screen(struct input_ctx *ictx, struct screen *s,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
screen_write_start_callback(sctx, s, cb, arg);
|
screen_write_start_callback(sctx, s, cb, arg);
|
||||||
|
sctx->owner = ictx->wp;
|
||||||
input_parse(ictx, buf, len);
|
input_parse(ictx, buf, len);
|
||||||
screen_write_stop(sctx);
|
screen_write_stop(sctx);
|
||||||
}
|
}
|
||||||
@@ -1477,7 +1469,6 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
struct screen *s = sctx->s;
|
struct screen *s = sctx->s;
|
||||||
const struct input_table_entry *entry;
|
const struct input_table_entry *entry;
|
||||||
struct options *oo;
|
struct options *oo;
|
||||||
struct input_osc_133_ctx osc133 = {0};
|
|
||||||
int i, n, m, ek, set, p;
|
int i, n, m, ek, set, p;
|
||||||
u_int cx, bg = ictx->cell.cell.bg;
|
u_int cx, bg = ictx->cell.cell.bg;
|
||||||
|
|
||||||
@@ -1751,19 +1742,13 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
case -1:
|
case -1:
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
/* Erasing to the end clears the whole screen at 0,0. */
|
|
||||||
if (s->cx == 0 && s->cy == 0)
|
|
||||||
osc133 = input_osc_133_save_marker(ictx);
|
|
||||||
screen_write_clearendofscreen(sctx, bg);
|
screen_write_clearendofscreen(sctx, bg);
|
||||||
input_osc_133_restore_marker(ictx, &osc133);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
screen_write_clearstartofscreen(sctx, bg);
|
screen_write_clearstartofscreen(sctx, bg);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
osc133 = input_osc_133_save_marker(ictx);
|
|
||||||
screen_write_clearscreen(sctx, bg);
|
screen_write_clearscreen(sctx, bg);
|
||||||
input_osc_133_restore_marker(ictx, &osc133);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (input_get(ictx, 1, 0, 0) == 0) {
|
if (input_get(ictx, 1, 0, 0) == 0) {
|
||||||
@@ -3310,63 +3295,6 @@ input_osc_133_mark_prompt(struct grid_line *gl, u_int col, const char *p)
|
|||||||
gl->flags |= GRID_LINE_START_PROMPT;
|
gl->flags |= GRID_LINE_START_PROMPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the running command's output start before clearing the screen. */
|
|
||||||
static struct input_osc_133_ctx
|
|
||||||
input_osc_133_save_marker(struct input_ctx *ictx)
|
|
||||||
{
|
|
||||||
struct window_pane *wp = ictx->wp;
|
|
||||||
struct screen *s = ictx->ctx.s;
|
|
||||||
struct grid *gd = s->grid;
|
|
||||||
struct grid_line *gl;
|
|
||||||
struct input_osc_133_ctx ctx = {0};
|
|
||||||
u_int y;
|
|
||||||
|
|
||||||
if (wp == NULL || s != &wp->base || SCREEN_IS_ALTERNATE(s) ||
|
|
||||||
(~wp->flags & PANE_CMDRUNNING))
|
|
||||||
return (ctx);
|
|
||||||
ctx.running = 1;
|
|
||||||
ctx.start = UINT_MAX;
|
|
||||||
ctx.collected = gd->scroll_collected;
|
|
||||||
for (y = gd->hsize + gd->sy; y > 0; y--) {
|
|
||||||
gl = grid_get_line(gd, y - 1);
|
|
||||||
if ((gl->flags & GRID_LINE_START_OUTPUT) &&
|
|
||||||
(~gl->flags & GRID_LINE_END_OUTPUT ||
|
|
||||||
gl->osc133_data.out_end_col < gl->osc133_data.out_start_col) &&
|
|
||||||
(~gl->flags & GRID_LINE_START_PROMPT ||
|
|
||||||
gl->osc133_data.prompt_col <= gl->osc133_data.out_start_col)) {
|
|
||||||
ctx.start = y - 1;
|
|
||||||
ctx.col = gl->osc133_data.out_start_col;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (gl->flags & (GRID_LINE_START_PROMPT|GRID_LINE_END_OUTPUT))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return (ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore the running command's output start if a screen clear removed it. */
|
|
||||||
static void
|
|
||||||
input_osc_133_restore_marker(struct input_ctx *ictx,
|
|
||||||
const struct input_osc_133_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct grid *gd = ictx->ctx.s->grid;
|
|
||||||
struct grid_line *gl;
|
|
||||||
u_int collected;
|
|
||||||
|
|
||||||
if (!ctx->running)
|
|
||||||
return;
|
|
||||||
collected = gd->scroll_collected - ctx->collected;
|
|
||||||
if (ctx->start != UINT_MAX && ctx->start >= collected) {
|
|
||||||
gl = grid_get_line(gd, ctx->start - collected);
|
|
||||||
if ((gl->flags & GRID_LINE_START_OUTPUT) &&
|
|
||||||
gl->osc133_data.out_start_col == ctx->col)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gl = grid_get_line(gd, gd->hsize);
|
|
||||||
gl->flags |= GRID_LINE_START_OUTPUT;
|
|
||||||
gl->osc133_data.out_start_col = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle the OSC 133 sequence. */
|
/* Handle the OSC 133 sequence. */
|
||||||
static void
|
static void
|
||||||
input_osc_133(struct input_ctx *ictx, const char *p)
|
input_osc_133(struct input_ctx *ictx, const char *p)
|
||||||
|
|||||||
@@ -231,6 +231,25 @@ for integration in plain marked; do
|
|||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Preserve C when the clear happens while copy mode suppresses tty updates.
|
||||||
|
$TMUX set-option -g scroll-on-clear off || exit 1
|
||||||
|
$TMUX new-window -d -n modeclear "seq 1 40; printf '\\033]133;A\\007p\\$ \\033]133;B\\007clear; echo hello; echo world\\n\\033]133;C\\007before\\n'; $TMUX wait-for -S modeclear-ready; $TMUX wait-for modeclear-go; printf '\\033[H\\033[2Jhello\\nworld\\n\\033]133;D;0\\007\\033]133;A\\007p\\$ \\033]133;B\\007'; $TMUX wait-for -S modeclear-done; exec sleep 100" || exit 1
|
||||||
|
$TMUX wait-for modeclear-ready || exit 1
|
||||||
|
$TMUX copy-mode -t :modeclear || exit 1
|
||||||
|
$TMUX wait-for -S modeclear-go || exit 1
|
||||||
|
$TMUX wait-for modeclear-done || exit 1
|
||||||
|
sleep 1
|
||||||
|
[ "$($TMUX display-message -p -t :modeclear.0 '#{pane_in_mode}')" = 1 ] || exit 1
|
||||||
|
$TMUX send-keys -t :modeclear.0 -X cancel || exit 1
|
||||||
|
$TMUX copy-mode -t :modeclear || exit 1
|
||||||
|
$TMUX send-keys -t :modeclear.0 -X cursor-up || exit 1
|
||||||
|
$TMUX send-keys -t :modeclear.0 C-o || exit 1
|
||||||
|
[ "$($TMUX display-message -p -t :modeclear.0 '#{selection_present}')" = 1 ] || exit 1
|
||||||
|
$TMUX set-buffer sentinel || exit 1
|
||||||
|
$TMUX send-keys -t :modeclear.0 -X copy-selection || exit 1
|
||||||
|
[ "$($TMUX show-buffer)" = "$(printf 'hello\nworld')" ] || exit 1
|
||||||
|
$TMUX send-keys -t :modeclear.0 -X cancel || exit 1
|
||||||
|
|
||||||
# Preserve C when scroll-on-clear keeps the command's earlier output.
|
# Preserve C when scroll-on-clear keeps the command's earlier output.
|
||||||
$TMUX set-option -g scroll-on-clear on || exit 1
|
$TMUX set-option -g scroll-on-clear on || exit 1
|
||||||
$TMUX new-window -d -n preserve "printf '\\033]133;A\\007p\\$ \\033]133;B\\007echo before; clear; echo hello; echo world\\n\\033]133;C\\007before\\n\\033[H\\033[2Jhello\\nworld\\n\\033]133;D;0\\007\\033]133;A\\007p\\$ \\033]133;B\\007'; exec sleep 100" || exit 1
|
$TMUX new-window -d -n preserve "printf '\\033]133;A\\007p\\$ \\033]133;B\\007echo before; clear; echo hello; echo world\\n\\033]133;C\\007before\\n\\033[H\\033[2Jhello\\nworld\\n\\033]133;D;0\\007\\033]133;A\\007p\\$ \\033]133;B\\007'; exec sleep 100" || exit 1
|
||||||
|
|||||||
@@ -401,6 +401,7 @@ screen_write_start_pane(struct screen_write_ctx *ctx, struct window_pane *wp,
|
|||||||
s = wp->screen;
|
s = wp->screen;
|
||||||
screen_write_init(ctx, s);
|
screen_write_init(ctx, s);
|
||||||
ctx->wp = wp;
|
ctx->wp = wp;
|
||||||
|
ctx->owner = wp;
|
||||||
|
|
||||||
if (log_get_level() != 0) {
|
if (log_get_level() != 0) {
|
||||||
log_debug("%s: size %ux%u, pane %%%u (at %u,%u)",
|
log_debug("%s: size %ux%u, pane %%%u (at %u,%u)",
|
||||||
@@ -2061,6 +2062,71 @@ screen_write_carriagereturn(struct screen_write_ctx *ctx)
|
|||||||
screen_write_set_cursor(ctx, 0, -1);
|
screen_write_set_cursor(ctx, 0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Saved OSC 133 output marker. */
|
||||||
|
struct screen_write_osc_133_ctx {
|
||||||
|
int running;
|
||||||
|
u_int start;
|
||||||
|
u_int col;
|
||||||
|
u_int collected;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Save the running command's output start before clearing the screen. */
|
||||||
|
static struct screen_write_osc_133_ctx
|
||||||
|
screen_write_osc_133_save_marker(struct screen_write_ctx *sctx)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = sctx->owner;
|
||||||
|
struct screen *s = sctx->s;
|
||||||
|
struct grid *gd = s->grid;
|
||||||
|
struct grid_line *gl;
|
||||||
|
struct screen_write_osc_133_ctx ctx = {0};
|
||||||
|
u_int y;
|
||||||
|
|
||||||
|
if (wp == NULL || s != &wp->base || SCREEN_IS_ALTERNATE(s) ||
|
||||||
|
(~wp->flags & PANE_CMDRUNNING))
|
||||||
|
return (ctx);
|
||||||
|
ctx.running = 1;
|
||||||
|
ctx.start = UINT_MAX;
|
||||||
|
ctx.collected = gd->scroll_collected;
|
||||||
|
for (y = gd->hsize + gd->sy; y > 0; y--) {
|
||||||
|
gl = grid_get_line(gd, y - 1);
|
||||||
|
if ((gl->flags & GRID_LINE_START_OUTPUT) &&
|
||||||
|
(~gl->flags & GRID_LINE_END_OUTPUT ||
|
||||||
|
gl->osc133_data.out_end_col < gl->osc133_data.out_start_col) &&
|
||||||
|
(~gl->flags & GRID_LINE_START_PROMPT ||
|
||||||
|
gl->osc133_data.prompt_col <= gl->osc133_data.out_start_col)) {
|
||||||
|
ctx.start = y - 1;
|
||||||
|
ctx.col = gl->osc133_data.out_start_col;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (gl->flags & (GRID_LINE_START_PROMPT|GRID_LINE_END_OUTPUT))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the running command's output start if a screen clear removed it. */
|
||||||
|
static void
|
||||||
|
screen_write_osc_133_restore_marker(struct screen_write_ctx *sctx,
|
||||||
|
const struct screen_write_osc_133_ctx *ctx)
|
||||||
|
{
|
||||||
|
struct grid *gd = sctx->s->grid;
|
||||||
|
struct grid_line *gl;
|
||||||
|
u_int collected;
|
||||||
|
|
||||||
|
if (!ctx->running)
|
||||||
|
return;
|
||||||
|
collected = gd->scroll_collected - ctx->collected;
|
||||||
|
if (ctx->start != UINT_MAX && ctx->start >= collected) {
|
||||||
|
gl = grid_get_line(gd, ctx->start - collected);
|
||||||
|
if ((gl->flags & GRID_LINE_START_OUTPUT) &&
|
||||||
|
gl->osc133_data.out_start_col == ctx->col)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gl = grid_get_line(gd, gd->hsize);
|
||||||
|
gl->flags |= GRID_LINE_START_OUTPUT;
|
||||||
|
gl->osc133_data.out_start_col = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear to end of screen from cursor. */
|
/* Clear to end of screen from cursor. */
|
||||||
void
|
void
|
||||||
screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||||
@@ -2072,6 +2138,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
u_int y, i, xoff, yoff, ocx, ocy;
|
u_int y, i, xoff, yoff, ocx, ocy;
|
||||||
struct visible_ranges *r;
|
struct visible_ranges *r;
|
||||||
struct visible_range *ri;
|
struct visible_range *ri;
|
||||||
|
struct screen_write_osc_133_ctx osc133 = {0};
|
||||||
|
|
||||||
#ifdef ENABLE_SIXEL
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
||||||
@@ -2081,6 +2148,10 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
screen_write_initctx(ctx, &ttyctx, 1, 1);
|
screen_write_initctx(ctx, &ttyctx, 1, 1);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
|
||||||
|
/* Erasing to the end clears the whole screen at 0,0. */
|
||||||
|
if (s->cx == 0 && s->cy == 0)
|
||||||
|
osc133 = screen_write_osc_133_save_marker(ctx);
|
||||||
|
|
||||||
/* Scroll into history if it is enabled and clearing entire screen. */
|
/* Scroll into history if it is enabled and clearing entire screen. */
|
||||||
if (s->cx == 0 &&
|
if (s->cx == 0 &&
|
||||||
s->cy == 0 &&
|
s->cy == 0 &&
|
||||||
@@ -2093,6 +2164,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
grid_view_clear(gd, s->cx, s->cy, sx - s->cx, 1, bg);
|
grid_view_clear(gd, s->cx, s->cy, sx - s->cx, 1, bg);
|
||||||
grid_view_clear(gd, 0, s->cy + 1, sx, sy - (s->cy + 1), bg);
|
grid_view_clear(gd, 0, s->cy + 1, sx, sy - (s->cy + 1), bg);
|
||||||
}
|
}
|
||||||
|
screen_write_osc_133_restore_marker(ctx, &osc133);
|
||||||
|
|
||||||
screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1));
|
screen_write_collect_clear(ctx, s->cy + 1, sy - (s->cy + 1));
|
||||||
screen_write_collect_flush(ctx, 0, __func__);
|
screen_write_collect_flush(ctx, 0, __func__);
|
||||||
@@ -2226,6 +2298,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
u_int y, i, xoff, yoff, ocx, ocy;
|
u_int y, i, xoff, yoff, ocx, ocy;
|
||||||
struct visible_ranges *r;
|
struct visible_ranges *r;
|
||||||
struct visible_range *ri;
|
struct visible_range *ri;
|
||||||
|
struct screen_write_osc_133_ctx osc133;
|
||||||
|
|
||||||
#ifdef ENABLE_SIXEL
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_free_all(s) && ctx->wp != NULL)
|
if (image_free_all(s) && ctx->wp != NULL)
|
||||||
@@ -2235,6 +2308,8 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
screen_write_initctx(ctx, &ttyctx, 1, 1);
|
screen_write_initctx(ctx, &ttyctx, 1, 1);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
|
||||||
|
osc133 = screen_write_osc_133_save_marker(ctx);
|
||||||
|
|
||||||
/* Scroll into history if it is enabled. */
|
/* Scroll into history if it is enabled. */
|
||||||
if ((s->grid->flags & GRID_HISTORY) &&
|
if ((s->grid->flags & GRID_HISTORY) &&
|
||||||
ctx->wp != NULL &&
|
ctx->wp != NULL &&
|
||||||
@@ -2242,6 +2317,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
|||||||
grid_view_clear_history(s->grid, bg);
|
grid_view_clear_history(s->grid, bg);
|
||||||
else
|
else
|
||||||
grid_view_clear(s->grid, 0, 0, sx, sy, bg);
|
grid_view_clear(s->grid, 0, 0, sx, sy, bg);
|
||||||
|
screen_write_osc_133_restore_marker(ctx, &osc133);
|
||||||
|
|
||||||
screen_write_collect_clear(ctx, 0, sy);
|
screen_write_collect_clear(ctx, 0, sy);
|
||||||
|
|
||||||
|
|||||||
1
tmux.h
1
tmux.h
@@ -1130,6 +1130,7 @@ typedef void (*screen_write_init_ctx_cb)(struct screen_write_ctx *,
|
|||||||
struct tty_ctx *);
|
struct tty_ctx *);
|
||||||
struct screen_write_ctx {
|
struct screen_write_ctx {
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
struct window_pane *owner; /* pane for screen metadata */
|
||||||
struct screen *s;
|
struct screen *s;
|
||||||
|
|
||||||
int flags;
|
int flags;
|
||||||
|
|||||||
Reference in New Issue
Block a user