Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2025-12-17 14:01:08 +00:00
7 changed files with 87 additions and 1 deletions

View File

@@ -1947,6 +1947,18 @@ format_cb_origin_flag(struct format_tree *ft)
return (NULL); return (NULL);
} }
/* Callback for synchronized_output_flag. */
static void *
format_cb_synchronized_output_flag(struct format_tree *ft)
{
if (ft->wp != NULL) {
if (ft->wp->base.mode & MODE_SYNC)
return (xstrdup("1"));
return (xstrdup("0"));
}
return (NULL);
}
/* Callback for pane_active. */ /* Callback for pane_active. */
static void * static void *
format_cb_pane_active(struct format_tree *ft) format_cb_pane_active(struct format_tree *ft)
@@ -3443,6 +3455,9 @@ static const struct format_table_entry format_table[] = {
{ "start_time", FORMAT_TABLE_TIME, { "start_time", FORMAT_TABLE_TIME,
format_cb_start_time format_cb_start_time
}, },
{ "synchronized_output_flag", FORMAT_TABLE_STRING,
format_cb_synchronized_output_flag
},
{ "tree_mode_format", FORMAT_TABLE_STRING, { "tree_mode_format", FORMAT_TABLE_STRING,
format_cb_tree_mode_format format_cb_tree_mode_format
}, },

10
input.c
View File

@@ -898,6 +898,8 @@ input_free(struct input_ctx *ictx)
evbuffer_free(ictx->since_ground); evbuffer_free(ictx->since_ground);
event_del(&ictx->ground_timer); event_del(&ictx->ground_timer);
screen_write_stop_sync(ictx->wp);
free(ictx); free(ictx);
} }
@@ -1901,6 +1903,11 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
case 2031: case 2031:
screen_write_mode_clear(sctx, MODE_THEME_UPDATES); screen_write_mode_clear(sctx, MODE_THEME_UPDATES);
break; break;
case 2026: /* synchronized output */
screen_write_stop_sync(ictx->wp);
if (ictx->wp != NULL)
ictx->wp->flags |= PANE_REDRAW;
break;
default: default:
log_debug("%s: unknown '%c'", __func__, ictx->ch); log_debug("%s: unknown '%c'", __func__, ictx->ch);
break; break;
@@ -1999,6 +2006,9 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
case 2031: case 2031:
screen_write_mode_set(sctx, MODE_THEME_UPDATES); screen_write_mode_set(sctx, MODE_THEME_UPDATES);
break; break;
case 2026: /* synchronized output */
screen_write_start_sync(ictx->wp);
break;
default: default:
log_debug("%s: unknown '%c'", __func__, ictx->ch); log_debug("%s: unknown '%c'", __func__, ictx->ch);
break; break;

View File

@@ -898,6 +898,9 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
struct grid_cell defaults; struct grid_cell defaults;
u_int i, j, top, x, y, width; u_int i, j, top, x, y, width;
if (wp->base.mode & MODE_SYNC)
screen_write_stop_sync(wp);
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id); log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id);
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx) if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx)

View File

