Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-06-28 21:49:05 +01:00
9 changed files with 363 additions and 161 deletions

View File

@@ -40,8 +40,8 @@ const struct cmd_entry cmd_new_pane_entry = {
.args = { "bB:c:de:EfF:hIkl:Lm:p:PR:s:S:t:T:vWx:X:y:Y:Z", 0, -1, NULL }, .args = { "bB:c:de:EfF:hIkl:Lm:p:PR:s:S:t:T:vWx:X:y:Y:Z", 0, -1, NULL },
.usage = "[-bdefhIklPvWZ] [-B border-lines] " .usage = "[-bdefhIklPvWZ] [-B border-lines] "
"[-c start-directory] [-e environment] " "[-c start-directory] [-e environment] "
"[-F format] [-l size] [-m message] [-p percentage] " "[-F format] [-l size] [-m message] [-p percentage] "
"[-s style] [-S active-border-style] " "[-s style] [-S active-border-style] "
"[-R inactive-border-style] [-T title] [-x width] [-y height] " "[-R inactive-border-style] [-T title] [-x width] [-y height] "
"[-X x-position] [-Y y-position] " CMD_TARGET_PANE_USAGE " " "[-X x-position] [-Y y-position] " CMD_TARGET_PANE_USAGE " "
@@ -95,7 +95,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
if (cmd_get_entry(self) == &cmd_new_pane_entry) if (cmd_get_entry(self) == &cmd_new_pane_entry)
is_floating = !args_has(args, 'L'); is_floating = !args_has(args, 'L');
else else
is_floating = 0; is_floating = window_pane_is_floating(wp);
flags = is_floating ? SPAWN_FLOATING : 0; flags = is_floating ? SPAWN_FLOATING : 0;
if (args_has(args, 'b')) if (args_has(args, 'b'))

276
layout.c
View File

@@ -31,8 +31,9 @@
* a cell which contains a list of cells, and 'leaf' to refer to a cell that * a cell which contains a list of cells, and 'leaf' to refer to a cell that
* contains a window pane. A leaf is considered to be 'tiled' if it is to be * contains a window pane. A leaf is considered to be 'tiled' if it is to be
* drawn as a part of the tiled layout. A 'neighbour' is a sibling that is also * drawn as a part of the tiled layout. A 'neighbour' is a sibling that is also
* tiled. A cell's 'split' size refers to the side that is shortened when * tiled or a node that contains a tiled leaf in a subtree. A cell's 'split'
* splitting it, determined by the parent's type. * size refers to the side that is shortened when splitting it, determined by
* the parent's type.
* *
* Each window has a pointer to the root of its layout tree (containing its * Each window has a pointer to the root of its layout tree (containing its
* panes), every pane has a pointer back to the cell containing it, and each * panes), every pane has a pointer back to the cell containing it, and each
@@ -296,6 +297,27 @@ layout_cell_is_first_tiled(struct layout_cell *lc)
return (lcchild == lc); return (lcchild == lc);
} }
static struct layout_cell *
layout_cell_get_first_tiled(struct layout_cell *lc)
{
struct layout_cell *lcchild, *lcchild2;
if (layout_cell_is_tiled(lc))
return (lc);
if (lc->type == LAYOUT_WINDOWPANE)
return (NULL);
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (layout_cell_is_tiled(lcchild))
return (lcchild);
if (lcchild->type != LAYOUT_WINDOWPANE) {
lcchild2 = layout_cell_get_first_tiled(lcchild);
if (lcchild2 != NULL)
return (lcchild2);
}
}
return (NULL);
}
/* Fix cell offsets for a child cell. */ /* Fix cell offsets for a child cell. */
static void static void
@@ -609,6 +631,20 @@ layout_resize_adjust(struct window *w, struct layout_cell *lc,
} }
} }
/* Resizes a cell to a specified size */
void
layout_resize_set_size(struct window *w, struct layout_cell *lc,
enum layout_type type, u_int size)
{
int change;
if (type == LAYOUT_LEFTRIGHT)
change = size - lc->sx;
else
change = size - lc->sy;
layout_resize_adjust(w, lc, type, change);
}
/* Find and return the nearest neighbour to a cell in a specific direction. */ /* Find and return the nearest neighbour to a cell in a specific direction. */
static struct layout_cell * static struct layout_cell *
layout_cell_get_neighbour_direction(struct layout_cell *lc, int direction) layout_cell_get_neighbour_direction(struct layout_cell *lc, int direction)
@@ -1184,6 +1220,101 @@ layout_resize_child_cells(struct window *w, struct layout_cell *lc)
} }
} }
/*
* Replaces the provided layout cell with a new node of the specified type and
* inserts the cell into it. Used when creating new cells requires a different
* layout type, or when the root layout is a window pane.
*/
struct layout_cell *
layout_replace_with_node(struct window *w, struct layout_cell *lc,
enum layout_type type)
{
struct layout_cell *lcparent;
lcparent = layout_create_cell(lc->parent);
layout_make_node(lcparent, type);
layout_set_size(lcparent, lc->sx, lc->sy, lc->xoff, lc->yoff);
if (lc->parent == NULL)
w->layout_root = lcparent;
else
TAILQ_REPLACE(&lc->parent->cells, lc, lcparent, entry);
/* Insert the old cell. */
lc->parent = lcparent;
TAILQ_INSERT_HEAD(&lcparent->cells, lc, entry);
return (lcparent);
}
/* Checks if there is enough space for two new panes. */
int
layout_split_check_space(struct window_pane *wp, struct layout_cell *lc,
enum layout_type type)
{
struct style *sb_style = &wp->scrollbar_style;
u_int minimum, sx = lc->sx, sy = lc->sy;
int scrollbars, status;
if (lc->flags & LAYOUT_CELL_FLOATING)
fatalx("floating cells cannot be split");
status = window_get_pane_status(wp->window);
scrollbars = options_get_number(wp->window->options, "pane-scrollbars");
switch (type) {
case LAYOUT_LEFTRIGHT:
if (scrollbars) {
minimum = PANE_MINIMUM * 2 + sb_style->width +
sb_style->pad;
} else
minimum = PANE_MINIMUM * 2 + 1;
if (sx < minimum)
return (0);
break;
case LAYOUT_TOPBOTTOM:
if (layout_add_horizontal_border(wp->window, lc, status))
minimum = PANE_MINIMUM * 2 + 2;
else
minimum = PANE_MINIMUM * 2 + 1;
if (sy < minimum)
return (0);
break;
default:
fatalx("bad layout type");
}
return (1);
}
/* Calculates the new cell sizes when splitting a pane. */
void
layout_split_sizes(struct layout_cell *lc, int size, int before,
enum layout_type type, u_int *size1, u_int *size2, u_int *saved_size)
{
u_int s1, s2, ss;
u_int sx = lc->sx, sy = lc->sy;
if (type == LAYOUT_LEFTRIGHT)
ss = sx;
else
ss = sy;
if (size < 0)
s2 = ((ss + 1) / 2) - 1;
else if (before)
s2 = ss - size - 1;
else
s2 = size;
if (s2 < PANE_MINIMUM)
s2 = PANE_MINIMUM;
else if (s2 > sx - 2)
s2 = ss - 2;
s1 = ss - 1 - s2;
*size1 = s1;
*size2 = s2;
*saved_size = ss;
}
/* /*
* Split a pane into two. size is a hint, or -1 for default half/half * Split a pane into two. size is a hint, or -1 for default half/half
* split. This must be followed by layout_assign_pane before much else happens! * split. This must be followed by layout_assign_pane before much else happens!
@@ -1193,11 +1324,10 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
int flags) int flags)
{ {
struct layout_cell *lc, *lcparent, *lcnew, *lc1, *lc2; struct layout_cell *lc, *lcparent, *lcnew, *lc1, *lc2;
struct style *sb_style = &wp->scrollbar_style; u_int sx, sy, xoff, yoff, size1, size2;
u_int sx, sy, xoff, yoff, size1, size2, minimum;
u_int new_size, saved_size, resize_first = 0; u_int new_size, saved_size, resize_first = 0;
int full_size = (flags & SPAWN_FULLSIZE), status; int full_size = (flags & SPAWN_FULLSIZE);
int scrollbars; int before = (flags & SPAWN_BEFORE);
/* /*
* If full_size is specified, add a new cell at the top of the window * If full_size is specified, add a new cell at the top of the window
@@ -1207,8 +1337,6 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
lc = wp->window->layout_root; lc = wp->window->layout_root;
else else
lc = wp->layout_cell; lc = wp->layout_cell;
status = window_get_pane_status(wp->window);
scrollbars = options_get_number(wp->window->options, "pane-scrollbars");
/* Copy the old cell size. */ /* Copy the old cell size. */
sx = lc->sx; sx = lc->sx;
@@ -1217,47 +1345,14 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
yoff = lc->yoff; yoff = lc->yoff;
/* Check there is enough space for the two new panes. */ /* Check there is enough space for the two new panes. */
switch (type) { if (!layout_split_check_space(wp, lc, type))
case LAYOUT_LEFTRIGHT: return (NULL);
if (scrollbars) {
minimum = PANE_MINIMUM * 2 + sb_style->width +
sb_style->pad;
} else
minimum = PANE_MINIMUM * 2 + 1;
if (sx < minimum)
return (NULL);
break;
case LAYOUT_TOPBOTTOM:
if (layout_add_horizontal_border(wp->window, lc, status))
minimum = PANE_MINIMUM * 2 + 2;
else
minimum = PANE_MINIMUM * 2 + 1;
if (sy < minimum)
return (NULL);
break;
default:
fatalx("bad layout type");
}
/* /*
* Calculate new cell sizes. size is the target size or -1 for middle * Calculate new cell sizes. size is the target size or -1 for middle
* split, size1 is the size of the top/left and size2 the bottom/right. * split, size1 is the size of the top/left and size2 the bottom/right.
*/ */
if (type == LAYOUT_LEFTRIGHT) layout_split_sizes(lc, size, before, type, &size1, &size2, &saved_size);
saved_size = sx;
else
saved_size = sy;
if (size < 0)
size2 = ((saved_size + 1) / 2) - 1;
else if (flags & SPAWN_BEFORE)
size2 = saved_size - size - 1;
else
size2 = size;
if (size2 < PANE_MINIMUM)
size2 = PANE_MINIMUM;
else if (size2 > saved_size - 2)
size2 = saved_size - 2;
size1 = saved_size - 1 - size2;
/* Which size are we using? */ /* Which size are we using? */
if (flags & SPAWN_BEFORE) if (flags & SPAWN_BEFORE)
@@ -1315,17 +1410,7 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
*/ */
/* Create and insert the replacement parent. */ /* Create and insert the replacement parent. */
lcparent = layout_create_cell(lc->parent); lcparent = layout_replace_with_node(wp->window, lc, type);
layout_make_node(lcparent, type);
layout_set_size(lcparent, sx, sy, xoff, yoff);
if (lc->parent == NULL)
wp->window->layout_root = lcparent;
else
TAILQ_REPLACE(&lc->parent->cells, lc, lcparent, entry);
/* Insert the old cell. */
lc->parent = lcparent;
TAILQ_INSERT_HEAD(&lcparent->cells, lc, entry);
/* Create the new child cell. */ /* Create the new child cell. */
lcnew = layout_create_cell(lcparent); lcnew = layout_create_cell(lcparent);
@@ -1384,14 +1469,7 @@ layout_floating_pane(struct window *w, struct window_pane *wp, u_int sx,
* Adding a pane to a root that isn't node. Must create and * Adding a pane to a root that isn't node. Must create and
* insert a new root. * insert a new root.
*/ */
lcparent = layout_create_cell(NULL); lcparent = layout_replace_with_node(w, lc, LAYOUT_TOPBOTTOM);
layout_make_node(lcparent, LAYOUT_TOPBOTTOM);
layout_set_size(lcparent, w->sx, w->sy, 0, 0);
w->layout_root = lcparent;
/* Insert the old cell. */
lc->parent = lcparent;
TAILQ_INSERT_HEAD(&lcparent->cells, lc, entry);
} }
lcnew = layout_create_cell(lcparent); lcnew = layout_create_cell(lcparent);
@@ -1712,7 +1790,75 @@ layout_remove_tile(struct window *w, struct layout_cell *lc)
layout_resize_adjust(w, lcneighbour, type, change); layout_resize_adjust(w, lcneighbour, type, change);
} }
/* Zeroing out the cell geometry until the cell is retiled. */ /*
layout_set_size(lc, 0, 0, 0, 0); * Zeroing out the cell geometry until the cell is retiled unless this
* is the top level node.
*/
if (lc->parent != NULL)
layout_set_size(lc, 0, 0, 0, 0);
return (1);
}
/*
* Inserts a cell back into the tiled layout by taking half the space from its
* nearest neighbour.
*/
int
layout_insert_tile(struct window *w, struct layout_cell *lc)
{
struct layout_cell *lcneighbour, *lctiled, *lcparent;
enum layout_type type;
u_int size1, size2, saved_size;
if (lc == NULL)
fatalx("layout cell cannot be null when tiling");
lcparent = lc->parent;
if (lc->flags & LAYOUT_CELL_FLOATING)
return (1);
if (lcparent == NULL) {
/* Only pane in the layout. */
layout_set_size(lc, w->sx, w->sy, 0, 0);
return (1);
}
type = lcparent->type;
lcneighbour = layout_cell_get_neighbour(lc);
if (lcneighbour == NULL) {
/*
* This will become the only visible cell in the parent.
* Tile the parent, then set the child's 'split' size.
*/
layout_insert_tile(w, lcparent);
if (type == LAYOUT_LEFTRIGHT)
size1 = lcparent->sx;
else
size1 = lcparent->sy;
layout_resize_set_size(w, lc, type, size1);
} else {
/*
* If the neighbour is a node, a tiled child in the subtree of
* the neighbour is needed to check for space.
*/
lctiled = layout_cell_get_first_tiled(lcneighbour);
if (!layout_split_check_space(lctiled->wp, lcneighbour, type))
return (0);
layout_split_sizes(lcneighbour, -1, 0, type, &size1, &size2,
&saved_size);
layout_resize_set_size(w, lc, type, size1);
layout_resize_set_size(w, lcneighbour, type, size2);
}
/* Setting opposite of the 'split' size to that of the parent. */
if (lcparent->type == LAYOUT_LEFTRIGHT) {
size1 = lcparent->sy;
type = LAYOUT_TOPBOTTOM;
} else {
size1 = lcparent->sx;
type = LAYOUT_LEFTRIGHT;
}
layout_resize_set_size(w, lc, type, size1);
return (1); return (1);
} }

