Thanks, some comments inline. On Sat, Jan 07, 2017 at 11:34:37AM +0000, Thomas Adam wrote: > On Tue, Jan 03, 2017 at 12:33:42PM +0000, Nicholas Marriott wrote: > > It can be in w->flags, or alternatively just walk the sessions, a flag > > would be faster though. > > Have a look at the patch attached; seems to work for me, including using > grouped sessions. > > I've removed session_is_linked() as a result. There's no longer a need for > it. > > Kindly, > Thomas
> commit 925a266a68c6c7473ce8d40077b373628c021f4c > Author: Thomas Adam <[email protected]> > Date: Fri Jan 6 17:32:16 2017 +0000 > > Handle linked windows with a dedicated flag > > diff --git a/cmd-kill-window.c b/cmd-kill-window.c > index 6365aecb..a2a2d18e 100644 > --- a/cmd-kill-window.c > +++ b/cmd-kill-window.c > @@ -61,7 +61,7 @@ cmd_kill_window_exec(struct cmd *self, struct cmdq_item > *item) > struct session *s = item->state.tflag.s; > > if (self->entry == &cmd_unlink_window_entry) { > - if (!args_has(self->args, 'k') && !session_is_linked(s, w)) { > + if (!args_has(self->args, 'k') && !(w->flags & WINDOW_LINKED)) { > cmdq_error(item, "window only linked to one session"); > return (CMD_RETURN_ERROR); > } > diff --git a/format.c b/format.c > index 70704f01..11b1a89f 100644 > --- a/format.c > +++ b/format.c > @@ -1164,7 +1164,7 @@ format_defaults_winlink(struct format_tree *ft, struct > session *s, > !!(wl->flags & WINLINK_SILENCE)); > format_add(ft, "window_last_flag", "%d", > !!(wl == TAILQ_FIRST(&s->lastw))); > - format_add(ft, "window_linked", "%d", session_is_linked(s, wl->window)); > + format_add(ft, "window_linked", "%d", w->flags & WINDOW_LINKED); This need to be !!(w->flags & WINDOW_LINKED): > > free(flags); > } > diff --git a/server-fn.c b/server-fn.c > index 83b3fe86..fcc2b08f 100644 > --- a/server-fn.c > +++ b/server-fn.c > @@ -233,7 +233,7 @@ server_link_window(struct session *src, struct winlink > *srcwl, > struct session *dst, int dstidx, int killflag, int selectflag, > char **cause) > { > - struct winlink *dstwl; > + struct winlink *dstwl, *wl; > struct session_group *srcsg, *dstsg; > > srcsg = session_group_find(src); > @@ -276,6 +276,9 @@ server_link_window(struct session *src, struct winlink > *srcwl, > if (dstwl == NULL) > return (-1); > > + if ((wl = winlink_find_by_window(&dst->windows, dstwl->window)) != NULL) > + wl->window->flags |= WINDOW_LINKED; > + > if (selectflag) > session_select(dst, dstwl->idx); > server_redraw_session_group(dst); > @@ -286,10 +289,17 @@ server_link_window(struct session *src, struct winlink > *srcwl, > void > server_unlink_window(struct session *s, struct winlink *wl) > { > + struct winlink *wl1; > + > if (session_detach(s, wl)) > server_destroy_session_group(s); > else > server_redraw_session_group(s); > + > + wl->window->flags &= ~WINDOW_LINKED; I think this is a use-after-free of wl if the window only had one link, it needs to happen before session_detach(). server_unlink_window should only remove the flag when there are no remaining links, so it should only remove the flag if TAILQ_NEXT(TAILQ_FIRST(&wl->window->winlinks)) == NULL. > + > + TAILQ_FOREACH(wl1, &wl->window->winlinks, wentry) > + wl1->window->flags &= ~WINDOW_LINKED; All the winlinks will point to the same window so you don't need to clear the flags on each. > } > > void > diff --git a/session.c b/session.c > index d89bc6a0..49254c28 100644 > --- a/session.c > +++ b/session.c > @@ -417,20 +417,6 @@ session_has(struct session *s, struct window *w) > return (0); > } > > -/* > - * Return 1 if a window is linked outside this session (not including session > - * groups). The window must be in this session! > - */ > -int > -session_is_linked(struct session *s, struct window *w) > -{ > - struct session_group *sg; > - > - if ((sg = session_group_find(s)) != NULL) > - return (w->references != session_group_count(sg)); > - return (w->references != 1); > -} > - > static struct winlink * > session_next_alert(struct winlink *wl) > { > diff --git a/tmux.h b/tmux.h > index faf5688e..57a12b8a 100644 > --- a/tmux.h > +++ b/tmux.h > @@ -892,6 +892,7 @@ struct window { > #define WINDOW_FORCEWIDTH 0x2000 > #define WINDOW_FORCEHEIGHT 0x4000 > #define WINDOW_STYLECHANGED 0x8000 > +#define WINDOW_LINKED 0x10000 > #define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE) > > int alerts_queued; > @@ -2265,7 +2266,6 @@ struct winlink *session_attach(struct session *, > struct window *, int, > char **); > int session_detach(struct session *, struct winlink *); > int session_has(struct session *, struct window *); > -int session_is_linked(struct session *, struct window *); > int session_next(struct session *, int); > int session_previous(struct session *, int); > int session_select(struct session *, int); -- You received this message because you are subscribed to the Google Groups "tmux-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
