summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2019-09-19 09:02:31 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2019-09-19 09:02:31 +0000
commit7696a238e06582760e8215b77ff4be8ce4f0e19a (patch)
treedd92302e895a7859a653b74eb2e9d0698490d358
parent6bea8aadad24b381017c2af11f597fd68971aafa (diff)
Add a "latest" window-size option which tries to size windows based on
the most recently used client. From Tommie Gannert in GitHub issue 1869 based on earlier changes from me.
-rw-r--r--usr.bin/tmux/cmd-break-pane.c3
-rw-r--r--usr.bin/tmux/cmd-new-session.c3
-rw-r--r--usr.bin/tmux/cmd-new-window.c3
-rw-r--r--usr.bin/tmux/cmd-respawn-window.c3
-rw-r--r--usr.bin/tmux/options-table.c4
-rw-r--r--usr.bin/tmux/resize.c185
-rw-r--r--usr.bin/tmux/server-client.c23
-rw-r--r--usr.bin/tmux/spawn.c3
-rw-r--r--usr.bin/tmux/tmux.110
-rw-r--r--usr.bin/tmux/tmux.h6
10 files changed, 158 insertions, 85 deletions
diff --git a/usr.bin/tmux/cmd-break-pane.c b/usr.bin/tmux/cmd-break-pane.c
index f2dcd034220..907658eb81e 100644
--- a/usr.bin/tmux/cmd-break-pane.c
+++ b/usr.bin/tmux/cmd-break-pane.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-break-pane.c,v 1.48 2019/06/20 11:59:59 nicm Exp $ */
+/* $OpenBSD: cmd-break-pane.c,v 1.49 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/cmd-new-session.c b/usr.bin/tmux/cmd-new-session.c
index b3fc5b00fa7..0421d4aedf3 100644
--- a/usr.bin/tmux/cmd-new-session.c
+++ b/usr.bin/tmux/cmd-new-session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-new-session.c,v 1.120 2019/06/03 18:28:37 nicm Exp $ */
+/* $OpenBSD: cmd-new-session.c,v 1.121 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/cmd-new-window.c b/usr.bin/tmux/cmd-new-window.c
index bc2c370bc78..e636752c330 100644
--- a/usr.bin/tmux/cmd-new-window.c
+++ b/usr.bin/tmux/cmd-new-window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-new-window.c,v 1.79 2019/04/28 20:05:50 nicm Exp $ */
+/* $OpenBSD: cmd-new-window.c,v 1.80 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/cmd-respawn-window.c b/usr.bin/tmux/cmd-respawn-window.c
index 6d5ccef222a..974d3a7ab85 100644
--- a/usr.bin/tmux/cmd-respawn-window.c
+++ b/usr.bin/tmux/cmd-respawn-window.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-respawn-window.c,v 1.39 2019/04/28 20:05:50 nicm Exp $ */
+/* $OpenBSD: cmd-respawn-window.c,v 1.40 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c
index 5e0f63fc729..78d302194a7 100644
--- a/usr.bin/tmux/options-table.c
+++ b/usr.bin/tmux/options-table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.110 2019/09/15 21:42:57 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.111 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/resize.c b/usr.bin/tmux/resize.c
index c1f88eb3146..04e3f9d6723 100644
--- a/usr.bin/tmux/resize.c
+++ b/usr.bin/tmux/resize.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resize.c,v 1.32 2019/05/11 06:34:56 nicm Exp $ */
+/* $OpenBSD: resize.c,v 1.33 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c
index 253fc028801..2fdde1da8bc 100644
--- a/usr.bin/tmux/server-client.c
+++ b/usr.bin/tmux/server-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-client.c,v 1.294 2019/08/28 07:34:32 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.295 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/spawn.c b/usr.bin/tmux/spawn.c
index c7d0ebb2d35..e34895a46bc 100644
--- a/usr.bin/tmux/spawn.c
+++ b/usr.bin/tmux/spawn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: spawn.c,v 1.7 2019/09/18 11:37:58 nicm Exp $ */
+/* $OpenBSD: spawn.c,v 1.8 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index c5a8799bf48..6b9a7731494 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.688 2019/09/15 21:42:57 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.689 2019/09/19 09:02:30 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 15 2019 $
+.Dd $Mdocdate: September 19 2019 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -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/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 3fb206f7d9c..4ae71c84200 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.927 2019/09/15 21:42:57 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.928 2019/09/19 09:02:30 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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 */