mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:44:18 +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",
 | 
			
		||||
	.alias = "selectl",
 | 
			
		||||
 | 
			
		||||
	.args = { "nopt:", 0, 1 },
 | 
			
		||||
	.usage = "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
 | 
			
		||||
	.args = { "Enopt:", 0, 1 },
 | 
			
		||||
	.usage = "[-Enop] " CMD_TARGET_PANE_USAGE " [layout-name]",
 | 
			
		||||
 | 
			
		||||
	.target = { 't', CMD_FIND_WINDOW, 0 },
 | 
			
		||||
	.target = { 't', CMD_FIND_PANE, 0 },
 | 
			
		||||
 | 
			
		||||
	.flags = CMD_AFTERHOOK,
 | 
			
		||||
	.exec = cmd_select_layout_exec
 | 
			
		||||
@@ -71,14 +71,14 @@ const struct cmd_entry cmd_previous_layout_entry = {
 | 
			
		||||
static enum cmd_retval
 | 
			
		||||
cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
{
 | 
			
		||||
	struct args	*args = self->args;
 | 
			
		||||
	struct winlink	*wl = item->target.wl;
 | 
			
		||||
	struct window	*w;
 | 
			
		||||
	const char	*layoutname;
 | 
			
		||||
	char		*oldlayout;
 | 
			
		||||
	int		 next, previous, layout;
 | 
			
		||||
	struct args		*args = self->args;
 | 
			
		||||
	struct winlink		*wl = item->target.wl;
 | 
			
		||||
	struct window		*w = wl->window;
 | 
			
		||||
	struct window_pane	*wp = item->target.wp;
 | 
			
		||||
	const char		*layoutname;
 | 
			
		||||
	char			*oldlayout;
 | 
			
		||||
	int			 next, previous, layout;
 | 
			
		||||
 | 
			
		||||
	w = wl->window;
 | 
			
		||||
	server_unzoom_window(w);
 | 
			
		||||
 | 
			
		||||
	next = self->entry == &cmd_next_layout_entry;
 | 
			
		||||
@@ -99,6 +99,11 @@ cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item)
 | 
			
		||||
		goto changed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (args_has(args, 'E')) {
 | 
			
		||||
		layout_spread_out(wp);
 | 
			
		||||
		goto changed;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!args_has(args, 'o')) {
 | 
			
		||||
		if (args->argc == 0)
 | 
			
		||||
			layout = w->lastlayout;
 | 
			
		||||
 
 | 
			
		||||
@@ -186,6 +186,7 @@ key_bindings_init(void)
 | 
			
		||||
		"bind = choose-buffer",
 | 
			
		||||
		"bind ? list-keys",
 | 
			
		||||
		"bind D choose-client",
 | 
			
		||||
		"bind E select-layout -E",
 | 
			
		||||
		"bind L switch-client -l",
 | 
			
		||||
		"bind M select-pane -M",
 | 
			
		||||
		"bind [ copy-mode",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										82
									
								
								layout-set.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								layout-set.c
									
									
									
									
									
								
							@@ -115,11 +115,11 @@ layout_set_previous(struct window *w)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
layout_set_even_h(struct window *w)
 | 
			
		||||
layout_set_even(struct window *w, enum layout_type type)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
	struct layout_cell	*lc, *lcnew;
 | 
			
		||||
	u_int			 i, n, width, xoff;
 | 
			
		||||
	u_int			 n;
 | 
			
		||||
 | 
			
		||||
	layout_print_cell(w->layout_root, __func__, 1);
 | 
			
		||||
 | 
			
		||||
@@ -128,36 +128,21 @@ layout_set_even_h(struct window *w)
 | 
			
		||||
	if (n <= 1)
 | 
			
		||||
		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. */
 | 
			
		||||
	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_LEFTRIGHT);
 | 
			
		||||
	layout_make_node(lc, type);
 | 
			
		||||
 | 
			
		||||
	/* Build new leaf cells. */
 | 
			
		||||
	i = xoff = 0;
 | 
			
		||||
	TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
			
		||||
		/* Create child cell. */
 | 
			
		||||
		lcnew = layout_create_cell(lc);
 | 
			
		||||
		layout_set_size(lcnew, width, w->sy, xoff, 0);
 | 
			
		||||
		layout_make_leaf(lcnew, wp);
 | 
			
		||||
		TAILQ_INSERT_TAIL(&lc->cells, lcnew, entry);
 | 
			
		||||
 | 
			
		||||
		i++;
 | 
			
		||||
		xoff += width + 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Allocate any remaining space. */
 | 
			
		||||
	if (w->sx > xoff - 1) {
 | 
			
		||||
		lc = TAILQ_LAST(&lc->cells, layout_cells);
 | 
			
		||||
		layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT,
 | 
			
		||||
		    w->sx - (xoff - 1));
 | 
			
		||||
	}
 | 
			
		||||
	/* Spread out cells. */
 | 
			
		||||
	layout_spread_cell(w, lc);
 | 
			
		||||
 | 
			
		||||
	/* Fix cell offsets. */
 | 
			
		||||
	layout_fix_offsets(lc);
 | 
			
		||||
@@ -169,59 +154,16 @@ layout_set_even_h(struct window *w)
 | 
			
		||||
	server_redraw_window(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
layout_set_even_h(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	layout_set_even(w, LAYOUT_LEFTRIGHT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
layout_set_even_v(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
	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);
 | 
			
		||||
	layout_set_even(w, LAYOUT_TOPBOTTOM);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
or downward (numerically higher).
 | 
			
		||||
.It Xo Ic select-layout
 | 
			
		||||
.Op Fl nop
 | 
			
		||||
.Op Fl t Ar target-window
 | 
			
		||||
.Op Fl Enop
 | 
			
		||||
.Op Fl t Ar target-pane
 | 
			
		||||
.Op Ar layout-name
 | 
			
		||||
.Xc
 | 
			
		||||
.D1 (alias: Ic selectl )
 | 
			
		||||
@@ -1942,6 +1942,8 @@ and
 | 
			
		||||
commands.
 | 
			
		||||
.Fl o
 | 
			
		||||
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
 | 
			
		||||
.Op Fl DdegLlMmRU
 | 
			
		||||
.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,
 | 
			
		||||
		     int, int, int);
 | 
			
		||||
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 */
 | 
			
		||||
char		*layout_dump(struct layout_cell *);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user