@@ -894,6 +894,52 @@ screen_write_mode_clear(struct screen_write_ctx *ctx, int mode)
log_debug("%s: %s", __func__, screen_mode_to_string(mode)); log_debug("%s: %s", __func__, screen_mode_to_string(mode));
} }
/* Sync timeout callback. */
static void
screen_write_sync_callback(__unused int fd, __unused short events, void *arg)
{
struct window_pane *wp = arg;
log_debug("%s: %%%u sync timer expired", __func__, wp->id);
evtimer_del(&wp->sync_timer);
if (wp->base.mode & MODE_SYNC) {
wp->base.mode &= ~MODE_SYNC;
wp->flags |= PANE_REDRAW;
}
}
/* Start sync mode. */
void
screen_write_start_sync(struct window_pane *wp)
{
struct timeval tv = { .tv_sec = 1, .tv_usec = 0 };
if (wp == NULL)
return;
wp->base.mode |= MODE_SYNC;
if (!event_initialized(&wp->sync_timer))
evtimer_set(&wp->sync_timer, screen_write_sync_callback, wp);
evtimer_add(&wp->sync_timer, &tv);
log_debug("%s: %%%u started sync mode", __func__, wp->id);
}
/* Stop sync mode. */
void
screen_write_stop_sync(struct window_pane *wp)
{
if (wp == NULL)
return;
if (event_initialized(&wp->sync_timer))
evtimer_del(&wp->sync_timer);
wp->base.mode &= ~MODE_SYNC;
log_debug("%s: %%%u stopped sync mode", __func__, wp->id);
}
/* Cursor up by ny. */ /* Cursor up by ny. */
void void
screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny) screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny)
@@ -1782,6 +1828,9 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
u_int y, cx, cy, last, items = 0; u_int y, cx, cy, last, items = 0;
struct tty_ctx ttyctx; struct tty_ctx ttyctx;
if (s->mode & MODE_SYNC)
return;
if (ctx->scrolled != 0) { if (ctx->scrolled != 0) {
log_debug("%s: scrolled %u (region %u-%u)", __func__, log_debug("%s: scrolled %u (region %u-%u)", __func__,
ctx->scrolled, s->rupper, s->rlower); ctx->scrolled, s->rupper, s->rlower);
@@ -2080,7 +2129,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
} }
/* Write to the screen. */ /* Write to the screen. */
if (!skip) { if (!skip && !(s->mode & MODE_SYNC)) {
if (selected) { if (selected) {
screen_select_cell(s, &tmp_gc, gc); screen_select_cell(s, &tmp_gc, gc);
ttyctx.cell = &tmp_gc; ttyctx.cell = &tmp_gc;

1
tmux.1
View File

@@ -6264,6 +6264,7 @@ The following variables are available, where appropriate:
.It Li "socket_path" Ta "" Ta "Server socket path" .It Li "socket_path" Ta "" Ta "Server socket path"
.It Li "sixel_support" Ta "" Ta "1 if server has support for SIXEL" .It Li "sixel_support" Ta "" Ta "1 if server has support for SIXEL"
.It Li "start_time" Ta "" Ta "Server start time" .It Li "start_time" Ta "" Ta "Server start time"
.It Li "synchronized_output_flag" Ta "" Ta "1 if pane has synchronized output enabled"
.It Li "uid" Ta "" Ta "Server UID" .It Li "uid" Ta "" Ta "Server UID"
.It Li "user" Ta "" Ta "Server user" .It Li "user" Ta "" Ta "Server user"
.It Li "version" Ta "" Ta "Server version" .It Li "version" Ta "" Ta "Server version"

4
tmux.h
View File

@@ -652,6 +652,7 @@ enum tty_code_code {
#define MODE_CURSOR_BLINKING_SET 0x20000 #define MODE_CURSOR_BLINKING_SET 0x20000
#define MODE_KEYS_EXTENDED_2 0x40000 #define MODE_KEYS_EXTENDED_2 0x40000
#define MODE_THEME_UPDATES 0x80000 #define MODE_THEME_UPDATES 0x80000
#define MODE_SYNC 0x100000
#define ALL_MODES 0xffffff #define ALL_MODES 0xffffff
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL) #define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
@@ -1222,6 +1223,7 @@ struct window_pane {
struct window_pane_resizes resize_queue; struct window_pane_resizes resize_queue;
struct event resize_timer; struct event resize_timer;
struct event sync_timer;
struct input_ctx *ictx; struct input_ctx *ictx;
@@ -3144,6 +3146,8 @@ void screen_write_preview(struct screen_write_ctx *, struct screen *, u_int,
void screen_write_backspace(struct screen_write_ctx *); void screen_write_backspace(struct screen_write_ctx *);
void screen_write_mode_set(struct screen_write_ctx *, int); void screen_write_mode_set(struct screen_write_ctx *, int);
void screen_write_mode_clear(struct screen_write_ctx *, int); void screen_write_mode_clear(struct screen_write_ctx *, int);
void screen_write_start_sync(struct window_pane *);
void screen_write_stop_sync(struct window_pane *);
void screen_write_cursorup(struct screen_write_ctx *, u_int); void screen_write_cursorup(struct screen_write_ctx *, u_int);
void screen_write_cursordown(struct screen_write_ctx *, u_int); void screen_write_cursordown(struct screen_write_ctx *, u_int);
void screen_write_cursorright(struct screen_write_ctx *, u_int); void screen_write_cursorright(struct screen_write_ctx *, u_int);

View File

@@ -1001,6 +1001,8 @@ window_pane_destroy(struct window_pane *wp)
if (event_initialized(&wp->resize_timer)) if (event_initialized(&wp->resize_timer))
event_del(&wp->resize_timer); event_del(&wp->resize_timer);
if (event_initialized(&wp->sync_timer))
event_del(&wp->sync_timer);
TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) { TAILQ_FOREACH_SAFE(r, &wp->resize_queue, entry, r1) {
TAILQ_REMOVE(&wp->resize_queue, r, entry); TAILQ_REMOVE(&wp->resize_queue, r, entry);
free(r); free(r);
@@ -1080,6 +1082,8 @@ window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
if (sx == wp->sx && sy == wp->sy) if (sx == wp->sx && sy == wp->sy)
return; return;
screen_write_stop_sync(wp);
r = xmalloc(sizeof *r); r = xmalloc(sizeof *r);
r->sx = sx; r->sx = sx;
r->sy = sy; r->sy = sy;