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.
pull/1161/head
nicm 2017-11-15 19:59:27 +00:00
parent 533a5719c5
commit 3b649d2fcd
6 changed files with 92 additions and 82 deletions

View File

@ -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;

View File

@ -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",

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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 *);