diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-09-19 09:02:31 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-09-19 09:02:31 +0000 |
commit | 7696a238e06582760e8215b77ff4be8ce4f0e19a (patch) | |
tree | dd92302e895a7859a653b74eb2e9d0698490d358 | |
parent | 6bea8aadad24b381017c2af11f597fd68971aafa (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.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-new-session.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-new-window.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-respawn-window.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/options-table.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/resize.c | 185 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 23 | ||||
-rw-r--r-- | usr.bin/tmux/spawn.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 10 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 6 |
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 */ |