Merge branch 'master' into floating_panes

This commit is contained in:
Dane Jensen
2026-06-14 19:54:43 -07:00
23 changed files with 749 additions and 120 deletions

View File

@@ -47,8 +47,8 @@ const struct cmd_entry cmd_choose_client_entry = {
.name = "choose-client", .name = "choose-client",
.alias = NULL, .alias = NULL,
.args = { "F:f:hK:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse }, .args = { "F:f:hiK:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
.usage = "[-hkNrZ] [-F format] [-f filter] [-K key-format] " .usage = "[-hikNrZ] [-F format] [-f filter] [-K key-format] "
"[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]", "[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]",
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },

View File

@@ -49,8 +49,10 @@ const struct cmd_entry cmd_move_pane_entry = {
.name = "move-pane", .name = "move-pane",
.alias = "movep", .alias = "movep",
.args = { "bdfhvp:l:s:t:", 0, 0, NULL }, .args = { "bdfhvl:L::P:R::s:t:U::X:Y:z:", 0, 0, NULL },
.usage = "[-bdfhv] [-l size] " CMD_SRCDST_PANE_USAGE, .usage = "[-bdfhv] [-D lines] [-l size] [-L columns] [-P position] "
"[-R columns] " CMD_SRCDST_PANE_USAGE " [-U lines] "
"[-X x-position] [-Y y-position] [-z z-index]",
.source = { 's', CMD_FIND_PANE, CMD_FIND_DEFAULT_MARKED }, .source = { 's', CMD_FIND_PANE, CMD_FIND_DEFAULT_MARKED },
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@@ -59,6 +61,231 @@ const struct cmd_entry cmd_move_pane_entry = {
.exec = cmd_join_pane_exec .exec = cmd_join_pane_exec
}; };
static enum cmd_retval
cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl,
struct window_pane *wp, const char *position)
{
struct window *w = wl->window;
struct layout_cell *lc = wp->layout_cell;
struct window_pane *owp;
int wx = w->sx, wy = w->sy, px = lc->sx;
int py = lc->sy, xoff = lc->xoff, yoff = lc->yoff;
if (strcmp(position, "top-left") == 0) {
xoff = 1;
yoff = 1;
} else if (strcmp(position, "top-centre") == 0 ||
strcmp(position, "top-center") == 0) {
xoff = (wx - px) / 2;
yoff = 1;
} else if (strcmp(position, "top-right") == 0) {
xoff = wx - px - 1;
yoff = 1;
} else if (strcmp(position, "centre-left") == 0 ||
strcmp(position, "center-left") == 0) {
xoff = 1;
yoff = (wy - py) / 2;
} else if (strcmp(position, "centre") == 0 ||
strcmp(position, "center") == 0) {
xoff = (wx - px) / 2;
yoff = (wy - py) / 2;
} else if (strcmp(position, "centre-right") == 0 ||
strcmp(position, "center-right") == 0) {
xoff = wx - px - 1;
yoff = (wy - py) / 2;
} else if (strcmp(position, "bottom-left") == 0) {
xoff = 1;
yoff = wy - py - 1;
} else if (strcmp(position, "bottom-centre") == 0 ||
strcmp(position, "bottom-center") == 0) {
xoff = (wx - px) / 2;
yoff = wy - py - 1;
} else if (strcmp(position, "bottom-right") == 0) {
xoff = wx - px - 1;
yoff = wy - py - 1;
} else if (strcmp(position, "top-left-centre") == 0 ||
strcmp(position, "top-left-center") == 0) {
xoff = wx / 4 - px / 2;
yoff = wy / 4 - py / 2;
} else if (strcmp(position, "top-right-centre") == 0 ||
strcmp(position, "top-right-center") == 0) {
xoff = (3 * wx) / 4 - px / 2;
yoff = wy / 4 - py / 2;
} else if (strcmp(position, "bottom-left-centre") == 0 ||
strcmp(position, "bottom-left-center") == 0) {
xoff = wx / 4 - px / 2;
yoff = (3 * wy) / 4 - py / 2;
} else if (strcmp(position, "bottom-right-centre") == 0 ||
strcmp(position, "bottom-right-center") == 0) {
xoff = (3 * wx) / 4 - px / 2;
yoff = (3 * wy) / 4 - py / 2;
} else if (strcmp(position, "front") == 0) {
TAILQ_REMOVE(&w->z_index, wp, zentry);
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
} else if (strcmp(position, "back") == 0) {
TAILQ_REMOVE(&w->z_index, wp, zentry);
TAILQ_FOREACH(owp, &w->z_index, zentry) {
if (!window_pane_is_floating(owp))
break;
}
if (owp != NULL)
TAILQ_INSERT_BEFORE(owp, wp, zentry);
else
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
} else if (strcmp(position, "forward") == 0) {
owp = TAILQ_PREV(wp, window_panes_zindex, zentry);
if (owp != NULL) {
TAILQ_REMOVE(&w->z_index, wp, zentry);
TAILQ_INSERT_BEFORE(owp, wp, zentry);
}
} else if (strcmp(position, "backward") == 0) {
owp = TAILQ_NEXT(wp, zentry);
if (owp != NULL && window_pane_is_floating(owp)) {
TAILQ_REMOVE(&w->z_index, wp, zentry);
TAILQ_INSERT_AFTER(&w->z_index, owp, wp, zentry);
}
} else if (strcmp(position, "forward-loop") == 0) {
owp = TAILQ_PREV(wp, window_panes_zindex, zentry);
TAILQ_REMOVE(&w->z_index, wp, zentry);
if (owp != NULL)
TAILQ_INSERT_BEFORE(owp, wp, zentry);
else {
TAILQ_FOREACH(owp, &w->z_index, zentry) {
if (!window_pane_is_floating(owp))
break;
}
if (owp != NULL)
TAILQ_INSERT_BEFORE(owp, wp, zentry);
else
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
}
} else if (strcmp(position, "backward-loop") == 0) {
owp = TAILQ_NEXT(wp, zentry);
if (owp != NULL && window_pane_is_floating(owp)) {
TAILQ_REMOVE(&w->z_index, wp, zentry);
TAILQ_INSERT_AFTER(&w->z_index, owp, wp, zentry);
} else {
TAILQ_REMOVE(&w->z_index, wp, zentry);
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
}
} else {
cmdq_error(item, "unknown position: %s", position);
return (CMD_RETURN_ERROR);
}
if (xoff != lc->xoff || yoff != lc->yoff) {
lc->xoff = xoff;
lc->yoff = yoff;
layout_fix_panes(w, NULL);
}
notify_window("window-layout-changed", w);
server_redraw_window(w);
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_join_pane_move(struct cmdq_item *item, struct args *args,
struct winlink *wl, struct window_pane *wp)
{
struct window *w = wl->window;
struct layout_cell *lc = wp->layout_cell;
const char *errstr, *argval;
const char flags[] = { 'U', 'D', 'L', 'R' };
char *cause = NULL, flag;
int xoff = lc->xoff, yoff = lc->yoff, adjust;
u_int i;
if (args_has(args, 'X')) {
xoff = args_percentage_and_expand(args, 'X', -(int)lc->sx,
w->sx, w->sx, item, &cause);
if (cause != NULL) {
cmdq_error(item, "position %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
}
if (args_has(args, 'Y')) {
yoff = args_percentage_and_expand(args, 'Y', -(int)lc->sy,
w->sy, w->sy, item, &cause);
if (cause != NULL) {
cmdq_error(item, "position %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
}
for (i = 0; i < nitems(flags); i++) {
flag = flags[i];
if (!args_has(args, flag))
continue;
argval = args_get(args, flag);
if (argval == NULL)
argval = "1";
adjust = strtonum(argval, INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(item, "offset %s", errstr);
return (CMD_RETURN_ERROR);
}
if (flag == 'U')
yoff -= adjust;
else if (flag == 'D')
yoff += adjust;
else if (flag == 'L')
xoff -= adjust;
else
xoff += adjust;
}
if (xoff != lc->xoff || yoff != lc->yoff) {
lc->xoff = xoff;
lc->yoff = yoff;
layout_fix_panes(w, NULL);
notify_window("window-layout-changed", w);
server_redraw_window(w);
}
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_join_pane_zindex(struct cmdq_item *item, struct winlink *wl,
struct window_pane *wp, const char *s)
{
struct window *w = wl->window;
struct window_pane *owp;
const char *errstr;
u_int n, z;
z = strtonum(s, 0, UINT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(item, "z-index %s", errstr);
return (CMD_RETURN_ERROR);
}
TAILQ_REMOVE(&w->z_index, wp, zentry);
n = 0;
TAILQ_FOREACH(owp, &w->z_index, zentry) {
if (!window_pane_is_floating(owp))
break;
if (n >= z)
break;
n++;
}
if (owp != NULL)
TAILQ_INSERT_BEFORE(owp, wp, zentry);
else
TAILQ_INSERT_TAIL(&w->z_index, wp, zentry);
notify_window("window-layout-changed", w);
server_redraw_window(w);
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval static enum cmd_retval
cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
{ {
@@ -70,6 +297,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
struct winlink *src_wl, *dst_wl; struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w; struct window *src_w, *dst_w;
struct window_pane *src_wp, *dst_wp; struct window_pane *src_wp, *dst_wp;
const char *s;
char *cause = NULL; char *cause = NULL;
int flags = 0, dst_idx; int flags = 0, dst_idx;
struct layout_cell *lc; struct layout_cell *lc;
@@ -81,6 +309,24 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
dst_idx = dst_wl->idx; dst_idx = dst_wl->idx;
server_unzoom_window(dst_w); server_unzoom_window(dst_w);
if (cmd_get_entry(self) == &cmd_move_pane_entry) {
if (!window_pane_is_floating(dst_wp)) {
cmdq_error(item, "pane is not floating");
return (CMD_RETURN_ERROR);
}
if ((s = args_get(args, 'P')) != NULL)
return (cmd_join_pane_place(item, dst_wl, dst_wp, s));
if ((s = args_get(args, 'z')) != NULL)
return (cmd_join_pane_zindex(item, dst_wl, dst_wp, s));
if (args_has(args, 'X') ||
args_has(args, 'Y') ||
args_has(args, 'U') ||
args_has(args, 'D') ||
args_has(args, 'L') ||
args_has(args, 'R'))
return (cmd_join_pane_move(item, args, dst_wl, dst_wp));
}
src_wl = source->wl; src_wl = source->wl;
src_wp = source->wp; src_wp = source->wp;
src_w = src_wl->window; src_w = src_wl->window;

View File

@@ -41,7 +41,7 @@ const struct cmd_entry cmd_resize_pane_entry = {
.alias = "resizep", .alias = "resizep",
.args = { "D::L::MR::Tt:U::x:y:Z", 0, 1, NULL }, .args = { "D::L::MR::Tt:U::x:y:Z", 0, 1, NULL },
.usage = "[-MTZ] [-U lines] [-D lines] [-L columns] [-R columns] " .usage = "[-MTZ] [-D lines] [-L columns] [-R columns] [-U lines] "
"[-x width] [-y height] " CMD_TARGET_PANE_USAGE, "[-x width] [-y height] " CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@@ -118,7 +118,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
switch (status) { switch (status) {
case PANE_STATUS_TOP: case PANE_STATUS_TOP:
if (y != INT_MAX && wp->yoff == 1) if (y != INT_MAX && wp->yoff == 1)

View File

@@ -119,7 +119,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
else else
lc = layout_get_tiled_cell(item, args, w, wp, flags, &cause); lc = layout_get_tiled_cell(item, args, w, wp, flags, &cause);
if (cause != NULL) { if (cause != NULL) {
cmdq_error(item, "size or position %s", cause); cmdq_error(item, "%s", cause);
free(cause); free(cause);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@@ -189,10 +189,11 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
} }
if (args_has(args, 'k') || args_has(args, 'm')) { if (args_has(args, 'k') || args_has(args, 'm')) {
options_set_number(new_wp->options, "remain-on-exit", 3); options_set_number(new_wp->options, "remain-on-exit", 3);
if (args_has(args, 'm')) if (args_has(args, 'm')) {
options_set_string(new_wp->options, options_set_string(new_wp->options,
"remain-on-exit-format", "remain-on-exit-format", 0, "%s",
0, "%s", args_get(args, 'm')); args_get(args, 'm'));
}
} }
if (args_has(args, 'T')) { if (args_has(args, 'T')) {
title = format_single_from_target(item, args_get(args, 'T')); title = format_single_from_target(item, args_get(args, 'T'));

View File

@@ -339,7 +339,7 @@ static int
getopt_internal(int nargc, char * const *nargv, const char *options, getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags) const struct option *long_options, int *idx, int flags)
{ {
char *oli; /* option letter list index */ const char *oli; /* option letter list index */
int optchar, short_too; int optchar, short_too;
static int posixly_correct = -1; static int posixly_correct = -1;

View File

@@ -152,7 +152,8 @@ environ_clear(struct environ *env, const char *name)
void void
environ_put(struct environ *env, const char *var, int flags) environ_put(struct environ *env, const char *var, int flags)
{ {
char *name, *value; char *name;
const char *value;
value = strchr(var, '='); value = strchr(var, '=');
if (value == NULL) if (value == NULL)

View File

@@ -118,6 +118,9 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
#define FORMAT_REPEAT 0x200000 #define FORMAT_REPEAT 0x200000
#define FORMAT_QUOTE_ARGUMENTS 0x400000 #define FORMAT_QUOTE_ARGUMENTS 0x400000
#define FORMAT_RELATIVE 0x800000 #define FORMAT_RELATIVE 0x800000
#define FORMAT_CLIENT_TERMCAP 0x1000000
#define FORMAT_CLIENT_TERMFEAT 0x2000000
#define FORMAT_CLIENT_ENVIRON 0x4000000
/* Limit on recursion. */ /* Limit on recursion. */
#define FORMAT_LOOP_LIMIT 100 #define FORMAT_LOOP_LIMIT 100
@@ -1162,7 +1165,7 @@ format_cb_pane_at_top(struct format_tree *ft)
return (NULL); return (NULL);
w = wp->window; w = wp->window;
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
if (status == PANE_STATUS_TOP) if (status == PANE_STATUS_TOP)
flag = (wp->yoff == 1); flag = (wp->yoff == 1);
else else
@@ -3792,7 +3795,7 @@ format_table_compare(const void *key0, const void *entry0)
} }
/* Get a format callback. */ /* Get a format callback. */
static struct format_table_entry * static const struct format_table_entry *
format_table_get(const char *key) format_table_get(const char *key)
{ {
return (bsearch(key, format_table, nitems(format_table), return (bsearch(key, format_table, nitems(format_table),
@@ -4087,18 +4090,14 @@ format_relative_time(time_t t)
{ {
time_t now, age; time_t now, age;
u_int d, h, m, s; u_int d, h, m, s;
char out[32], sign; char out[32];
time(&now); time(&now);
if (t > now)
return (NULL);
if (t == now) if (t == now)
return (xstrdup("0s")); return (xstrdup("0s"));
if (t > now) { age = now - t;
sign = '+';
age = t - now;
} else {
sign = '-';
age = now - t;
}
d = age / 86400; d = age / 86400;
h = (age % 86400) / 3600; h = (age % 86400) / 3600;
@@ -4107,21 +4106,21 @@ format_relative_time(time_t t)
if (d != 0) { if (d != 0) {
if (h != 0) if (h != 0)
xsnprintf(out, sizeof out, "%c%ud%uh", sign, d, h); xsnprintf(out, sizeof out, "%ud%uh", d, h);
else else
xsnprintf(out, sizeof out, "%c%ud", sign, d); xsnprintf(out, sizeof out, "%ud", d);
} else if (h != 0) { } else if (h != 0) {
if (m != 0) if (m != 0)
xsnprintf(out, sizeof out, "%c%uh%um", sign, h, m); xsnprintf(out, sizeof out, "%uh%um", h, m);
else else
xsnprintf(out, sizeof out, "%c%uh", sign, h); xsnprintf(out, sizeof out, "%uh", h);
} else if (m != 0) { } else if (m != 0) {
if (s != 0) if (s != 0)
xsnprintf(out, sizeof out, "%c%um%us", sign, m, s); xsnprintf(out, sizeof out, "%um%us", m, s);
else else
xsnprintf(out, sizeof out, "%c%um", sign, m); xsnprintf(out, sizeof out, "%um", m);
} else } else
xsnprintf(out, sizeof out, "%c%us", sign, s); xsnprintf(out, sizeof out, "%us", s);
return (xstrdup(out)); return (xstrdup(out));
} }
@@ -4130,7 +4129,7 @@ static char *
format_find(struct format_tree *ft, const char *key, int modifiers, format_find(struct format_tree *ft, const char *key, int modifiers,
const char *time_format) const char *time_format)
{ {
struct format_table_entry *fte; const struct format_table_entry *fte;
void *value; void *value;
struct format_entry *fe, fe_find; struct format_entry *fe, fe_find;
struct environ_entry *envent; struct environ_entry *envent;
@@ -4443,7 +4442,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
/* /*
* Modifiers are a ; separated list of the forms: * Modifiers are a ; separated list of the forms:
* l,m,C,a,b,c,d,n,t,w,q,E,T,S,W,P,R,<,> * l,m,C,a,b,c,d,I,n,t,w,q,E,T,S,W,P,R,<,>
* =a * =a
* =/a * =/a
* =/a/ * =/a/
@@ -4484,7 +4483,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
} }
/* Now try single character with arguments. */ /* Now try single character with arguments. */
if (strchr("mCLNPSst=pReqW", cp[0]) == NULL) if (strchr("ImCLNPSst=pReqW", cp[0]) == NULL)
break; break;
c = cp[0]; c = cp[0];
@@ -5125,6 +5124,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
struct format_modifier *bool_op_n = NULL; struct format_modifier *bool_op_n = NULL;
u_int i, count, nsub = 0, nrep; u_int i, count, nsub = 0, nrep;
struct format_expand_state next; struct format_expand_state next;
struct environ_entry *envent;
/* Set sorting defaults. */ /* Set sorting defaults. */
sc->order = SORT_ORDER; sc->order = SORT_ORDER;
@@ -5207,6 +5207,16 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
case 'n': case 'n':
modifiers |= FORMAT_LENGTH; modifiers |= FORMAT_LENGTH;
break; break;
case 'I':
if (fm->argc < 1)
break;
if (strchr(fm->argv[0], 'f') != NULL)
modifiers |= FORMAT_CLIENT_TERMFEAT;
if (strchr(fm->argv[0], 'c') != NULL)
modifiers |= FORMAT_CLIENT_TERMCAP;
if (strchr(fm->argv[0], 'e') != NULL)
modifiers |= FORMAT_CLIENT_ENVIRON;
break;
case 't': case 't':
modifiers |= FORMAT_TIMESTRING; modifiers |= FORMAT_TIMESTRING;
if (fm->argc < 1) if (fm->argc < 1)
@@ -5218,7 +5228,8 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
else if (fm->argc >= 2 && else if (fm->argc >= 2 &&
strchr(fm->argv[0], 'f') != NULL) { strchr(fm->argv[0], 'f') != NULL) {
free(time_format); free(time_format);
time_format = format_strip(es, fm->argv[1]); time_format = format_strip(es,
fm->argv[1]);
} }
break; break;
case 'q': case 'q':
@@ -5333,6 +5344,38 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
} }
} }
/* Look up client capability, feature or environment. */
if ((modifiers & FORMAT_CLIENT_TERMCAP) ||
(modifiers & FORMAT_CLIENT_TERMFEAT) ||
(modifiers & FORMAT_CLIENT_ENVIRON)) {
if (ft->c == NULL ||
ft->c->tty.term == NULL ||
ft->c->flags & CLIENT_UNATTACHEDFLAGS) {
value = xstrdup("");
goto done;
}
if (modifiers & FORMAT_CLIENT_TERMCAP) {
if (tty_term_has_name(ft->c->tty.term, copy))
value = xstrdup("1");
else
value = xstrdup("0");
}
if (modifiers & FORMAT_CLIENT_TERMFEAT) {
if (tty_feature_present(ft->c->tty.term, copy))
value = xstrdup("1");
else
value = xstrdup("0");
}
if (modifiers & FORMAT_CLIENT_ENVIRON) {
envent = environ_find(ft->c->environ, copy);
if (envent != NULL && envent->value != NULL)
value = xstrdup(envent->value);
else
value = xstrdup("");
}
goto done;
}
/* Is this a literal string? */ /* Is this a literal string? */
if (modifiers & FORMAT_LITERAL) { if (modifiers & FORMAT_LITERAL) {
format_log(es, "literal string is '%s'", copy); format_log(es, "literal string is '%s'", copy);

View File

@@ -483,7 +483,7 @@ input_key_vt10x(struct bufferevent *bev, key_code key)
{ {
struct utf8_data ud; struct utf8_data ud;
key_code onlykey; key_code onlykey;
char *p; const char *p;
static const char *standard_map[2] = { static const char *standard_map[2] = {
"1!9(0)=+;:'\",<.>/-8? 2", "1!9(0)=+;:'\",<.>/-8? 2",
"119900=+;;'',,..\x1f\x1f\x7f\x7f\0\0", "119900=+;;'',,..\x1f\x1f\x7f\x7f\0\0",

16
input.c
View File

@@ -1365,7 +1365,7 @@ input_esc_dispatch(struct input_ctx *ictx)
{ {
struct screen_write_ctx *sctx = &ictx->ctx; struct screen_write_ctx *sctx = &ictx->ctx;
struct screen *s = sctx->s; struct screen *s = sctx->s;
struct input_table_entry *entry; const struct input_table_entry *entry;
if (ictx->flags & INPUT_DISCARD) if (ictx->flags & INPUT_DISCARD)
return (0); return (0);
@@ -1439,12 +1439,12 @@ input_esc_dispatch(struct input_ctx *ictx)
static int static int
input_csi_dispatch(struct input_ctx *ictx) input_csi_dispatch(struct input_ctx *ictx)
{ {
struct screen_write_ctx *sctx = &ictx->ctx; struct screen_write_ctx *sctx = &ictx->ctx;
struct screen *s = sctx->s; struct screen *s = sctx->s;
struct input_table_entry *entry; const struct input_table_entry *entry;
struct options *oo; struct options *oo;
int i, n, m, ek, set, p; int i, n, m, ek, set, p;
u_int cx, bg = ictx->cell.cell.bg; u_int cx, bg = ictx->cell.cell.bg;
if (ictx->flags & INPUT_DISCARD) if (ictx->flags & INPUT_DISCARD)
return (0); return (0);
@@ -3225,7 +3225,7 @@ static int
input_osc_52_parse(struct input_ctx *ictx, const char *p, u_char **out, input_osc_52_parse(struct input_ctx *ictx, const char *p, u_char **out,
int *outlen, char *clip) int *outlen, char *clip)
{ {
char *end; const char *end;
size_t len; size_t len;
const char *allow = "cpqs01234567"; const char *allow = "cpqs01234567";
u_int i, j = 0; u_int i, j = 0;

View File

@@ -409,8 +409,10 @@ key_bindings_init(void)
"bind -N 'Choose a window from a list' w { choose-tree -Zw }", "bind -N 'Choose a window from a list' w { choose-tree -Zw }",
"bind -N 'Kill the active pane' x { confirm-before -p\"kill-pane #P? (y/n)\" kill-pane }", "bind -N 'Kill the active pane' x { confirm-before -p\"kill-pane #P? (y/n)\" kill-pane }",
"bind -N 'Zoom the active pane' z { resize-pane -Z }", "bind -N 'Zoom the active pane' z { resize-pane -Z }",
"bind -N 'Swap the active pane with the pane above' '{' { swap-pane -U }", "bind -N 'Move pane to top-left corner' '{' { resize-pane -x50% -y50%; move-pane -P top-left }",
"bind -N 'Swap the active pane with the pane below' '}' { swap-pane -D }", "bind -N 'Move pane to top-right corner' '}' { resize-pane -x50% -y50%; move-pane -P top-right }",
"bind -N 'Move pane to bottom-left corner' 'M-{' { resize-pane -x50% -y50%; move-pane -P bottom-left }",
"bind -N 'Move pane to bottom-right corner' 'M-}' { resize-pane -x50% -y50%; move-pane -P bottom-right }",
"bind -N 'Show messages' '~' { show-messages }", "bind -N 'Show messages' '~' { show-messages }",
"bind -N 'Enter copy mode and scroll up' PPage { copy-mode -u }", "bind -N 'Enter copy mode and scroll up' PPage { copy-mode -u }",
"bind -N 'Select the pane above the active pane' -r Up { select-pane -U }", "bind -N 'Select the pane above the active pane' -r Up { select-pane -U }",
@@ -432,13 +434,13 @@ key_bindings_init(void)
"bind -N 'Move the visible part of the window left' -r S-Left { refresh-client -L 10 }", "bind -N 'Move the visible part of the window left' -r S-Left { refresh-client -L 10 }",
"bind -N 'Move the visible part of the window right' -r S-Right { refresh-client -R 10 }", "bind -N 'Move the visible part of the window right' -r S-Right { refresh-client -R 10 }",
"bind -N 'Reset so the visible part of the window follows the cursor' -r DC { refresh-client -c }", "bind -N 'Reset so the visible part of the window follows the cursor' -r DC { refresh-client -c }",
"bind -N 'Resize the pane up by 5' -r M-Up { resize-pane -U 5 }", "bind -N 'Resize the pane up by 5' -r M-Up if -F '#{?floating_pane_flag}' { resizep -D-5 } { resize-pane -U 5 }",
"bind -N 'Resize the pane down by 5' -r M-Down { resize-pane -D 5 }", "bind -N 'Resize the pane down by 5' -r M-Down { resize-pane -D 5 }",
"bind -N 'Resize the pane left by 5' -r M-Left { resize-pane -L 5 }", "bind -N 'Resize the pane left by 5' -r M-Left if -F '#{?floating_pane_flag}' { resizep -R-5 } { resize-pane -L 5 }",
"bind -N 'Resize the pane right by 5' -r M-Right { resize-pane -R 5 }", "bind -N 'Resize the pane right by 5' -r M-Right resize-pane -R 5",
"bind -N 'Resize the pane up' -r C-Up { resize-pane -U }", "bind -N 'Resize the pane up' -r C-Up if -F '#{?floating_pane_flag}' { resizep -D-1 } { resize-pane -U }",
"bind -N 'Resize the pane down' -r C-Down { resize-pane -D }", "bind -N 'Resize the pane down' -r C-Down { resize-pane -D }",
"bind -N 'Resize the pane left' -r C-Left { resize-pane -L }", "bind -N 'Resize the pane left' -r C-Left if -F '#{?floating_pane_flag}' { resizep -R-1 } { resize-pane -L }",
"bind -N 'Resize the pane right' -r C-Right { resize-pane -R }", "bind -N 'Resize the pane right' -r C-Right { resize-pane -R }",
/* Menu keys */ /* Menu keys */

View File

@@ -379,6 +379,8 @@ layout_construct(struct layout_cell *lcparent, const char **layout,
struct layout_cell *lcchild; struct layout_cell *lcchild;
*lc = layout_construct_cell(lcparent, layout); *lc = layout_construct_cell(lcparent, layout);
if (*lc == NULL)
return (-1);
switch (**layout) { switch (**layout) {
case ',': case ',':

View File

@@ -319,7 +319,7 @@ layout_cell_is_first_tiled(struct layout_cell *lc)
static int static int
layout_cell_is_top(struct window *w, struct layout_cell *lc) layout_cell_is_top(struct window *w, struct layout_cell *lc)
{ {
struct layout_cell *next; struct layout_cell *next, *edge;
while (lc != w->layout_root) { while (lc != w->layout_root) {
next = lc->parent; next = lc->parent;
@@ -337,15 +337,22 @@ layout_cell_is_top(struct window *w, struct layout_cell *lc)
static int static int
layout_cell_is_bottom(struct window *w, struct layout_cell *lc) layout_cell_is_bottom(struct window *w, struct layout_cell *lc)
{ {
struct layout_cell *next; struct layout_cell *next, *edge;
while (lc != w->layout_root) { while (lc != w->layout_root) {
next = lc->parent; next = lc->parent;
if (next == NULL) if (next == NULL)
return (0); return (0);
if (next->type == LAYOUT_TOPBOTTOM && if (next->type == LAYOUT_TOPBOTTOM) {
lc != TAILQ_LAST(&next->cells, layout_cells)) edge = TAILQ_LAST(&next->cells, layout_cells);
return (0); while (edge != NULL) {
if (~edge->flags & LAYOUT_CELL_FLOATING)
break;
edge = TAILQ_PREV(edge, layout_cells, entry);
}
if (lc != edge)
return (0);
}
lc = next; lc = next;
} }
return (1); return (1);
@@ -375,7 +382,7 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
int status, scrollbars, sb_pos, sb_w, sb_pad; int status, scrollbars, sb_pos, sb_w, sb_pad;
u_int sx, sy; u_int sx, sy;
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
scrollbars = options_get_number(w->options, "pane-scrollbars"); scrollbars = options_get_number(w->options, "pane-scrollbars");
sb_pos = options_get_number(w->options, "pane-scrollbars-position"); sb_pos = options_get_number(w->options, "pane-scrollbars-position");
@@ -453,7 +460,7 @@ layout_resize_check(struct window *w, struct layout_cell *lc,
u_int available, minimum; u_int available, minimum;
int status, scrollbars; int status, scrollbars;
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
scrollbars = options_get_number(w->options, "pane-scrollbars"); scrollbars = options_get_number(w->options, "pane-scrollbars");
if (lc->type == LAYOUT_WINDOWPANE) { if (lc->type == LAYOUT_WINDOWPANE) {
@@ -892,6 +899,8 @@ layout_resize_floating_pane_to(struct window_pane *wp, enum layout_type type,
return; return;
} }
if (size >= PANE_MINIMUM + 2)
size -= 2;
if (size < PANE_MINIMUM || size > PANE_MAXIMUM) { if (size < PANE_MINIMUM || size > PANE_MAXIMUM) {
*cause = xstrdup("size is too big or too small"); *cause = xstrdup("size is too big or too small");
return; return;
@@ -937,6 +946,7 @@ layout_resize_floating_pane(struct window_pane *wp, enum layout_type type,
} }
} }
/* Resize a layout cell. */
void void
layout_resize_layout(struct window *w, struct layout_cell *lc, layout_resize_layout(struct window *w, struct layout_cell *lc,
enum layout_type type, int change, int opposite) enum layout_type type, int change, int opposite)
@@ -982,8 +992,11 @@ layout_resize_pane(struct window_pane *wp, enum layout_type type, int change,
return; return;
/* If this is the last cell, move back one. */ /* If this is the last cell, move back one. */
if (lc == TAILQ_LAST(&lcparent->cells, layout_cells)) if (lc == TAILQ_LAST(&lcparent->cells, layout_cells)) {
lc = TAILQ_PREV(lc, layout_cells, entry); do
lc = TAILQ_PREV(lc, layout_cells, entry);
while (lc->flags & LAYOUT_CELL_FLOATING);
}
layout_resize_layout(wp->window, lc, type, change, opposite); layout_resize_layout(wp->window, lc, type, change, opposite);
} }
@@ -1248,7 +1261,7 @@ 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 = options_get_number(wp->window->options, "pane-border-status"); status = window_get_pane_status(wp->window);
scrollbars = options_get_number(wp->window->options, "pane-scrollbars"); scrollbars = options_get_number(wp->window->options, "pane-scrollbars");
/* Copy the old cell size. */ /* Copy the old cell size. */
@@ -1475,7 +1488,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
number++; number++;
if (number <= 1) if (number <= 1)
return (0); return (0);
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
if (parent->type == LAYOUT_LEFTRIGHT) if (parent->type == LAYOUT_LEFTRIGHT)
size = parent->sx; size = parent->sx;
@@ -1614,30 +1627,43 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
struct layout_cell *lcnew; struct layout_cell *lcnew;
u_int sx = w->sx / 2, sy = w->sy / 4; u_int sx = w->sx / 2, sy = w->sy / 4;
int ox = INT_MAX, oy = INT_MAX; int ox = INT_MAX, oy = INT_MAX;
char *error;
if (args_has(args, 'x')) { if (args_has(args, 'x')) {
sx = args_percentage_and_expand(args, 'x', 0, w->sx - 1, w->sx, sx = args_percentage_and_expand(args, 'x', 0, w->sx - 1, w->sx,
item, cause); item, &error);
if (*cause != NULL) if (error != NULL) {
xasprintf(cause, "position %s", error);
free(error);
return (NULL); return (NULL);
}
} }
if (args_has(args, 'y')) { if (args_has(args, 'y')) {
sy = args_percentage_and_expand(args, 'y', 0, w->sy - 1, w->sy, sy = args_percentage_and_expand(args, 'y', 0, w->sy - 1, w->sy,
item, cause); item, &error);
if (*cause != NULL) if (error != NULL) {
xasprintf(cause, "position %s", error);
free(error);
return (NULL); return (NULL);
}
} }
if (args_has(args, 'X')) { if (args_has(args, 'X')) {
ox = args_percentage_and_expand(args, 'X', -sx, w->sx, ox = args_percentage_and_expand(args, 'X', -sx, w->sx,
w->sx, item, cause); w->sx, item, &error);
if (*cause != NULL) if (error != NULL) {
xasprintf(cause, "size %s", error);
free(error);
return (NULL); return (NULL);
}
} }
if (args_has(args, 'Y')) { if (args_has(args, 'Y')) {
oy = args_percentage_and_expand(args, 'Y', -sy, w->sy, oy = args_percentage_and_expand(args, 'Y', -sy, w->sy,
w->sy, item, cause); w->sy, item, &error);
if (*cause != NULL) if (error != NULL) {
xasprintf(cause, "size %s", error);
free(error);
return (NULL); return (NULL);
}
} }
if (ox == INT_MAX) { if (ox == INT_MAX) {

View File

@@ -49,6 +49,7 @@ struct mode_tree_data {
const struct menu_item *menu; const struct menu_item *menu;
struct sort_criteria sort_crit; struct sort_criteria sort_crit;
const char *view_name;
mode_tree_build_cb buildcb; mode_tree_build_cb buildcb;
mode_tree_draw_cb drawcb; mode_tree_draw_cb drawcb;
@@ -700,6 +701,12 @@ mode_tree_add(struct mode_tree_data *mtd, struct mode_tree_item *parent,
return (mti); return (mti);
} }
void
mode_tree_view_name(struct mode_tree_data *mtd, const char *name)
{
mtd->view_name = name;
}
void void
mode_tree_draw_as_parent(struct mode_tree_item *mti) mode_tree_draw_as_parent(struct mode_tree_item *mti)
{ {
@@ -884,9 +891,12 @@ mode_tree_draw(struct mode_tree_data *mtd)
screen_write_box(&ctx, w, sy - h, BOX_LINES_DEFAULT, NULL, NULL); screen_write_box(&ctx, w, sy - h, BOX_LINES_DEFAULT, NULL, NULL);
if (mtd->sort_crit.order_seq != NULL) { if (mtd->sort_crit.order_seq != NULL) {
xasprintf(&text, " %s (sort: %s%s)", mti->name, xasprintf(&text, " %s (sort: %s%s)%s%s%s", mti->name,
sort_order_to_string(mtd->sort_crit.order), sort_order_to_string(mtd->sort_crit.order),
mtd->sort_crit.reversed ? ", reversed" : ""); mtd->sort_crit.reversed ? ", reversed" : "",
mtd->view_name == NULL ? "" : " (view: ",
mtd->view_name == NULL ? "" : mtd->view_name,
mtd->view_name == NULL ? "" : ")");
} else } else
xasprintf(&text, " %s", mti->name); xasprintf(&text, " %s", mti->name);
if (w - 2 >= strlen(text)) { if (w - 2 >= strlen(text)) {

View File

@@ -211,7 +211,7 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
} }
/* Top/bottom borders. */ /* Top/bottom borders. */
if (vsplit && pane_status == PANE_STATUS_OFF && sb_w == 0) { if (vsplit && pane_status == PANE_STATUS_OFF) {
if (wp->yoff == 0 && py == sy && px <= sx / 2) if (wp->yoff == 0 && py == sy && px <= sx / 2)
return (SCREEN_REDRAW_BORDER_BOTTOM); return (SCREEN_REDRAW_BORDER_BOTTOM);
if (wp->yoff != 0 && py == wp->yoff - 1 && px > sx / 2) if (wp->yoff != 0 && py == wp->yoff - 1 && px > sx / 2)
@@ -220,9 +220,10 @@ screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
if (sb_pos == PANE_SCROLLBARS_LEFT) { if (sb_pos == PANE_SCROLLBARS_LEFT) {
if ((wp->xoff - sb_w == 0 || px >= wp->xoff - sb_w) && if ((wp->xoff - sb_w == 0 || px >= wp->xoff - sb_w) &&
(px <= ex || (sb_w != 0 && px < ex + sb_w))) { (px <= ex || (sb_w != 0 && px < ex + sb_w))) {
if (wp->yoff != 0 && py == wp->yoff - 1) if (pane_status != PANE_STATUS_BOTTOM &&
wp->yoff != 0 && py == wp->yoff - 1)
return (SCREEN_REDRAW_BORDER_TOP); return (SCREEN_REDRAW_BORDER_TOP);
if (py == ey) if (pane_status != PANE_STATUS_TOP && py == ey)
return (SCREEN_REDRAW_BORDER_BOTTOM); return (SCREEN_REDRAW_BORDER_BOTTOM);
} }
} else { /* sb_pos == PANE_SCROLLBARS_RIGHT */ } else { /* sb_pos == PANE_SCROLLBARS_RIGHT */
@@ -619,7 +620,7 @@ screen_redraw_make_pane_status(struct client *c, struct window_pane *wp,
width = 0; width = 0;
else else
width = wp->sx + sb_w - 2; width = wp->sx + sb_w - 2;
max_width = (int)w->sx - (wp->xoff + 2) - sb_w; max_width = (int)w->sx - (wp->xoff + 2);
if (max_width < 0) if (max_width < 0)
max_width = 0; max_width = 0;
if (width > (u_int)max_width) if (width > (u_int)max_width)
@@ -703,7 +704,7 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
width = size; width = size;
} else if (xoff < ctx->ox && xoff + size > ctx->ox + ctx->sx) { } else if (xoff < ctx->ox && xoff + size > ctx->ox + ctx->sx) {
/* Both left and right not visible. */ /* Both left and right not visible. */
l = ctx->ox; l = ctx->ox - xoff;
x = 0; x = 0;
width = ctx->sx; width = ctx->sx;
} else if (xoff < ctx->ox) { } else if (xoff < ctx->ox) {
@@ -776,7 +777,6 @@ screen_redraw_set_context(struct client *c, struct screen_redraw_ctx *ctx)
struct session *s = c->session; struct session *s = c->session;
struct options *oo = s->options; struct options *oo = s->options;
struct window *w = s->curw->window; struct window *w = s->curw->window;
struct options *wo = w->options;
u_int lines; u_int lines;
memset(ctx, 0, sizeof *ctx); memset(ctx, 0, sizeof *ctx);
@@ -789,11 +789,12 @@ screen_redraw_set_context(struct client *c, struct screen_redraw_ctx *ctx)
ctx->statustop = 1; ctx->statustop = 1;
ctx->statuslines = lines; ctx->statuslines = lines;
ctx->pane_status = options_get_number(wo, "pane-border-status"); ctx->pane_status = window_get_pane_status(w);
ctx->pane_lines = options_get_number(wo, "pane-border-lines"); ctx->pane_lines = options_get_number(w->options, "pane-border-lines");
ctx->pane_scrollbars = options_get_number(wo, "pane-scrollbars"); ctx->pane_scrollbars = options_get_number(w->options,
ctx->pane_scrollbars_pos = options_get_number(wo, "pane-scrollbars");
ctx->pane_scrollbars_pos = options_get_number(w->options,
"pane-scrollbars-position"); "pane-scrollbars-position");
tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy); tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy);
@@ -1123,7 +1124,7 @@ screen_redraw_is_visible(struct visible_ranges *r, u_int px)
return (1); return (1);
for (i = 0; i < r->used; i++) { for (i = 0; i < r->used; i++) {
ri = &r->ranges[i]; ri = &r->ranges[i];
if (ri->nx != 0 && px >= ri->px && px <= ri->px + ri->nx) if (ri->nx != 0 && px >= ri->px && px < ri->px + ri->nx)
return (1); return (1);
} }
return (0); return (0);
@@ -1145,11 +1146,13 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
u_int lb, rb, tb, bb; u_int lb, rb, tb, bb;
u_int i, s; u_int i, s;
if (px + width <= 0 || py < 0) if (py < 0 || width == 0)
goto empty; goto empty;
if (px < 0) { if (px < 0) {
if ((u_int)-px >= width)
goto empty;
width -= (u_int)-px;
px = 0; px = 0;
width += px;
} }
if (base_wp == NULL) { if (base_wp == NULL) {
@@ -1196,7 +1199,8 @@ screen_redraw_get_visible_ranges(struct window_pane *base_wp, int px,
(u_int)py < tb || (u_int)py < tb ||
(u_int)py > bb) (u_int)py > bb)
continue; continue;
if (!window_pane_is_floating(wp) && (u_int)py == bb) if (!window_pane_is_floating(wp) &&
((u_int)py == tb || (u_int)py == bb))
continue; continue;
sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad; sb_w = wp->scrollbar_style.width + wp->scrollbar_style.pad;

View File

@@ -603,15 +603,14 @@ server_client_check_mouse_in_pane(struct window_pane *wp, int px, int py,
u_int *sl_mpos) u_int *sl_mpos)
{ {
struct window *w = wp->window; struct window *w = wp->window;
struct options *wo = w->options;
struct window_pane *fwp; struct window_pane *fwp;
int pane_status, sb, sb_pos, sb_w, sb_pad; int pane_status, sb, sb_pos, sb_w, sb_pad;
int pane_status_line, sl_top, sl_bottom; int pane_status_line, sl_top, sl_bottom;
int bdr_bottom, bdr_top, bdr_left, bdr_right; int bdr_bottom, bdr_top, bdr_left, bdr_right;
sb = options_get_number(wo, "pane-scrollbars"); sb = options_get_number(w->options, "pane-scrollbars");
sb_pos = options_get_number(wo, "pane-scrollbars-position"); sb_pos = options_get_number(w->options, "pane-scrollbars-position");
pane_status = options_get_number(wo, "pane-border-status"); pane_status = window_get_pane_status(w);
if (window_pane_show_scrollbar(wp, sb)) { if (window_pane_show_scrollbar(wp, sb)) {
sb_w = wp->scrollbar_style.width; sb_w = wp->scrollbar_style.width;
@@ -915,8 +914,7 @@ have_event:
log_debug("mouse %u,%u on pane %%%u", x, y, log_debug("mouse %u,%u on pane %%%u", x, y,
wp->id); wp->id);
} else if (loc == KEYC_MOUSE_LOCATION_BORDER) { } else if (loc == KEYC_MOUSE_LOCATION_BORDER) {
sr = window_pane_border_status_get_range(wp, px, sr = window_pane_status_get_range(wp, px, py);
py);
if (sr != NULL) { if (sr != NULL) {
n = sr->argument; n = sr->argument;
loc = KEYC_MOUSE_LOCATION_CONTROL0 + n; loc = KEYC_MOUSE_LOCATION_CONTROL0 + n;

113
tmux.1
View File

@@ -2324,6 +2324,11 @@ that line.
(emacs: C\-Down) (emacs: C\-Down)
.Xc .Xc
Scroll down. Scroll down.
If
.Ic mode\-keys
is
.Ic vi ,
the cursor is fixed relative to the text.
.It Xo .It Xo
.Ic scroll\-down\-and\-cancel .Ic scroll\-down\-and\-cancel
.Xc .Xc
@@ -2365,6 +2370,11 @@ that line.
(emacs: C\-Up) (emacs: C\-Up)
.Xc .Xc
Scroll up. Scroll up.
If
.Ic mode\-keys
is
.Ic vi ,
the cursor is fixed relative to the text.
.It Xo .It Xo
.Ic search\-again .Ic search\-again
(vi: n) (vi: n)
@@ -2868,7 +2878,7 @@ The
command works only if at least one client is attached. command works only if at least one client is attached.
.It Xo .It Xo
.Ic choose\-tree .Ic choose\-tree
.Op Fl GhkNrswyZ .Op Fl GhikNrswyZ
.Op Fl F Ar format .Op Fl F Ar format
.Op Fl f Ar filter .Op Fl f Ar filter
.Op Fl K Ar key\-format .Op Fl K Ar key\-format
@@ -2920,6 +2930,7 @@ The following keys may be used in tree mode:
.It Li "O" Ta "Change sort order" .It Li "O" Ta "Change sort order"
.It Li "r" Ta "Reverse sort order" .It Li "r" Ta "Reverse sort order"
.It Li "v" Ta "Toggle preview" .It Li "v" Ta "Toggle preview"
.It Li "i" Ta "Change view (preview and client information)"
.It Li "F1 or C\-h" Ta "Display help" .It Li "F1 or C\-h" Ta "Display help"
.It Li "q" Ta "Exit mode" .It Li "q" Ta "Exit mode"
.El .El
@@ -2959,6 +2970,8 @@ first.
.Pp .Pp
.Fl N .Fl N
starts without the preview or if given twice with the larger preview. starts without the preview or if given twice with the larger preview.
.Fl i
starts showing client information instead of the preview.
.Fl h .Fl h
hides the pane containing the mode. hides the pane containing the mode.
.Fl k .Fl k
@@ -3357,13 +3370,77 @@ The pane must not already be hidden.
.Tg movep .Tg movep
.It Xo Ic move\-pane .It Xo Ic move\-pane
.Op Fl bdfhv .Op Fl bdfhv
.Op Fl D Op Ar lines
.Op Fl l Ar size .Op Fl l Ar size
.Op Fl L Op Ar columns
.Op Fl P Ar position
.Op Fl R Op Ar columns
.Op Fl s Ar src\-pane .Op Fl s Ar src\-pane
.Op Fl t Ar dst\-pane .Op Fl t Ar dst\-pane
.Op Fl U Op Ar lines
.Op Fl X Ar x\-position
.Op Fl Y Ar y\-position
.Op Fl z Ar z\-index
.Xc .Xc
.D1 Pq alias: Ic movep .D1 Pq alias: Ic movep
Does the same as Does the same as
.Ic join\-pane . .Ic join\-pane ,
except if given
.Fl D ,
.Fl L ,
.Fl P ,
.Fl R ,
.Fl U ,
.Fl X ,
.Fl Y
or
.Fl z
in which case move the target floating pane.
.Fl D ,
.Fl L ,
.Fl R
and
.Fl U
move it down, left, right or up by
.Ar lines
or
.Ar columns
(one if omitted).
.Fl P
moves it to
.Ar position ,
which may be one of:
.Bl -column "XXXXXXXXXXXXXXXXXX" "X"
.It Sy "Position" Ta Sy "Meaning"
.It Li "top-left" Ta "Top left"
.It Li "top-centre" Ta "Top and horizontal centre"
.It Li "top-right" Ta "Top right"
.It Li "centre-left" Ta "Vertical centre and left"
.It Li "centre" Ta "Centre"
.It Li "centre-right" Ta "Vertical centre and right"
.It Li "bottom-left" Ta "Bottom left"
.It Li "bottom-centre" Ta "Bottom and horizontal centre"
.It Li "bottom-right" Ta "Bottom right"
.It Li "top-left-centre" Ta "Centre of top-left quadrant"
.It Li "top-right-centre" Ta "Centre of top-right quadrant"
.It Li "bottom-left-centre" Ta "Centre of bottom-left quadrant"
.It Li "bottom-right-centre" Ta "Centre of botton-right quadrant"
.It Li "front" Ta "Front of floating panes"
.It Li "back" Ta "Back of floating panes"
.It Li "forward" Ta "Forward one floating pane"
.It Li "backward" Ta "Backward one floating pane"
.It Li "forward-loop" Ta "Forward but back if already at front"
.It Li "backward-loop" Ta "Backward but front if already at back"
.El
.Pp
.Fl X
and
.Fl Y
move it to an absolute position.
.Fl z
moves the pane to the given
.Ar z-index ,
where zero is the front.
.Tg movew .Tg movew
.It Xo Ic move\-window .It Xo Ic move\-window
.Op Fl abrdk .Op Fl abrdk
@@ -3665,13 +3742,13 @@ if specified, to
.Tg resizep .Tg resizep
.It Xo Ic resize\-pane .It Xo Ic resize\-pane
.Op Fl MTZ .Op Fl MTZ
.Op Fl t Ar target\-pane
.Op Fl U Ar lines
.Op Fl D Ar lines .Op Fl D Ar lines
.Op Fl L Ar columns .Op Fl L Ar columns
.Op Fl R Ar columns .Op Fl R Ar columns
.Op Fl U Ar lines
.Op Fl x Ar width .Op Fl x Ar width
.Op Fl y Ar height .Op Fl y Ar height
.Op Fl t Ar target\-pane
.Xc .Xc
.D1 Pq alias: Ic resizep .D1 Pq alias: Ic resizep
Resize a pane, up, down, left or right by a specified adjustment with Resize a pane, up, down, left or right by a specified adjustment with
@@ -3679,10 +3756,8 @@ Resize a pane, up, down, left or right by a specified adjustment with
.Fl D , .Fl D ,
.Fl L .Fl L
or or
.Fl R , .Fl R ;
or or to an absolute size with
to an absolute size
with
.Fl x .Fl x
or or
.Fl y . .Fl y .
@@ -6527,9 +6602,9 @@ will use shorter but less accurate time format for times in the past.
.Ql r .Ql r
.Pq Ql t/r .Pq Ql t/r
will show the time relative to the current time, for example will show the time relative to the current time, for example
.Ql \-1m .Ql \1m
or or
.Ql +2m23s . .Ql 2m23s .
A custom format may be given using an A custom format may be given using an
.Ql f .Ql f
suffix (note that suffix (note that
@@ -6546,6 +6621,24 @@ see
.Xr strftime 3 . .Xr strftime 3 .
.Pp .Pp
The The
.Ql I:\&
prefix will interrogate the client.
.Ql I/f
will be true if
.Nm
believes that the client supports the given terminal feature, for example
.Ql I/f:RGB ,
.Ql I/c
will be true if a client has the given
.Xr terminfo 3
capability, for example
.Ql I/c:smcup ,
and
.Ql I/e
gives the value of a client environment variable, for example
.Ql #{I/e:FOO} .
.Pp
The
.Ql b:\& .Ql b:\&
and and
.Ql d:\& .Ql d:\&

10
tmux.h
View File

@@ -2784,6 +2784,7 @@ int tty_term_read_list(const char *, int, char ***, u_int *,
char **); char **);
void tty_term_free_list(char **, u_int); void tty_term_free_list(char **, u_int);
int tty_term_has(struct tty_term *, enum tty_code_code); int tty_term_has(struct tty_term *, enum tty_code_code);
int tty_term_has_name(struct tty_term *, const char *);
const char *tty_term_string(struct tty_term *, enum tty_code_code); const char *tty_term_string(struct tty_term *, enum tty_code_code);
const char *tty_term_string_i(struct tty_term *, enum tty_code_code, int); const char *tty_term_string_i(struct tty_term *, enum tty_code_code, int);
const char *tty_term_string_ii(struct tty_term *, enum tty_code_code, int, const char *tty_term_string_ii(struct tty_term *, enum tty_code_code, int,
@@ -2801,6 +2802,7 @@ const char *tty_term_describe(struct tty_term *, enum tty_code_code);
/* tty-features.c */ /* tty-features.c */
void tty_add_features(int *, const char *, const char *); void tty_add_features(int *, const char *, const char *);
const char *tty_get_features(int); const char *tty_get_features(int);
int tty_feature_present(struct tty_term *, const char *);
int tty_apply_features(struct tty_term *, int); int tty_apply_features(struct tty_term *, int);
void tty_default_features(int *, const char *, u_int); void tty_default_features(int *, const char *, u_int);
@@ -3529,8 +3531,9 @@ int window_pane_get_bg_control_client(struct window_pane *);
int window_get_bg_client(struct window_pane *); int window_get_bg_client(struct window_pane *);
enum client_theme window_pane_get_theme(struct window_pane *); enum client_theme window_pane_get_theme(struct window_pane *);
void window_pane_send_theme_update(struct window_pane *); void window_pane_send_theme_update(struct window_pane *);
struct style_range *window_pane_border_status_get_range(struct window_pane *, int window_get_pane_status(struct window *);
u_int, u_int); struct style_range *window_pane_status_get_range(struct window_pane *, u_int,
u_int);
int window_pane_is_floating(struct window_pane *); int window_pane_is_floating(struct window_pane *);
/* layout.c */ /* layout.c */
@@ -3628,6 +3631,7 @@ void mode_tree_resize(struct mode_tree_data *, u_int, u_int);
struct mode_tree_item *mode_tree_add(struct mode_tree_data *, struct mode_tree_item *mode_tree_add(struct mode_tree_data *,
struct mode_tree_item *, void *, uint64_t, const char *, struct mode_tree_item *, void *, uint64_t, const char *,
const char *, int); const char *, int);
void mode_tree_view_name(struct mode_tree_data *, const char *);
void mode_tree_draw_as_parent(struct mode_tree_item *); void mode_tree_draw_as_parent(struct mode_tree_item *);
void mode_tree_no_tag(struct mode_tree_item *); void mode_tree_no_tag(struct mode_tree_item *);
void mode_tree_align(struct mode_tree_item *, int); void mode_tree_align(struct mode_tree_item *, int);
@@ -3669,7 +3673,7 @@ int window_copy_get_current_offset(struct window_pane *, u_int *,
char *window_copy_get_hyperlink(struct window_pane *, u_int, u_int); char *window_copy_get_hyperlink(struct window_pane *, u_int, u_int);
void window_copy_set_line_numbers(struct window_pane *, int); void window_copy_set_line_numbers(struct window_pane *, int);
/* window-option.c */ /* window-customize.c */
extern const struct window_mode window_customize_mode; extern const struct window_mode window_customize_mode;
/* names.c */ /* names.c */

View File

@@ -442,6 +442,45 @@ tty_get_features(int feat)
return (s); return (s);
} }
int
tty_feature_present(struct tty_term *term, const char *name)
{
const struct tty_feature *tf = NULL;
const char *const *capability;
u_int i;
char *copy;
for (i = 0; i < nitems(tty_features); i++) {
tf = tty_features[i];
if (strcmp(tf->name, name) == 0) {
if (term->features & (1 << i))
return (1);
break;
}
}
/*
* We don't just have the feature flag set. Check if the capabilities
* supported by the client are actual set instead.
*/
if (tf == NULL || strcmp(name, "ignorefkeys") == 0)
return (0);
if (tf->flags != 0 && (term->flags & tf->flags) != tf->flags)
return (0);
capability = tf->capabilities;
while (*capability != NULL) {
copy = xstrdup(*capability);
copy[strcspn(copy, "=")] = '\0';
if (!tty_term_has_name(term, copy)) {
free(copy);
return (0);
}
free(copy);
capability++;
}
return (1);
}
int int
tty_apply_features(struct tty_term *term, int feat) tty_apply_features(struct tty_term *term, int feat)
{ {

View File

@@ -776,6 +776,18 @@ tty_term_has(struct tty_term *term, enum tty_code_code code)
return (term->codes[code].type != TTYCODE_NONE); return (term->codes[code].type != TTYCODE_NONE);
} }
int
tty_term_has_name(struct tty_term *term, const char *name)
{
u_int i;
for (i = 0; i < tty_term_ncodes(); i++) {
if (strcmp(tty_term_codes[i].name, name) == 0)
return (tty_term_has(term, i));
}
return (0);
}
const char * const char *
tty_term_string(struct tty_term *term, enum tty_code_code code) tty_term_string(struct tty_term *term, enum tty_code_code code)
{ {

View File

@@ -47,6 +47,93 @@ static void window_client_key(struct window_mode_entry *,
"M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \ "M-#{a:#{e|+:97,#{e|-:#{line},10}}}" \
"}" "}"
#define WINDOW_CLIENT_FEATURE(f) \
"#{?#{I/f:" #f "}," \
"#[fg=green],#[dim]}#{p/15:#{l:" #f "}}" \
"#[default]"
static const char *window_client_info_lines[] = {
"Client Name #[acs]x#[default] "
"#{client_name} "
"#[dim](PID #{client_pid})#[default]",
"Session #[acs]x#[default] "
"#{session_name}",
"Attach Time #[acs]x#[default] "
"#{t:client_created} "
"#[dim](#{t/r:client_created})#[default]",
"Activity Time #[acs]x#[default] "
"#{t:client_activity} "
"#[dim](#{t/r:client_activity})#[default]",
"Terminal Type #[acs]x#[default] "
"#{?client_termtype,#{client_termtype},Unknown}",
"TERM #[acs]x#[default] "
"#{client_termname}",
"Size #[acs]x#[default] "
"#{client_width}x#{client_height} "
"#[dim](cell #{client_cell_width}x#{client_cell_height})#[default]",
"Bytes Written #[acs]x#[default] "
"#{client_written} "
"#[dim](#{client_discarded} discarded)#[default]",
"Features #[acs]x#[default] "
WINDOW_CLIENT_FEATURE(256) " "
WINDOW_CLIENT_FEATURE(RGB) " "
WINDOW_CLIENT_FEATURE(bpaste) " "
WINDOW_CLIENT_FEATURE(ccolour),
" #[acs]x#[default] "
WINDOW_CLIENT_FEATURE(clipboard) " "
WINDOW_CLIENT_FEATURE(cstyle) " "
WINDOW_CLIENT_FEATURE(extkeys) " "
WINDOW_CLIENT_FEATURE(focus),
" #[acs]x#[default] "
WINDOW_CLIENT_FEATURE(hyperlinks) " "
WINDOW_CLIENT_FEATURE(ignorefkeys) " "
WINDOW_CLIENT_FEATURE(margins) " "
WINDOW_CLIENT_FEATURE(mouse),
" #[acs]x#[default] "
WINDOW_CLIENT_FEATURE(osc7) " "
WINDOW_CLIENT_FEATURE(overline) " "
WINDOW_CLIENT_FEATURE(progressbar) " "
WINDOW_CLIENT_FEATURE(rectfill),
" #[acs]x#[default] "
WINDOW_CLIENT_FEATURE(sixel) " "
WINDOW_CLIENT_FEATURE(strikethrough) " "
WINDOW_CLIENT_FEATURE(sync) " "
WINDOW_CLIENT_FEATURE(title),
" #[acs]x#[default] "
WINDOW_CLIENT_FEATURE(usstyle),
"#[acs]qqqqqqqqqqqqqqn#{R:q,#{window_width}}#[default]",
"prefix #[acs]x#[default] "
"#{prefix}",
"mouse #[acs]x#[default] "
"#{?mouse,#{?#{I/c:kmous},,#[fg=red]}on,#[dim]off} "
"#{?#{I/c:kmous},,#[align=right]unavailable: [kmous] missing}",
"set-clipboard #[acs]x#[default] "
"#{?#{!=:#{set-clipboard},off},#{?#{I/f:clipboard},,#[fg=red]}#{set-clipboard},#[dim]off} "
"#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}",
"get-clipboard #[acs]x#[default] "
"#{?#{!=:#{get-clipboard},off},#{?#{I/f:clipboard},,#[fg=red]}#{get-clipboard},#[dim]off} "
"#{?#{I/f:clipboard},,#[align=right]unavailable: [Ms] missing}",
"focus-events #[acs]x#[default] "
"#{?focus-events,#{?#{I/f:focus},,#[fg=red]}on,#[dim]off} "
"#{?#{I/f:focus},,#[align=right]unavailable: [Enfcs] or [Dcfcs] missing}",
"extended-keys #[acs]x#[default] "
"#{?#{!=:#{extended-keys},off},#{?#{I/f:extkeys},,#[fg=red]}#{extended-keys},#[dim]off} "
"#{?#{I/f:extkeys},,#[align=right]unavailable: [Eneks] or [Dseks] missing}",
"set-titles #[acs]x#[default] "
"#{?set-titles,on,#[dim]off}",
"escape-time #[acs]x#[default] "
"#{escape-time} ms",
};
static const struct menu_item window_client_menu_items[] = { static const struct menu_item window_client_menu_items[] = {
{ "Detach", 'd', NULL }, { "Detach", 'd', NULL },
{ "Detach Tagged", 'D', NULL }, { "Detach Tagged", 'D', NULL },
@@ -82,7 +169,9 @@ struct window_client_modedata {
char *format; char *format;
char *key_format; char *key_format;
char *command; char *command;
int hide_preview_this_pane; int hide_preview_this_pane;
int preview_is_info;
struct window_client_itemdata **item_list; struct window_client_itemdata **item_list;
u_int item_size; u_int item_size;
@@ -162,6 +251,32 @@ window_client_build(void *modedata, struct sort_criteria *sort_crit,
} }
} }
static void
window_client_draw_info(__unused void *modedata, void *itemdata,
struct screen_write_ctx *ctx, u_int sx, u_int sy)
{
struct window_client_itemdata *item = itemdata;
struct client *c = item->c;
struct screen *s = ctx->s;
u_int cx = s->cx, cy = s->cy, i;
struct format_tree *ft;
char *expanded;
ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
screen_write_cursormove(ctx, cx, cy, 0);
for (i = 0; i < nitems(window_client_info_lines); i++) {
if (i == sy)
break;
expanded = format_expand(ft, window_client_info_lines[i]);
screen_write_cursormove(ctx, cx, cy + i, 0);
format_draw(ctx, &grid_default_cell, sx, expanded, NULL, 0);
free(expanded);
}
format_free(ft);
}
static void static void
window_client_draw(void *modedata, void *itemdata, window_client_draw(void *modedata, void *itemdata,
struct screen_write_ctx *ctx, u_int sx, u_int sy) struct screen_write_ctx *ctx, u_int sx, u_int sy)
@@ -175,6 +290,10 @@ window_client_draw(void *modedata, void *itemdata,
if (c->session == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS)) if (c->session == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
return; return;
if (data->preview_is_info) {
window_client_draw_info(modedata, itemdata, ctx, sx, sy);
return;
}
wp = c->session->curw->window->active; wp = c->session->curw->window->active;
if (data->hide_preview_this_pane && wp == data->wp) { if (data->hide_preview_this_pane && wp == data->wp) {
if (!TAILQ_EMPTY(&c->session->curw->window->last_panes)) if (!TAILQ_EMPTY(&c->session->curw->window->last_panes))
@@ -250,6 +369,7 @@ window_client_sort(struct sort_criteria *sort_crit)
} }
static const char* window_client_help_lines[] = { static const char* window_client_help_lines[] = {
"\r\033[1m i \033[0m\016x\017 \033[0mToggle info view\n",
"\r\033[1m Enter \033[0m\016x\017 \033[0mChoose selected %1\n", "\r\033[1m Enter \033[0m\016x\017 \033[0mChoose selected %1\n",
"\r\033[1m d \033[0m\016x\017 \033[0mDetach selected %1\n", "\r\033[1m d \033[0m\016x\017 \033[0mDetach selected %1\n",
"\r\033[1m D \033[0m\016x\017 \033[0mDetach tagged %1s\n", "\r\033[1m D \033[0m\016x\017 \033[0mDetach tagged %1s\n",
@@ -280,6 +400,7 @@ window_client_init(struct window_mode_entry *wme,
wme->data = data = xcalloc(1, sizeof *data); wme->data = data = xcalloc(1, sizeof *data);
data->wp = wp; data->wp = wp;
data->hide_preview_this_pane = args != NULL && args_has(args, 'h'); data->hide_preview_this_pane = args != NULL && args_has(args, 'h');
data->preview_is_info = args != NULL && args_has(args, 'i');
if (args == NULL || !args_has(args, 'F')) if (args == NULL || !args_has(args, 'F'))
data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT); data->format = xstrdup(WINDOW_CLIENT_DEFAULT_FORMAT);
@@ -300,6 +421,11 @@ window_client_init(struct window_mode_entry *wme,
window_client_help, data, window_client_menu_items, &s); window_client_help, data, window_client_menu_items, &s);
mode_tree_zoom(data->data, args); mode_tree_zoom(data->data, args);
if (data->preview_is_info)
mode_tree_view_name(data->data, "info");
else
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);
@@ -389,6 +515,14 @@ window_client_key(struct window_mode_entry *wme, struct client *c,
mode_tree_each_tagged(mtd, window_client_do_detach, c, key, 0); mode_tree_each_tagged(mtd, window_client_do_detach, c, key, 0);
mode_tree_build(mtd); mode_tree_build(mtd);
break; break;
case 'i':
data->preview_is_info = !data->preview_is_info;
if (data->preview_is_info)
mode_tree_view_name(mtd, "info");
else
mode_tree_view_name(mtd, "preview");
mode_tree_build(mtd);
break;
case '\r': case '\r':
item = mode_tree_get_current(mtd); item = mode_tree_get_current(mtd);
mode_tree_run_command(c, NULL, data->command, item->c->ttyname); mode_tree_run_command(c, NULL, data->command, item->c->ttyname);

View File

@@ -175,7 +175,7 @@ window_clock_init(struct window_mode_entry *wme,
struct window_clock_mode_data *data; struct window_clock_mode_data *data;
struct screen *s; struct screen *s;
wme->data = data = xmalloc(sizeof *data); wme->data = data = xcalloc(1, sizeof *data);
data->tim = time(NULL); data->tim = time(NULL);
evtimer_set(&data->timer, window_clock_timer_callback, wme); evtimer_set(&data->timer, window_clock_timer_callback, wme);

View File

@@ -5102,14 +5102,10 @@ window_copy_set_line_numbers(struct window_pane *wp, int enabled)
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes); struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
struct window_copy_mode_data *data; struct window_copy_mode_data *data;
if (wme == NULL) if (wme == NULL || wme->mode != &window_copy_mode)
return;
if (wme->mode != &window_copy_mode)
return; return;
data = wme->data; data = wme->data;
if (data == NULL) if (data == NULL || data->line_numbers == enabled)
return;
if (data->line_numbers == enabled)
return; return;
data->line_numbers = enabled; data->line_numbers = enabled;
window_copy_redraw_screen(wme); window_copy_redraw_screen(wme);
@@ -6109,6 +6105,7 @@ static void
window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only) window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct options *oo = wme->wp->window->options;
struct screen *s = &data->screen; struct screen *s = &data->screen;
u_int ox, oy, px, py; u_int ox, oy, px, py;
int norectsel; int norectsel;
@@ -6124,6 +6121,11 @@ window_copy_cursor_up(struct window_mode_entry *wme, int scroll_only)
if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely)
window_copy_other_end(wme); window_copy_other_end(wme);
if (scroll_only && options_get_number(oo, "mode-keys") == MODEKEY_VI) {
if (data->cy < screen_size_y(s) - 1)
window_copy_update_cursor(wme, data->cx, data->cy + 1);
}
if (scroll_only || data->cy == 0) { if (scroll_only || data->cy == 0) {
if (norectsel) if (norectsel)
data->cx = data->lastcx; data->cx = data->lastcx;
@@ -6183,6 +6185,7 @@ static void
window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only) window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only)
{ {
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
struct options *oo = wme->wp->window->options;
struct screen *s = &data->screen; struct screen *s = &data->screen;
u_int ox, oy, px, py; u_int ox, oy, px, py;
int norectsel; int norectsel;
@@ -6198,6 +6201,11 @@ window_copy_cursor_down(struct window_mode_entry *wme, int scroll_only)
if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely) if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely)
window_copy_other_end(wme); window_copy_other_end(wme);
if (scroll_only && options_get_number(oo, "mode-keys") == MODEKEY_VI) {
if (data->cy > 0)
window_copy_update_cursor(wme, data->cx, data->cy - 1);
}
if (scroll_only || data->cy == screen_size_y(s) - 1) { if (scroll_only || data->cy == screen_size_y(s) - 1) {
if (norectsel) if (norectsel)
data->cx = data->lastcx; data->cx = data->lastcx;

View File

@@ -648,7 +648,7 @@ window_get_active_at(struct window *w, u_int x, u_int y)
int pane_status, xoff, yoff; int pane_status, xoff, yoff;
u_int sx, sy; u_int sx, sy;
pane_status = options_get_number(w->options, "pane-border-status"); pane_status = window_get_pane_status(w);
if (pane_status == PANE_STATUS_TOP) { if (pane_status == PANE_STATUS_TOP) {
/* /*
@@ -656,10 +656,12 @@ window_get_active_at(struct window *w, u_int x, u_int y)
* bottom border. * bottom border.
*/ */
TAILQ_FOREACH(wp, &w->z_index, zentry) { TAILQ_FOREACH(wp, &w->z_index, zentry) {
if (!window_pane_visible(wp) || window_pane_is_floating(wp)) if (!window_pane_visible(wp) ||
window_pane_is_floating(wp))
continue; continue;
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy); window_pane_full_size_offset(wp, &xoff, &yoff, &sx,
&sy);
if ((int)x < xoff || x > xoff + sx) if ((int)x < xoff || x > xoff + sx)
continue; continue;
if ((int)y == yoff - 1) if ((int)y == yoff - 1)
@@ -706,7 +708,7 @@ window_find_string(struct window *w, const char *s)
x = w->sx / 2; x = w->sx / 2;
y = w->sy / 2; y = w->sy / 2;
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
if (status == PANE_STATUS_TOP) if (status == PANE_STATUS_TOP)
top++; top++;
else if (status == PANE_STATUS_BOTTOM) else if (status == PANE_STATUS_BOTTOM)
@@ -1587,7 +1589,7 @@ window_pane_find_up(struct window_pane *wp)
if (wp == NULL) if (wp == NULL)
return (NULL); return (NULL);
w = wp->window; w = wp->window;
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
list = NULL; list = NULL;
size = 0; size = 0;
@@ -1648,7 +1650,7 @@ window_pane_find_down(struct window_pane *wp)
if (wp == NULL) if (wp == NULL)
return (NULL); return (NULL);
w = wp->window; w = wp->window;
status = options_get_number(w->options, "pane-border-status"); status = window_get_pane_status(w);
list = NULL; list = NULL;
size = 0; size = 0;
@@ -2164,21 +2166,19 @@ window_pane_send_theme_update(struct window_pane *wp)
} }
struct style_range * struct style_range *
window_pane_border_status_get_range(struct window_pane *wp, u_int x, u_int y) window_pane_status_get_range(struct window_pane *wp, u_int x, u_int y)
{ {
struct style_ranges *srs; struct style_ranges *srs;
struct window *w; struct window *w;
struct options *wo;
u_int line; u_int line;
int pane_status; int pane_status;
if (wp == NULL) if (wp == NULL)
return (NULL); return (NULL);
w = wp->window; w = wp->window;
wo = w->options;
srs = &wp->border_status_line.ranges; srs = &wp->border_status_line.ranges;
pane_status = options_get_number(wo, "pane-border-status"); pane_status = window_get_pane_status(w);
if (pane_status == PANE_STATUS_TOP) if (pane_status == PANE_STATUS_TOP)
line = wp->yoff - 1; line = wp->yoff - 1;
else if (pane_status == PANE_STATUS_BOTTOM) else if (pane_status == PANE_STATUS_BOTTOM)
@@ -2193,6 +2193,12 @@ 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)); return (style_ranges_get_range(srs, x - wp->xoff - 2));
} }
int
window_get_pane_status(struct window *w)
{
return (options_get_number(w->options, "pane-border-status"));
}
int int
window_pane_is_floating(struct window_pane *wp) window_pane_is_floating(struct window_pane *wp)
{ {