GitHub issue 3588.
-/* $OpenBSD: cmd-find.c,v 1.82 2022/11/01 09:46:14 nicm Exp $ */
+/* $OpenBSD: cmd-find.c,v 1.83 2023/07/10 09:24:53 nicm Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicholas.marriott@gmail.com>
/* Try special characters. */
if (strcmp(pane, "!") == 0) {
- fs->wp = fs->w->last;
+ fs->wp = TAILQ_FIRST(&fs->w->last_panes);
if (fs->wp == NULL)
return (-1);
return (0);
-/* $OpenBSD: cmd-select-pane.c,v 1.68 2021/08/21 10:22:39 nicm Exp $ */
+/* $OpenBSD: cmd-select-pane.c,v 1.69 2023/07/10 09:24:53 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
struct options_entry *o;
if (entry == &cmd_last_pane_entry || args_has(args, 'l')) {
- lastwp = w->last;
+ /*
+ * Check for no last pane found in case the other pane was
+ * spawned without being visited (for example split-window -d).
+ */
+ lastwp = TAILQ_FIRST(&w->last_panes);
if (lastwp == NULL && window_count_panes(w) == 2) {
lastwp = TAILQ_PREV(w->active, window_panes, entry);
if (lastwp == NULL)
-/* $OpenBSD: cmd-swap-pane.c,v 1.42 2023/01/17 06:50:55 nicm Exp $ */
+/* $OpenBSD: cmd-swap-pane.c,v 1.43 2023/07/10 09:24:53 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
window_set_active_pane(dst_w, src_wp, 1);
}
if (src_w != dst_w) {
- if (src_w->last == src_wp)
- src_w->last = NULL;
- if (dst_w->last == dst_wp)
- dst_w->last = NULL;
+ window_pane_stack_remove(&src_w->last_panes, src_wp);
+ window_pane_stack_remove(&dst_w->last_panes, dst_wp);
colour_palette_from_option(&src_wp->palette, src_wp->options);
colour_palette_from_option(&dst_wp->palette, dst_wp->options);
}
-/* $OpenBSD: format.c,v 1.315 2023/07/03 10:48:26 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.316 2023/07/10 09:24:53 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
format_cb_pane_last(struct format_tree *ft)
{
if (ft->wp != NULL) {
- if (ft->wp == ft->wp->window->last)
+ if (ft->wp == TAILQ_FIRST(&ft->wp->window->last_panes))
return (xstrdup("1"));
return (xstrdup("0"));
}
-/* $OpenBSD: spawn.c,v 1.32 2023/07/09 22:54:52 nicm Exp $ */
+/* $OpenBSD: spawn.c,v 1.33 2023/07/10 09:24:53 nicm Exp $ */
/*
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
window_pane_resize(sc->wp0, w->sx, w->sy);
layout_init(w, sc->wp0);
+ w->active = NULL;
window_set_active_pane(w, sc->wp0, 0);
}
-/* $OpenBSD: tmux.h,v 1.1200 2023/07/03 16:47:43 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1201 2023/07/10 09:24:53 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
#define PANE_REDRAW 0x1
#define PANE_DROP 0x2
#define PANE_FOCUSED 0x4
-/* 0x8 unused */
+#define PANE_VISITED 0x8
/* 0x10 unused */
/* 0x20 unused */
#define PANE_INPUTOFF 0x40
int border_gc_set;
struct grid_cell border_gc;
- TAILQ_ENTRY(window_pane) entry;
+ TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */
+ TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */
RB_ENTRY(window_pane) tree_entry;
};
TAILQ_HEAD(window_panes, window_pane);
struct timeval activity_time;
struct window_pane *active;
- struct window_pane *last;
+ struct window_panes last_panes;
struct window_panes panes;
int lastlayout;
#define WINLINK_ACTIVITY 0x2
#define WINLINK_SILENCE 0x4
#define WINLINK_ALERTFLAGS (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_SILENCE)
+#define WINLINK_VISITED 0x8
RB_ENTRY(winlink) entry;
TAILQ_ENTRY(winlink) wentry;
struct window_pane *window_pane_find_down(struct window_pane *);
struct window_pane *window_pane_find_left(struct window_pane *);
struct window_pane *window_pane_find_right(struct window_pane *);
+void window_pane_stack_push(struct window_panes *,
+ struct window_pane *);
+void window_pane_stack_remove(struct window_panes *,
+ struct window_pane *);
void window_set_name(struct window *, const char *);
void window_add_ref(struct window *, const char *);
void window_remove_ref(struct window *, const char *);
-/* $OpenBSD: window.c,v 1.285 2023/03/27 08:47:57 nicm Exp $ */
+/* $OpenBSD: window.c,v 1.286 2023/07/10 09:24:53 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
winlink_stack_remove(stack, wl);
TAILQ_INSERT_HEAD(stack, wl, sentry);
+ wl->flags |= WINLINK_VISITED;
}
void
winlink_stack_remove(struct winlink_stack *stack, struct winlink *wl)
{
- struct winlink *wl2;
-
- if (wl == NULL)
- return;
-
- TAILQ_FOREACH(wl2, stack, sentry) {
- if (wl2 == wl) {
- TAILQ_REMOVE(stack, wl, sentry);
- return;
- }
+ if (wl != NULL && (wl->flags & WINLINK_VISITED)) {
+ TAILQ_REMOVE(stack, wl, sentry);
+ wl->flags &= ~WINLINK_VISITED;
}
}
w->flags = 0;
TAILQ_INIT(&w->panes);
+ TAILQ_INIT(&w->last_panes);
w->active = NULL;
w->lastlayout = -1;
int
window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
{
+ struct window_pane *lastwp;
+
log_debug("%s: pane %%%u", __func__, wp->id);
if (wp == w->active)
return (0);
- w->last = w->active;
+ lastwp = w->active;
+
+ window_pane_stack_remove(&w->last_panes, wp);
+ window_pane_stack_push(&w->last_panes, lastwp);
w->active = wp;
w->active->active_point = next_active_point++;
w->active->flags |= PANE_CHANGED;
if (options_get_number(global_options, "focus-events")) {
- window_pane_update_focus(w->last);
+ window_pane_update_focus(lastwp);
window_pane_update_focus(w->active);
}
if (wp == marked_pane.wp)
server_clear_marked();
+ window_pane_stack_remove(&w->last_panes, wp);
if (wp == w->active) {
- w->active = w->last;
- w->last = NULL;
+ w->active = TAILQ_FIRST(&w->last_panes);
if (w->active == NULL) {
w->active = TAILQ_PREV(wp, window_panes, entry);
if (w->active == NULL)
w->active = TAILQ_NEXT(wp, entry);
}
if (w->active != NULL) {
+ window_pane_stack_remove(&w->last_panes, w->active);
w->active->flags |= PANE_CHANGED;
notify_window("window-pane-changed", w);
window_update_focus(w);
}
- } else if (wp == w->last)
- w->last = NULL;
+ }
}
void
{
struct window_pane *wp;
+ while (!TAILQ_EMPTY(&w->last_panes)) {
+ wp = TAILQ_FIRST(&w->last_panes);
+ window_pane_stack_remove(&w->last_panes, wp);
+ }
+
while (!TAILQ_EMPTY(&w->panes)) {
wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry);
return (best);
}
+void
+window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
+{
+ if (wp != NULL) {
+ window_pane_stack_remove(stack, wp);
+ TAILQ_INSERT_HEAD(stack, wp, sentry);
+ wp->flags |= PANE_VISITED;
+ }
+}
+
+void
+window_pane_stack_remove(struct window_panes *stack, struct window_pane *wp)
+{
+ if (wp != NULL && (wp->flags & PANE_VISITED)) {
+ TAILQ_REMOVE(stack, wp, sentry);
+ wp->flags &= ~PANE_VISITED;
+ }
+}
+
/* Clear alert flags for a winlink */
void
winlink_clear_flags(struct winlink *wl)