mirror of
https://github.com/tmux/tmux.git
synced 2026-10-17 00:44:54 +00:00
Clear stale pane references correctly when respawning windows, GitHub
issue 5757 from Alejandro Pacheco.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: screen-redraw.c,v 1.169 2026/10/16 07:59:06 nicm Exp $ */
|
/* $OpenBSD: screen-redraw.c,v 1.170 2026/10/16 14:26:08 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1096,11 +1096,17 @@ redraw_client_has_window(struct client *c, struct window *w)
|
|||||||
return (c->redraw_scene != NULL && c->redraw_scene->w == w);
|
return (c->redraw_scene != NULL && c->redraw_scene->w == w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark a window's cached redraw scenes as out of date. */
|
/*
|
||||||
|
* Mark a window's cached redraw scenes as out of date. Generations are unique
|
||||||
|
* across all windows so a scene can never match a new window that reuses the
|
||||||
|
* address of a freed one.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
redraw_invalidate_scene(struct window *w)
|
redraw_invalidate_scene(struct window *w)
|
||||||
{
|
{
|
||||||
w->redraw_scene_generation++;
|
static uint64_t next_generation;
|
||||||
|
|
||||||
|
w->redraw_scene_generation = ++next_generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free all pending damage for a window. */
|
/* Free all pending damage for a window. */
|
||||||
|
|||||||
3
spawn.c
3
spawn.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: spawn.c,v 1.57 2026/10/08 07:50:05 nicm Exp $ */
|
/* $OpenBSD: spawn.c,v 1.58 2026/10/16 14:26:08 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -142,6 +142,7 @@ spawn_window(struct spawn_context *sc, char **cause)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window_unzoom(w, 1);
|
||||||
sc->wp0 = TAILQ_FIRST(&w->panes);
|
sc->wp0 = TAILQ_FIRST(&w->panes);
|
||||||
TAILQ_REMOVE(&w->panes, sc->wp0, entry);
|
TAILQ_REMOVE(&w->panes, sc->wp0, entry);
|
||||||
|
|
||||||
|
|||||||
33
window.c
33
window.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: window.c,v 1.387 2026/10/16 11:34:49 bket Exp $ */
|
/* $OpenBSD: window.c,v 1.388 2026/10/16 14:26:08 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -447,6 +447,7 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
|
|||||||
|
|
||||||
w->id = next_window_id++;
|
w->id = next_window_id++;
|
||||||
RB_INSERT(windows, &windows, w);
|
RB_INSERT(windows, &windows, w);
|
||||||
|
redraw_invalidate_scene(w);
|
||||||
|
|
||||||
if (gettimeofday(&w->creation_time, NULL) != 0)
|
if (gettimeofday(&w->creation_time, NULL) != 0)
|
||||||
fatal("gettimeofday failed");
|
fatal("gettimeofday failed");
|
||||||
@@ -1189,6 +1190,19 @@ window_add_pane(struct window *w, struct window_pane *other, u_int hlimit,
|
|||||||
return (wp);
|
return (wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_forget_pane(struct window *w, struct window_pane *wp)
|
||||||
|
{
|
||||||
|
if (wp == marked_pane.wp)
|
||||||
|
server_clear_marked();
|
||||||
|
if (wp == w->modal_last)
|
||||||
|
w->modal_last = NULL;
|
||||||
|
if (wp == w->was_zoomed)
|
||||||
|
w->was_zoomed = NULL;
|
||||||
|
window_pane_stack_remove(&w->last_panes, wp);
|
||||||
|
redraw_invalidate_scene(w);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_lost_pane(struct window *w, struct window_pane *wp)
|
window_lost_pane(struct window *w, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@@ -1196,14 +1210,8 @@ window_lost_pane(struct window *w, struct window_pane *wp)
|
|||||||
|
|
||||||
log_debug("%s: @%u pane %%%u", __func__, w->id, wp->id);
|
log_debug("%s: @%u pane %%%u", __func__, w->id, wp->id);
|
||||||
|
|
||||||
if (wp == marked_pane.wp)
|
window_forget_pane(w, wp);
|
||||||
server_clear_marked();
|
|
||||||
if (wp == w->modal_last)
|
|
||||||
w->modal_last = NULL;
|
|
||||||
if (wp == w->was_zoomed)
|
|
||||||
w->was_zoomed = NULL;
|
|
||||||
|
|
||||||
window_pane_stack_remove(&w->last_panes, wp);
|
|
||||||
if (wp == w->active) {
|
if (wp == w->active) {
|
||||||
lastwp = NULL;
|
lastwp = NULL;
|
||||||
if (wp == w->modal) {
|
if (wp == w->modal) {
|
||||||
@@ -1226,11 +1234,9 @@ window_lost_pane(struct window *w, struct window_pane *wp)
|
|||||||
window_fire_pane_changed(w, w->active, wp);
|
window_fire_pane_changed(w, w->active, wp);
|
||||||
window_update_focus(w);
|
window_update_focus(w);
|
||||||
}
|
}
|
||||||
} else if (wp == w->modal) {
|
} else if (wp == w->modal)
|
||||||
w->modal = w->modal_last = NULL;
|
w->modal = w->modal_last = NULL;
|
||||||
}
|
}
|
||||||
redraw_invalidate_scene(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
window_remove_pane(struct window *w, struct window_pane *wp)
|
window_remove_pane(struct window *w, struct window_pane *wp)
|
||||||
@@ -1357,6 +1363,11 @@ window_destroy_panes(struct window *w)
|
|||||||
|
|
||||||
while (!TAILQ_EMPTY(&w->panes)) {
|
while (!TAILQ_EMPTY(&w->panes)) {
|
||||||
wp = TAILQ_FIRST(&w->panes);
|
wp = TAILQ_FIRST(&w->panes);
|
||||||
|
window_forget_pane(w, wp);
|
||||||
|
if (wp == w->active)
|
||||||
|
w->active = NULL;
|
||||||
|
if (wp == w->modal)
|
||||||
|
w->modal = NULL;
|
||||||
TAILQ_REMOVE(&w->panes, wp, entry);
|
TAILQ_REMOVE(&w->panes, wp, entry);
|
||||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||||
window_pane_destroy(wp);
|
window_pane_destroy(wp);
|
||||||
|
|||||||
Reference in New Issue
Block a user