Fix crash when minimising pane.

This commit is contained in:
Michael Grant
2026-05-13 22:28:14 +01:00
parent 6b16e93f1b
commit 1ff3dafe4e
5 changed files with 54 additions and 53 deletions

View File

@@ -30,7 +30,8 @@
static enum cmd_retval cmd_minimise_pane_minimise_exec(struct cmd *, struct cmdq_item *);
static enum cmd_retval cmd_minimise_pane_unminimise_exec(struct cmd *, struct cmdq_item *);
static enum cmd_retval cmd_minimise_pane_minimise(struct window *, struct window_pane *);
static enum cmd_retval cmd_minimise_pane_minimise(struct window *, struct window_pane *,
struct cmdq_item *);
static enum cmd_retval cmd_minimise_pane_unminimise(struct window *, struct window_pane *);
const struct cmd_entry cmd_minimise_pane_entry = {
@@ -73,10 +74,11 @@ cmd_minimise_pane_minimise_exec(struct cmd *self, struct cmdq_item *item)
enum cmd_retval rv;
if (args_has(args, 'a')) {
struct window_pane *active_pane = w->active;
TAILQ_FOREACH(wp, &w->z_index, zentry) {
if (!window_pane_visible(wp))
if (!window_pane_visible(wp) || wp == active_pane)
continue;
rv = cmd_minimise_pane_minimise(w, wp);
rv = cmd_minimise_pane_minimise(w, wp, item);
if (rv != CMD_RETURN_NORMAL)
return (rv);
}
@@ -95,7 +97,7 @@ cmd_minimise_pane_minimise_exec(struct cmd *self, struct cmdq_item *item)
cmdq_error(item, "No target pane to miminise.");
return (CMD_RETURN_ERROR);
}
return(cmd_minimise_pane_minimise(w, wp));
return (cmd_minimise_pane_minimise(w, wp, item));
}
}
@@ -139,18 +141,37 @@ cmd_minimise_pane_unminimise_exec(struct cmd *self, struct cmdq_item *item)
}
static enum cmd_retval
cmd_minimise_pane_minimise(struct window *w, struct window_pane *wp)
cmd_minimise_pane_minimise(struct window *w, struct window_pane *wp,
__attribute__((unused)) struct cmdq_item *item)
{
struct window_pane *wp2;
struct window_pane *pwp = NULL;
/* Ignore if already minimised to prevent double-redistribution. */
if (wp->flags & PANE_MINIMISED)
return (CMD_RETURN_NORMAL);
wp->flags |= PANE_MINIMISED;
window_deactivate_pane(w, wp, 1);
if (wp == w->active) {
/*
* Unzoom before searching: under zoom, window_pane_visible
* returns false for every non-active pane.
*/
if (w->flags & WINDOW_ZOOMED)
window_unzoom(w, 1);
/* Find previous active pane. */
TAILQ_FOREACH(pwp, &w->last_panes, sentry) {
if (pwp != wp && window_pane_visible(pwp))
break;
}
if (pwp == NULL) {
TAILQ_FOREACH(pwp, &w->z_index, zentry) {
if (pwp != wp &&
window_pane_visible(pwp))
break;
}
}
}
wp->flags |= PANE_MINIMISED;
/* Fix pane offsets and sizes. */
if (w->layout_root != NULL) {
wp->saved_layout_cell = wp->layout_cell;
layout_minimise_cell(w, wp->layout_cell);
@@ -158,17 +179,22 @@ cmd_minimise_pane_minimise(struct window *w, struct window_pane *wp)
layout_fix_panes(w, NULL);
}
/* Find next visible window in z-index. */
TAILQ_FOREACH(wp2, &w->z_index, zentry) {
if (!window_pane_visible(wp2))
continue;
break;
}
if (wp2 != NULL)
window_set_active_pane(w, wp2, 1);
window_pane_stack_remove(&w->last_panes, wp);
if (pwp != NULL) {
window_set_active_pane(w, pwp, 1);
} else if (wp == w->active) {
/* No visible previous active pane; null active pane
* to show dots background. */
w->active = NULL;
if (options_get_number(global_options, "focus-events"))
window_pane_update_focus(wp);
notify_window("window-pane-changed", w);
notify_window("window-layout-changed", w);
server_redraw_window(w);
} else {
notify_window("window-layout-changed", w);
server_redraw_window(w);
}
return (CMD_RETURN_NORMAL);
}

View File

@@ -77,6 +77,9 @@ control_notify_window_pane_changed(struct window *w)
{
struct client *c;
if (w->active == NULL)
return;
TAILQ_FOREACH(c, &clients, entry) {
if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
continue;

View File

@@ -2197,7 +2197,7 @@ server_client_set_path(struct client *c)
struct session *s = c->session;
const char *path;
if (s->curw == NULL)
if (s->curw == NULL || s->curw->window->active == NULL)
return;
if (s->curw->window->active->base.path == NULL)
path = "";
@@ -2217,7 +2217,7 @@ server_client_set_progress_bar(struct client *c)
struct session *s = c->session;
struct progress_bar *pane_pb;
if (s->curw == NULL)
if (s->curw == NULL || s->curw->window->active == NULL)
return;
pane_pb = &s->curw->window->active->base.progress_bar;
if (pane_pb->state == c->progress_bar.state &&

2
tmux.h
View File

@@ -3412,8 +3412,6 @@ struct window_pane *window_find_string(struct window *, const char *);
int window_has_pane(struct window *, struct window_pane *);
int window_set_active_pane(struct window *, struct window_pane *,
int);
int window_deactivate_pane(struct window *, struct window_pane *,
int);
void window_update_focus(struct window *);
void window_pane_update_focus(struct window_pane *);
void window_redraw_active_switch(struct window *,

View File

@@ -570,32 +570,6 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
return (1);
}
int
window_deactivate_pane(struct window *w, struct window_pane *wp, int notify)
{
struct window_pane *lastwp;
log_debug("%s: pane %%%u", __func__, wp->id);
if (w->flags & WINDOW_ZOOMED)
window_unzoom(w, 1);
lastwp = w->active;
window_pane_stack_remove(&w->last_panes, wp);
window_pane_stack_push(&w->last_panes, lastwp);
w->active = NULL;
if (options_get_number(global_options, "focus-events")) {
window_pane_update_focus(lastwp);
}
tty_update_window_offset(w);
if (notify)
notify_window("window-pane-changed", w);
return (1);
}
static int
window_pane_get_palette(struct window_pane *wp, int c)