View File

@@ -1524,6 +1524,7 @@ screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
struct grid_line *gl; struct grid_line *gl;
u_int sx = screen_size_x(s); u_int sx = screen_size_x(s);
struct screen_write_citem *ci = ctx->item; struct screen_write_citem *ci = ctx->item;
u_int flags;
gl = grid_get_line(s->grid, s->grid->hsize + s->cy); gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg)) if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))
@@ -1534,7 +1535,10 @@ screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
ctx->wp->flags |= PANE_REDRAW; ctx->wp->flags |= PANE_REDRAW;
#endif #endif
flags = gl->flags & (GRID_LINE_START_PROMPT|GRID_LINE_START_OUTPUT);
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg); grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
gl->flags |= flags;
screen_write_collect_clear(ctx, s->cy, 1); screen_write_collect_clear(ctx, s->cy, 1);
ci->x = 0; ci->x = 0;

219
tmux.1
View File

@@ -2744,6 +2744,15 @@ and
.Fl Y .Fl Y
options set the position of the upper-left corner of the pane. options set the position of the upper-left corner of the pane.
If omitted, new floating panes are cascaded from the top-left of the window. If omitted, new floating panes are cascaded from the top-left of the window.
The
.Fl x ,
.Fl y ,
.Fl X ,
and
.Fl Y
options may be followed by
.Ql %
to specify a percentage of the window size.
.Pp .Pp
If the pane had previously been floating, the position and sizes are restored If the pane had previously been floating, the position and sizes are restored
from the saved values not specified by the from the saved values not specified by the
@@ -3588,7 +3597,7 @@ but a different format may be specified with
.Fl F . .Fl F .
.Tg newp .Tg newp
.It Xo Ic new\-pane .It Xo Ic new\-pane
.Op Fl bdefhIkPvWZ .Op Fl bdefhIkLPvWZ
.Op Fl B Ar border\-lines .Op Fl B Ar border\-lines
.Op Fl c Ar start\-directory .Op Fl c Ar start\-directory
.Op Fl e Ar environment .Op Fl e Ar environment
@@ -3601,101 +3610,49 @@ but a different format may be specified with
.Op Fl S Ar active\-border\-style .Op Fl S Ar active\-border\-style
.Op Fl t Ar target\-pane .Op Fl t Ar target\-pane
.Op Fl T Ar title .Op Fl T Ar title
.Op Fl x Ar width
.Op Fl y Ar height
.Op Fl X Ar x-position
.Op Fl Y Ar y-position
.Op Ar shell\-command Op Ar argument ... .Op Ar shell\-command Op Ar argument ...
.Xc .Xc
.D1 Pq alias: Ic newp .D1 Pq alias: Ic newp
Create a new pane. Creates a new floating pane.
The new pane is created by splitting The
.Ar target\-pane . .Fl x
If and
.Fl d .Fl y
is given, the session does not make the new pane the current pane. options set the width and height of the floating pane in columns and lines
.Fl Z respectively.
zooms if the window is not zoomed, or keeps it zoomed if already zoomed. The default is half the window width and a quarter the window height.
.Fl s The
sets the style for the pane content. .Fl X
.Fl S and
sets the border style when the pane is active and .Fl Y
.Fl R options set the position of the upper-left corner of the pane.
sets the border style when the pane is inactive (see If omitted, new floating panes are cascaded from the top-left of the window.
.Sx STYLES ) . The
.Fl T .Fl x ,
sets the pane title. .Fl y ,
.Fl X ,
and
.Fl Y
options may be followed by
.Ql %
to specify a percentage of the window size.
.Fl B .Fl B
sets the pane border lines for floating panes; see sets the pane border lines for floating panes; see
.Ic pane\-border\-lines . .Ic pane\-border\-lines .
.Pp .Pp
.Fl h
does a horizontal split and
.Fl v
a vertical split; if neither is specified,
.Fl v
is assumed.
The The
.Fl l .Fl L
option specifies the size of the new pane in lines (for vertical split) or in option makes
columns (for horizontal split); .Ic new\-pane
.Ar size behave like
may be followed by .Ic split\-window .
.Ql %
to specify a percentage of the available space.
.Fl p
is a shorthand option for this.
The
.Fl b
option causes the new pane to be created to the left of or above
.Ar target\-pane .
The
.Fl f
option creates a new pane spanning the full window height (with
.Fl h )
or full window width (with
.Fl v ) ,
instead of splitting the active pane.
.Pp
.Fl k
keeps the pane open after the optional
.Ar shell\-command
exits and waits for a key to be pressed before closing it.
The message shown is controlled by the
.Ic remain\-on\-exit\-format
option.
.Fl m Ar message
is equivalent to
.Fl k
but also sets the
.Ic remain\-on\-exit\-format
option for this pane to
.Ar message .
.Pp
.Fl W
Waits until
.Ar shell\-command
exits, then returns its exit status.
For example:
.Bd -literal -offset indent
$ tmux new-pane -W 'vi afile'
$ echo $?
0
.Ed
.Pp
.Fl E ,
or an empty
.Ar shell\-command ,
(\[aq]\[aq]) will create an empty pane with no command running in it;
.Ic display-message
.Fl I
can write to an empty pane.
The
.Fl I
flag will create an empty pane and forward any output from stdin to it.
For example:
.Bd -literal -offset indent
$ make 2>&1|tmux new\-pane \-dI &
.Ed
.Pp .Pp
All other options have the same meaning as for the All other options have the same meaning as for the
.Ic new\-window .Ic split\-window
command. command.
.Tg nextl .Tg nextl
.It Ic next\-layout Op Fl t Ar target\-window .It Ic next\-layout Op Fl t Ar target\-window
@@ -4050,14 +4007,92 @@ the command behaves like
.Op Ar shell\-command Op Ar argument ... .Op Ar shell\-command Op Ar argument ...
.Xc .Xc
.D1 Pq alias: Ic splitw .D1 Pq alias: Ic splitw
Creates a new pane by splitting Create a new pane by splitting
.Ar target\-pane . .Ar target\-pane .
Shares behavior with If
.Ic new\-pane . .Fl d
is given, the session does not make the new pane the current pane.
.Fl Z
zooms if the window is not zoomed, or keeps it zoomed if already zoomed.
.Fl s
sets the style for the pane content.
.Fl S
sets the border style when the pane is active and
.Fl R
sets the border style when the pane is inactive (see
.Sx STYLES ) .
.Fl T
sets the pane title.
.Pp
.Fl h
does a horizontal split and
.Fl v
a vertical split; if neither is specified,
.Fl v
is assumed.
The
.Fl l
option specifies the size of the new pane in lines (for vertical split) or in
columns (for horizontal split);
.Ar size
may be followed by
.Ql %
to specify a percentage of the available space.
.Fl p
is a shorthand option for this.
The
.Fl b
option causes the new pane to be created to the left of or above
.Ar target\-pane .
The
.Fl f
option creates a new pane spanning the full window height (with
.Fl h )
or full window width (with
.Fl v ) ,
instead of splitting the active pane.
.Pp
.Fl k
keeps the pane open after the optional
.Ar shell\-command
exits and waits for a key to be pressed before closing it.
The message shown is controlled by the
.Ic remain\-on\-exit\-format
option.
.Fl m Ar message
is equivalent to
.Fl k
but also sets the
.Ic remain\-on\-exit\-format
option for this pane to
.Ar message .
.Pp
.Fl W
Waits until
.Ar shell\-command
exits, then returns its exit status.
For example:
.Bd -literal -offset indent
$ tmux new-pane -W 'vi afile'
$ echo $?
0
.Ed
.Pp
.Fl E ,
or an empty
.Ar shell\-command ,
(\[aq]\[aq]) will create an empty pane with no command running in it;
.Ic display-message
.Fl I
can write to an empty pane.
The
.Fl I
flag will create an empty pane and forward any output from stdin to it.
For example:
.Bd -literal -offset indent
$ make 2>&1|tmux new\-pane \-dI &
.Ed
.Pp .Pp
See
.Ic new\-pane
for more details.
.Tg swapp .Tg swapp
.It Xo Ic swap\-pane .It Xo Ic swap\-pane
.Op Fl dDUZ .Op Fl dDUZ

