diff options
author | nicm <nicm> | 2019-09-19 09:02:30 +0000 |
---|---|---|
committer | nicm <nicm> | 2019-09-19 09:02:30 +0000 |
commit | 647887b794c00285047aa54ac0d44ae50c7847d7 (patch) | |
tree | c173a9c9f68dd40248df0b0685189241c074ec4d | |
parent | d01847735903496c25e1d24375b911edffa56ef8 (diff) | |
download | rtmux-647887b794c00285047aa54ac0d44ae50c7847d7.tar.gz rtmux-647887b794c00285047aa54ac0d44ae50c7847d7.tar.bz2 rtmux-647887b794c00285047aa54ac0d44ae50c7847d7.zip |
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-- | cmd-break-pane.c | 1 | ||||
-rw-r--r-- | cmd-new-session.c | 1 | ||||
-rw-r--r-- | cmd-new-window.c | 1 | ||||
-rw-r--r-- | cmd-respawn-window.c | 1 | ||||
-rw-r--r-- | options-table.c | 2 | ||||
-rw-r--r-- | resize.c | 183 | ||||
-rw-r--r-- | server-client.c | 21 | ||||
-rw-r--r-- | spawn.c | 1 | ||||
-rw-r--r-- | tmux.1 | 6 | ||||
-rw-r--r-- | tmux.h | 4 |
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. */ @@ -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(); @@ -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; @@ -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 @@ -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 */ |