mirror of
https://github.com/tmux/tmux.git
synced 2025-01-05 23:38:48 +00:00
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.
This commit is contained in:
parent
d018477359
commit
647887b794
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
183
resize.c
183
resize.c
@ -149,14 +149,121 @@ done:
|
||||
*sy = WINDOW_MAXIMUM;
|
||||
}
|
||||
|
||||
void
|
||||
recalculate_size(struct window *w)
|
||||
{
|
||||
struct session *s;
|
||||
struct client *c;
|
||||
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;
|
||||
u_int sx, sy, cx, cy;
|
||||
int type, current, has, changed;
|
||||
|
||||
/*
|
||||
* Clear attached count and update saved status line information for
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
1
spawn.c
1
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;
|
||||
|
6
tmux.1
6
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
|
||||
|
4
tmux.h
4
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user