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);
}
/* 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. */
static void *
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,
format_cb_start_time
},
{ "synchronized_output_flag", FORMAT_TABLE_STRING,
format_cb_synchronized_output_flag
},
{ "tree_mode_format", FORMAT_TABLE_STRING,
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);
event_del(&ictx->ground_timer);
screen_write_stop_sync(ictx->wp);
free(ictx);
}
@@ -1901,6 +1903,11 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
case 2031:
screen_write_mode_clear(sctx, MODE_THEME_UPDATES);
break;
case 2026: /* synchronized output */
screen_write_stop_sync(ictx->wp);
if (ictx->wp != NULL)
ictx->wp->flags |= PANE_REDRAW;
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
break;
@@ -1999,6 +2006,9 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
case 2031:
screen_write_mode_set(sctx, MODE_THEME_UPDATES);
break;
case 2026: /* synchronized output */
screen_write_start_sync(ictx->wp);
break;
default:
log_debug("%s: unknown '%c'", __func__, ictx->ch);
break;

View File

@@ -898,6 +898,9 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
struct grid_cell defaults;
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);
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));
}
/* 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. */
void
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;
struct tty_ctx ttyctx;
if (s->mode & MODE_SYNC)
return;
if (ctx->scrolled != 0) {
log_debug("%s: scrolled %u (region %u-%u)", __func__,
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. */
if (!skip) {
if (!skip && !(s->mode & MODE_SYNC)) {
if (selected) {
screen_select_cell(s, &tmp_gc, 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 "sixel_support" Ta "" Ta "1 if server has support for SIXEL"
.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 "user" Ta "" Ta "Server user"
.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_KEYS_EXTENDED_2 0x40000
#define MODE_THEME_UPDATES 0x80000
#define MODE_SYNC 0x100000
#define ALL_MODES 0xffffff
#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 event resize_timer;
struct event sync_timer;
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_mode_set(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_cursordown(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))
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_REMOVE(&wp->resize_queue, r, entry);
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)
return;
screen_write_stop_sync(wp);
r = xmalloc(sizeof *r);
r->sx = sx;
r->sy = sy;