When a pane is respawned, reset the control mode offsets. GitHub issue

5498 from Alex Rattray.
This commit is contained in:
nicm
2026-08-18 07:43:44 +00:00
committed by tmux update bot
parent 72c5037f06
commit 4714f478fe
3 changed files with 38 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: control.c,v 1.65 2026/08/04 11:18:22 nicm Exp $ */
/* $OpenBSD: control.c,v 1.66 2026/08/18 07:43:44 nicm Exp $ */
/*
* Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -388,6 +388,25 @@ control_pause_pane(struct client *c, struct window_pane *wp)
}
}
/*
* Reset a pane after its buffer has been replaced: drop any output still
* queued from the old buffer and start again from the pane's own offset.
*/
void
control_reset_pane(struct client *c, struct window_pane *wp)
{
struct control_pane *cp;
if (c->control_state == NULL)
return;
cp = control_get_pane(c, wp);
if (cp == NULL)
return;
control_discard_pane(c, cp);
memcpy(&cp->offset, &wp->offset, sizeof cp->offset);
memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
}
/* Write an already-formatted line, queueing it behind %output if needed. */
static void
control_write_line(struct client *c, char *line)

18
spawn.c
View File

@@ -1,4 +1,4 @@
/* $OpenBSD: spawn.c,v 1.50 2026/07/23 09:38:27 nicm Exp $ */
/* $OpenBSD: spawn.c,v 1.51 2026/08/18 07:43:44 nicm Exp $ */
/*
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -245,7 +245,7 @@ struct window_pane *
spawn_pane(struct spawn_context *sc, char **cause)
{
struct cmdq_item *item = sc->item;
struct client *c;
struct client *c, *loop;
struct session *s = sc->s;
struct session *ts;
struct window *w = sc->wl->window;
@@ -333,6 +333,20 @@ spawn_pane(struct spawn_context *sc, char **cause)
input_free(sc->wp0->ictx);
sc->wp0->ictx = NULL;
}
/*
* The old buffer is gone and the new one starts empty, so
* offsets into the old buffer no longer mean anything. Reset
* them, and drop output control clients still had queued.
*/
sc->wp0->offset.used = 0;
sc->wp0->base_offset = 0;
sc->wp0->pipe_offset.used = 0;
TAILQ_FOREACH(loop, &clients, entry) {
if (loop->flags & CLIENT_CONTROL)
control_reset_pane(loop, sc->wp0);
}
new_wp = sc->wp0;
new_wp->flags &= ~(PANE_STATUSREADY|PANE_STATUSDRAWN);
} else {

3
tmux.h
View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tmux.h,v 1.1425 2026/08/17 20:04:00 nicm Exp $ */
/* $OpenBSD: tmux.h,v 1.1426 2026/08/18 07:43:44 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -3986,6 +3986,7 @@ void control_set_pane_on(struct client *, struct window_pane *);
void control_set_pane_off(struct client *, struct window_pane *);
void control_continue_pane(struct client *, struct window_pane *);
void control_pause_pane(struct client *, struct window_pane *);
void control_reset_pane(struct client *, struct window_pane *);
void control_set_window_size(struct client *, u_int, u_int, u_int);
int control_get_window_size(struct client *, u_int, u_int *, u_int *);
void control_clear_window_size(struct client *, u_int);