mirror of
https://github.com/tmux/tmux.git
synced 2026-05-23 13:20:14 +00:00
Merge branch 'obsd-master'
This commit is contained in:
@@ -73,7 +73,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
}
|
||||
server_unzoom_window(w);
|
||||
|
||||
if (window_count_panes(w) == 1) {
|
||||
if (window_count_panes(w, 1) == 1) {
|
||||
if (server_link_window(src_s, wl, dst_s, idx, 0,
|
||||
!args_has(args, 'd'), &cause) != 0) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
|
||||
@@ -170,7 +170,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
} else
|
||||
server_status_session(dst_s);
|
||||
|
||||
if (window_count_panes(src_w) == 0)
|
||||
if (window_count_panes(src_w, 1) == 0)
|
||||
server_kill_window(src_w, 1);
|
||||
else
|
||||
notify_window("window-layout-changed", src_w);
|
||||
|
||||
@@ -103,7 +103,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
* spawned without being visited (for example split-window -d).
|
||||
*/
|
||||
lastwp = TAILQ_FIRST(&w->last_panes);
|
||||
if (lastwp == NULL && window_count_panes(w) == 2) {
|
||||
if (lastwp == NULL && window_count_panes(w, 1) == 2) {
|
||||
lastwp = TAILQ_PREV(w->active, window_panes, entry);
|
||||
if (lastwp == NULL)
|
||||
lastwp = TAILQ_NEXT(w->active, entry);
|
||||
|
||||
@@ -27,22 +27,23 @@
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Split a window (add a new pane).
|
||||
* Create a new pane.
|
||||
*/
|
||||
|
||||
#define SPLIT_WINDOW_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
|
||||
|
||||
static enum cmd_retval cmd_split_window_exec(struct cmd *,
|
||||
struct cmdq_item *);
|
||||
static enum cmd_retval cmd_split_window_exec(struct cmd *, struct cmdq_item *);
|
||||
|
||||
const struct cmd_entry cmd_split_window_entry = {
|
||||
.name = "split-window",
|
||||
.alias = "splitw",
|
||||
const struct cmd_entry cmd_new_pane_entry = {
|
||||
.name = "new-pane",
|
||||
.alias = "newp",
|
||||
|
||||
.args = { "bc:de:fF:hIl:p:Pt:vZ", 0, -1, NULL },
|
||||
.usage = "[-bdefhIPvZ] [-c start-directory] [-e environment] "
|
||||
"[-F format] [-l size] " CMD_TARGET_PANE_USAGE
|
||||
" [shell-command [argument ...]]",
|
||||
.args = { "bc:de:fF:hIkl:m:p:PR:s:S:t:vZ", 0, -1, NULL },
|
||||
.usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] "
|
||||
"[-F format] [-l size] [-m message] [-p percentage] "
|
||||
"[-s style] [-S active-border-style] "
|
||||
"[-R inactive-border-style] " CMD_TARGET_PANE_USAGE " "
|
||||
"[shell-command [argument ...]]",
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
|
||||
@@ -50,6 +51,46 @@ const struct cmd_entry cmd_split_window_entry = {
|
||||
.exec = cmd_split_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_split_window_entry = {
|
||||
.name = "split-window",
|
||||
.alias = "splitw",
|
||||
|
||||
.args = { "bc:de:fF:hIkl:m:p:PR:s:S:t:vZ", 0, -1, NULL },
|
||||
.usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] "
|
||||
"[-F format] [-l size] [-m message] [-p percentage] "
|
||||
"[-s style] [-S active-border-style] "
|
||||
"[-R inactive-border-style] " CMD_TARGET_PANE_USAGE " "
|
||||
"[shell-command [argument ...]]",
|
||||
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_split_window_exec
|
||||
};
|
||||
|
||||
static struct layout_cell *
|
||||
cmd_split_window_get_tiled_layout_cell(struct cmdq_item *item,
|
||||
struct args *args, struct window *w, struct window_pane *wp, int flags)
|
||||
{
|
||||
enum layout_type type;
|
||||
struct layout_cell *lc = NULL;
|
||||
char *cause = NULL;
|
||||
int size;
|
||||
|
||||
if (window_pane_tile_geometry(w, wp, &size, &flags, &type, item, args,
|
||||
&cause) != 0) {
|
||||
cmdq_error(item, "invalid tiled geometry %s", cause);
|
||||
free(cause);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
|
||||
lc = layout_split_pane(wp, type, size, flags);
|
||||
if (lc == NULL)
|
||||
cmdq_error(item, "no space for new pane");
|
||||
return (lc);
|
||||
}
|
||||
|
||||
static enum cmd_retval
|
||||
cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
@@ -62,51 +103,14 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct winlink *wl = target->wl;
|
||||
struct window *w = wl->window;
|
||||
struct window_pane *wp = target->wp, *new_wp;
|
||||
enum layout_type type;
|
||||
struct layout_cell *lc;
|
||||
struct layout_cell *lc = NULL;
|
||||
struct cmd_find_state fs;
|
||||
int size, flags, input;
|
||||
const char *template;
|
||||
int flags, input;
|
||||
const char *template, *style;
|
||||
char *cause = NULL, *cp;
|
||||
struct args_value *av;
|
||||
u_int count = args_count(args), curval = 0;
|
||||
u_int count = args_count(args);
|
||||
|
||||
type = LAYOUT_TOPBOTTOM;
|
||||
if (args_has(args, 'h'))
|
||||
type = LAYOUT_LEFTRIGHT;
|
||||
|
||||
/* If the 'p' flag is dropped then this bit can be moved into 'l'. */
|
||||
if (args_has(args, 'l') || args_has(args, 'p')) {
|
||||
if (args_has(args, 'f')) {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = w->sy;
|
||||
else
|
||||
curval = w->sx;
|
||||
} else {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = wp->sy;
|
||||
else
|
||||
curval = wp->sx;
|
||||
}
|
||||
}
|
||||
|
||||
size = -1;
|
||||
if (args_has(args, 'l')) {
|
||||
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
||||
item, &cause);
|
||||
} else if (args_has(args, 'p')) {
|
||||
size = args_strtonum_and_expand(args, 'p', 0, 100, item,
|
||||
&cause);
|
||||
if (cause == NULL)
|
||||
size = curval * size / 100;
|
||||
}
|
||||
if (cause != NULL) {
|
||||
cmdq_error(item, "size %s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
|
||||
input = (args_has(args, 'I') && count == 0);
|
||||
|
||||
flags = 0;
|
||||
@@ -117,11 +121,9 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (input || (count == 1 && *args_string(args, 0) == '\0'))
|
||||
flags |= SPAWN_EMPTY;
|
||||
|
||||
lc = layout_split_pane(wp, type, size, flags);
|
||||
if (lc == NULL) {
|
||||
cmdq_error(item, "no space for new pane");
|
||||
lc = cmd_split_window_get_tiled_layout_cell(item, args, w, wp, flags);
|
||||
if (lc == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
sc.item = item;
|
||||
sc.s = s;
|
||||
@@ -156,6 +158,44 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
environ_free(sc.environ);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
style = args_get(args, 's');
|
||||
if (style != NULL) {
|
||||
if (options_set_string(new_wp->options, "window-style", 0,
|
||||
"%s", style) == NULL) {
|
||||
cmdq_error(item, "bad style: %s", style);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
options_set_string(new_wp->options, "window-active-style", 0,
|
||||
"%s", style);
|
||||
new_wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED
|
||||
|PANE_THEMECHANGED);
|
||||
}
|
||||
style = args_get(args, 'S');
|
||||
if (style != NULL) {
|
||||
if (options_set_string(new_wp->options,
|
||||
"pane-active-border-style", 0, "%s", style) == NULL) {
|
||||
cmdq_error(item, "bad active border style: %s", style);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
style = args_get(args, 'R');
|
||||
if (style != NULL) {
|
||||
if (options_set_string(new_wp->options, "pane-border-style", 0,
|
||||
"%s", style) == NULL) {
|
||||
cmdq_error(item, "bad inactive border style: %s",
|
||||
style);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
if (args_has(args, 'k') || args_has(args, 'm')) {
|
||||
options_set_number(new_wp->options, "remain-on-exit", 3);
|
||||
if (args_has(args, 'm'))
|
||||
options_set_string(new_wp->options,
|
||||
"remain-on-exit-format",
|
||||
0, "%s", args_get(args, 'm'));
|
||||
}
|
||||
|
||||
if (input) {
|
||||
switch (window_pane_start_input(new_wp, item, &cause)) {
|
||||
case -1:
|
||||
|
||||
2
cmd.c
2
cmd.c
@@ -71,6 +71,7 @@ extern const struct cmd_entry cmd_lock_server_entry;
|
||||
extern const struct cmd_entry cmd_lock_session_entry;
|
||||
extern const struct cmd_entry cmd_move_pane_entry;
|
||||
extern const struct cmd_entry cmd_move_window_entry;
|
||||
extern const struct cmd_entry cmd_new_pane_entry;
|
||||
extern const struct cmd_entry cmd_new_session_entry;
|
||||
extern const struct cmd_entry cmd_new_window_entry;
|
||||
extern const struct cmd_entry cmd_next_layout_entry;
|
||||
@@ -163,6 +164,7 @@ const struct cmd_entry *cmd_table[] = {
|
||||
&cmd_lock_session_entry,
|
||||
&cmd_move_pane_entry,
|
||||
&cmd_move_window_entry,
|
||||
&cmd_new_pane_entry,
|
||||
&cmd_new_session_entry,
|
||||
&cmd_new_window_entry,
|
||||
&cmd_next_layout_entry,
|
||||
|
||||
8
file.c
8
file.c
@@ -399,6 +399,10 @@ file_read(struct client *c, const char *path, client_file_cb cb, void *cbdata)
|
||||
}
|
||||
for (;;) {
|
||||
size = fread(buffer, 1, sizeof buffer, f);
|
||||
if (ferror(f)) {
|
||||
cf->error = errno;
|
||||
goto done;
|
||||
}
|
||||
if (evbuffer_add(cf->buffer, buffer, size) != 0) {
|
||||
cf->error = ENOMEM;
|
||||
goto done;
|
||||
@@ -671,7 +675,7 @@ file_write_close(struct client_files *files, struct imsg *imsg)
|
||||
|
||||
/* Client file read error callback. */
|
||||
static void
|
||||
file_read_error_callback(__unused struct bufferevent *bev, __unused short what,
|
||||
file_read_error_callback(__unused struct bufferevent *bev, short what,
|
||||
void *arg)
|
||||
{
|
||||
struct client_file *cf = arg;
|
||||
@@ -680,7 +684,7 @@ file_read_error_callback(__unused struct bufferevent *bev, __unused short what,
|
||||
log_debug("read error file %d", cf->stream);
|
||||
|
||||
msg.stream = cf->stream;
|
||||
msg.error = 0;
|
||||
msg.error = (what & EVBUFFER_ERROR) ? EIO : 0;
|
||||
proc_send(cf->peer, MSG_READ_DONE, -1, &msg, sizeof msg);
|
||||
|
||||
bufferevent_free(cf->event);
|
||||
|
||||
10
format.c
10
format.c
@@ -2060,7 +2060,7 @@ static void *
|
||||
format_cb_pane_bottom(struct format_tree *ft)
|
||||
{
|
||||
if (ft->wp != NULL)
|
||||
return (format_printf("%u", ft->wp->yoff + ft->wp->sy - 1));
|
||||
return (format_printf("%d", ft->wp->yoff + ft->wp->sy - 1));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -2219,7 +2219,7 @@ static void *
|
||||
format_cb_pane_left(struct format_tree *ft)
|
||||
{
|
||||
if (ft->wp != NULL)
|
||||
return (format_printf("%u", ft->wp->xoff));
|
||||
return (format_printf("%d", ft->wp->xoff));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -2343,7 +2343,7 @@ static void *
|
||||
format_cb_pane_right(struct format_tree *ft)
|
||||
{
|
||||
if (ft->wp != NULL)
|
||||
return (format_printf("%u", ft->wp->xoff + ft->wp->sx - 1));
|
||||
return (format_printf("%d", ft->wp->xoff + ft->wp->sx - 1));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -2385,7 +2385,7 @@ static void *
|
||||
format_cb_pane_top(struct format_tree *ft)
|
||||
{
|
||||
if (ft->wp != NULL)
|
||||
return (format_printf("%u", ft->wp->yoff));
|
||||
return (format_printf("%d", ft->wp->yoff));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -2936,7 +2936,7 @@ static void *
|
||||
format_cb_window_panes(struct format_tree *ft)
|
||||
{
|
||||
if (ft->w != NULL)
|
||||
return (format_printf("%u", window_count_panes(ft->w)));
|
||||
return (format_printf("%u", window_count_panes(ft->w, 1)));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,15 +45,20 @@ grid_reader_line_length(struct grid_reader *gr)
|
||||
|
||||
/* Move cursor forward one position. */
|
||||
void
|
||||
grid_reader_cursor_right(struct grid_reader *gr, int wrap, int all)
|
||||
grid_reader_cursor_right(struct grid_reader *gr, int wrap, int all, int onemore)
|
||||
{
|
||||
u_int px;
|
||||
struct grid_cell gc;
|
||||
|
||||
if (all)
|
||||
px = gr->gd->sx;
|
||||
else
|
||||
else if (onemore)
|
||||
px = grid_reader_line_length(gr);
|
||||
else {
|
||||
px = grid_reader_line_length(gr);
|
||||
if (px != 0)
|
||||
px--;
|
||||
}
|
||||
|
||||
if (wrap && gr->cx >= px && gr->cy < gr->gd->hsize + gr->gd->sy - 1) {
|
||||
grid_reader_cursor_start_of_line(gr, 0);
|
||||
|
||||
176
layout-custom.c
176
layout-custom.c
@@ -27,10 +27,11 @@ static struct layout_cell *layout_find_bottomright(struct layout_cell *);
|
||||
static u_short layout_checksum(const char *);
|
||||
static int layout_append(struct layout_cell *, char *,
|
||||
size_t);
|
||||
static struct layout_cell *layout_construct(struct layout_cell *,
|
||||
const char **);
|
||||
static int layout_construct(struct layout_cell *,
|
||||
const char **, struct layout_cell **,
|
||||
struct layout_cell **);
|
||||
static void layout_assign(struct window_pane **,
|
||||
struct layout_cell *);
|
||||
struct layout_cell *, int);
|
||||
|
||||
/* Find the bottom-right cell. */
|
||||
static struct layout_cell *
|
||||
@@ -58,14 +59,30 @@ layout_checksum(const char *layout)
|
||||
|
||||
/* Dump layout as a string. */
|
||||
char *
|
||||
layout_dump(__unused struct window *w, struct layout_cell *root)
|
||||
layout_dump(struct window *w, struct layout_cell *root)
|
||||
{
|
||||
char layout[8192], *out;
|
||||
char layout[8192], *out;
|
||||
int bracket = 0;
|
||||
struct window_pane *wp;
|
||||
|
||||
*layout = '\0';
|
||||
if (layout_append(root, layout, sizeof layout) != 0)
|
||||
return (NULL);
|
||||
|
||||
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||
if (~wp->flags & PANE_FLOATING)
|
||||
break;
|
||||
if (!bracket) {
|
||||
strlcat(layout, "<", sizeof layout);
|
||||
bracket = 1;
|
||||
}
|
||||
if (layout_append(wp->layout_cell, layout, sizeof layout) != 0)
|
||||
return (NULL);
|
||||
strlcat(layout, ",", sizeof layout);
|
||||
}
|
||||
if (bracket)
|
||||
layout[strlen(layout) - 1] = '>';
|
||||
|
||||
xasprintf(&out, "%04hx,%s", layout_checksum(layout), layout);
|
||||
return (out);
|
||||
}
|
||||
@@ -81,12 +98,13 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
|
||||
|
||||
if (len == 0)
|
||||
return (-1);
|
||||
|
||||
if (lc == NULL)
|
||||
return (0);
|
||||
if (lc->wp != NULL) {
|
||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%u,%u,%u",
|
||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d,%u",
|
||||
lc->sx, lc->sy, lc->xoff, lc->yoff, lc->wp->id);
|
||||
} else {
|
||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%u,%u",
|
||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d",
|
||||
lc->sx, lc->sy, lc->xoff, lc->yoff);
|
||||
}
|
||||
if (tmplen > (sizeof tmp) - 1)
|
||||
@@ -109,6 +127,7 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
|
||||
}
|
||||
buf[strlen(buf) - 1] = brackets[0];
|
||||
break;
|
||||
case LAYOUT_FLOATING:
|
||||
case LAYOUT_WINDOWPANE:
|
||||
break;
|
||||
}
|
||||
@@ -124,6 +143,7 @@ layout_check(struct layout_cell *lc)
|
||||
u_int n = 0;
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_FLOATING:
|
||||
case LAYOUT_WINDOWPANE:
|
||||
break;
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
@@ -156,7 +176,7 @@ layout_check(struct layout_cell *lc)
|
||||
int
|
||||
layout_parse(struct window *w, const char *layout, char **cause)
|
||||
{
|
||||
struct layout_cell *lc, *lcchild;
|
||||
struct layout_cell *lcchild, *tiled_lc = NULL, *floating_lc = NULL;
|
||||
struct window_pane *wp;
|
||||
u_int npanes, ncells, sx = 0, sy = 0;
|
||||
u_short csum;
|
||||
@@ -174,20 +194,27 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
}
|
||||
|
||||
/* Build the layout. */
|
||||
lc = layout_construct(NULL, &layout);
|
||||
if (lc == NULL) {
|
||||
if (layout_construct(NULL, &layout, &tiled_lc, &floating_lc) != 0) {
|
||||
*cause = xstrdup("invalid layout");
|
||||
return (-1);
|
||||
}
|
||||
if (tiled_lc == NULL) {
|
||||
/* A stub layout cell for an empty window. */
|
||||
tiled_lc = layout_create_cell(NULL);
|
||||
tiled_lc->type = LAYOUT_LEFTRIGHT;
|
||||
layout_set_size(tiled_lc, w->sx, w->sy, 0, 0);
|
||||
}
|
||||
if (*layout != '\0') {
|
||||
*cause = xstrdup("invalid layout");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Check this window will fit into the layout. */
|
||||
npanes = window_count_panes(w, 1);
|
||||
for (;;) {
|
||||
npanes = window_count_panes(w);
|
||||
ncells = layout_count_cells(lc);
|
||||
ncells = layout_count_cells(tiled_lc);
|
||||
if (floating_lc != NULL)
|
||||
ncells += layout_count_cells(floating_lc);
|
||||
if (npanes > ncells) {
|
||||
xasprintf(cause, "have %u panes but need %u", npanes,
|
||||
ncells);
|
||||
@@ -196,9 +223,17 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
if (npanes == ncells)
|
||||
break;
|
||||
|
||||
/* Fewer panes than cells - close the bottom right. */
|
||||
lcchild = layout_find_bottomright(lc);
|
||||
layout_destroy_cell(w, lcchild, &lc);
|
||||
/*
|
||||
* Fewer panes than cells - close floating panes first
|
||||
* then close the bottom right until none remain.
|
||||
*/
|
||||
if (floating_lc != NULL && !TAILQ_EMPTY(&floating_lc->cells)) {
|
||||
lcchild = TAILQ_FIRST(&floating_lc->cells);
|
||||
layout_destroy_cell(w, lcchild, &floating_lc);
|
||||
} else {
|
||||
lcchild = layout_find_bottomright(tiled_lc);
|
||||
layout_destroy_cell(w, lcchild, &tiled_lc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -206,91 +241,108 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
* an incorrect top cell size - if it is larger than the top child then
|
||||
* correct that (if this is still wrong the check code will catch it).
|
||||
*/
|
||||
switch (lc->type) {
|
||||
|
||||
switch (tiled_lc->type) {
|
||||
case LAYOUT_WINDOWPANE:
|
||||
break;
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
|
||||
sy = lcchild->sy + 1;
|
||||
sx += lcchild->sx + 1;
|
||||
}
|
||||
break;
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
|
||||
sx = lcchild->sx + 1;
|
||||
sy += lcchild->sy + 1;
|
||||
}
|
||||
break;
|
||||
case LAYOUT_FLOATING:
|
||||
*cause = xstrdup("invalid layout");
|
||||
goto fail;
|
||||
}
|
||||
if (lc->type != LAYOUT_WINDOWPANE && (lc->sx != sx || lc->sy != sy)) {
|
||||
log_debug("fix layout %u,%u to %u,%u", lc->sx, lc->sy, sx,sy);
|
||||
layout_print_cell(lc, __func__, 0);
|
||||
lc->sx = sx - 1; lc->sy = sy - 1;
|
||||
if (tiled_lc->type != LAYOUT_WINDOWPANE &&
|
||||
(tiled_lc->sx != sx || tiled_lc->sy != sy)) {
|
||||
layout_print_cell(tiled_lc, __func__, 0);
|
||||
tiled_lc->sx = sx - 1; tiled_lc->sy = sy - 1;
|
||||
}
|
||||
|
||||
/* Check the new layout. */
|
||||
if (!layout_check(lc)) {
|
||||
if (!layout_check(tiled_lc)) {
|
||||
*cause = xstrdup("size mismatch after applying layout");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Resize to the layout size. */
|
||||
window_resize(w, lc->sx, lc->sy, -1, -1);
|
||||
/* Resize window to the layout size. */
|
||||
if (sx != 0 && sy != 0)
|
||||
window_resize(w, tiled_lc->sx, tiled_lc->sy, -1, -1);
|
||||
|
||||
/* Destroy the old layout and swap to the new. */
|
||||
layout_free_cell(w->layout_root);
|
||||
w->layout_root = lc;
|
||||
w->layout_root = tiled_lc;
|
||||
|
||||
/* Assign the panes into the cells. */
|
||||
wp = TAILQ_FIRST(&w->panes);
|
||||
layout_assign(&wp, lc);
|
||||
if (tiled_lc != NULL)
|
||||
layout_assign(&wp, tiled_lc, 0);
|
||||
if (floating_lc != NULL)
|
||||
layout_assign(&wp, floating_lc, PANE_FLOATING);
|
||||
|
||||
/* Update pane offsets and sizes. */
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
recalculate_sizes();
|
||||
layout_print_cell(tiled_lc, __func__, 0);
|
||||
|
||||
layout_print_cell(lc, __func__, 0);
|
||||
/* Free the floating layout cell, no longer needed. */
|
||||
if (floating_lc != NULL)
|
||||
layout_free_cell(floating_lc);
|
||||
|
||||
notify_window("window-layout-changed", w);
|
||||
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
layout_free_cell(lc);
|
||||
layout_free_cell(tiled_lc);
|
||||
layout_free_cell(floating_lc);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Assign panes into cells. */
|
||||
static void
|
||||
layout_assign(struct window_pane **wp, struct layout_cell *lc)
|
||||
layout_assign(struct window_pane **wp, struct layout_cell *lc, int flags)
|
||||
{
|
||||
struct layout_cell *lcchild;
|
||||
|
||||
if (lc == NULL)
|
||||
return;
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_WINDOWPANE:
|
||||
layout_make_leaf(lc, *wp);
|
||||
(*wp)->flags |= flags;
|
||||
*wp = TAILQ_NEXT(*wp, entry);
|
||||
return;
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
case LAYOUT_FLOATING:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||
layout_assign(wp, lcchild);
|
||||
layout_assign(wp, lcchild, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Construct a cell from all or part of a layout tree. */
|
||||
static struct layout_cell *
|
||||
layout_construct(struct layout_cell *lcparent, const char **layout)
|
||||
layout_construct_cell(struct layout_cell *lcparent, const char **layout)
|
||||
{
|
||||
struct layout_cell *lc, *lcchild;
|
||||
u_int sx, sy, xoff, yoff;
|
||||
struct layout_cell *lc;
|
||||
u_int sx, sy;
|
||||
int xoff, yoff;
|
||||
const char *saved;
|
||||
|
||||
if (!isdigit((u_char) **layout))
|
||||
return (NULL);
|
||||
if (sscanf(*layout, "%ux%u,%u,%u", &sx, &sy, &xoff, &yoff) != 4)
|
||||
if (sscanf(*layout, "%ux%u,%d,%d", &sx, &sy, &xoff, &yoff) != 4)
|
||||
return (NULL);
|
||||
|
||||
while (isdigit((u_char) **layout))
|
||||
@@ -325,17 +377,41 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
||||
lc->xoff = xoff;
|
||||
lc->yoff = yoff;
|
||||
|
||||
return (lc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a character string layout, recursively construct cells.
|
||||
* Possible return values:
|
||||
* lc LAYOUT_WINDOWPANE, no children
|
||||
* lc LAYOUT_LEFTRIGHT or LAYOUT_TOPBOTTOM, with children
|
||||
* floating_lc LAYOUT_FLOATING, with children
|
||||
*/
|
||||
static int
|
||||
layout_construct(struct layout_cell *lcparent, const char **layout,
|
||||
struct layout_cell **lc, struct layout_cell **floating_lc)
|
||||
{
|
||||
struct layout_cell *lcchild, *saved_lc;
|
||||
|
||||
*lc = layout_construct_cell(lcparent, layout);
|
||||
|
||||
switch (**layout) {
|
||||
case ',':
|
||||
case '}':
|
||||
case ']':
|
||||
case '>':
|
||||
case '\0':
|
||||
return (lc);
|
||||
return (0);
|
||||
case '{':
|
||||
lc->type = LAYOUT_LEFTRIGHT;
|
||||
(*lc)->type = LAYOUT_LEFTRIGHT;
|
||||
break;
|
||||
case '[':
|
||||
lc->type = LAYOUT_TOPBOTTOM;
|
||||
(*lc)->type = LAYOUT_TOPBOTTOM;
|
||||
break;
|
||||
case '<':
|
||||
saved_lc = *lc;
|
||||
*lc = layout_create_cell(lcparent);
|
||||
(*lc)->type = LAYOUT_FLOATING;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
@@ -343,13 +419,12 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
||||
|
||||
do {
|
||||
(*layout)++;
|
||||
lcchild = layout_construct(lc, layout);
|
||||
if (lcchild == NULL)
|
||||
if (layout_construct(*lc, layout, &lcchild, floating_lc) != 0)
|
||||
goto fail;
|
||||
TAILQ_INSERT_TAIL(&lc->cells, lcchild, entry);
|
||||
TAILQ_INSERT_TAIL(&(*lc)->cells, lcchild, entry);
|
||||
} while (**layout == ',');
|
||||
|
||||
switch (lc->type) {
|
||||
switch ((*lc)->type) {
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
if (**layout != '}')
|
||||
goto fail;
|
||||
@@ -358,14 +433,21 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
||||
if (**layout != ']')
|
||||
goto fail;
|
||||
break;
|
||||
case LAYOUT_FLOATING:
|
||||
if (**layout != '>')
|
||||
goto fail;
|
||||
*floating_lc = *lc;
|
||||
*lc = saved_lc;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
(*layout)++;
|
||||
|
||||
return (lc);
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
layout_free_cell(lc);
|
||||
return (NULL);
|
||||
layout_free_cell(*lc);
|
||||
layout_free_cell(*floating_lc);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
12
layout-set.c
12
layout-set.c
@@ -133,7 +133,7 @@ layout_set_even(struct window *w, enum layout_type type)
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
n = window_count_panes(w, 0);
|
||||
if (n <= 1)
|
||||
return;
|
||||
|
||||
@@ -201,7 +201,7 @@ layout_set_main_h(struct window *w)
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
n = window_count_panes(w, 0);
|
||||
if (n <= 1)
|
||||
return;
|
||||
n--; /* take off main pane */
|
||||
@@ -299,7 +299,7 @@ layout_set_main_h_mirrored(struct window *w)
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
n = window_count_panes(w, 0);
|
||||
if (n <= 1)
|
||||
return;
|
||||
n--; /* take off main pane */
|
||||
@@ -397,7 +397,7 @@ layout_set_main_v(struct window *w)
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
n = window_count_panes(w, 0);
|
||||
if (n <= 1)
|
||||
return;
|
||||
n--; /* take off main pane */
|
||||
@@ -495,7 +495,7 @@ layout_set_main_v_mirrored(struct window *w)
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
n = window_count_panes(w, 0);
|
||||
if (n <= 1)
|
||||
return;
|
||||
n--; /* take off main pane */
|
||||
@@ -593,7 +593,7 @@ layout_set_tiled(struct window *w)
|
||||
layout_print_cell(w->layout_root, __func__, 1);
|
||||
|
||||
/* Get number of panes. */
|
||||
n = window_count_panes(w);
|
||||
n = window_count_panes(w, 0);
|
||||
if (n <= 1)
|
||||
return;
|
||||
|
||||
|
||||
95
layout.c
95
layout.c
@@ -46,7 +46,10 @@ static int layout_set_size_check(struct window *, struct layout_cell *,
|
||||
enum layout_type, int);
|
||||
static void layout_resize_child_cells(struct window *,
|
||||
struct layout_cell *);
|
||||
void layout_redistribute_cells(struct window *, struct layout_cell *,
|
||||
enum layout_type);
|
||||
|
||||
/* Create a new layout cell. */
|
||||
struct layout_cell *
|
||||
layout_create_cell(struct layout_cell *lcparent)
|
||||
{
|
||||
@@ -61,14 +64,15 @@ layout_create_cell(struct layout_cell *lcparent)
|
||||
lc->sx = UINT_MAX;
|
||||
lc->sy = UINT_MAX;
|
||||
|
||||
lc->xoff = UINT_MAX;
|
||||
lc->yoff = UINT_MAX;
|
||||
lc->xoff = INT_MAX;
|
||||
lc->yoff = INT_MAX;
|
||||
|
||||
lc->wp = NULL;
|
||||
|
||||
return (lc);
|
||||
}
|
||||
|
||||
/* Free a layout cell. */
|
||||
void
|
||||
layout_free_cell(struct layout_cell *lc)
|
||||
{
|
||||
@@ -83,21 +87,40 @@ layout_free_cell(struct layout_cell *lc)
|
||||
layout_free_cell(lcchild);
|
||||
}
|
||||
break;
|
||||
case LAYOUT_FLOATING:
|
||||
/*
|
||||
* A floating layout cell is only used temporarily while
|
||||
* select-layout constructs a layout. Remove the children from
|
||||
* the temporary layout, then free temporary floating layout
|
||||
* cell. Each floating pane has stub layout.
|
||||
*/
|
||||
while (!TAILQ_EMPTY(&lc->cells)) {
|
||||
lcchild = TAILQ_FIRST(&lc->cells);
|
||||
TAILQ_REMOVE(&lc->cells, lcchild, entry);
|
||||
lcchild->parent = NULL;
|
||||
}
|
||||
break;
|
||||
case LAYOUT_WINDOWPANE:
|
||||
if (lc->wp != NULL)
|
||||
if (lc->wp != NULL) {
|
||||
lc->wp->layout_cell->parent = NULL;
|
||||
lc->wp->layout_cell = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
free(lc);
|
||||
}
|
||||
|
||||
/* Log a cell. */
|
||||
void
|
||||
layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
||||
{
|
||||
struct layout_cell *lcchild;
|
||||
const char *type;
|
||||
|
||||
if (lc == NULL)
|
||||
return;
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
type = "LEFTRIGHT";
|
||||
@@ -105,6 +128,9 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
type = "TOPBOTTOM";
|
||||
break;
|
||||
case LAYOUT_FLOATING:
|
||||
type = "FLOATING";
|
||||
break;
|
||||
case LAYOUT_WINDOWPANE:
|
||||
type = "WINDOWPANE";
|
||||
break;
|
||||
@@ -112,12 +138,13 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
||||
type = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
log_debug("%s:%*s%p type %s [parent %p] wp=%p [%u,%u %ux%u]", hdr, n,
|
||||
log_debug("%s:%*s%p type %s [parent %p] wp=%p [%d,%d %ux%u]", hdr, n,
|
||||
" ", lc, type, lc->parent, lc->wp, lc->xoff, lc->yoff, lc->sx,
|
||||
lc->sy);
|
||||
switch (lc->type) {
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
case LAYOUT_FLOATING:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||
layout_print_cell(lcchild, hdr, n + 1);
|
||||
break;
|
||||
@@ -126,14 +153,17 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for a cell by the border position. */
|
||||
struct layout_cell *
|
||||
layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
||||
{
|
||||
struct layout_cell *lcchild, *last = NULL;
|
||||
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
if (x >= lcchild->xoff && x < lcchild->xoff + lcchild->sx &&
|
||||
y >= lcchild->yoff && y < lcchild->yoff + lcchild->sy) {
|
||||
if ((int)x >= lcchild->xoff &&
|
||||
(int)x < lcchild->xoff + (int)lcchild->sx &&
|
||||
(int)y >= lcchild->yoff &&
|
||||
(int)y < lcchild->yoff + (int)lcchild->sy) {
|
||||
/* Inside the cell - recurse. */
|
||||
return (layout_search_by_border(lcchild, x, y));
|
||||
}
|
||||
@@ -145,14 +175,17 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
if (x < lcchild->xoff && x >= last->xoff + last->sx)
|
||||
if ((int)x < lcchild->xoff &&
|
||||
(int)x >= last->xoff + (int)last->sx)
|
||||
return (last);
|
||||
break;
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
if (y < lcchild->yoff && y >= last->yoff + last->sy)
|
||||
if ((int)y < lcchild->yoff &&
|
||||
(int)y >= last->yoff + (int)last->sy)
|
||||
return (last);
|
||||
break;
|
||||
case LAYOUT_WINDOWPANE:
|
||||
case LAYOUT_FLOATING:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -162,9 +195,9 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Set cell size. */
|
||||
void
|
||||
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, u_int xoff,
|
||||
u_int yoff)
|
||||
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, int xoff, int yoff)
|
||||
{
|
||||
lc->sx = sx;
|
||||
lc->sy = sy;
|
||||
@@ -173,6 +206,7 @@ layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, u_int xoff,
|
||||
lc->yoff = yoff;
|
||||
}
|
||||
|
||||
/* Make a cell a leaf cell. */
|
||||
void
|
||||
layout_make_leaf(struct layout_cell *lc, struct window_pane *wp)
|
||||
{
|
||||
@@ -184,6 +218,7 @@ layout_make_leaf(struct layout_cell *lc, struct window_pane *wp)
|
||||
lc->wp = wp;
|
||||
}
|
||||
|
||||
/* Make a cell a node cell. */
|
||||
void
|
||||
layout_make_node(struct layout_cell *lc, enum layout_type type)
|
||||
{
|
||||
@@ -203,7 +238,7 @@ static void
|
||||
layout_fix_offsets1(struct layout_cell *lc)
|
||||
{
|
||||
struct layout_cell *lcchild;
|
||||
u_int xoff, yoff;
|
||||
int xoff, yoff;
|
||||
|
||||
if (lc->type == LAYOUT_LEFTRIGHT) {
|
||||
xoff = lc->xoff;
|
||||
@@ -246,6 +281,8 @@ layout_cell_is_top(struct window *w, struct layout_cell *lc)
|
||||
|
||||
while (lc != w->layout_root) {
|
||||
next = lc->parent;
|
||||
if (next == NULL)
|
||||
return (0);
|
||||
if (next->type == LAYOUT_TOPBOTTOM &&
|
||||
lc != TAILQ_FIRST(&next->cells))
|
||||
return (0);
|
||||
@@ -262,6 +299,8 @@ layout_cell_is_bottom(struct window *w, struct layout_cell *lc)
|
||||
|
||||
while (lc != w->layout_root) {
|
||||
next = lc->parent;
|
||||
if (next == NULL)
|
||||
return (0);
|
||||
if (next->type == LAYOUT_TOPBOTTOM &&
|
||||
lc != TAILQ_LAST(&next->cells, layout_cells))
|
||||
return (0);
|
||||
@@ -307,7 +346,8 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
|
||||
sx = lc->sx;
|
||||
sy = lc->sy;
|
||||
|
||||
if (layout_add_horizontal_border(w, lc, status)) {
|
||||
if ((~wp->flags & PANE_FLOATING) &&
|
||||
layout_add_horizontal_border(w, lc, status)) {
|
||||
if (status == PANE_STATUS_TOP)
|
||||
wp->yoff++;
|
||||
sy--;
|
||||
@@ -346,14 +386,14 @@ u_int
|
||||
layout_count_cells(struct layout_cell *lc)
|
||||
{
|
||||
struct layout_cell *lcchild;
|
||||
u_int count;
|
||||
u_int count = 0;
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_WINDOWPANE:
|
||||
return (1);
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
count = 0;
|
||||
case LAYOUT_FLOATING:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||
count += layout_count_cells(lcchild);
|
||||
return (count);
|
||||
@@ -470,13 +510,22 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||
struct layout_cell *lcother, *lcparent;
|
||||
|
||||
/*
|
||||
* If no parent, this is the last pane so window close is imminent and
|
||||
* there is no need to resize anything.
|
||||
* If no parent, this is either a floating pane or the last
|
||||
* pane so window close is imminent and there is no need to
|
||||
* resize anything.
|
||||
*/
|
||||
lcparent = lc->parent;
|
||||
if (lcparent == NULL) {
|
||||
if (lc->wp != NULL && ~lc->wp->flags & PANE_FLOATING)
|
||||
*lcroot = NULL;
|
||||
layout_free_cell(lc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* A floating cell need only be removed from the parent. */
|
||||
if (lcparent->type == LAYOUT_FLOATING) {
|
||||
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||
layout_free_cell(lc);
|
||||
*lcroot = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -499,12 +548,13 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||
* replace it by that cell.
|
||||
*/
|
||||
lc = TAILQ_FIRST(&lcparent->cells);
|
||||
if (TAILQ_NEXT(lc, entry) == NULL) {
|
||||
if (lc != NULL && TAILQ_NEXT(lc, entry) == NULL) {
|
||||
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||
|
||||
lc->parent = lcparent->parent;
|
||||
if (lc->parent == NULL) {
|
||||
lc->xoff = 0; lc->yoff = 0;
|
||||
lc->xoff = 0;
|
||||
lc->yoff = 0;
|
||||
*lcroot = lc;
|
||||
} else
|
||||
TAILQ_REPLACE(&lc->parent->cells, lcparent, lc, entry);
|
||||
@@ -513,6 +563,7 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize layout for pane. */
|
||||
void
|
||||
layout_init(struct window *w, struct window_pane *wp)
|
||||
{
|
||||
@@ -524,6 +575,7 @@ layout_init(struct window *w, struct window_pane *wp)
|
||||
layout_fix_panes(w, NULL);
|
||||
}
|
||||
|
||||
/* Free layout for pane. */
|
||||
void
|
||||
layout_free(struct window *w)
|
||||
{
|
||||
@@ -741,7 +793,7 @@ layout_resize_pane_shrink(struct window *w, struct layout_cell *lc,
|
||||
return (size);
|
||||
}
|
||||
|
||||
/* Assign window pane to newly split cell. */
|
||||
/* Assign window pane to new cell. */
|
||||
void
|
||||
layout_assign_pane(struct layout_cell *lc, struct window_pane *wp,
|
||||
int do_not_resize)
|
||||
@@ -1085,6 +1137,9 @@ layout_close_pane(struct window_pane *wp)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
|
||||
if (wp->layout_cell == NULL)
|
||||
return;
|
||||
|
||||
/* Remove the cell. */
|
||||
layout_destroy_cell(w, wp->layout_cell, &w->layout_root);
|
||||
|
||||
|
||||
@@ -1033,6 +1033,7 @@ server_client_is_bracket_paste(struct client *c, key_code key)
|
||||
{
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_PASTE_START) {
|
||||
c->flags |= CLIENT_BRACKETPASTING;
|
||||
c->paste_time = current_time;
|
||||
log_debug("%s: bracket paste on", c->name);
|
||||
return (0);
|
||||
}
|
||||
@@ -1066,6 +1067,7 @@ server_client_is_assume_paste(struct client *c)
|
||||
if (c->flags & CLIENT_ASSUMEPASTING)
|
||||
return (1);
|
||||
c->flags |= CLIENT_ASSUMEPASTING;
|
||||
c->paste_time = current_time;
|
||||
log_debug("%s: assume paste on", c->name);
|
||||
return (0);
|
||||
}
|
||||
@@ -2133,7 +2135,7 @@ server_client_set_progress_bar(struct client *c)
|
||||
struct session *s = c->session;
|
||||
struct progress_bar *pane_pb;
|
||||
|
||||
if (s->curw == NULL)
|
||||
if (s->curw == NULL || s->curw->window->active == NULL)
|
||||
return;
|
||||
pane_pb = &s->curw->window->active->base.progress_bar;
|
||||
if (pane_pb->state == c->progress_bar.state &&
|
||||
@@ -2505,6 +2507,13 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
||||
c->out_fd = -1;
|
||||
}
|
||||
|
||||
/* If pasting has taken too long, turn it off. */
|
||||
if (c->flags & (CLIENT_BRACKETPASTING|CLIENT_ASSUMEPASTING) &&
|
||||
current_time - c->paste_time > CLIENT_PASTE_TIME_LIMIT) {
|
||||
log_debug("%s: paste time limit exceeded", c->name);
|
||||
c->flags &= ~(CLIENT_BRACKETPASTING|CLIENT_ASSUMEPASTING);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is the first client, load configuration files. Any later
|
||||
* clients are allowed to continue with their command even if the
|
||||
|
||||
@@ -184,7 +184,7 @@ server_kill_pane(struct window_pane *wp)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
|
||||
if (window_count_panes(w) == 1) {
|
||||
if (window_count_panes(w, 1) == 1) {
|
||||
server_kill_window(w, 1);
|
||||
recalculate_sizes();
|
||||
} else {
|
||||
|
||||
20
sort.c
20
sort.c
@@ -56,8 +56,8 @@ sort_buffer_cmp(const void *a0, const void *b0)
|
||||
struct sort_criteria *sort_crit = sort_criteria;
|
||||
const struct paste_buffer *const *a = a0;
|
||||
const struct paste_buffer *const *b = b0;
|
||||
const struct paste_buffer *pa = *a;
|
||||
const struct paste_buffer *pb = *b;
|
||||
const struct paste_buffer *pa = *a;
|
||||
const struct paste_buffer *pb = *b;
|
||||
int result = 0;
|
||||
|
||||
switch (sort_crit->order) {
|
||||
@@ -92,8 +92,8 @@ sort_client_cmp(const void *a0, const void *b0)
|
||||
struct sort_criteria *sort_crit = sort_criteria;
|
||||
const struct client *const *a = a0;
|
||||
const struct client *const *b = b0;
|
||||
const struct client *ca = *a;
|
||||
const struct client *cb = *b;
|
||||
const struct client *ca = *a;
|
||||
const struct client *cb = *b;
|
||||
int result = 0;
|
||||
|
||||
switch (sort_crit->order) {
|
||||
@@ -425,7 +425,11 @@ sort_get_clients(u_int *n, struct sort_criteria *sort_crit)
|
||||
|
||||
i = 0;
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
if (lsz <= i) {
|
||||
if (c->flags & CLIENT_UNATTACHEDFLAGS)
|
||||
continue;
|
||||
if (~c->flags & CLIENT_ATTACHED)
|
||||
continue;
|
||||
if (lsz <= i) {
|
||||
lsz += 100;
|
||||
l = xreallocarray(l, lsz, sizeof *l);
|
||||
}
|
||||
@@ -468,7 +472,7 @@ sort_get_panes(u_int *n, struct sort_criteria *sort_crit)
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
u_int i;
|
||||
u_int i;
|
||||
static struct window_pane **l = NULL;
|
||||
static u_int lsz = 0;
|
||||
|
||||
@@ -499,7 +503,7 @@ sort_get_panes_session(struct session *s, u_int *n,
|
||||
struct winlink *wl = NULL;
|
||||
struct window *w = NULL;
|
||||
struct window_pane *wp = NULL;
|
||||
u_int i;
|
||||
u_int i;
|
||||
static struct window_pane **l = NULL;
|
||||
static u_int lsz = 0;
|
||||
|
||||
@@ -526,7 +530,7 @@ sort_get_panes_window(struct window *w, u_int *n,
|
||||
struct sort_criteria *sort_crit)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
u_int i;
|
||||
u_int i;
|
||||
static struct window_pane **l = NULL;
|
||||
static u_int lsz = 0;
|
||||
|
||||
|
||||
184
tmux.1
184
tmux.1
@@ -936,6 +936,37 @@ or
|
||||
.Ic list\-panes
|
||||
commands.
|
||||
.Pp
|
||||
.Em target\-session ,
|
||||
.Em target\-window
|
||||
or
|
||||
.Em target\-pane
|
||||
each denote the
|
||||
.Ql type
|
||||
of target the command needs to work on.
|
||||
If a target is not explicitly qualified using
|
||||
.Ql \&:
|
||||
and
|
||||
.Ql \&. ,
|
||||
.Nm
|
||||
will pick what seems to be the best choice available.
|
||||
For example, if a
|
||||
.Em target-pane
|
||||
of
|
||||
.Ql 1
|
||||
is used with a current window that has only one pane,
|
||||
.Nm
|
||||
knows that the
|
||||
.Ql 1
|
||||
cannot mean a pane, so it will look for the active pane in window 1, or the
|
||||
active pane in the current window in session 1.
|
||||
Only if none of these are present will it report an error.
|
||||
If it is important that a specific pane, window or session always be used,
|
||||
such as from a script, the target should be fully qualified (for example a
|
||||
.Em target-pane
|
||||
of
|
||||
.Ql -t:.1 ) ,
|
||||
or pane, window or session IDs should be used.
|
||||
.Pp
|
||||
.Ar shell\-command
|
||||
arguments are
|
||||
.Xr sh 1
|
||||
@@ -3270,6 +3301,98 @@ By default, it uses the format
|
||||
.Ql #{session_name}:#{window_index}
|
||||
but a different format may be specified with
|
||||
.Fl F .
|
||||
.Tg newp
|
||||
.It Xo Ic new\-pane
|
||||
.Op Fl bdefhIkPvZ
|
||||
.Op Fl c Ar start\-directory
|
||||
.Op Fl e Ar environment
|
||||
.Op Fl F Ar format
|
||||
.Op Fl l Ar size
|
||||
.Op Fl m Ar message
|
||||
.Op Fl p Ar percentage
|
||||
.Op Fl R Ar inactive\-border\-style
|
||||
.Op Fl s Ar style
|
||||
.Op Fl S Ar active\-border\-style
|
||||
.Op Fl t Ar target\-pane
|
||||
.Op Ar shell\-command Op Ar argument ...
|
||||
.Xc
|
||||
.D1 Pq alias: Ic newp
|
||||
Create a new pane.
|
||||
The new pane is created by splitting
|
||||
.Ar target\-pane .
|
||||
If
|
||||
.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 ) .
|
||||
.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
|
||||
An empty
|
||||
.Ar shell\-command
|
||||
(\[aq]\[aq]) will create a pane with no command running in it.
|
||||
The
|
||||
.Fl I
|
||||
flag (if
|
||||
.Ar shell\-command
|
||||
is not specified or empty)
|
||||
will create an empty pane and forward any output from stdin to it.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
$ make 2>&1|tmux splitw \-dI &
|
||||
.Ed
|
||||
.Pp
|
||||
All other options have the same meaning as for the
|
||||
.Ic new\-window
|
||||
command.
|
||||
.Tg nextl
|
||||
.It Ic next\-layout Op Fl t Ar target\-window
|
||||
.D1 Pq alias: Ic nextl
|
||||
@@ -3594,65 +3717,28 @@ the command behaves like
|
||||
.Ic last\-window .
|
||||
.Tg splitw
|
||||
.It Xo Ic split\-window
|
||||
.Op Fl bdfhIvPZ
|
||||
.Op Fl bdefhIkPvZ
|
||||
.Op Fl c Ar start\-directory
|
||||
.Op Fl e Ar environment
|
||||
.Op Fl F Ar format
|
||||
.Op Fl l Ar size
|
||||
.Op Fl m Ar message
|
||||
.Op Fl p Ar percentage
|
||||
.Op Fl R Ar inactive\-border\-style
|
||||
.Op Fl s Ar style
|
||||
.Op Fl S Ar active\-border\-style
|
||||
.Op Fl t Ar target\-pane
|
||||
.Op Ar shell\-command Op Ar argument ...
|
||||
.Xc
|
||||
.D1 Pq alias: Ic splitw
|
||||
Create a new pane by splitting
|
||||
.Ar target\-pane :
|
||||
.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.
|
||||
The
|
||||
.Fl b
|
||||
option causes the new pane to be created to the left of or above
|
||||
Creates a new pane by splitting
|
||||
.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.
|
||||
.Fl Z
|
||||
zooms if the window is not zoomed, or keeps it zoomed if already zoomed.
|
||||
Shares behavior with
|
||||
.Ic new\-pane .
|
||||
.Pp
|
||||
An empty
|
||||
.Ar shell\-command
|
||||
(\[aq]\[aq]) will create a pane with no command running in it.
|
||||
Output can be sent to such a pane with the
|
||||
.Ic display\-message
|
||||
command.
|
||||
The
|
||||
.Fl I
|
||||
flag (if
|
||||
.Ar shell\-command
|
||||
is not specified or empty)
|
||||
will create an empty pane and forward any output from stdin to it.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
$ make 2>&1|tmux splitw \-dI &
|
||||
.Ed
|
||||
.Pp
|
||||
All other options have the same meaning as for the
|
||||
.Ic new\-window
|
||||
command.
|
||||
See
|
||||
.Ic new\-pane
|
||||
for more details.
|
||||
.Tg swapp
|
||||
.It Xo Ic swap\-pane
|
||||
.Op Fl dDUZ
|
||||
|
||||
31
tmux.h
31
tmux.h
@@ -1336,9 +1336,11 @@ struct window_pane {
|
||||
|
||||
TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */
|
||||
TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */
|
||||
TAILQ_ENTRY(window_pane) zentry; /* z-index link in list of all panes */
|
||||
RB_ENTRY(window_pane) tree_entry;
|
||||
};
|
||||
TAILQ_HEAD(window_panes, window_pane);
|
||||
TAILQ_HEAD(window_panes_zindex, window_pane);
|
||||
RB_HEAD(window_pane_tree, window_pane);
|
||||
|
||||
/* Window structure. */
|
||||
@@ -1358,6 +1360,7 @@ struct window {
|
||||
|
||||
struct window_pane *active;
|
||||
struct window_panes last_panes;
|
||||
struct window_panes z_index;
|
||||
struct window_panes panes;
|
||||
|
||||
int lastlayout;
|
||||
@@ -1451,6 +1454,7 @@ TAILQ_HEAD(winlink_stack, winlink);
|
||||
enum layout_type {
|
||||
LAYOUT_LEFTRIGHT,
|
||||
LAYOUT_TOPBOTTOM,
|
||||
LAYOUT_FLOATING,
|
||||
LAYOUT_WINDOWPANE
|
||||
};
|
||||
|
||||
@@ -1466,8 +1470,8 @@ struct layout_cell {
|
||||
u_int sx;
|
||||
u_int sy;
|
||||
|
||||
u_int xoff;
|
||||
u_int yoff;
|
||||
int xoff;
|
||||
int yoff;
|
||||
|
||||
struct window_pane *wp;
|
||||
struct layout_cells cells;
|
||||
@@ -1747,10 +1751,10 @@ struct tty_ctx {
|
||||
u_int orlower;
|
||||
|
||||
/* Target region (usually pane) offset and size. */
|
||||
u_int xoff;
|
||||
u_int yoff;
|
||||
u_int rxoff;
|
||||
u_int ryoff;
|
||||
int xoff;
|
||||
int yoff;
|
||||
int rxoff;
|
||||
int ryoff;
|
||||
u_int sx;
|
||||
u_int sy;
|
||||
|
||||
@@ -1982,6 +1986,9 @@ struct client_window {
|
||||
};
|
||||
RB_HEAD(client_windows, client_window);
|
||||
|
||||
/* Maximum time to be pasting. */
|
||||
#define CLIENT_PASTE_TIME_LIMIT 5
|
||||
|
||||
/* Client connection. */
|
||||
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
|
||||
typedef void (*prompt_free_cb)(void *);
|
||||
@@ -2121,6 +2128,7 @@ struct client {
|
||||
|
||||
struct key_table *keytable;
|
||||
key_code last_key;
|
||||
time_t paste_time;
|
||||
|
||||
uint64_t redraw_panes;
|
||||
uint64_t redraw_scrollbars;
|
||||
@@ -2317,6 +2325,7 @@ struct spawn_context {
|
||||
#define SPAWN_FULLSIZE 0x20
|
||||
#define SPAWN_EMPTY 0x40
|
||||
#define SPAWN_ZOOM 0x80
|
||||
#define SPAWN_FLOATING 0x100
|
||||
};
|
||||
|
||||
/* Paste buffer. */
|
||||
@@ -3206,7 +3215,7 @@ void grid_reader_start(struct grid_reader *, struct grid *, u_int, u_int);
|
||||
void grid_reader_get_cursor(struct grid_reader *, u_int *, u_int *);
|
||||
u_int grid_reader_line_length(struct grid_reader *);
|
||||
int grid_reader_in_set(struct grid_reader *, const char *);
|
||||
void grid_reader_cursor_right(struct grid_reader *, int, int);
|
||||
void grid_reader_cursor_right(struct grid_reader *, int, int, int);
|
||||
void grid_reader_cursor_left(struct grid_reader *, int);
|
||||
void grid_reader_cursor_down(struct grid_reader *);
|
||||
void grid_reader_cursor_up(struct grid_reader *);
|
||||
@@ -3409,7 +3418,7 @@ struct window_pane *window_pane_next_by_number(struct window *,
|
||||
struct window_pane *window_pane_previous_by_number(struct window *,
|
||||
struct window_pane *, u_int);
|
||||
int window_pane_index(struct window_pane *, u_int *);
|
||||
u_int window_count_panes(struct window *);
|
||||
u_int window_count_panes(struct window *, int);
|
||||
void window_destroy_panes(struct window *);
|
||||
struct window_pane *window_pane_find_by_id_str(const char *);
|
||||
struct window_pane *window_pane_find_by_id(u_int);
|
||||
@@ -3463,6 +3472,9 @@ enum client_theme window_pane_get_theme(struct window_pane *);
|
||||
void window_pane_send_theme_update(struct window_pane *);
|
||||
struct style_range *window_pane_border_status_get_range(struct window_pane *,
|
||||
u_int, u_int);
|
||||
int window_pane_tile_geometry(struct window *,
|
||||
struct window_pane *, int *, int *, enum layout_type *,
|
||||
struct cmdq_item *, struct args *, char **);
|
||||
|
||||
/* layout.c */
|
||||
u_int layout_count_cells(struct layout_cell *);
|
||||
@@ -3474,8 +3486,7 @@ void layout_destroy_cell(struct window *, struct layout_cell *,
|
||||
void layout_resize_layout(struct window *, struct layout_cell *,
|
||||
enum layout_type, int, int);
|
||||
struct layout_cell *layout_search_by_border(struct layout_cell *, u_int, u_int);
|
||||
void layout_set_size(struct layout_cell *, u_int, u_int, u_int,
|
||||
u_int);
|
||||
void layout_set_size(struct layout_cell *, u_int, u_int, int, int);
|
||||
void layout_make_leaf(struct layout_cell *, struct window_pane *);
|
||||
void layout_make_node(struct layout_cell *, enum layout_type);
|
||||
void layout_fix_offsets(struct window *);
|
||||
|
||||
57
tty-draw.c
57
tty-draw.c
@@ -29,7 +29,6 @@ enum tty_draw_line_state {
|
||||
TTY_DRAW_LINE_NEW2,
|
||||
TTY_DRAW_LINE_EMPTY,
|
||||
TTY_DRAW_LINE_SAME,
|
||||
TTY_DRAW_LINE_PAD,
|
||||
TTY_DRAW_LINE_DONE
|
||||
};
|
||||
static const char* tty_draw_line_states[] = {
|
||||
@@ -39,7 +38,6 @@ static const char* tty_draw_line_states[] = {
|
||||
"NEW2",
|
||||
"EMPTY",
|
||||
"SAME",
|
||||
"PAD",
|
||||
"DONE"
|
||||
};
|
||||
|
||||
@@ -100,25 +98,6 @@ tty_draw_line_clear(struct tty *tty, u_int px, u_int py, u_int nx,
|
||||
}
|
||||
}
|
||||
|
||||
/* Is this cell empty? */
|
||||
static u_int
|
||||
tty_draw_line_get_empty(const struct grid_cell *gc, u_int nx)
|
||||
{
|
||||
u_int empty = 0;
|
||||
|
||||
if (gc->data.width != 1 && gc->data.width > nx)
|
||||
empty = nx;
|
||||
else if (gc->attr == 0 && gc->link == 0) {
|
||||
if (gc->flags & GRID_FLAG_CLEARED)
|
||||
empty = 1;
|
||||
else if (gc->flags & GRID_FLAG_TAB)
|
||||
empty = gc->data.width;
|
||||
else if (gc->data.size == 1 && *gc->data.data == ' ')
|
||||
empty = 1;
|
||||
}
|
||||
return (empty);
|
||||
}
|
||||
|
||||
/* Draw a line from screen to tty. */
|
||||
void
|
||||
tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
@@ -239,6 +218,9 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
next_state = TTY_DRAW_LINE_DONE;
|
||||
gcp = &grid_default_cell;
|
||||
} else {
|
||||
if (i > nx)
|
||||
fatalx("position %u > width %u", i, nx);
|
||||
|
||||
/* Get the current cell. */
|
||||
grid_view_get_cell(gd, px + i, py, &gc);
|
||||
|
||||
@@ -253,20 +235,36 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
}
|
||||
|
||||
/* Work out the the empty width. */
|
||||
if (px >= ex || i >= ex - px)
|
||||
empty = 0;
|
||||
if (px >= ex || i >= ex - px) {
|
||||
/* Outside the area being drawn. */
|
||||
empty = 1;
|
||||
else if (gcp->bg != last.bg)
|
||||
empty = 0;
|
||||
else
|
||||
empty = tty_draw_line_get_empty(gcp, nx - i);
|
||||
} else if (gcp->data.width > nx - i) {
|
||||
/* Wide character that has been truncated. */
|
||||
empty = nx - i;
|
||||
} else if (gcp->flags & GRID_FLAG_PADDING) {
|
||||
/* Orphan padding cell. */
|
||||
empty = 1;
|
||||
} else if (gcp->bg == last.bg && gcp->attr == 0 &&
|
||||
gcp->link == 0) {
|
||||
/*
|
||||
* No attributes - empty if cleared, tab or
|
||||
* space.
|
||||
*/
|
||||
if (gcp->flags & GRID_FLAG_CLEARED)
|
||||
empty = 1;
|
||||
else if (gcp->flags & GRID_FLAG_TAB)
|
||||
empty = gcp->data.width;
|
||||
else if (gcp->data.size == 1 &&
|
||||
*gcp->data.data == ' ')
|
||||
empty = 1;
|
||||
}
|
||||
|
||||
/* Work out the next state. */
|
||||
if (empty != 0)
|
||||
next_state = TTY_DRAW_LINE_EMPTY;
|
||||
else if (current_state == TTY_DRAW_LINE_FIRST)
|
||||
next_state = TTY_DRAW_LINE_SAME;
|
||||
else if (gcp->flags & GRID_FLAG_PADDING)
|
||||
next_state = TTY_DRAW_LINE_PAD;
|
||||
else if (grid_cells_look_equal(gcp, &last)) {
|
||||
if (gcp->data.size > (sizeof buf) - len)
|
||||
next_state = TTY_DRAW_LINE_FLUSH;
|
||||
@@ -312,8 +310,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
}
|
||||
|
||||
/* Append the cell if it is not empty and not padding. */
|
||||
if (next_state != TTY_DRAW_LINE_EMPTY &&
|
||||
next_state != TTY_DRAW_LINE_PAD) {
|
||||
if (next_state != TTY_DRAW_LINE_EMPTY) {
|
||||
memcpy(buf + len, gcp->data.data, gcp->data.size);
|
||||
len += gcp->data.size;
|
||||
width += gcp->data.width;
|
||||
|
||||
@@ -98,7 +98,7 @@ static const char *tty_feature_hyperlinks_capabilities[] = {
|
||||
#if defined (__OpenBSD__) || (defined(NCURSES_VERSION_MAJOR) && \
|
||||
(NCURSES_VERSION_MAJOR > 5 || \
|
||||
(NCURSES_VERSION_MAJOR == 5 && NCURSES_VERSION_MINOR > 8)))
|
||||
"*:Hls=\\E]8;%?%p1%l%tid=%p1%s%;;%p2%s\\E\\\\",
|
||||
"Hls=\\E]8;%?%p1%l%tid=%p1%s%;;%p2%s\\E\\\\",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
@@ -527,8 +527,13 @@ tty_default_features(int *feat, const char *name, u_int version)
|
||||
},
|
||||
{ .name = "foot",
|
||||
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
||||
"ccolour,"
|
||||
"cstyle,"
|
||||
"extkeys"
|
||||
"extkeys,"
|
||||
"usstyle,"
|
||||
"sync,"
|
||||
"osc7,"
|
||||
"hyperlinks"
|
||||
},
|
||||
{ .name = "WezTerm",
|
||||
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
||||
|
||||
@@ -119,6 +119,8 @@ static void window_copy_copy_line(struct window_mode_entry *, char **,
|
||||
static int window_copy_in_set(struct window_mode_entry *, u_int, u_int,
|
||||
const char *);
|
||||
static u_int window_copy_find_length(struct window_mode_entry *, u_int);
|
||||
static u_int window_copy_cursor_limit(struct window_mode_entry *, u_int,
|
||||
int);
|
||||
static void window_copy_cursor_start_of_line(struct window_mode_entry *);
|
||||
static void window_copy_cursor_back_to_indentation(
|
||||
struct window_mode_entry *);
|
||||
@@ -898,9 +900,9 @@ window_copy_get_line(struct window_pane *wp, u_int y)
|
||||
{
|
||||
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct grid *gd = data->screen.grid;
|
||||
struct grid *gd = data->backing->grid;
|
||||
|
||||
return (format_grid_line(gd, gd->hsize + y));
|
||||
return (format_grid_line(gd, gd->hsize + y - data->oy));
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -1662,7 +1664,7 @@ window_copy_cmd_history_bottom(struct window_copy_cmd_state *cs)
|
||||
window_copy_other_end(wme);
|
||||
|
||||
data->cy = screen_size_y(&data->screen) - 1;
|
||||
data->cx = window_copy_find_length(wme, screen_hsize(s) + data->cy);
|
||||
data->cx = window_copy_cursor_limit(wme, screen_hsize(s) + data->cy, 0);
|
||||
data->oy = 0;
|
||||
|
||||
if (data->searchmark != NULL && !data->timeout)
|
||||
@@ -2683,6 +2685,8 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
|
||||
data->cx = data->searchx;
|
||||
data->cy = data->searchy;
|
||||
data->oy = data->searcho;
|
||||
data->cx = window_copy_cursor_limit(wme,
|
||||
screen_hsize(data->backing) + data->cy - data->oy, 0);
|
||||
action = WINDOW_COPY_CMD_REDRAW;
|
||||
}
|
||||
if (*arg0 == '\0') {
|
||||
@@ -2738,6 +2742,8 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
|
||||
data->cx = data->searchx;
|
||||
data->cy = data->searchy;
|
||||
data->oy = data->searcho;
|
||||
data->cx = window_copy_cursor_limit(wme,
|
||||
screen_hsize(data->backing) + data->cy - data->oy, 0);
|
||||
action = WINDOW_COPY_CMD_REDRAW;
|
||||
}
|
||||
if (*arg0 == '\0') {
|
||||
@@ -5151,7 +5157,17 @@ window_copy_update_cursor(struct window_mode_entry *wme, u_int cx, u_int cy)
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *s = &data->screen;
|
||||
struct screen_write_ctx ctx;
|
||||
u_int old_cx, old_cy, width, content_sx;
|
||||
u_int old_cx, old_cy, py, width, content_sx;
|
||||
u_int maxx;
|
||||
int allow_onemore;
|
||||
|
||||
allow_onemore = (data->screen.sel != NULL && data->rectflag);
|
||||
if (cy < screen_size_y(s)) {
|
||||
py = screen_hsize(data->backing) + cy - data->oy;
|
||||
maxx = window_copy_cursor_limit(wme, py, allow_onemore);
|
||||
if (cx > maxx)
|
||||
cx = maxx;
|
||||
}
|
||||
|
||||
old_cx = data->cx; old_cy = data->cy;
|
||||
data->cx = cx; data->cy = cy;
|
||||
@@ -5644,7 +5660,7 @@ window_copy_clear_selection(struct window_mode_entry *wme)
|
||||
data->selflag = SEL_CHAR;
|
||||
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
px = window_copy_find_length(wme, py);
|
||||
px = window_copy_cursor_limit(wme, py, data->rectflag);
|
||||
if (data->cx > px)
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
}
|
||||
@@ -5666,6 +5682,22 @@ window_copy_find_length(struct window_mode_entry *wme, u_int py)
|
||||
return (grid_line_length(data->backing->grid, py));
|
||||
}
|
||||
|
||||
static u_int
|
||||
window_copy_cursor_limit(struct window_mode_entry *wme, u_int py,
|
||||
int allow_onemore)
|
||||
{
|
||||
struct options *oo = wme->wp->window->options;
|
||||
u_int len;
|
||||
|
||||
len = window_copy_find_length(wme, py);
|
||||
if (allow_onemore ||
|
||||
options_get_number(oo, "mode-keys") != MODEKEY_VI)
|
||||
return (len);
|
||||
if (len == 0)
|
||||
return (0);
|
||||
return (len - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
window_copy_cursor_start_of_line(struct window_mode_entry *wme)
|
||||
{
|
||||
@@ -5723,6 +5755,8 @@ window_copy_cursor_end_of_line(struct window_mode_entry *wme)
|
||||
else
|
||||
grid_reader_cursor_end_of_line(&gr, 1, 0);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
if (data->screen.sel == NULL || !data->rectflag)
|
||||
px = window_copy_cursor_limit(wme, py, 0);
|
||||
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
|
||||
data->oy, oldy, px, py, 0);
|
||||
}
|
||||
@@ -5773,6 +5807,10 @@ window_copy_other_end(struct window_mode_entry *wme)
|
||||
data->cy = screen_size_y(s) - 1;
|
||||
} else
|
||||
data->cy = cy + sely - yy;
|
||||
yy = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
hsize = window_copy_cursor_limit(wme, yy, data->rectflag);
|
||||
if (data->cx > hsize)
|
||||
data->cx = hsize;
|
||||
|
||||
window_copy_update_selection(wme, 1, 1);
|
||||
window_copy_redraw_screen(wme);
|
||||
@@ -5800,18 +5838,22 @@ window_copy_cursor_left(struct window_mode_entry *wme)
|
||||
static void
|
||||
window_copy_cursor_right(struct window_mode_entry *wme, int all)
|
||||
{
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct options *oo = wp->window->options;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, oldy, hsize;
|
||||
int onemore;
|
||||
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
oldy = data->cy;
|
||||
onemore = (options_get_number(oo, "mode-keys") != MODEKEY_VI);
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_right(&gr, 1, all);
|
||||
grid_reader_cursor_right(&gr, 1, all, onemore);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
|
||||
data->oy, oldy, px, py, 0);
|
||||
@@ -6026,20 +6068,23 @@ static void
|
||||
window_copy_cursor_jump_to_back(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct options *oo = wme->wp->window->options;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, oldy, hsize;
|
||||
int onemore;
|
||||
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
oldy = data->cy;
|
||||
onemore = (options_get_number(oo, "mode-keys") != MODEKEY_VI);
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_left(&gr, 0);
|
||||
grid_reader_cursor_left(&gr, 0);
|
||||
if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) {
|
||||
grid_reader_cursor_right(&gr, 1, 0);
|
||||
grid_reader_cursor_right(&gr, 1, 0, onemore);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px,
|
||||
py);
|
||||
@@ -6086,7 +6131,7 @@ window_copy_cursor_next_word_end_pos(struct window_mode_entry *wme,
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
if (options_get_number(oo, "mode-keys") == MODEKEY_VI) {
|
||||
if (!grid_reader_in_set(&gr, WHITESPACE))
|
||||
grid_reader_cursor_right(&gr, 0, 0);
|
||||
grid_reader_cursor_right(&gr, 0, 0, 0);
|
||||
grid_reader_cursor_next_word_end(&gr, separators);
|
||||
grid_reader_cursor_left(&gr, 1);
|
||||
} else
|
||||
@@ -6116,7 +6161,7 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
if (options_get_number(oo, "mode-keys") == MODEKEY_VI) {
|
||||
if (!grid_reader_in_set(&gr, WHITESPACE))
|
||||
grid_reader_cursor_right(&gr, 0, 0);
|
||||
grid_reader_cursor_right(&gr, 0, 0, 0);
|
||||
grid_reader_cursor_next_word_end(&gr, separators);
|
||||
grid_reader_cursor_left(&gr, 1);
|
||||
} else
|
||||
@@ -6350,7 +6395,7 @@ window_copy_rectangle_set(struct window_mode_entry *wme, int rectflag)
|
||||
data->rectflag = rectflag;
|
||||
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
px = window_copy_find_length(wme, py);
|
||||
px = window_copy_cursor_limit(wme, py, data->rectflag);
|
||||
if (data->cx > px)
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
|
||||
|
||||
@@ -387,7 +387,7 @@ window_tree_build(void *modedata, struct sort_criteria *sort_crit,
|
||||
*tag = (uint64_t)data->fs.wl;
|
||||
break;
|
||||
case WINDOW_TREE_PANE:
|
||||
if (window_count_panes(data->fs.wl->window) == 1)
|
||||
if (window_count_panes(data->fs.wl->window, 1) == 1)
|
||||
*tag = (uint64_t)data->fs.wl;
|
||||
else
|
||||
*tag = (uint64_t)data->fs.wp;
|
||||
@@ -578,7 +578,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
|
||||
struct format_tree *ft;
|
||||
struct options *oo;
|
||||
|
||||
total = window_count_panes(w);
|
||||
total = window_count_panes(w, 1);
|
||||
|
||||
if (sx / total < 24) {
|
||||
visible = sx / 24;
|
||||
|
||||
136
window.c
136
window.c
@@ -71,7 +71,7 @@ static struct window_pane *window_pane_create(struct window *, u_int, u_int,
|
||||
u_int);
|
||||
static void window_pane_destroy(struct window_pane *);
|
||||
static void window_pane_full_size_offset(struct window_pane *wp,
|
||||
u_int *xoff, u_int *yoff, u_int *sx, u_int *sy);
|
||||
int *xoff, int *yoff, u_int *sx, u_int *sy);
|
||||
|
||||
RB_GENERATE(windows, window, entry, window_cmp);
|
||||
RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
|
||||
@@ -306,6 +306,7 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
|
||||
w->flags = 0;
|
||||
|
||||
TAILQ_INIT(&w->panes);
|
||||
TAILQ_INIT(&w->z_index);
|
||||
TAILQ_INIT(&w->last_panes);
|
||||
w->active = NULL;
|
||||
|
||||
@@ -530,6 +531,8 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
|
||||
|
||||
if (wp == w->active)
|
||||
return (0);
|
||||
if (w->flags & WINDOW_ZOOMED)
|
||||
window_unzoom(w, 1);
|
||||
lastwp = w->active;
|
||||
|
||||
window_pane_stack_remove(&w->last_panes, wp);
|
||||
@@ -672,7 +675,7 @@ window_zoom(struct window_pane *wp)
|
||||
if (w->flags & WINDOW_ZOOMED)
|
||||
return (-1);
|
||||
|
||||
if (window_count_panes(w) == 1)
|
||||
if (window_count_panes(w, 1) == 1)
|
||||
return (-1);
|
||||
|
||||
if (w->active != wp)
|
||||
@@ -859,14 +862,15 @@ window_pane_index(struct window_pane *wp, u_int *i)
|
||||
}
|
||||
|
||||
u_int
|
||||
window_count_panes(struct window *w)
|
||||
window_count_panes(struct window *w, int with_floating)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
u_int n;
|
||||
u_int n = 0;
|
||||
|
||||
n = 0;
|
||||
TAILQ_FOREACH(wp, &w->panes, entry)
|
||||
n++;
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (with_floating || ~wp->flags & PANE_FLOATING)
|
||||
n++;
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
|
||||
@@ -1388,7 +1392,7 @@ window_pane_choose_best(struct window_pane **list, u_int size)
|
||||
* scrollbars if they were visible but not including the border(s).
|
||||
*/
|
||||
static void
|
||||
window_pane_full_size_offset(struct window_pane *wp, u_int *xoff, u_int *yoff,
|
||||
window_pane_full_size_offset(struct window_pane *wp, int *xoff, int *yoff,
|
||||
u_int *sx, u_int *sy)
|
||||
{
|
||||
struct window *w = wp->window;
|
||||
@@ -1422,9 +1426,9 @@ window_pane_find_up(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
u_int edge, left, right, end, size;
|
||||
int status, found;
|
||||
u_int xoff, yoff, sx, sy;
|
||||
int edge, left, right, end, status, found;
|
||||
int xoff, yoff;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1439,25 +1443,25 @@ window_pane_find_up(struct window_pane *wp)
|
||||
edge = yoff;
|
||||
if (status == PANE_STATUS_TOP) {
|
||||
if (edge == 1)
|
||||
edge = w->sy + 1;
|
||||
edge = (int)w->sy + 1;
|
||||
} else if (status == PANE_STATUS_BOTTOM) {
|
||||
if (edge == 0)
|
||||
edge = w->sy;
|
||||
edge = (int)w->sy;
|
||||
} else {
|
||||
if (edge == 0)
|
||||
edge = w->sy + 1;
|
||||
edge = (int)w->sy + 1;
|
||||
}
|
||||
|
||||
left = xoff;
|
||||
right = xoff + sx;
|
||||
right = xoff + (int)sx;
|
||||
|
||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||
if (next == wp)
|
||||
continue;
|
||||
if (yoff + sy + 1 != edge)
|
||||
if (yoff + (int)sy + 1 != edge)
|
||||
continue;
|
||||
end = xoff + sx - 1;
|
||||
end = xoff + (int)sx - 1;
|
||||
|
||||
found = 0;
|
||||
if (xoff < left && end > right)
|
||||
@@ -1483,9 +1487,9 @@ window_pane_find_down(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
u_int edge, left, right, end, size;
|
||||
int status, found;
|
||||
u_int xoff, yoff, sx, sy;
|
||||
int edge, left, right, end, status, found;
|
||||
int xoff, yoff;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1497,20 +1501,20 @@ window_pane_find_down(struct window_pane *wp)
|
||||
|
||||
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
||||
|
||||
edge = yoff + sy + 1;
|
||||
edge = yoff + (int)sy + 1;
|
||||
if (status == PANE_STATUS_TOP) {
|
||||
if (edge >= w->sy)
|
||||
if (edge >= (int)w->sy)
|
||||
edge = 1;
|
||||
} else if (status == PANE_STATUS_BOTTOM) {
|
||||
if (edge >= w->sy - 1)
|
||||
if (edge >= (int)w->sy - 1)
|
||||
edge = 0;
|
||||
} else {
|
||||
if (edge >= w->sy)
|
||||
if (edge >= (int)w->sy)
|
||||
edge = 0;
|
||||
}
|
||||
|
||||
left = wp->xoff;
|
||||
right = wp->xoff + wp->sx;
|
||||
right = wp->xoff + (int)wp->sx;
|
||||
|
||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||
@@ -1518,7 +1522,7 @@ window_pane_find_down(struct window_pane *wp)
|
||||
continue;
|
||||
if (yoff != edge)
|
||||
continue;
|
||||
end = xoff + sx - 1;
|
||||
end = xoff + (int)sx - 1;
|
||||
|
||||
found = 0;
|
||||
if (xoff < left && end > right)
|
||||
@@ -1544,9 +1548,9 @@ window_pane_find_left(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
u_int edge, top, bottom, end, size;
|
||||
int found;
|
||||
u_int xoff, yoff, sx, sy;
|
||||
int edge, top, bottom, end, found;
|
||||
int xoff, yoff;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1559,18 +1563,18 @@ window_pane_find_left(struct window_pane *wp)
|
||||
|
||||
edge = xoff;
|
||||
if (edge == 0)
|
||||
edge = w->sx + 1;
|
||||
edge = (int)w->sx + 1;
|
||||
|
||||
top = yoff;
|
||||
bottom = yoff + sy;
|
||||
bottom = yoff + (int)sy;
|
||||
|
||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||
if (next == wp)
|
||||
continue;
|
||||
if (xoff + sx + 1 != edge)
|
||||
if (xoff + (int)sx + 1 != edge)
|
||||
continue;
|
||||
end = yoff + sy - 1;
|
||||
end = yoff + (int)sy - 1;
|
||||
|
||||
found = 0;
|
||||
if (yoff < top && end > bottom)
|
||||
@@ -1596,9 +1600,9 @@ window_pane_find_right(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
u_int edge, top, bottom, end, size;
|
||||
int found;
|
||||
u_int xoff, yoff, sx, sy;
|
||||
int edge, top, bottom, end, found;
|
||||
int xoff, yoff;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1609,12 +1613,12 @@ window_pane_find_right(struct window_pane *wp)
|
||||
|
||||
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
||||
|
||||
edge = xoff + sx + 1;
|
||||
if (edge >= w->sx)
|
||||
edge = xoff + (int)sx + 1;
|
||||
if (edge >= (int)w->sx)
|
||||
edge = 0;
|
||||
|
||||
top = wp->yoff;
|
||||
bottom = wp->yoff + wp->sy;
|
||||
bottom = wp->yoff + (int)wp->sy;
|
||||
|
||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||
@@ -1622,7 +1626,7 @@ window_pane_find_right(struct window_pane *wp)
|
||||
continue;
|
||||
if (xoff != edge)
|
||||
continue;
|
||||
end = yoff + sy - 1;
|
||||
end = yoff + (int)sy - 1;
|
||||
|
||||
found = 0;
|
||||
if (yoff < top && end > bottom)
|
||||
@@ -1642,6 +1646,7 @@ window_pane_find_right(struct window_pane *wp)
|
||||
return (best);
|
||||
}
|
||||
|
||||
/* Add window to stack. */
|
||||
void
|
||||
window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
|
||||
{
|
||||
@@ -1652,6 +1657,7 @@ window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove window from stack. */
|
||||
void
|
||||
window_pane_stack_remove(struct window_panes *stack, struct window_pane *wp)
|
||||
{
|
||||
@@ -2032,3 +2038,53 @@ window_pane_border_status_get_range(struct window_pane *wp, u_int x, u_int y)
|
||||
*/
|
||||
return (style_ranges_get_range(srs, x - wp->xoff - 2));
|
||||
}
|
||||
|
||||
int
|
||||
window_pane_tile_geometry(struct window *w, struct window_pane *wp,
|
||||
int *out_size, int *out_flags, enum layout_type *out_type,
|
||||
struct cmdq_item *item, struct args *args, char **cause)
|
||||
{
|
||||
int size = -1, flags = *out_flags;
|
||||
enum layout_type type;
|
||||
u_int curval = 0;
|
||||
|
||||
type = LAYOUT_TOPBOTTOM;
|
||||
if (args_has(args, 'h'))
|
||||
type = LAYOUT_LEFTRIGHT;
|
||||
|
||||
if (args_has(args, 'l') || args_has(args, 'p')) {
|
||||
if (args_has(args, 'f')) {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = w->sy;
|
||||
else
|
||||
curval = w->sx;
|
||||
} else {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = wp->sy;
|
||||
else
|
||||
curval = wp->sx;
|
||||
}
|
||||
}
|
||||
|
||||
if (args_has(args, 'l')) {
|
||||
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
||||
item, cause);
|
||||
} else if (args_has(args, 'p')) {
|
||||
size = args_strtonum_and_expand(args, 'p', 0, 100, item,
|
||||
cause);
|
||||
if (cause == NULL)
|
||||
size = curval * size / 100;
|
||||
}
|
||||
if (*cause != NULL)
|
||||
return (-1);
|
||||
|
||||
if (args_has(args, 'b'))
|
||||
flags |= SPAWN_BEFORE;
|
||||
if (args_has(args, 'f'))
|
||||
flags |= SPAWN_FULLSIZE;
|
||||
|
||||
*out_size = size;
|
||||
*out_flags = flags;
|
||||
*out_type = type;
|
||||
return (0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user