Annotation of src/usr.bin/tmux/resize.c, Revision 1.28
1.28 ! nicm 1: /* $OpenBSD: resize.c,v 1.27 2018/10/18 08:38:01 nicm Exp $ */
1.1 nicm 2:
3: /*
1.19 nicm 4: * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1 nicm 5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
21: #include <string.h>
22:
23: #include "tmux.h"
24:
1.27 nicm 25: void
26: resize_window(struct window *w, u_int sx, u_int sy)
27: {
28: int zoomed;
29:
30: /* Check size limits. */
31: if (sx < WINDOW_MINIMUM)
32: sx = WINDOW_MINIMUM;
33: if (sx > WINDOW_MAXIMUM)
34: sx = WINDOW_MAXIMUM;
35: if (sy < WINDOW_MINIMUM)
36: sy = WINDOW_MINIMUM;
37: if (sy > WINDOW_MAXIMUM)
38: sy = WINDOW_MAXIMUM;
39:
40: /* If the window is zoomed, unzoom. */
41: zoomed = w->flags & WINDOW_ZOOMED;
42: if (zoomed)
43: window_unzoom(w);
44:
45: /* Resize the layout first. */
46: layout_resize(w, sx, sy);
47:
48: /* Resize the window, it can be no smaller than the layout. */
49: if (sx < w->layout_root->sx)
50: sx = w->layout_root->sx;
51: if (sy < w->layout_root->sy)
52: sy = w->layout_root->sy;
53: window_resize(w, sx, sy);
54:
55: /* Restore the window zoom state. */
56: if (zoomed)
57: window_zoom(w->active);
58:
59: tty_update_window_offset(w);
60: server_redraw_window(w);
61: notify_window("window-layout-changed", w);
62: }
1.1 nicm 63:
64: void
1.27 nicm 65: default_window_size(struct session *s, struct window *w, u_int *sx, u_int *sy,
66: int type)
1.1 nicm 67: {
1.27 nicm 68: struct client *c;
69: u_int cx, cy;
70: const char *value;
71:
72: if (type == -1)
73: type = options_get_number(global_w_options, "window-size");
74: if (type == WINDOW_SIZE_MANUAL)
75: goto manual;
1.1 nicm 76:
1.27 nicm 77: if (type == WINDOW_SIZE_LARGEST) {
78: *sx = *sy = 0;
79: TAILQ_FOREACH(c, &clients, entry) {
80: if (c->session == NULL)
81: continue;
82: if (c->flags & CLIENT_NOSIZEFLAGS)
83: continue;
84: if (w != NULL && !session_has(c->session, w))
85: continue;
86: if (w == NULL && c->session != s)
87: continue;
88:
89: cx = c->tty.sx;
90: cy = c->tty.sy - status_line_size(c);
1.9 nicm 91:
1.27 nicm 92: if (cx > *sx)
93: *sx = cx;
94: if (cy > *sy)
95: *sy = cy;
96: }
97: if (*sx == 0 || *sy == 0)
98: goto manual;
99: } else {
100: *sx = *sy = UINT_MAX;
1.17 nicm 101: TAILQ_FOREACH(c, &clients, entry) {
1.27 nicm 102: if (c->session == NULL)
1.23 nicm 103: continue;
1.27 nicm 104: if (c->flags & CLIENT_NOSIZEFLAGS)
1.1 nicm 105: continue;
1.27 nicm 106: if (w != NULL && !session_has(c->session, w))
107: continue;
108: if (w == NULL && c->session != s)
109: continue;
110:
111: cx = c->tty.sx;
112: cy = c->tty.sy - status_line_size(c);
113:
114: if (cx < *sx)
115: *sx = cx;
116: if (cy < *sy)
117: *sy = cy;
1.1 nicm 118: }
1.27 nicm 119: if (*sx == UINT_MAX || *sy == UINT_MAX)
120: goto manual;
121: }
122: goto done;
123:
124: manual:
125: value = options_get_string(s->options, "default-size");
126: if (sscanf(value, "%ux%u", sx, sy) != 2) {
127: *sx = 80;
128: *sy = 24;
129: }
130:
131: done:
132: if (*sx < WINDOW_MINIMUM)
133: *sx = WINDOW_MINIMUM;
134: if (*sx > WINDOW_MAXIMUM)
135: *sx = WINDOW_MAXIMUM;
136: if (*sy < WINDOW_MINIMUM)
137: *sy = WINDOW_MINIMUM;
138: if (*sy > WINDOW_MAXIMUM)
139: *sy = WINDOW_MAXIMUM;
140: }
1.1 nicm 141:
1.27 nicm 142: void
143: recalculate_sizes(void)
144: {
145: struct session *s;
146: struct client *c;
147: struct window *w;
148: u_int sx, sy, cx, cy;
149: int flags, type, current, has, changed;
150:
151: /*
152: * Clear attached count and update saved status line information for
153: * each session.
154: */
155: RB_FOREACH(s, sessions, &sessions) {
156: s->attached = 0;
157: status_update_saved(s);
158: }
1.9 nicm 159:
1.27 nicm 160: /*
161: * Increment attached count and check the status line size for each
162: * client.
163: */
164: TAILQ_FOREACH(c, &clients, entry) {
165: if ((s = c->session) == NULL)
1.1 nicm 166: continue;
167:
1.27 nicm 168: flags = c->flags;
169: if (flags & CLIENT_SUSPENDED)
170: continue;
171: if ((flags & CLIENT_CONTROL) && (~flags & CLIENT_SIZECHANGED))
172: continue;
1.1 nicm 173:
1.27 nicm 174: if (c->tty.sy <= status_line_size(c))
175: c->flags |= CLIENT_STATUSOFF;
176: else
177: c->flags &= ~CLIENT_STATUSOFF;
1.21 nicm 178:
1.27 nicm 179: s->attached++;
1.1 nicm 180: }
181:
1.27 nicm 182: /* Walk each window and adjust the size. */
1.15 nicm 183: RB_FOREACH(w, windows, &windows) {
184: if (w->active == NULL)
1.1 nicm 185: continue;
1.27 nicm 186: log_debug("%s: @%u is %u,%u", __func__, w->id, w->sx, w->sy);
1.1 nicm 187:
1.27 nicm 188: type = options_get_number(w->options, "window-size");
189: if (type == WINDOW_SIZE_MANUAL)
1.1 nicm 190: continue;
1.28 ! nicm 191: current = options_get_number(w->options, "aggressive-resize");
1.1 nicm 192:
1.27 nicm 193: changed = 1;
194: if (type == WINDOW_SIZE_LARGEST) {
195: sx = sy = 0;
196: TAILQ_FOREACH(c, &clients, entry) {
197: if ((s = c->session) == NULL)
198: continue;
199: if (current)
200: has = (s->curw->window == w);
201: else
202: has = session_has(s, w);
203: if (!has)
204: continue;
205:
206: cx = c->tty.sx;
207: cy = c->tty.sy - status_line_size(c);
208:
209: if (cx > sx)
210: sx = cx;
211: if (cy > sy)
212: sy = cy;
213: }
214: if (sx == 0 || sy == 0)
215: changed = 0;
216: } else {
217: sx = sy = UINT_MAX;
218: TAILQ_FOREACH(c, &clients, entry) {
219: if ((s = c->session) == NULL)
220: continue;
221: if (current)
222: has = (s->curw->window == w);
223: else
224: has = session_has(s, w);
225: if (!has)
226: continue;
227:
228: cx = c->tty.sx;
229: cy = c->tty.sy - status_line_size(c);
230:
231: if (cx < sx)
232: sx = cx;
233: if (cy < sy)
234: sy = cy;
235: }
236: if (sx == UINT_MAX || sy == UINT_MAX)
237: changed = 0;
1.14 nicm 238: }
1.27 nicm 239: if (w->sx == sx && w->sy == sy)
240: changed = 0;
1.1 nicm 241:
1.27 nicm 242: if (!changed) {
243: tty_update_window_offset(w);
1.1 nicm 244: continue;
1.2 nicm 245: }
1.27 nicm 246: log_debug("%s: @%u changed to %u,%u", __func__, w->id, sx, sy);
247: resize_window(w, sx, sy);
1.1 nicm 248: }
249: }