Do not rely on window reference count for linked formats because they

are also used for notifications, GitHub issue 4258.
This commit is contained in:
nicm 2024-11-25 08:34:01 +00:00
parent 5fd45b3892
commit 420af9e108
3 changed files with 39 additions and 10 deletions

View File

@ -2490,9 +2490,20 @@ format_cb_window_last_flag(struct format_tree *ft)
static void * static void *
format_cb_window_linked(struct format_tree *ft) format_cb_window_linked(struct format_tree *ft)
{ {
struct winlink *wl;
struct session *s;
int found = 0;
if (ft->wl != NULL) { if (ft->wl != NULL) {
if (session_is_linked(ft->wl->session, ft->wl->window)) RB_FOREACH(s, sessions, &sessions) {
return (xstrdup("1")); RB_FOREACH(wl, winlinks, &s->windows) {
if (wl->window == ft->wl->window) {
if (found)
return (xstrdup("1"));
found = 1;
}
}
}
return (xstrdup("0")); return (xstrdup("0"));
} }
return (NULL); return (NULL);
@ -2502,9 +2513,27 @@ format_cb_window_linked(struct format_tree *ft)
static void * static void *
format_cb_window_linked_sessions(struct format_tree *ft) format_cb_window_linked_sessions(struct format_tree *ft)
{ {
if (ft->wl != NULL) struct window *w;
return (format_printf("%u", ft->wl->window->references)); struct session_group *sg;
return (NULL); struct session *s;
u_int n = 0;
if (ft->wl == NULL)
return (NULL);
w = ft->wl->window;
RB_FOREACH(sg, session_groups, &session_groups) {
s = TAILQ_FIRST(&sg->sessions);
if (winlink_find_by_window(&s->windows, w) != NULL)
n++;
}
RB_FOREACH(s, sessions, &sessions) {
if (session_group_contains(s) != NULL)
continue;
if (winlink_find_by_window(&s->windows, w) != NULL)
n++;
}
return (format_printf("%u", n));
} }
/* Callback for window_marked_flag. */ /* Callback for window_marked_flag. */

View File

@ -33,12 +33,9 @@ u_int next_session_id;
struct session_groups session_groups = RB_INITIALIZER(&session_groups); struct session_groups session_groups = RB_INITIALIZER(&session_groups);
static void session_free(int, short, void *); static void session_free(int, short, void *);
static void session_lock_timer(int, short, void *); static void session_lock_timer(int, short, void *);
static struct winlink *session_next_alert(struct winlink *); static struct winlink *session_next_alert(struct winlink *);
static struct winlink *session_previous_alert(struct winlink *); static struct winlink *session_previous_alert(struct winlink *);
static void session_group_remove(struct session *); static void session_group_remove(struct session *);
static void session_group_synchronize1(struct session *, struct session *); static void session_group_synchronize1(struct session *, struct session *);
@ -49,12 +46,12 @@ session_cmp(struct session *s1, struct session *s2)
} }
RB_GENERATE(sessions, session, entry, session_cmp); RB_GENERATE(sessions, session, entry, session_cmp);
static int int
session_group_cmp(struct session_group *s1, struct session_group *s2) session_group_cmp(struct session_group *s1, struct session_group *s2)
{ {
return (strcmp(s1->name, s2->name)); return (strcmp(s1->name, s2->name));
} }
RB_GENERATE_STATIC(session_groups, session_group, entry, session_group_cmp); RB_GENERATE(session_groups, session_group, entry, session_group_cmp);
/* /*
* Find if session is still alive. This is true if it is still on the global * Find if session is still alive. This is true if it is still on the global

3
tmux.h
View File

@ -3348,9 +3348,12 @@ void control_notify_paste_buffer_deleted(const char *);
/* session.c */ /* session.c */
extern struct sessions sessions; extern struct sessions sessions;
extern struct session_groups session_groups;
extern u_int next_session_id; extern u_int next_session_id;
int session_cmp(struct session *, struct session *); int session_cmp(struct session *, struct session *);
RB_PROTOTYPE(sessions, session, entry, session_cmp); RB_PROTOTYPE(sessions, session, entry, session_cmp);
int session_group_cmp(struct session_group *, struct session_group *s2);
RB_PROTOTYPE(session_groups, session_group, entry, session_group_cmp);
int session_alive(struct session *); int session_alive(struct session *);
struct session *session_find(const char *); struct session *session_find(const char *);
struct session *session_find_by_id_str(const char *); struct session *session_find_by_id_str(const char *);