From c50d0751229110b7b10b9f7a005d4d0ce723c220 Mon Sep 17 00:00:00 2001 From: Michael Grant Date: Thu, 1 Oct 2026 11:14:28 +0100 Subject: [PATCH] Keep focus on a visible pane when panes are shown, spawned or closed. Co-Authored-By: Claude Opus 5.5 --- spawn.c | 10 +++++++--- window.c | 11 +++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/spawn.c b/spawn.c index bf4984c16..526cea8f9 100644 --- a/spawn.c +++ b/spawn.c @@ -254,7 +254,7 @@ spawn_pane(struct spawn_context *sc, char **cause) char path[PATH_MAX]; const char *cmd, *tmp, *home = find_home(); const char *actual_cwd = NULL; - int argc; + int argc, detached; u_int idx; struct termios now; u_int hlimit; @@ -588,6 +588,11 @@ complete: return (new_wp); if (sc->flags & SPAWN_ZOOM) window_zoom(new_wp); + + /* Make the pane active, even if detached, if keys would go nowhere. */ + detached = (sc->flags & SPAWN_DETACHED); + if (w->active == NULL || (w->active->flags & PANE_HIDDEN)) + detached = 0; if (sc->flags & SPAWN_MODAL) { w->modal_last = w->active; w->modal = new_wp; @@ -596,8 +601,7 @@ complete: window_set_active_pane(w, new_wp, 0); else window_set_active_pane(w, new_wp, 1); - } else if (((~sc->flags & SPAWN_DETACHED) || w->active == NULL) && - w->modal == NULL) { + } else if (!detached && w->modal == NULL) { if (sc->flags & SPAWN_NONOTIFY) window_set_active_pane(w, new_wp, 0); else diff --git a/window.c b/window.c index 5357f9d18..be053ee51 100644 --- a/window.c +++ b/window.c @@ -765,8 +765,11 @@ window_activate_pane(struct window *w, struct window_pane *wp, int notify, if (w->modal != NULL && wp != w->modal) return (0); - if (wp->flags & PANE_HIDDEN) + if (wp->flags & PANE_HIDDEN) { window_show_pane(wp); + if (wp == w->active) + return (1); + } if (wp == w->active) return (0); if (!window_pane_is_visible(wp)) { @@ -1099,6 +1102,10 @@ window_show_pane(struct window_pane *wp) events_fire_window("window-layout-changed", w); redraw_invalidate_scene(w); server_redraw_window(w); + + /* Keys go nowhere if the active pane is hidden, so use this one. */ + if (w->active != NULL && (w->active->flags & PANE_HIDDEN)) + window_set_active_pane(w, wp, 1); return (0); } @@ -1327,7 +1334,7 @@ window_lost_pane(struct window *w, struct window_pane *wp) w->active = lastwp; else w->active = TAILQ_FIRST(&w->last_panes); - if (w->active != NULL && !window_pane_is_visible(w->active)) { + if (w->active == NULL || !window_pane_is_visible(w->active)) { /* Use the topmost pane that can be seen. */ TAILQ_FOREACH(lastwp, &w->z_index, zentry) { if (lastwp != wp &&