-/* $OpenBSD: layout-set.c,v 1.30 2021/03/11 06:31:05 nicm Exp $ */
+/* $OpenBSD: layout-set.c,v 1.31 2024/08/21 05:03:13 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
static void layout_set_even_h(struct window *);
static void layout_set_even_v(struct window *);
static void layout_set_main_h(struct window *);
+static void layout_set_main_h_mirrored(struct window *);
static void layout_set_main_v(struct window *);
+static void layout_set_main_v_mirrored(struct window *);
static void layout_set_tiled(struct window *);
static const struct {
{ "even-horizontal", layout_set_even_h },
{ "even-vertical", layout_set_even_v },
{ "main-horizontal", layout_set_main_h },
+ { "main-horizontal-mirrored", layout_set_main_h_mirrored },
{ "main-vertical", layout_set_main_v },
+ { "main-vertical-mirrored", layout_set_main_v_mirrored },
{ "tiled", layout_set_tiled },
};
server_redraw_window(w);
}
+static void
+layout_set_main_h_mirrored(struct window *w)
+{
+ struct window_pane *wp;
+ struct layout_cell *lc, *lcmain, *lcother, *lcchild;
+ u_int n, mainh, otherh, sx, sy;
+ char *cause;
+ const char *s;
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ /* Get number of panes. */
+ n = window_count_panes(w);
+ if (n <= 1)
+ return;
+ n--; /* take off main pane */
+
+ /* Find available height - take off one line for the border. */
+ sy = w->sy - 1;
+
+ /* Get the main pane height. */
+ s = options_get_string(w->options, "main-pane-height");
+ mainh = args_string_percentage(s, 0, sy, sy, &cause);
+ if (cause != NULL) {
+ mainh = 24;
+ free(cause);
+ }
+
+ /* Work out the other pane height. */
+ if (mainh + PANE_MINIMUM >= sy) {
+ if (sy <= PANE_MINIMUM + PANE_MINIMUM)
+ mainh = PANE_MINIMUM;
+ else
+ mainh = sy - PANE_MINIMUM;
+ otherh = PANE_MINIMUM;
+ } else {
+ s = options_get_string(w->options, "other-pane-height");
+ otherh = args_string_percentage(s, 0, sy, sy, &cause);
+ if (cause != NULL || otherh == 0) {
+ otherh = sy - mainh;
+ free(cause);
+ } else if (otherh > sy || sy - otherh < mainh)
+ otherh = sy - mainh;
+ else
+ mainh = sy - otherh;
+ }
+
+ /* Work out what width is needed. */
+ sx = (n * (PANE_MINIMUM + 1)) - 1;
+ if (sx < w->sx)
+ sx = w->sx;
+
+ /* Free old tree and create a new root. */
+ layout_free(w);
+ lc = w->layout_root = layout_create_cell(NULL);
+ layout_set_size(lc, sx, mainh + otherh + 1, 0, 0);
+ layout_make_node(lc, LAYOUT_TOPBOTTOM);
+
+ /* Create the other pane. */
+ lcother = layout_create_cell(lc);
+ layout_set_size(lcother, sx, otherh, 0, 0);
+ if (n == 1) {
+ wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
+ layout_make_leaf(lcother, wp);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+ } else {
+ layout_make_node(lcother, LAYOUT_LEFTRIGHT);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+
+ /* Add the remaining panes as children. */
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (wp == TAILQ_FIRST(&w->panes))
+ continue;
+ lcchild = layout_create_cell(lcother);
+ layout_set_size(lcchild, PANE_MINIMUM, otherh, 0, 0);
+ layout_make_leaf(lcchild, wp);
+ TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
+ }
+ layout_spread_cell(w, lcother);
+ }
+
+ /* Create the main pane. */
+ lcmain = layout_create_cell(lc);
+ layout_set_size(lcmain, sx, mainh, 0, 0);
+ layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
+ TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
+
+ /* Fix cell offsets. */
+ layout_fix_offsets(w);
+ layout_fix_panes(w, NULL);
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ window_resize(w, lc->sx, lc->sy, -1, -1);
+ notify_window("window-layout-changed", w);
+ server_redraw_window(w);
+}
+
static void
layout_set_main_v(struct window *w)
{
server_redraw_window(w);
}
+static void
+layout_set_main_v_mirrored(struct window *w)
+{
+ struct window_pane *wp;
+ struct layout_cell *lc, *lcmain, *lcother, *lcchild;
+ u_int n, mainw, otherw, sx, sy;
+ char *cause;
+ const char *s;
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ /* Get number of panes. */
+ n = window_count_panes(w);
+ if (n <= 1)
+ return;
+ n--; /* take off main pane */
+
+ /* Find available width - take off one line for the border. */
+ sx = w->sx - 1;
+
+ /* Get the main pane width. */
+ s = options_get_string(w->options, "main-pane-width");
+ mainw = args_string_percentage(s, 0, sx, sx, &cause);
+ if (cause != NULL) {
+ mainw = 80;
+ free(cause);
+ }
+
+ /* Work out the other pane width. */
+ if (mainw + PANE_MINIMUM >= sx) {
+ if (sx <= PANE_MINIMUM + PANE_MINIMUM)
+ mainw = PANE_MINIMUM;
+ else
+ mainw = sx - PANE_MINIMUM;
+ otherw = PANE_MINIMUM;
+ } else {
+ s = options_get_string(w->options, "other-pane-width");
+ otherw = args_string_percentage(s, 0, sx, sx, &cause);
+ if (cause != NULL || otherw == 0) {
+ otherw = sx - mainw;
+ free(cause);
+ } else if (otherw > sx || sx - otherw < mainw)
+ otherw = sx - mainw;
+ else
+ mainw = sx - otherw;
+ }
+
+ /* Work out what height is needed. */
+ sy = (n * (PANE_MINIMUM + 1)) - 1;
+ if (sy < w->sy)
+ sy = w->sy;
+
+ /* Free old tree and create a new root. */
+ layout_free(w);
+ lc = w->layout_root = layout_create_cell(NULL);
+ layout_set_size(lc, mainw + otherw + 1, sy, 0, 0);
+ layout_make_node(lc, LAYOUT_LEFTRIGHT);
+
+ /* Create the other pane. */
+ lcother = layout_create_cell(lc);
+ layout_set_size(lcother, otherw, sy, 0, 0);
+ if (n == 1) {
+ wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
+ layout_make_leaf(lcother, wp);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+ } else {
+ layout_make_node(lcother, LAYOUT_TOPBOTTOM);
+ TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
+
+ /* Add the remaining panes as children. */
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (wp == TAILQ_FIRST(&w->panes))
+ continue;
+ lcchild = layout_create_cell(lcother);
+ layout_set_size(lcchild, otherw, PANE_MINIMUM, 0, 0);
+ layout_make_leaf(lcchild, wp);
+ TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
+ }
+ layout_spread_cell(w, lcother);
+ }
+
+ /* Create the main pane. */
+ lcmain = layout_create_cell(lc);
+ layout_set_size(lcmain, mainw, sy, 0, 0);
+ layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
+ TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
+
+ /* Fix cell offsets. */
+ layout_fix_offsets(w);
+ layout_fix_panes(w, NULL);
+
+ layout_print_cell(w->layout_root, __func__, 1);
+
+ window_resize(w, lc->sx, lc->sy, -1, -1);
+ notify_window("window-layout-changed", w);
+ server_redraw_window(w);
+}
+
void
layout_set_tiled(struct window *w)
{
-.\" $OpenBSD: tmux.1,v 1.948 2024/08/21 04:17:09 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.949 2024/08/21 05:03:13 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
Change to the pane above, below, to the left, or to the right of the current
pane.
.It M-1 to M-5
-Arrange panes in one of the five preset layouts: even-horizontal,
-even-vertical, main-horizontal, main-vertical, or tiled.
+Arrange panes in one of the seven preset layouts:
+even-horizontal, even-vertical,
+main-horizontal, main-horizontal-mirrored,
+main-vertical, main-vertical, or tiled.
.It Space
Arrange the current window in the next preset layout.
.It M-n
Use the
.Em main-pane-height
window option to specify the height of the top pane.
-.It Ic main-vertical
-Similar to
+.It Ic main-horizontal-mirrored
+The same as
.Ic main-horizontal
-but the large pane is placed on the left and the others spread from top to
-bottom along the right.
-See the
+but mirrored so the main pane is at the bottom of the window.
+.It Ic main-vertical
+A large (main) pane is shown on the left of the window and the remaining panes
+are spread from top to bottom in the leftover space on the right.
+Use the
.Em main-pane-width
-window option.
+window option to specify the width of the left pane.
+.It Ic main-vertical-mirrored
+The same as
+.Ic main-vertical
+but mirrored so the main pane is on the right of the window.
.It Ic tiled
Panes are spread out as evenly as possible over the window in both rows and
columns.
.It Ic main-pane-height Ar height
.It Ic main-pane-width Ar width
Set the width or height of the main (left or top) pane in the
-.Ic main-horizontal
+.Ic main-horizontal,
+.Ic main-horizontal-mirrored,
+.Ic main-vertical,
or
-.Ic main-vertical
+.Ic main-vertical-mirrored
layouts.
If suffixed by
.Ql % ,
.It Ic other-pane-height Ar height
Set the height of the other panes (not the main pane) in the
.Ic main-horizontal
-layout.
+and
+.Ic main-horizontal-mirrored
+layouts.
If this option is set to 0 (the default), it will have no effect.
If both the
.Ic main-pane-height
.Ic other-pane-height ,
but set the width of other panes in the
.Ic main-vertical
-layout.
+and
+.Ic main-vertical-mirrored
+layouts.
.Pp
.It Ic pane-active-border-style Ar style
Set the pane border style for the currently active pane.