mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Add a common function for spreading out cells and use it for the two
even layouts and to add a -E flag to select-layout to spread out cells evenly without changing parent cells.
This commit is contained in:
		@@ -33,10 +33,10 @@ const struct cmd_entry cmd_select_layout_entry = {
 | 
				
			|||||||
	.name = "select-layout",
 | 
						.name = "select-layout",
 | 
				
			||||||
	.alias = "selectl",
 | 
						.alias = "selectl",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.args = { "nopt:", 0, 1 },
 | 
						.args = { "Enopt:", 0, 1 },
 | 
				
			||||||
	.usage = "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
 | 
						.usage = "[-Enop] " CMD_TARGET_PANE_USAGE " [layout-name]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.target = { 't', CMD_FIND_WINDOW, 0 },
 | 
						.target = { 't', CMD_FIND_PANE, 0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.flags = CMD_AFTERHOOK,
 | 
						.flags = CMD_AFTERHOOK,
 | 
				
			||||||
	.exec = cmd_select_layout_exec
 | 
						.exec = cmd_select_layout_exec
 | 
				
			||||||
@@ -71,14 +71,14 @@ const struct cmd_entry cmd_previous_layout_entry = {
 | 
				
			|||||||
static enum cmd_retval
 | 
					static enum cmd_retval
 | 
				
			||||||
cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
 | 
					cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct args	*args = self->args;
 | 
						struct args		*args = self->args;
 | 
				
			||||||
	struct winlink	*wl = item->target.wl;
 | 
						struct winlink		*wl = item->target.wl;
 | 
				
			||||||
	struct window	*w;
 | 
						struct window		*w = wl->window;
 | 
				
			||||||
	const char	*layoutname;
 | 
						struct window_pane	*wp = item->target.wp;
 | 
				
			||||||
	char		*oldlayout;
 | 
						const char		*layoutname;
 | 
				
			||||||
	int		 next, previous, layout;
 | 
						char			*oldlayout;
 | 
				
			||||||
 | 
						int			 next, previous, layout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	w = wl->window;
 | 
					 | 
				
			||||||
	server_unzoom_window(w);
 | 
						server_unzoom_window(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	next = self->entry == &cmd_next_layout_entry;
 | 
						next = self->entry == &cmd_next_layout_entry;
 | 
				
			||||||
@@ -99,6 +99,11 @@ cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
		goto changed;
 | 
							goto changed;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (args_has(args, 'E')) {
 | 
				
			||||||
 | 
							layout_spread_out(wp);
 | 
				
			||||||
 | 
							goto changed;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!args_has(args, 'o')) {
 | 
						if (!args_has(args, 'o')) {
 | 
				
			||||||
		if (args->argc == 0)
 | 
							if (args->argc == 0)
 | 
				
			||||||
			layout = w->lastlayout;
 | 
								layout = w->lastlayout;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -186,6 +186,7 @@ key_bindings_init(void)
 | 
				
			|||||||
		"bind = choose-buffer",
 | 
							"bind = choose-buffer",
 | 
				
			||||||
		"bind ? list-keys",
 | 
							"bind ? list-keys",
 | 
				
			||||||
		"bind D choose-client",
 | 
							"bind D choose-client",
 | 
				
			||||||
 | 
							"bind E select-layout -E",
 | 
				
			||||||
		"bind L switch-client -l",
 | 
							"bind L switch-client -l",
 | 
				
			||||||
		"bind M select-pane -M",
 | 
							"bind M select-pane -M",
 | 
				
			||||||
		"bind [ copy-mode",
 | 
							"bind [ copy-mode",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										82
									
								
								layout-set.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								layout-set.c
									
									
									
									
									
								
							@@ -115,11 +115,11 @@ layout_set_previous(struct window *w)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
layout_set_even_h(struct window *w)
 | 
					layout_set_even(struct window *w, enum layout_type type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						struct window_pane	*wp;
 | 
				
			||||||
	struct layout_cell	*lc, *lcnew;
 | 
						struct layout_cell	*lc, *lcnew;
 | 
				
			||||||
	u_int			 i, n, width, xoff;
 | 
						u_int			 n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	layout_print_cell(w->layout_root, __func__, 1);
 | 
						layout_print_cell(w->layout_root, __func__, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,36 +128,21 @@ layout_set_even_h(struct window *w)
 | 
				
			|||||||
	if (n <= 1)
 | 
						if (n <= 1)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* How many can we fit? */
 | 
					 | 
				
			||||||
	width = (w->sx - (n - 1)) / n;
 | 
					 | 
				
			||||||
	if (width < PANE_MINIMUM)
 | 
					 | 
				
			||||||
		width = PANE_MINIMUM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Free the old root and construct a new. */
 | 
						/* Free the old root and construct a new. */
 | 
				
			||||||
	layout_free(w);
 | 
						layout_free(w);
 | 
				
			||||||
	lc = w->layout_root = layout_create_cell(NULL);
 | 
						lc = w->layout_root = layout_create_cell(NULL);
 | 
				
			||||||
	layout_set_size(lc, w->sx, w->sy, 0, 0);
 | 
						layout_set_size(lc, w->sx, w->sy, 0, 0);
 | 
				
			||||||
	layout_make_node(lc, LAYOUT_LEFTRIGHT);
 | 
						layout_make_node(lc, type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Build new leaf cells. */
 | 
						/* Build new leaf cells. */
 | 
				
			||||||
	i = xoff = 0;
 | 
					 | 
				
			||||||
	TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
		/* Create child cell. */
 | 
					 | 
				
			||||||
		lcnew = layout_create_cell(lc);
 | 
							lcnew = layout_create_cell(lc);
 | 
				
			||||||
		layout_set_size(lcnew, width, w->sy, xoff, 0);
 | 
					 | 
				
			||||||
		layout_make_leaf(lcnew, wp);
 | 
							layout_make_leaf(lcnew, wp);
 | 
				
			||||||
		TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
 | 
							TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
		xoff += width + 1;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Allocate any remaining space. */
 | 
						/* Spread out cells. */
 | 
				
			||||||
	if (w->sx > xoff - 1) {
 | 
						layout_spread_cell(w, lc);
 | 
				
			||||||
		lc = TAILQ_LAST(&lc->cells, layout_cells);
 | 
					 | 
				
			||||||
		layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT,
 | 
					 | 
				
			||||||
		    w->sx - (xoff - 1));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Fix cell offsets. */
 | 
						/* Fix cell offsets. */
 | 
				
			||||||
	layout_fix_offsets(lc);
 | 
						layout_fix_offsets(lc);
 | 
				
			||||||
@@ -169,59 +154,16 @@ layout_set_even_h(struct window *w)
 | 
				
			|||||||
	server_redraw_window(w);
 | 
						server_redraw_window(w);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					layout_set_even_h(struct window *w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						layout_set_even(w, LAYOUT_LEFTRIGHT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
layout_set_even_v(struct window *w)
 | 
					layout_set_even_v(struct window *w)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct window_pane	*wp;
 | 
						layout_set_even(w, LAYOUT_TOPBOTTOM);
 | 
				
			||||||
	struct layout_cell	*lc, *lcnew;
 | 
					 | 
				
			||||||
	u_int			 i, n, height, yoff;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	layout_print_cell(w->layout_root, __func__, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Get number of panes. */
 | 
					 | 
				
			||||||
	n = window_count_panes(w);
 | 
					 | 
				
			||||||
	if (n <= 1)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* How many can we fit? */
 | 
					 | 
				
			||||||
	height = (w->sy - (n - 1)) / n;
 | 
					 | 
				
			||||||
	if (height < PANE_MINIMUM)
 | 
					 | 
				
			||||||
		height = PANE_MINIMUM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Free the old root and construct a new. */
 | 
					 | 
				
			||||||
	layout_free(w);
 | 
					 | 
				
			||||||
	lc = w->layout_root = layout_create_cell(NULL);
 | 
					 | 
				
			||||||
	layout_set_size(lc, w->sx, w->sy, 0, 0);
 | 
					 | 
				
			||||||
	layout_make_node(lc, LAYOUT_TOPBOTTOM);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Build new leaf cells. */
 | 
					 | 
				
			||||||
	i = yoff = 0;
 | 
					 | 
				
			||||||
	TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
					 | 
				
			||||||
		/* Create child cell. */
 | 
					 | 
				
			||||||
		lcnew = layout_create_cell(lc);
 | 
					 | 
				
			||||||
		layout_set_size(lcnew, w->sx, height, 0, yoff);
 | 
					 | 
				
			||||||
		layout_make_leaf(lcnew, wp);
 | 
					 | 
				
			||||||
		TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
		yoff += height + 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Allocate any remaining space. */
 | 
					 | 
				
			||||||
	if (w->sy > yoff - 1) {
 | 
					 | 
				
			||||||
		lc = TAILQ_LAST(&lc->cells, layout_cells);
 | 
					 | 
				
			||||||
		layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM,
 | 
					 | 
				
			||||||
		    w->sy - (yoff - 1));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Fix cell offsets. */
 | 
					 | 
				
			||||||
	layout_fix_offsets(lc);
 | 
					 | 
				
			||||||
	layout_fix_panes(w, w->sx, w->sy);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	layout_print_cell(w->layout_root, __func__, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	notify_window("window-layout-changed", w);
 | 
					 | 
				
			||||||
	server_redraw_window(w);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								layout.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								layout.c
									
									
									
									
									
								
							@@ -983,3 +983,61 @@ layout_close_pane(struct window_pane *wp)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	notify_window("window-layout-changed", w);
 | 
						notify_window("window-layout-changed", w);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					layout_spread_cell(struct window *w, struct layout_cell *parent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct layout_cell	*lc;
 | 
				
			||||||
 | 
						u_int			 number, each, size;
 | 
				
			||||||
 | 
						int			 change, changed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						number = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH (lc, &parent->cells, entry)
 | 
				
			||||||
 | 
						    number++;
 | 
				
			||||||
 | 
						if (number <= 1)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (parent->type == LAYOUT_LEFTRIGHT)
 | 
				
			||||||
 | 
							size = parent->sx;
 | 
				
			||||||
 | 
						else if (parent->type == LAYOUT_TOPBOTTOM)
 | 
				
			||||||
 | 
							size = parent->sy;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						each = (size - (number - 1)) / number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						changed = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH (lc, &parent->cells, entry) {
 | 
				
			||||||
 | 
							if (TAILQ_NEXT(lc, entry) == NULL)
 | 
				
			||||||
 | 
								each = size - (each * (number - 1));
 | 
				
			||||||
 | 
							change = 0;
 | 
				
			||||||
 | 
							if (parent->type == LAYOUT_LEFTRIGHT) {
 | 
				
			||||||
 | 
								change = each - (int)lc->sx;
 | 
				
			||||||
 | 
								layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT, change);
 | 
				
			||||||
 | 
							} else if (parent->type == LAYOUT_TOPBOTTOM) {
 | 
				
			||||||
 | 
								change = each - (int)lc->sy;
 | 
				
			||||||
 | 
								layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, change);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (change != 0)
 | 
				
			||||||
 | 
								changed = 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (changed);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_spread_out(struct window_pane *wp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct layout_cell	*parent;
 | 
				
			||||||
 | 
						struct window		*w = wp->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent = wp->layout_cell->parent;
 | 
				
			||||||
 | 
						if (parent == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							if (layout_spread_cell(w, parent)) {
 | 
				
			||||||
 | 
								layout_fix_offsets(parent);
 | 
				
			||||||
 | 
								layout_fix_panes(w, w->sx, w->sy);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} while ((parent = parent->parent) != NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.1
									
									
									
									
									
								
							@@ -1923,8 +1923,8 @@ lower) with
 | 
				
			|||||||
.Fl U
 | 
					.Fl U
 | 
				
			||||||
or downward (numerically higher).
 | 
					or downward (numerically higher).
 | 
				
			||||||
.It Xo Ic select-layout
 | 
					.It Xo Ic select-layout
 | 
				
			||||||
.Op Fl nop
 | 
					.Op Fl Enop
 | 
				
			||||||
.Op Fl t Ar target-window
 | 
					.Op Fl t Ar target-pane
 | 
				
			||||||
.Op Ar layout-name
 | 
					.Op Ar layout-name
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
.D1 (alias: Ic selectl )
 | 
					.D1 (alias: Ic selectl )
 | 
				
			||||||
@@ -1942,6 +1942,8 @@ and
 | 
				
			|||||||
commands.
 | 
					commands.
 | 
				
			||||||
.Fl o
 | 
					.Fl o
 | 
				
			||||||
applies the last set layout if possible (undoes the most recent layout change).
 | 
					applies the last set layout if possible (undoes the most recent layout change).
 | 
				
			||||||
 | 
					.Fl E
 | 
				
			||||||
 | 
					spreads the current pane and any panes next to it out evenly.
 | 
				
			||||||
.It Xo Ic select-pane
 | 
					.It Xo Ic select-pane
 | 
				
			||||||
.Op Fl DdegLlMmRU
 | 
					.Op Fl DdegLlMmRU
 | 
				
			||||||
.Op Fl P Ar style
 | 
					.Op Fl P Ar style
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2213,6 +2213,8 @@ void		 layout_assign_pane(struct layout_cell *, struct window_pane *);
 | 
				
			|||||||
struct layout_cell *layout_split_pane(struct window_pane *, enum layout_type,
 | 
					struct layout_cell *layout_split_pane(struct window_pane *, enum layout_type,
 | 
				
			||||||
		     int, int, int);
 | 
							     int, int, int);
 | 
				
			||||||
void		 layout_close_pane(struct window_pane *);
 | 
					void		 layout_close_pane(struct window_pane *);
 | 
				
			||||||
 | 
					int		 layout_spread_cell(struct window *, struct layout_cell *);
 | 
				
			||||||
 | 
					void		 layout_spread_out(struct window_pane *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* layout-custom.c */
 | 
					/* layout-custom.c */
 | 
				
			||||||
char		*layout_dump(struct layout_cell *);
 | 
					char		*layout_dump(struct layout_cell *);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user