mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	kill-window -a cannot just walk the list of windows because if
renumber-windows is on, the window it wants to keep could be moved. Change to renumber afterwards and also behave better if the window is linked into the session twice. GitHub issue 2287.
This commit is contained in:
		@@ -160,7 +160,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
		server_status_session(dst_s);
 | 
			
		||||
 | 
			
		||||
	if (window_count_panes(src_w) == 0)
 | 
			
		||||
		server_kill_window(src_w);
 | 
			
		||||
		server_kill_window(src_w, 1);
 | 
			
		||||
	else
 | 
			
		||||
		notify_window("window-layout-changed", src_w);
 | 
			
		||||
	notify_window("window-layout-changed", dst_w);
 | 
			
		||||
 
 | 
			
		||||
@@ -57,9 +57,10 @@ cmd_kill_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
{
 | 
			
		||||
	struct args		*args = cmd_get_args(self);
 | 
			
		||||
	struct cmd_find_state	*target = cmdq_get_target(item);
 | 
			
		||||
	struct winlink		*wl = target->wl, *wl2, *wl3;
 | 
			
		||||
	struct winlink		*wl = target->wl, *loop;
 | 
			
		||||
	struct window		*w = wl->window;
 | 
			
		||||
	struct session		*s = target->s;
 | 
			
		||||
	u_int			 found;
 | 
			
		||||
 | 
			
		||||
	if (cmd_get_entry(self) == &cmd_unlink_window_entry) {
 | 
			
		||||
		if (!args_has(args, 'k') && !session_is_linked(s, w)) {
 | 
			
		||||
@@ -67,16 +68,43 @@ cmd_kill_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
			return (CMD_RETURN_ERROR);
 | 
			
		||||
		}
 | 
			
		||||
		server_unlink_window(s, wl);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (args_has(args, 'a')) {
 | 
			
		||||
			RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) {
 | 
			
		||||
				if (wl != wl2)
 | 
			
		||||
					server_kill_window(wl2->window);
 | 
			
		||||
			}
 | 
			
		||||
		} else
 | 
			
		||||
			server_kill_window(wl->window);
 | 
			
		||||
		recalculate_sizes();
 | 
			
		||||
		return (CMD_RETURN_NORMAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	recalculate_sizes();
 | 
			
		||||
	if (args_has(args, 'a')) {
 | 
			
		||||
		if (RB_PREV(winlinks, &s->windows, wl) == NULL &&
 | 
			
		||||
		    RB_NEXT(winlinks, &s->windows, wl) == NULL)
 | 
			
		||||
			return (CMD_RETURN_NORMAL);
 | 
			
		||||
 | 
			
		||||
		/* Kill all windows except the current one. */
 | 
			
		||||
		do {
 | 
			
		||||
			found = 0;
 | 
			
		||||
			RB_FOREACH(loop, winlinks, &s->windows) {
 | 
			
		||||
				if (loop->window != wl->window) {
 | 
			
		||||
					server_kill_window(loop->window, 0);
 | 
			
		||||
					found++;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} while (found != 0);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * If the current window appears in the session more than once,
 | 
			
		||||
		 * kill it as well.
 | 
			
		||||
		 */
 | 
			
		||||
		found = 0;
 | 
			
		||||
		RB_FOREACH(loop, winlinks, &s->windows) {
 | 
			
		||||
			if (loop->window == wl->window)
 | 
			
		||||
				found++;
 | 
			
		||||
		}
 | 
			
		||||
		if (found > 1)
 | 
			
		||||
			server_kill_window(wl->window, 0);
 | 
			
		||||
 | 
			
		||||
		server_renumber_all();
 | 
			
		||||
		return (CMD_RETURN_NORMAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	server_kill_window(wl->window, 1);
 | 
			
		||||
	return (CMD_RETURN_NORMAL);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								server-fn.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								server-fn.c
									
									
									
									
									
								
							@@ -183,7 +183,7 @@ server_kill_pane(struct window_pane *wp)
 | 
			
		||||
	struct window	*w = wp->window;
 | 
			
		||||
 | 
			
		||||
	if (window_count_panes(w) == 1) {
 | 
			
		||||
		server_kill_window(w);
 | 
			
		||||
		server_kill_window(w, 1);
 | 
			
		||||
		recalculate_sizes();
 | 
			
		||||
	} else {
 | 
			
		||||
		server_unzoom_window(w);
 | 
			
		||||
@@ -195,19 +195,15 @@ server_kill_pane(struct window_pane *wp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_kill_window(struct window *w)
 | 
			
		||||
server_kill_window(struct window *w, int renumber)
 | 
			
		||||
{
 | 
			
		||||
	struct session		*s, *next_s, *target_s;
 | 
			
		||||
	struct session_group	*sg;
 | 
			
		||||
	struct winlink		*wl;
 | 
			
		||||
 | 
			
		||||
	next_s = RB_MIN(sessions, &sessions);
 | 
			
		||||
	while (next_s != NULL) {
 | 
			
		||||
		s = next_s;
 | 
			
		||||
		next_s = RB_NEXT(sessions, &sessions, s);
 | 
			
		||||
	struct session	*s, *s1;
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH_SAFE(s, sessions, &sessions, s1) {
 | 
			
		||||
		if (!session_has(s, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		server_unzoom_window(w);
 | 
			
		||||
		while ((wl = winlink_find_by_window(&s->windows, w)) != NULL) {
 | 
			
		||||
			if (session_detach(s, wl)) {
 | 
			
		||||
@@ -217,17 +213,35 @@ server_kill_window(struct window *w)
 | 
			
		||||
				server_redraw_session_group(s);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (options_get_number(s->options, "renumber-windows")) {
 | 
			
		||||
			if ((sg = session_group_contains(s)) != NULL) {
 | 
			
		||||
				TAILQ_FOREACH(target_s, &sg->sessions, gentry)
 | 
			
		||||
					session_renumber_windows(target_s);
 | 
			
		||||
			} else
 | 
			
		||||
				session_renumber_windows(s);
 | 
			
		||||
		}
 | 
			
		||||
		if (renumber)
 | 
			
		||||
			server_renumber_session(s);
 | 
			
		||||
	}
 | 
			
		||||
	recalculate_sizes();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_renumber_session(struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	struct session_group	*sg;
 | 
			
		||||
 | 
			
		||||
	if (options_get_number(s->options, "renumber-windows")) {
 | 
			
		||||
		if ((sg = session_group_contains(s)) != NULL) {
 | 
			
		||||
			TAILQ_FOREACH(s, &sg->sessions, gentry)
 | 
			
		||||
			    session_renumber_windows(s);
 | 
			
		||||
		} else
 | 
			
		||||
			session_renumber_windows(s);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_renumber_all(void)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(s, sessions, &sessions)
 | 
			
		||||
		server_renumber_session(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
server_link_window(struct session *src, struct winlink *srcwl,
 | 
			
		||||
    struct session *dst, int dstidx, int killflag, int selectflag,
 | 
			
		||||
@@ -354,7 +368,7 @@ server_destroy_pane(struct window_pane *wp, int notify)
 | 
			
		||||
	window_remove_pane(w, wp);
 | 
			
		||||
 | 
			
		||||
	if (TAILQ_EMPTY(&w->panes))
 | 
			
		||||
		server_kill_window(w);
 | 
			
		||||
		server_kill_window(w, 1);
 | 
			
		||||
	else
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2420,7 +2420,9 @@ void	 server_lock(void);
 | 
			
		||||
void	 server_lock_session(struct session *);
 | 
			
		||||
void	 server_lock_client(struct client *);
 | 
			
		||||
void	 server_kill_pane(struct window_pane *);
 | 
			
		||||
void	 server_kill_window(struct window *);
 | 
			
		||||
void	 server_kill_window(struct window *, int);
 | 
			
		||||
void	 server_renumber_session(struct session *);
 | 
			
		||||
void	 server_renumber_all(void);
 | 
			
		||||
int	 server_link_window(struct session *,
 | 
			
		||||
	     struct winlink *, struct session *, int, int, int, char **);
 | 
			
		||||
void	 server_unlink_window(struct session *, struct winlink *);
 | 
			
		||||
 
 | 
			
		||||
@@ -1054,7 +1054,7 @@ window_tree_kill_each(__unused void *modedata, void *itemdata,
 | 
			
		||||
		break;
 | 
			
		||||
	case WINDOW_TREE_WINDOW:
 | 
			
		||||
		if (wl != NULL)
 | 
			
		||||
			server_kill_window(wl->window);
 | 
			
		||||
			server_kill_window(wl->window, 1);
 | 
			
		||||
		break;
 | 
			
		||||
	case WINDOW_TREE_PANE:
 | 
			
		||||
		if (wp != NULL)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user