5
tmux.c
View File

@@ -290,7 +290,10 @@ clean_name(const char *name, const char* forbid)
return (NULL); return (NULL);
copy = xstrdup(name); copy = xstrdup(name);
for (cp = copy; *cp != '\0'; cp++) { for (cp = copy; *cp != '\0'; cp++) {
if (strchr(forbid, *cp) != NULL) if (*cp == '#' && strchr(forbid, '#') != NULL) {
if (cp[1] == '(')
*cp = '_';
} else if (strchr(forbid, *cp) != NULL)
*cp = '_'; *cp = '_';
} }
utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);

9
tmux.h
View File

@@ -3678,6 +3678,8 @@ void layout_fix_offsets(struct window *);
void layout_fix_panes(struct window *, struct window_pane *); void layout_fix_panes(struct window *, struct window_pane *);
void layout_resize_adjust(struct window *, struct layout_cell *, void layout_resize_adjust(struct window *, struct layout_cell *,
enum layout_type, int); enum layout_type, int);
void layout_resize_set_size(struct window *, struct layout_cell *,
enum layout_type, u_int);
struct layout_cell *layout_cell_get_neighbour(struct layout_cell *); struct layout_cell *layout_cell_get_neighbour(struct layout_cell *);
void layout_init(struct window *, struct window_pane *); void layout_init(struct window *, struct window_pane *);
void layout_free(struct window *); void layout_free(struct window *);
@@ -3692,6 +3694,12 @@ int layout_resize_floating_pane_to(struct window_pane *,
enum layout_type, u_int, char **); enum layout_type, u_int, char **);
void layout_assign_pane(struct layout_cell *, struct window_pane *, void layout_assign_pane(struct layout_cell *, struct window_pane *,
int); int);
int layout_split_check_space(struct window_pane *,
struct layout_cell *, enum layout_type);
void layout_split_sizes(struct layout_cell *, int, int,
enum layout_type, u_int *, u_int *, u_int *);
struct layout_cell *layout_replace_with_node(struct window *,
struct layout_cell *, enum layout_type);
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);
struct layout_cell *layout_floating_pane(struct window *, struct window_pane *, struct layout_cell *layout_floating_pane(struct window *, struct window_pane *,
@@ -3708,6 +3716,7 @@ int layout_floating_args_parse(struct cmdq_item *, struct args *,
enum pane_lines, struct window *, u_int *, u_int *, int *, enum pane_lines, struct window *, u_int *, u_int *, int *,
int *, char **); int *, char **);
int layout_remove_tile(struct window *, struct layout_cell *); int layout_remove_tile(struct window *, struct layout_cell *);
int layout_insert_tile(struct window *, struct layout_cell *);
/* layout-custom.c */ /* layout-custom.c */
char *layout_dump(struct window *, struct layout_cell *); char *layout_dump(struct window *, struct layout_cell *);

View File

@@ -5154,6 +5154,9 @@ window_copy_write_line(struct window_mode_entry *wme,
else else
content_sx = sx; content_sx = sx;
screen_write_cursormove(ctx, 0, py, 0);
screen_write_clearline(ctx, 8);
ft = format_create_defaults(NULL, NULL, NULL, NULL, wp); ft = format_create_defaults(NULL, NULL, NULL, NULL, wp);
style_apply(&gc, oo, "copy-mode-position-style", ft); style_apply(&gc, oo, "copy-mode-position-style", ft);

View File

@@ -1138,6 +1138,7 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs,
window_tree_get_key, window_tree_swap, window_tree_sort, window_tree_get_key, window_tree_swap, window_tree_sort,
window_tree_help, data, window_tree_menu_items, &s); window_tree_help, data, window_tree_menu_items, &s);
mode_tree_zoom(data->data, args); mode_tree_zoom(data->data, args);
mode_tree_view_name(data->data, "preview");
mode_tree_build(data->data); mode_tree_build(data->data);
mode_tree_draw(data->data); mode_tree_draw(data->data);

View File

@@ -631,6 +631,7 @@ window_redraw_active_switch(struct window *w, struct window_pane *wp)
TAILQ_REMOVE(&w->z_index, wp, zentry); TAILQ_REMOVE(&w->z_index, wp, zentry);
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry); TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
wp->flags |= PANE_REDRAW; wp->flags |= PANE_REDRAW;
redraw_invalidate_scene(w);
} }
wp = w->active; wp = w->active;