summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--cmd-attach-session.c2
-rw-r--r--cmd-break-pane.c2
-rw-r--r--cmd-list-sessions.c3
-rw-r--r--cmd-new-session.c60
-rw-r--r--cmd-refresh-client.c78
-rw-r--r--cmd-resize-window.c109
-rw-r--r--cmd-select-pane.c35
-rw-r--r--cmd-set-option.c15
-rw-r--r--cmd-split-window.c2
-rw-r--r--cmd-swap-pane.c2
-rw-r--r--cmd-switch-client.c1
-rw-r--r--cmd.c2
-rw-r--r--format.c43
-rw-r--r--input-keys.c4
-rw-r--r--key-bindings.c5
-rw-r--r--key-string.c2
-rw-r--r--layout-custom.c2
-rw-r--r--layout-set.c8
-rw-r--r--layout.c65
-rw-r--r--options-table.c37
-rw-r--r--resize.c310
-rw-r--r--screen-redraw.c282
-rw-r--r--screen-write.c150
-rw-r--r--server-client.c71
-rw-r--r--server-fn.c1
-rw-r--r--session.c15
-rw-r--r--status.c20
-rw-r--r--tmux.h78
-rw-r--r--tty.c495
-rw-r--r--window.c60
31 files changed, 1372 insertions, 588 deletions
diff --git a/Makefile b/Makefile
index e6d9e6b3..8947cd53 100644
--- a/Makefile
+++ b/Makefile
@@ -44,6 +44,7 @@ SRCS= alerts.c \
cmd-rename-session.c \
cmd-rename-window.c \
cmd-resize-pane.c \
+ cmd-resize-window.c \
cmd-respawn-pane.c \
cmd-respawn-window.c \
cmd-rotate-window.c \
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 0db0d855..73ff530d 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -115,6 +115,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
c->session = s;
if (~item->shared->flags & CMDQ_SHARED_REPEAT)
server_client_set_key_table(c, NULL);
+ tty_update_client_offset(c);
status_timer_start(c);
notify_client("client-session-changed", c);
session_update_activity(s, NULL);
@@ -142,6 +143,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
c->session = s;
server_client_set_key_table(c, NULL);
+ tty_update_client_offset(c);
status_timer_start(c);
notify_client("client-session-changed", c);
session_update_activity(s, NULL);
diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index 74ecce6f..3b929dee 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -76,7 +76,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
window_lost_pane(w, wp);
layout_close_pane(wp);
- w = wp->window = window_create(dst_s->sx, dst_s->sy);
+ w = wp->window = window_create(w->sx, w->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c
index df8a25bc..72ff47e8 100644
--- a/cmd-list-sessions.c
+++ b/cmd-list-sessions.c
@@ -30,8 +30,7 @@
#define LIST_SESSIONS_TEMPLATE \
"#{session_name}: #{session_windows} windows " \
- "(created #{t:session_created}) " \
- "[#{session_width}x#{session_height}]" \
+ "(created #{t:session_created})" \
"#{?session_grouped, (group ,}" \
"#{session_group}#{?session_grouped,),}" \
"#{?session_attached, (attached),}"
diff --git a/cmd-new-session.c b/cmd-new-session.c
index e809de24..162a50bd 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -71,14 +71,15 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
struct session *s, *as, *groupwith;
struct window *w;
struct environ *env;
+ struct options *oo;
struct termios tio, *tiop;
struct session_group *sg;
const char *errstr, *template, *group, *prefix;
- const char *path, *cmd, *tmp;
+ const char *path, *cmd, *tmp, *value;
char **argv, *cause, *cp, *newname, *cwd = NULL;
int detached, already_attached, idx, argc;
int is_control = 0;
- u_int sx, sy;
+ u_int sx, sy, dsx = 80, dsy = 24;
struct environ_entry *envent;
struct cmd_find_state fs;
enum cmd_retval retval;
@@ -189,44 +190,53 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
}
}
- /* Find new session size. */
- if (!detached) {
- sx = c->tty.sx;
- sy = c->tty.sy;
- if (!is_control &&
- sy > 0 &&
- options_get_number(global_s_options, "status"))
- sy--;
- } else {
- sx = 80;
- sy = 24;
- }
- if ((is_control || detached) && args_has(args, 'x')) {
+ /* Get default session size. */
+ if (args_has(args, 'x')) {
tmp = args_get(args, 'x');
if (strcmp(tmp, "-") == 0) {
if (c != NULL)
- sx = c->tty.sx;
+ dsx = c->tty.sx;
} else {
- sx = strtonum(tmp, 1, USHRT_MAX, &errstr);
+ dsx = strtonum(tmp, 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(item, "width %s", errstr);
goto error;
}
}
}
- if ((is_control || detached) && args_has(args, 'y')) {
+ if (args_has(args, 'y')) {
tmp = args_get(args, 'y');
if (strcmp(tmp, "-") == 0) {
if (c != NULL)
- sy = c->tty.sy;
+ dsy = c->tty.sy;
} else {
- sy = strtonum(tmp, 1, USHRT_MAX, &errstr);
+ dsy = strtonum(tmp, 1, USHRT_MAX, &errstr);
if (errstr != NULL) {
cmdq_error(item, "height %s", errstr);
goto error;
}
}
}
+
+ /* Find new session size. */
+ if (!detached && !is_control) {
+ sx = c->tty.sx;
+ sy = c->tty.sy;
+ if (!is_control &&
+ sy > 0 &&
+ options_get_number(global_s_options, "status"))
+ sy--;
+ } else {
+ value = options_get_string(global_s_options, "default-size");
+ if (sscanf(value, "%ux%u", &sx, &sy) != 2) {
+ sx = 80;
+ sy = 24;
+ }
+ if (args_has(args, 'x'))
+ sx = dsx;
+ if (args_has(args, 'y'))
+ sy = dsy;
+ }
if (sx == 0)
sx = 1;
if (sy == 0)
@@ -262,10 +272,15 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (c != NULL && !args_has(args, 'E'))
environ_update(global_s_options, c->environ, env);
+ /* Set up the options. */
+ oo = options_create(global_s_options);
+ if (args_has(args, 'x') || args_has(args, 'y'))
+ options_set_string(oo, "default-size", 0, "%ux%u", dsx, dsy);
+
/* Create the new session. */
idx = -1 - options_get_number(global_s_options, "base-index");
- s = session_create(prefix, newname, argc, argv, path, cwd, env, tiop,
- idx, sx, sy, &cause);
+ s = session_create(prefix, newname, argc, argv, path, cwd, env, oo,
+ tiop, idx, &cause);
environ_free(env);
if (s == NULL) {
cmdq_error(item, "create session failed: %s", cause);
@@ -313,6 +328,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
c->session = s;
if (~item->shared->flags & CMDQ_SHARED_REPEAT)
server_client_set_key_table(c, NULL);
+ tty_update_client_offset(c);
status_timer_start(c);
notify_client("client-session-changed", c);
session_update_activity(s, NULL);
diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c
index 0f45c2d5..e5ae099f 100644
--- a/cmd-refresh-client.c
+++ b/cmd-refresh-client.c
@@ -18,6 +18,8 @@
#include <sys/types.h>
+#include <stdlib.h>
+
#include "tmux.h"
/*
@@ -31,8 +33,8 @@ const struct cmd_entry cmd_refresh_client_entry = {
.name = "refresh-client",
.alias = "refresh",
- .args = { "C:lSt:", 0, 0 },
- .usage = "[-lS] [-C size] " CMD_TARGET_CLIENT_USAGE,
+ .args = { "cC:DlLRSt:U", 0, 1 },
+ .usage = "[-cDlLRSU] [-C size] " CMD_TARGET_CLIENT_USAGE " [adjustment]",
.flags = CMD_AFTERHOOK,
.exec = cmd_refresh_client_exec
@@ -43,11 +45,64 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
struct client *c;
- const char *size;
- u_int w, h;
+ struct tty *tty;
+ struct window *w;
+ const char *size, *errstr;
+ u_int x, y, adjust;
if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL)
return (CMD_RETURN_ERROR);
+ tty = &c->tty;
+
+ if (args_has(args, 'c') ||
+ args_has(args, 'L') ||
+ args_has(args, 'R') ||
+ args_has(args, 'U') ||
+ args_has(args, 'D'))
+ {
+ if (args->argc == 0)
+ adjust = 1;
+ else {
+ adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ cmdq_error(item, "adjustment %s", errstr);
+ return (CMD_RETURN_ERROR);
+ }
+ }
+
+ if (args_has(args, 'c'))
+ c->pan_window = NULL;
+ else {
+ w = c->session->curw->window;
+ if (c->pan_window != w) {
+ c->pan_window = w;
+ c->pan_ox = tty->oox;
+ c->pan_oy = tty->ooy;
+ }
+ if (args_has(args, 'L')) {
+ if (c->pan_ox > adjust)
+ c->pan_ox -= adjust;
+ else
+ c->pan_ox = 0;
+ } else if (args_has(args, 'R')) {
+ c->pan_ox += adjust;
+ if (c->pan_ox > w->sx - tty->osx)
+ c->pan_ox = w->sx - tty->osx;
+ } else if (args_has(args, 'U')) {
+ if (c->pan_oy > adjust)
+ c->pan_oy -= adjust;
+ else
+ c->pan_oy = 0;
+ } else if (args_has(args, 'D')) {
+ c->pan_oy += adjust;
+ if (c->pan_oy > w->sy - tty->osy)
+ c->pan_oy = w->sy - tty->osy;
+ }
+ }
+ tty_update_client_offset(c);
+ server_redraw_client(c);
+ return (CMD_RETURN_NORMAL);
+ }
if (args_has(args, 'l')) {
if (c->session != NULL)
@@ -57,12 +112,13 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
cmdq_error(item, "missing size");
return (CMD_RETURN_ERROR);
}
- if (sscanf(size, "%u,%u", &w, &h) != 2) {
+ if (sscanf(size, "%u,%u", &x, &y) != 2 &&
+ sscanf(size, "%ux%u", &x, &y)) {
cmdq_error(item, "bad size argument");
return (CMD_RETURN_ERROR);
}
- if (w < PANE_MINIMUM || w > 5000 ||
- h < PANE_MINIMUM || h > 5000) {
+ if (x < WINDOW_MINIMUM || x > WINDOW_MAXIMUM ||
+ y < WINDOW_MINIMUM || y > WINDOW_MAXIMUM) {
cmdq_error(item, "size too small or too big");
return (CMD_RETURN_ERROR);
}
@@ -70,16 +126,18 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
cmdq_error(item, "not a control client");
return (CMD_RETURN_ERROR);
}
- tty_set_size(&c->tty, w, h);
+ tty_set_size(&c->tty, x, y);
c->flags |= CLIENT_SIZECHANGED;
recalculate_sizes();
- } else if (args_has(args, 'S')) {
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'S')) {
c->flags |= CLIENT_STATUSFORCE;
server_status_client(c);
} else {
c->flags |= CLIENT_STATUSFORCE;
server_redraw_client(c);
}
-
return (CMD_RETURN_NORMAL);
}
diff --git a/cmd-resize-window.c b/cmd-resize-window.c
new file mode 100644
index 00000000..d780b6ee
--- /dev/null
+++ b/cmd-resize-window.c
@@ -0,0 +1,109 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2018 Nicholas Marriott <nicholas.marriott@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+
+#include "tmux.h"
+
+/*
+ * Increase or decrease window size.
+ */
+
+static enum cmd_retval cmd_resize_window_exec(struct cmd *,
+ struct cmdq_item *);
+
+const struct cmd_entry cmd_resize_window_entry = {
+ .name = "resize-window",
+ .alias = "resizew",
+
+ .args = { "aADLRt:Ux:y:", 0, 1 },
+ .usage = "[-aADLRU] [-x width] [-y height] " CMD_TARGET_WINDOW_USAGE " "
+ "[adjustment]",
+
+ .target = { 't', CMD_FIND_WINDOW, 0 },
+
+ .flags = CMD_AFTERHOOK,
+ .exec = cmd_resize_window_exec
+};
+
+static enum cmd_retval
+cmd_resize_window_exec(struct cmd *self, struct cmdq_item *item)
+{
+ struct args *args = self->args;
+ struct winlink *wl = item->target.wl;
+ struct window *w = wl->window;
+ struct session *s = item->target.s;
+ const char *errstr;
+ char *cause;
+ u_int adjust, sx, sy;
+
+ if (args->argc == 0)
+ adjust = 1;
+ else {
+ adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ cmdq_error(item, "adjustment %s", errstr);
+ return (CMD_RETURN_ERROR);
+ }
+ }
+
+ sx = w->sx;
+ sy = w->sy;
+
+ if (args_has(args, 'x')) {
+ sx = args_strtonum(args, 'x', WINDOW_MINIMUM, WINDOW_MAXIMUM,
+ &cause);
+ if (cause != NULL) {
+ cmdq_error(item, "width %s", cause);
+ free(cause);
+ return (CMD_RETURN_ERROR);
+ }
+ }
+ if (args_has(args, 'y')) {
+ sy = args_strtonum(args, 'y', WINDOW_MINIMUM, WINDOW_MAXIMUM,
+ &cause);
+ if (cause != NULL) {
+ cmdq_error(item, "height %s", cause);
+ free(cause);
+ return (CMD_RETURN_ERROR);
+ }
+ }
+
+ if (args_has(args, 'L')) {
+ if (sx >= adjust)
+ sx -= adjust;
+ } else if (args_has(args, 'R'))
+ sx += adjust;
+ else if (args_has(args, 'U')) {
+ if (sy >= adjust)
+ sy -= adjust;
+ } else if (args_has(args, 'D'))
+ sy += adjust;
+
+ if (args_has(args, 'A'))
+ default_window_size(s, w, &sx, &sy, WINDOW_SIZE_LARGEST);
+ else if (args_has(args, 'a'))
+ default_window_size(s, w, &sx, &sy, WINDOW_SIZE_SMALLEST);
+
+ options_set_number(w->options, "window-size", WINDOW_SIZE_MANUAL);
+ resize_window(w, sx, sy);
+
+ return (CMD_RETURN_NORMAL);
+}
diff --git a/cmd-select-pane.c b/cmd-select-pane.c
index a2345fe1..90ca46ba 100644
--- a/cmd-select-pane.c
+++ b/cmd-select-pane.c
@@ -54,6 +54,31 @@ const struct cmd_entry cmd_last_pane_entry = {
.exec = cmd_select_pane_exec
};
+static void
+cmd_select_pane_redraw(struct window *w)
+{
+ struct client *c;
+
+ /*
+ * Redraw entire window if it is bigger than the client (the
+ * offset may change), otherwise just draw borders.
+ */
+
+ TAILQ_FOREACH(c, &clients, entry) {
+ if (c->session == NULL)
+ continue;
+ if (c->session->curw->window == w && tty_window_bigger(&c->tty))
+ server_redraw_client(c);
+ else {
+ if (c->session->curw->window == w)
+ c->flags |= CLIENT_REDRAWBORDERS;
+ if (session_has(c->session, w))
+ c->flags |= CLIENT_REDRAWSTATUS;
+ }
+
+ }
+}
+
static enum cmd_retval
cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
{
@@ -87,8 +112,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
window_redraw_active_switch(w, lastwp);
if (window_set_active_pane(w, lastwp)) {
cmd_find_from_winlink(current, wl, 0);
- server_status_window(w);
- server_redraw_window_borders(w);
+ cmd_select_pane_redraw(w);
}
}
return (CMD_RETURN_NORMAL);
@@ -168,16 +192,11 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
if (wp == w->active)
return (CMD_RETURN_NORMAL);
server_unzoom_window(wp->window);
- if (!window_pane_visible(wp)) {
- cmdq_error(item, "pane not visible");
- return (CMD_RETURN_ERROR);
- }
window_redraw_active_switch(w, wp);
if (window_set_active_pane(w, wp)) {
cmd_find_from_winlink_pane(current, wl, wp, 0);
hooks_insert(s->hooks, item, current, "after-select-pane");
- server_status_window(w);
- server_redraw_window_borders(w);
+ cmd_select_pane_redraw(w);
}
return (CMD_RETURN_NORMAL);
diff --git a/cmd-set-option.c b/cmd-set-option.c
index bdc42cae..c4b82004 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -18,6 +18,7 @@
#include <sys/types.h>
+#include <fnmatch.h>
#include <stdlib.h>
#include <string.h>
@@ -260,7 +261,7 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
}
if (strcmp(name, "pane-border-status") == 0) {
RB_FOREACH(w, windows, &windows)
- layout_fix_panes(w, w->sx, w->sy);
+ layout_fix_panes(w);
}
RB_FOREACH(s, sessions, &sessions)
status_update_saved(s);
@@ -297,7 +298,8 @@ cmd_set_option_set(struct cmd *self, struct cmdq_item *item, struct options *oo,
int append = args_has(args, 'a');
struct options_entry *o;
long long number;
- const char *errstr;
+ const char *errstr, *new;
+ char *old;
key_code key;
oe = options_table_entry(parent);
@@ -310,7 +312,16 @@ cmd_set_option_set(struct cmd *self, struct cmdq_item *item, struct options *oo,
switch (oe->type) {
case OPTIONS_TABLE_STRING:
+ old = xstrdup(options_get_string(oo, oe->name));
options_set_string(oo, oe->name, append, "%s", value);
+ new = options_get_string(oo, oe->name);
+ if (oe->pattern != NULL && fnmatch(oe->pattern, new, 0) != 0) {
+ options_set_string(oo, oe->name, 0, "%s", old);
+ free(old);
+ cmdq_error(item, "value is invalid: %s", value);
+ return (-1);
+ }
+ free(old);
return (0);
case OPTIONS_TABLE_NUMBER:
number = strtonum(value, oe->minimum, oe->maximum, &errstr);
diff --git a/cmd-split-window.c b/cmd-split-window.c
index 7b58f81f..28821413 100644
--- a/cmd-split-window.c
+++ b/cmd-split-window.c
@@ -148,7 +148,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
}
environ_free(env);
- layout_fix_panes(w, w->sx, w->sy);
+ layout_fix_panes(w);
server_redraw_window(w);
if (!args_has(args, 'd')) {
diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c
index 7283bf53..1de272c4 100644
--- a/cmd-swap-pane.c
+++ b/cmd-swap-pane.c
@@ -105,8 +105,6 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
window_set_active_pane(dst_w, src_wp);
} else {
tmp_wp = dst_wp;
- if (!window_pane_visible(tmp_wp))
- tmp_wp = src_wp;
window_set_active_pane(src_w, tmp_wp);
}
} else {
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index 180635df..6181073d 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -128,6 +128,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
c->session = s;
if (~item->shared->flags & CMDQ_SHARED_REPEAT)
server_client_set_key_table(c, NULL);
+ tty_update_client_offset(c);
status_timer_start(c);
notify_client("client-session-changed", c);
session_update_activity(s, NULL);
diff --git a/cmd.c b/cmd.c
index b90d5ea2..9226e6c2 100644
--- a/cmd.c
+++ b/cmd.c
@@ -81,6 +81,7 @@ extern const struct cmd_entry cmd_refresh_client_entry;
extern const struct cmd_entry cmd_rename_session_entry;
extern const struct cmd_entry cmd_rename_window_entry;
extern const struct cmd_entry cmd_resize_pane_entry;
+extern const struct cmd_entry cmd_resize_window_entry;
extern const struct cmd_entry cmd_respawn_pane_entry;
extern const struct cmd_entry cmd_respawn_window_entry;
extern const struct cmd_entry cmd_rotate_window_entry;
@@ -167,6 +168,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_rename_session_entry,
&cmd_rename_window_entry,
&cmd_resize_pane_entry,
+ &cmd_resize_window_entry,
&cmd_respawn_pane_entry,
&cmd_respawn_window_entry,
&cmd_rotate_window_entry,
diff --git a/format.c b/format.c
index 126bbc14..21365457 100644
--- a/format.c
+++ b/format.c
@@ -52,8 +52,7 @@ static int format_replace(struct format_tree *, const char *, size_t,
static void format_defaults_session(struct format_tree *,
struct session *);
static void format_defaults_client(struct format_tree *, struct client *);
-static void format_defaults_winlink(struct format_tree *,
- struct winlink *);
+static void format_defaults_winlink(struct format_tree *, struct winlink *);
/* Entry in format job tree. */
struct format_job {
@@ -107,9 +106,10 @@ struct format_entry {
/* Format entry tree. */
struct format_tree {
- struct window *w;
- struct winlink *wl;
+ struct client *c;
struct session *s;
+ struct winlink *wl;
+ struct window *w;
struct window_pane *wp;
struct client *client;
@@ -1347,8 +1347,6 @@ format_defaults_session(struct format_tree *ft, struct session *s)
format_add(ft, "session_name", "%s", s->name);
format_add(ft, "session_windows", "%u", winlink_count(&s->windows));
- format_add(ft, "session_width", "%u", s->sx);
- format_add(ft, "session_height", "%u", s->sy);
format_add(ft, "session_id", "$%u", s->id);
sg = session_group_contains(s);
@@ -1383,6 +1381,7 @@ format_defaults_client(struct format_tree *ft, struct client *c)
if (ft->s == NULL)
ft->s = c->session;
+ ft->c = c;
format_add(ft, "client_name", "%s", c->name);
format_add(ft, "client_pid", "%ld", (long) c->pid);
@@ -1451,8 +1450,11 @@ format_defaults_window(struct format_tree *ft, struct window *w)
static void
format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
{
+ struct client *c = ft->c;
struct session *s = wl->session;
struct window *w = wl->window;
+ int flag;
+ u_int ox, oy, sx, sy;
if (ft->w == NULL)
ft->w = wl->window;
@@ -1460,6 +1462,15 @@ format_defaults_winlink(struct format_tree *ft, struct winlink *wl)
format_defaults_window(ft, w);
+ if (c != NULL) {
+ flag = tty_window_offset(&c->tty, &ox, &oy, &sx, &sy);
+ format_add(ft, "window_bigger", "%d", flag);
+ if (flag) {
+ format_add(ft, "window_offset_x", "%u", ox);
+ format_add(ft, "window_offset_y", "%u", oy);
+ }
+ }
+
format_add(ft, "window_index", "%d", wl->idx);
format_add_cb(ft, "window_stack_index", format_cb_window_stack_index);
format_add(ft, "window_flags", "%s", window_printable_flags(wl));
@@ -1509,18 +1520,14 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp)
format_add(ft, "pane_dead_status", "%d", WEXITSTATUS(status));
format_add(ft, "pane_dead", "%d", wp->fd == -1);
- if (window_pane_visible(wp)) {
- format_add(ft, "pane_left", "%u", wp->xoff);
- format_add(ft, "pane_top", "%u", wp->yoff);
- format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1);
- format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1);
- format_add(ft, "pane_at_left", "%d", wp->xoff == 0);
- format_add(ft, "pane_at_top", "%d", wp->yoff == 0);
- format_add(ft, "pane_at_right", "%d",
- wp->xoff + wp->sx == w->sx);
- format_add(ft, "pane_at_bottom", "%d",
- wp->yoff + wp->sy == w->sy);
- }
+ format_add(ft, "pane_left", "%u", wp->xoff);
+ format_add(ft, "pane_top", "%u", wp->yoff);
+ format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1);
+ format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1);
+ format_add(ft, "pane_at_left", "%d", wp->xoff == 0);
+ format_add(ft, "pane_at_top", "%d", wp->yoff == 0);
+ format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == w->sx);
+ format_add(ft, "pane_at_bottom", "%d", wp->yoff + wp->sy == w->sy);
format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base);
if (wp->mode != NULL)
diff --git a/input-keys.c b/input-keys.c
index 34710dac..39401a38 100644
--- a/input-keys.c
+++ b/input-keys.c
@@ -248,10 +248,10 @@ input_key_mouse(struct window_pane *wp, struct mouse_event *m)
if ((mode & ALL_MOUSE_MODES) == 0)
return;
- if (!window_pane_visible(wp))
- return;
if (cmd_mouse_at(wp, m, &x, &y, 0) != 0)
return;
+ if (!window_pane_visible(wp))
+ return;
/* If this pane is not in button or all mode, discard motion events. */
if (MOUSE_DRAG(m->b) &&
diff --git a/key-bindings.c b/key-bindings.c
index c717f5ae..fbc54fb8 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -258,6 +258,11 @@ key_bindings_init(void)
"bind M-n next-window -a",
"bind M-o rotate-window -D",
"bind M-p previous-window -a",
+ "bind -r S-Up refresh-client -U 10",
+ "bind -r S-Down refresh-client -D 10",
+ "bind -r S-Left refresh-client -L 10",
+ "bind -r S-Right refresh-client -R 10",
+ "bind -r DC refresh-client -c",
"bind -r M-Up resize-pane -U 5",
"bind -r M-Down resize-pane -D 5",
"bind -r M-Left resize-pane -L 5",
diff --git a/key-string.c b/key-string.c
index bb49b59f..8442727d 100644
--- a/key-string.c
+++ b/key-string.c
@@ -43,7 +43,9 @@ static const struct {
{ "F11", KEYC_F11 },
{ "F12", KEYC_F12 },
{ "IC", KEYC_IC },
+ { "Insert", KEYC_IC },
{ "DC", KEYC_DC },
+ { "Delete", KEYC_DC },
{ "Home", KEYC_HOME },
{ "End", KEYC_END },
{ "NPage", KEYC_NPAGE },
diff --git a/layout-custom.c b/layout-custom.c
index 1b8f576e..9886afe1 100644
--- a/layout-custom.c
+++ b/layout-custom.c
@@ -167,7 +167,7 @@ layout_parse(struct window *w, const char *layout)
/* Update pane offsets and sizes. */
layout_fix_offsets(lc);
- layout_fix_panes(w, lc->sx, lc->sy);
+ layout_fix_panes(w);
/* Then resize the layout back to the original window size. */
layout_resize(w, sx, sy);
diff --git a/layout-set.c b/layout-set.c
index 5055f672..b9769ed5 100644
--- a/layout-set.c
+++ b/layout-set.c
@@ -148,7 +148,7 @@ layout_set_even(struct window *w, enum layout_type type)
/* Fix cell offsets. */
layout_fix_offsets(lc);
- layout_fix_panes(w, w->sx, w->sy);
+ layout_fix_panes(w);
layout_print_cell(w->layout_root, __func__, 1);
@@ -284,7 +284,7 @@ layout_set_main_h(struct window *w)
/* Fix cell offsets. */
layout_fix_offsets(lc);
- layout_fix_panes(w, w->sx, w->sy);
+ layout_fix_panes(w);
layout_print_cell(w->layout_root, __func__, 1);
@@ -408,7 +408,7 @@ layout_set_main_v(struct window *w)
/* Fix cell offsets. */
layout_fix_offsets(lc);
- layout_fix_panes(w, w->sx, w->sy);
+ layout_fix_panes(w);
layout_print_cell(w->layout_root, __func__, 1);
@@ -511,7 +511,7 @@ layout_set_tiled(struct window *w)
/* Fix cell offsets. */
layout_fix_offsets(lc);
- layout_fix_panes(w, w->sx, w->sy);
+ layout_fix_panes(w);
layout_print_cell(w->layout_root, __func__, 1);
diff --git a/layout.c b/layout.c
index 4ad645e0..89026b91 100644
--- a/layout.c
+++ b/layout.c
@@ -253,71 +253,29 @@ layout_need_status(struct layout_cell *lc, int at_top)
/* Update pane offsets and sizes based on their cells. */
void
-layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
+layout_fix_panes(struct window *w)
{
struct window_pane *wp;
struct layout_cell *lc;
- u_int sx, sy;
- int shift, status, at_top;
+ int shift, status;
status = options_get_number(w->options, "pane-border-status");
- at_top = (status == 1);
TAILQ_FOREACH(wp, &w->panes, entry) {
if ((lc = wp->layout_cell) == NULL)
continue;
if (status != 0)
- shift = layout_need_status(lc, at_top);
+ shift = layout_need_status(lc, status == 1);
else
shift = 0;
wp->xoff = lc->xoff;
wp->yoff = lc->yoff;
- if (shift && at_top)
+ if (shift && status == 1)
wp->yoff += 1;
- /*
- * Layout cells are limited by the smallest size of other cells
- * within the same row or column; if this isn't the case
- * resizing becomes difficult.
- *
- * However, panes do not have to take up their entire cell, so
- * they can be cropped to the window edge if the layout
- * overflows and they are partly visible.
- *
- * This stops cells being hidden unnecessarily.
- */
-
- /*
- * Work out the horizontal size. If the pane is actually
- * outside the window or the entire pane is already visible,
- * don't crop.
- */
- if (lc->xoff >= wsx || lc->xoff + lc->sx < wsx)
- sx = lc->sx;
- else {
- sx = wsx - lc->xoff;
- if (sx < 1)
- sx = lc->sx;
- }
-
- /*
- * Similarly for the vertical size; the minimum vertical size
- * is two because scroll regions cannot be one line.
- */
- if (lc->yoff >= wsy || lc->yoff + lc->sy < wsy)
- sy = lc->sy;
- else {
- sy = wsy - lc->yoff;
- if (sy < 2)
- sy = lc->sy;
- }
-
- if (shift)
- sy -= 1;
-
- window_pane_resize(wp, sx, sy);
+ window_pane_resize(wp, lc->sx, lc->sy - shift);