summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-break-pane.c1
-rw-r--r--cmd-new-session.c1
-rw-r--r--cmd-new-window.c1
-rw-r--r--cmd-respawn-window.c1
-rw-r--r--options-table.c2
-rw-r--r--resize.c183
-rw-r--r--server-client.c21
-rw-r--r--spawn.c1
-rw-r--r--tmux.16
-rw-r--r--tmux.h4
10 files changed, 147 insertions, 74 deletions
diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index b4c5b7cd..8b430ff7 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -81,6 +81,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
wp->flags |= PANE_STYLECHANGED;
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
+ w->latest = c;
if (!args_has(args, 'n')) {
name = default_window_name(w);
diff --git a/cmd-new-session.c b/cmd-new-session.c
index e0540815..c7c407c6 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -259,6 +259,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
memset(&sc, 0, sizeof sc);
sc.item = item;
sc.s = s;
+ sc.c = c;
sc.name = args_get(args, 'n');
sc.argc = args->argc;
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 6cb33dd9..9a1025e9 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -72,6 +72,7 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
memset(&sc, 0, sizeof sc);
sc.item = item;
sc.s = s;
+ sc.c = c;
sc.name = args_get(args, 'n');
sc.argc = args->argc;
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index aec22912..497e401e 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -59,6 +59,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
sc.item = item;
sc.s = s;
sc.wl = wl;
+ sc.c = cmd_find_client(item, NULL, 1);
sc.name = NULL;
sc.argc = args->argc;
diff --git a/options-table.c b/options-table.c
index d012f448..77dbfb13 100644
--- a/options-table.c
+++ b/options-table.c
@@ -64,7 +64,7 @@ static const char *options_table_set_clipboard_list[] = {
"off", "external", "on", NULL
};
static const char *options_table_window_size_list[] = {
- "largest", "smallest", "manual", NULL
+ "largest", "smallest", "manual", "latest", NULL
};
/* Status line format. */
diff --git a/resize.c b/resize.c
index 0e0b070d..b1a4b590 100644
--- a/resize.c
+++ b/resize.c
@@ -150,14 +150,121 @@ done:
}
void
-recalculate_sizes(void)
+recalculate_size(struct window *w)
{
struct session *s;
struct client *c;
- struct window *w;
u_int sx, sy, cx, cy;
int type, current, has, changed;
+ if (w->active == NULL)
+ return;
+ log_debug("%s: @%u is %u,%u", __func__, w->id, w->sx, w->sy);
+
+ type = options_get_number(w->options, "window-size");
+ current = options_get_number(w->options, "aggressive-resize");
+
+ changed = 1;
+ switch (type) {
+ case WINDOW_SIZE_LARGEST:
+ sx = sy = 0;
+ TAILQ_FOREACH(c, &clients, entry) {
+ if (ignore_client_size(c))
+ continue;
+ s = c->session;
+
+ if (current)
+ has = (s->curw->window == w);
+ else
+ has = session_has(s, w);
+ if (!has)
+ continue;
+
+ cx = c->tty.sx;
+ cy = c->tty.sy - status_line_size(c);
+
+ if (cx > sx)
+ sx = cx;
+ if (cy > sy)
+ sy = cy;
+ }
+ if (sx == 0 || sy == 0)
+ changed = 0;
+ break;
+ case WINDOW_SIZE_SMALLEST:
+ sx = sy = UINT_MAX;
+ TAILQ_FOREACH(c, &clients, entry) {
+ if (ignore_client_size(c))
+ continue;
+ s = c->session;
+
+ if (current)
+ has = (s->curw->window == w);
+ else
+ has = session_has(s, w);
+ if (!has)
+ continue;
+
+ cx = c->tty.sx;
+ cy = c->tty.sy - status_line_size(c);
+
+ if (cx < sx)
+ sx = cx;
+ if (cy < sy)
+ sy = cy;
+ }
+ if (sx == UINT_MAX || sy == UINT_MAX)
+ changed = 0;
+ break;
+ case WINDOW_SIZE_LATEST:
+ sx = sy = UINT_MAX;
+ TAILQ_FOREACH(c, &clients, entry) {
+ if (ignore_client_size(c))
+ continue;
+ if (c != w->latest)
+ continue;
+ s = c->session;
+
+ if (current)
+ has = (s->curw->window == w);
+ else
+ has = session_has(s, w);
+ if (!has)
+ continue;
+
+ cx = c->tty.sx;
+ cy = c->tty.sy - status_line_size(c);
+
+ if (cx < sx)
+ sx = cx;
+ if (cy < sy)
+ sy = cy;
+ }
+ if (sx == UINT_MAX || sy == UINT_MAX)
+ changed = 0;
+ break;
+ case WINDOW_SIZE_MANUAL:
+ changed = 0;
+ break;
+ }
+ if (changed && w->sx == sx && w->sy == sy)
+ changed = 0;
+
+ if (!changed) {
+ tty_update_window_offset(w);
+ return;
+ }
+ log_debug("%s: @%u changed to %u,%u", __func__, w->id, sx, sy);
+ resize_window(w, sx, sy);
+}
+
+void
+recalculate_sizes(void)
+{
+ struct session *s;
+ struct client *c;
+ struct window *w;
+
/*
* Clear attached count and update saved status line information for
* each session.
@@ -183,74 +290,6 @@ recalculate_sizes(void)
}
/* Walk each window and adjust the size. */
- RB_FOREACH(w, windows, &windows) {
- if (w->active == NULL)
- continue;
- log_debug("%s: @%u is %u,%u", __func__, w->id, w->sx, w->sy);
-
- type = options_get_number(w->options, "window-size");
- if (type == WINDOW_SIZE_MANUAL)
- continue;
- current = options_get_number(w->options, "aggressive-resize");
-
- changed = 1;
- if (type == WINDOW_SIZE_LARGEST) {
- sx = sy = 0;
- TAILQ_FOREACH(c, &clients, entry) {
- if (ignore_client_size(c))
- continue;
- s = c->session;
-
- if (current)
- has = (s->curw->window == w);
- else
- has = session_has(s, w);
- if (!has)
- continue;
-
- cx = c->tty.sx;
- cy = c->tty.sy - status_line_size(c);
-
- if (cx > sx)
- sx = cx;
- if (cy > sy)
- sy = cy;
- }
- if (sx == 0 || sy == 0)
- changed = 0;
- } else {
- sx = sy = UINT_MAX;
- TAILQ_FOREACH(c, &clients, entry) {
- if (ignore_client_size(c))
- continue;
- s = c->session;
-
- if (current)
- has = (s->curw->window == w);
- else
- has = session_has(s, w);
- if (!has)
- continue;
-
- cx = c->tty.sx;
- cy = c->tty.sy - status_line_size(c);
-
- if (cx < sx)
- sx = cx;
- if (cy < sy)
- sy = cy;
- }
- if (sx == UINT_MAX || sy == UINT_MAX)
- changed = 0;
- }
- if (w->sx == sx && w->sy == sy)
- changed = 0;
-
- if (!changed) {
- tty_update_window_offset(w);
- continue;
- }
- log_debug("%s: @%u changed to %u,%u", __func__, w->id, sx, sy);
- resize_window(w, sx, sy);
- }
+ RB_FOREACH(w, windows, &windows)
+ recalculate_size(w);
}
diff --git a/server-client.c b/server-client.c
index 4b60f5c0..36ebf85b 100644
--- a/server-client.c
+++ b/server-client.c
@@ -996,6 +996,24 @@ server_client_assume_paste(struct session *s)
return (0);
}
+/* Has the latest client changed? */
+static void
+server_client_update_latest(struct client *c)
+{
+ struct window *w;
+
+ if (c->session == NULL)
+ return;
+ w = c->session->curw->window;
+
+ if (w->latest == c)
+ return;
+ w->latest = c;
+
+ if (options_get_number(w->options, "window-size") == WINDOW_SIZE_LATEST)
+ recalculate_size(w);
+}
+
/*
* Handle data key input from client. This owns and can modify the key event it
* is given and is responsible for freeing it.
@@ -1192,6 +1210,8 @@ forward_key:
window_pane_key(wp, c, s, wl, key, m);
out:
+ if (s != NULL)
+ server_client_update_latest(c);
free(event);
return (CMD_RETURN_NORMAL);
}
@@ -1737,6 +1757,7 @@ server_client_dispatch(struct imsg *imsg, void *arg)
if (c->flags & CLIENT_CONTROL)
break;
+ server_client_update_latest(c);
server_client_clear_overlay(c);
tty_resize(&c->tty);
recalculate_sizes();
diff --git a/spawn.c b/spawn.c
index 52763083..1917955e 100644
--- a/spawn.c
+++ b/spawn.c
@@ -164,6 +164,7 @@ spawn_window(struct spawn_context *sc, char **cause)
if (s->curw == NULL)
s->curw = sc->wl;
sc->wl->session = s;
+ w->latest = sc->c;
winlink_set_window(sc->wl, w);
} else
w = NULL;
diff --git a/tmux.1 b/tmux.1
index c99e506c..ff19c225 100644
--- a/tmux.1
+++ b/tmux.1
@@ -3659,7 +3659,7 @@ see the
section.
.Pp
.It Xo Ic window-size
-.Ar largest | Ar smallest | Ar manual
+.Ar largest | Ar smallest | Ar manual | Ar latest
.Xc
Configure how
.Nm
@@ -3674,6 +3674,10 @@ If
the size of a new window is set from the
.Ic default-size
option and windows are resized automatically.
+With
+.Ar latest ,
+.Nm
+uses the size of the client that had the most recent activity.
See also the
.Ic resize-window
command and the
diff --git a/tmux.h b/tmux.h
index 5f7e5104..6e6fee96 100644
--- a/tmux.h
+++ b/tmux.h
@@ -905,6 +905,7 @@ RB_HEAD(window_pane_tree, window_pane);
/* Window structure. */
struct window {
u_int id;
+ void *latest;
char *name;
struct event name_event;
@@ -970,6 +971,7 @@ TAILQ_HEAD(winlink_stack, winlink);
#define WINDOW_SIZE_LARGEST 0
#define WINDOW_SIZE_SMALLEST 1
#define WINDOW_SIZE_MANUAL 2
+#define WINDOW_SIZE_LATEST 3
/* Pane border status option. */
#define PANE_STATUS_OFF 0
@@ -1670,6 +1672,7 @@ struct spawn_context {
struct session *s;
struct winlink *wl;
+ struct client *c;
struct window_pane *wp0;
struct layout_cell *lc;
@@ -2195,6 +2198,7 @@ void status_prompt_save_history(void);
void resize_window(struct window *, u_int, u_int);
void default_window_size(struct session *, struct window *, u_int *,
u_int *, int);
+void recalculate_size(struct window *);
void recalculate_sizes(void);
/* input.c */