Home | History | Annotate | Line # | Download | only in dist
      1  1.2  christos /* $OpenBSD$ */
      2  1.1      jmmv 
      3  1.1      jmmv /*
      4  1.2  christos  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott (at) gmail.com>
      5  1.1      jmmv  *
      6  1.1      jmmv  * Permission to use, copy, modify, and distribute this software for any
      7  1.1      jmmv  * purpose with or without fee is hereby granted, provided that the above
      8  1.1      jmmv  * copyright notice and this permission notice appear in all copies.
      9  1.1      jmmv  *
     10  1.1      jmmv  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11  1.1      jmmv  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12  1.1      jmmv  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13  1.1      jmmv  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14  1.1      jmmv  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
     15  1.1      jmmv  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     16  1.1      jmmv  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17  1.1      jmmv  */
     18  1.1      jmmv 
     19  1.1      jmmv #include <sys/types.h>
     20  1.1      jmmv 
     21  1.1      jmmv #include <string.h>
     22  1.1      jmmv 
     23  1.1      jmmv #include "tmux.h"
     24  1.1      jmmv 
     25  1.2  christos void
     26  1.2  christos resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
     27  1.2  christos {
     28  1.2  christos 	int	zoomed;
     29  1.2  christos 
     30  1.2  christos 	/* Check size limits. */
     31  1.2  christos 	if (sx < WINDOW_MINIMUM)
     32  1.2  christos 		sx = WINDOW_MINIMUM;
     33  1.2  christos 	if (sx > WINDOW_MAXIMUM)
     34  1.2  christos 		sx = WINDOW_MAXIMUM;
     35  1.2  christos 	if (sy < WINDOW_MINIMUM)
     36  1.2  christos 		sy = WINDOW_MINIMUM;
     37  1.2  christos 	if (sy > WINDOW_MAXIMUM)
     38  1.2  christos 		sy = WINDOW_MAXIMUM;
     39  1.2  christos 
     40  1.2  christos 	/* If the window is zoomed, unzoom. */
     41  1.2  christos 	zoomed = w->flags & WINDOW_ZOOMED;
     42  1.2  christos 	if (zoomed)
     43  1.6       wiz 		window_unzoom(w, 1);
     44  1.2  christos 
     45  1.2  christos 	/* Resize the layout first. */
     46  1.2  christos 	layout_resize(w, sx, sy);
     47  1.2  christos 
     48  1.2  christos 	/* Resize the window, it can be no smaller than the layout. */
     49  1.2  christos 	if (sx < w->layout_root->sx)
     50  1.2  christos 		sx = w->layout_root->sx;
     51  1.2  christos 	if (sy < w->layout_root->sy)
     52  1.2  christos 		sy = w->layout_root->sy;
     53  1.2  christos 	window_resize(w, sx, sy, xpixel, ypixel);
     54  1.5       wiz 	log_debug("%s: @%u resized to %ux%u; layout %ux%u", __func__, w->id,
     55  1.2  christos 	    sx, sy, w->layout_root->sx, w->layout_root->sy);
     56  1.2  christos 
     57  1.2  christos 	/* Restore the window zoom state. */
     58  1.2  christos 	if (zoomed)
     59  1.2  christos 		window_zoom(w->active);
     60  1.2  christos 
     61  1.2  christos 	tty_update_window_offset(w);
     62  1.2  christos 	server_redraw_window(w);
     63  1.2  christos 	notify_window("window-layout-changed", w);
     64  1.5       wiz 	notify_window("window-resized", w);
     65  1.3  christos 	w->flags &= ~WINDOW_RESIZE;
     66  1.2  christos }
     67  1.2  christos 
     68  1.2  christos static int
     69  1.2  christos ignore_client_size(struct client *c)
     70  1.2  christos {
     71  1.2  christos 	struct client	*loop;
     72  1.2  christos 
     73  1.2  christos 	if (c->session == NULL)
     74  1.2  christos 		return (1);
     75  1.2  christos 	if (c->flags & CLIENT_NOSIZEFLAGS)
     76  1.2  christos 		return (1);
     77  1.3  christos 	if (c->flags & CLIENT_IGNORESIZE) {
     78  1.2  christos 		/*
     79  1.3  christos 		 * Ignore flagged clients if there are any attached clients
     80  1.3  christos 		 * that aren't flagged.
     81  1.2  christos 		 */
     82  1.2  christos 		TAILQ_FOREACH (loop, &clients, entry) {
     83  1.2  christos 			if (loop->session == NULL)
     84  1.2  christos 				continue;
     85  1.2  christos 			if (loop->flags & CLIENT_NOSIZEFLAGS)
     86  1.2  christos 				continue;
     87  1.3  christos 			if (~loop->flags & CLIENT_IGNORESIZE)
     88  1.2  christos 				return (1);
     89  1.2  christos 		}
     90  1.2  christos 	}
     91  1.5       wiz 	if ((c->flags & CLIENT_CONTROL) &&
     92  1.5       wiz 	    (~c->flags & CLIENT_SIZECHANGED) &&
     93  1.5       wiz 	    (~c->flags & CLIENT_WINDOWSIZECHANGED))
     94  1.2  christos 		return (1);
     95  1.2  christos 	return (0);
     96  1.2  christos }
     97  1.1      jmmv 
     98  1.3  christos static u_int
     99  1.3  christos clients_with_window(struct window *w)
    100  1.3  christos {
    101  1.3  christos 	struct client	*loop;
    102  1.3  christos 	u_int		 n = 0;
    103  1.3  christos 
    104  1.3  christos 	TAILQ_FOREACH(loop, &clients, entry) {
    105  1.3  christos 		if (ignore_client_size(loop) || !session_has(loop->session, w))
    106  1.3  christos 			continue;
    107  1.3  christos 		if (++n > 1)
    108  1.3  christos 			break;
    109  1.3  christos 	}
    110  1.3  christos 	return (n);
    111  1.3  christos }
    112  1.3  christos 
    113  1.3  christos static int
    114  1.4  christos clients_calculate_size(int type, int current, struct client *c,
    115  1.4  christos     struct session *s, struct window *w, int (*skip_client)(struct client *,
    116  1.4  christos     int, int, struct session *, struct window *), u_int *sx, u_int *sy,
    117  1.4  christos     u_int *xpixel, u_int *ypixel)
    118  1.1      jmmv {
    119  1.5       wiz 	struct client		*loop;
    120  1.5       wiz 	struct client_window	*cw;
    121  1.5       wiz 	u_int			 cx, cy, n = 0;
    122  1.2  christos 
    123  1.3  christos 	/*
    124  1.3  christos 	 * Start comparing with 0 for largest and UINT_MAX for smallest or
    125  1.3  christos 	 * latest.
    126  1.3  christos 	 */
    127  1.5       wiz 	if (type == WINDOW_SIZE_LARGEST) {
    128  1.5       wiz 		*sx = 0;
    129  1.5       wiz 		*sy = 0;
    130  1.5       wiz 	} else if (type == WINDOW_SIZE_MANUAL) {
    131  1.5       wiz 		*sx = w->manual_sx;
    132  1.5       wiz 		*sy = w->manual_sy;
    133  1.5       wiz 		log_debug("%s: manual size %ux%u", __func__, *sx, *sy);
    134  1.5       wiz 	} else {
    135  1.5       wiz 		*sx = UINT_MAX;
    136  1.5       wiz 		*sy = UINT_MAX;
    137  1.5       wiz 	}
    138  1.3  christos 	*xpixel = *ypixel = 0;
    139  1.3  christos 
    140  1.3  christos 	/*
    141  1.3  christos 	 * For latest, count the number of clients with this window. We only
    142  1.3  christos 	 * care if there is more than one.
    143  1.3  christos 	 */
    144  1.4  christos 	if (type == WINDOW_SIZE_LATEST && w != NULL)
    145  1.3  christos 		n = clients_with_window(w);
    146  1.3  christos 
    147  1.5       wiz 	/* Skip setting the size if manual */
    148  1.5       wiz 	if (type == WINDOW_SIZE_MANUAL)
    149  1.5       wiz 		goto skip;
    150  1.5       wiz 
    151  1.3  christos 	/* Loop over the clients and work out the size. */
    152  1.3  christos 	TAILQ_FOREACH(loop, &clients, entry) {
    153  1.4  christos 		if (loop != c && ignore_client_size(loop)) {
    154  1.5       wiz 			log_debug("%s: ignoring %s (1)", __func__, loop->name);
    155  1.3  christos 			continue;
    156  1.4  christos 		}
    157  1.4  christos 		if (loop != c && skip_client(loop, type, current, s, w)) {
    158  1.5       wiz 			log_debug("%s: skipping %s (1)", __func__, loop->name);
    159  1.3  christos 			continue;
    160  1.4  christos 		}
    161  1.3  christos 
    162  1.3  christos 		/*
    163  1.3  christos 		 * If there are multiple clients attached, only accept the
    164  1.3  christos 		 * latest client; otherwise let the only client be chosen as
    165  1.3  christos 		 * for smallest.
    166  1.3  christos 		 */
    167  1.4  christos 		if (type == WINDOW_SIZE_LATEST && n > 1 && loop != w->latest) {
    168  1.4  christos 			log_debug("%s: %s is not latest", __func__, loop->name);
    169  1.3  christos 			continue;
    170  1.4  christos 		}
    171  1.2  christos 
    172  1.5       wiz 		/*
    173  1.5       wiz 		 * If the client has a per-window size, use this instead if it is
    174  1.5       wiz 		 * smaller.
    175  1.5       wiz 		 */
    176  1.5       wiz 		if (w != NULL)
    177  1.5       wiz 			cw = server_client_get_client_window(loop, w->id);
    178  1.5       wiz 		else
    179  1.5       wiz 			cw = NULL;
    180  1.5       wiz 
    181  1.3  christos 		/* Work out this client's size. */
    182  1.5       wiz 		if (cw != NULL && cw->sx != 0 && cw->sy != 0) {
    183  1.5       wiz 			cx = cw->sx;
    184  1.5       wiz 			cy = cw->sy;
    185  1.5       wiz 		} else {
    186  1.5       wiz 			cx = loop->tty.sx;
    187  1.5       wiz 			cy = loop->tty.sy - status_line_size(loop);
    188  1.5       wiz 		}
    189  1.1      jmmv 
    190  1.3  christos 		/*
    191  1.3  christos 		 * If it is larger or smaller than the best so far, update the
    192  1.3  christos 		 * new size.
    193  1.3  christos 		 */
    194  1.3  christos 		if (type == WINDOW_SIZE_LARGEST) {
    195  1.2  christos 			if (cx > *sx)
    196  1.2  christos 				*sx = cx;
    197  1.2  christos 			if (cy > *sy)
    198  1.2  christos 				*sy = cy;
    199  1.3  christos 		} else {
    200  1.2  christos 			if (cx < *sx)
    201  1.2  christos 				*sx = cx;
    202  1.2  christos 			if (cy < *sy)
    203  1.2  christos 				*sy = cy;
    204  1.3  christos 		}
    205  1.3  christos 		if (loop->tty.xpixel > *xpixel && loop->tty.ypixel > *ypixel) {
    206  1.3  christos 			*xpixel = loop->tty.xpixel;
    207  1.3  christos 			*ypixel = loop->tty.ypixel;
    208  1.3  christos 		}
    209  1.4  christos 		log_debug("%s: after %s (%ux%u), size is %ux%u", __func__,
    210  1.4  christos 		    loop->name, cx, cy, *sx, *sy);
    211  1.3  christos 	}
    212  1.5       wiz 	if (*sx != UINT_MAX && *sy != UINT_MAX)
    213  1.5       wiz 		log_debug("%s: calculated size %ux%u", __func__, *sx, *sy);
    214  1.5       wiz 	else
    215  1.5       wiz 		log_debug("%s: no calculated size", __func__);
    216  1.5       wiz 
    217  1.5       wiz skip:
    218  1.5       wiz 	/*
    219  1.5       wiz 	 * Do not allow any size to be larger than the per-client window size
    220  1.5       wiz 	 * if one exists.
    221  1.5       wiz 	 */
    222  1.5       wiz 	if (w != NULL) {
    223  1.5       wiz 		TAILQ_FOREACH(loop, &clients, entry) {
    224  1.5       wiz 			if (loop != c && ignore_client_size(loop))
    225  1.5       wiz 				continue;
    226  1.5       wiz 			if (loop != c && skip_client(loop, type, current, s, w))
    227  1.5       wiz 				continue;
    228  1.5       wiz 
    229  1.5       wiz 			/* Look up per-window size if any. */
    230  1.5       wiz 			if (~loop->flags & CLIENT_WINDOWSIZECHANGED)
    231  1.5       wiz 				continue;
    232  1.5       wiz 			cw = server_client_get_client_window(loop, w->id);
    233  1.5       wiz 			if (cw == NULL)
    234  1.5       wiz 				continue;
    235  1.5       wiz 
    236  1.5       wiz 			/* Clamp the size. */
    237  1.5       wiz 			log_debug("%s: %s size for @%u is %ux%u", __func__,
    238  1.5       wiz 			    loop->name, w->id, cw->sx, cw->sy);
    239  1.5       wiz 			if (cw->sx != 0 && *sx > cw->sx)
    240  1.5       wiz 				*sx = cw->sx;
    241  1.5       wiz 			if (cw->sy != 0 && *sy > cw->sy)
    242  1.5       wiz 				*sy = cw->sy;
    243  1.5       wiz 		}
    244  1.5       wiz 	}
    245  1.5       wiz 	if (*sx != UINT_MAX && *sy != UINT_MAX)
    246  1.5       wiz 		log_debug("%s: calculated size %ux%u", __func__, *sx, *sy);
    247  1.5       wiz 	else
    248  1.5       wiz 		log_debug("%s: no calculated size", __func__);
    249  1.3  christos 
    250  1.3  christos 	/* Return whether a suitable size was found. */
    251  1.5       wiz 	if (type == WINDOW_SIZE_MANUAL) {
    252  1.5       wiz 		log_debug("%s: type is manual", __func__);
    253  1.5       wiz 		return (1);
    254  1.5       wiz 	}
    255  1.4  christos 	if (type == WINDOW_SIZE_LARGEST) {
    256  1.4  christos 		log_debug("%s: type is largest", __func__);
    257  1.3  christos 		return (*sx != 0 && *sy != 0);
    258  1.4  christos 	}
    259  1.4  christos 	if (type == WINDOW_SIZE_LATEST)
    260  1.4  christos 		log_debug("%s: type is latest", __func__);
    261  1.4  christos 	else
    262  1.4  christos 		log_debug("%s: type is smallest", __func__);
    263  1.3  christos 	return (*sx != UINT_MAX && *sy != UINT_MAX);
    264  1.3  christos }
    265  1.3  christos 
    266  1.3  christos static int
    267  1.7       wiz default_window_size_skip_client(struct client *loop, __unused int type,
    268  1.3  christos     __unused int current, struct session *s, struct window *w)
    269  1.3  christos {
    270  1.3  christos 	if (w != NULL && !session_has(loop->session, w))
    271  1.3  christos 		return (1);
    272  1.3  christos 	if (w == NULL && loop->session != s)
    273  1.3  christos 		return (1);
    274  1.3  christos 	return (0);
    275  1.3  christos }
    276  1.3  christos 
    277  1.3  christos void
    278  1.3  christos default_window_size(struct client *c, struct session *s, struct window *w,
    279  1.3  christos 	u_int *sx, u_int *sy, u_int *xpixel, u_int *ypixel, int type)
    280  1.3  christos {
    281  1.3  christos 	const char	*value;
    282  1.3  christos 
    283  1.3  christos 	/* Get type if not provided. */
    284  1.3  christos 	if (type == -1)
    285  1.3  christos 		type = options_get_number(global_w_options, "window-size");
    286  1.2  christos 
    287  1.3  christos 	/*
    288  1.3  christos 	 * Latest clients can use the given client if suitable. If there is no
    289  1.3  christos 	 * client and no window, use the default size as for manual type.
    290  1.3  christos 	 */
    291  1.5       wiz 	if (type == WINDOW_SIZE_LATEST && c != NULL && !ignore_client_size(c)) {
    292  1.5       wiz 		*sx = c->tty.sx;
    293  1.5       wiz 		*sy = c->tty.sy - status_line_size(c);
    294  1.5       wiz 		*xpixel = c->tty.xpixel;
    295  1.5       wiz 		*ypixel = c->tty.ypixel;
    296  1.5       wiz 		log_debug("%s: using %ux%u from %s", __func__, *sx, *sy,
    297  1.5       wiz 		    c->name);
    298  1.5       wiz 		goto done;
    299  1.5       wiz 	}
    300  1.5       wiz 
    301  1.7       wiz 	/*
    302  1.7       wiz 	 * Ignore the given client if it is a control client - the creating
    303  1.7       wiz 	 * client should only affect the size if it is not a control client.
    304  1.7       wiz 	 */
    305  1.7       wiz 	if (c != NULL && (c->flags & CLIENT_CONTROL))
    306  1.7       wiz 		c = NULL;
    307  1.1      jmmv 
    308  1.3  christos 	/*
    309  1.3  christos 	 * Look for a client to base the size on. If none exists (or the type
    310  1.3  christos 	 * is manual), use the default-size option.
    311  1.3  christos 	 */
    312  1.4  christos 	if (!clients_calculate_size(type, 0, c, s, w,
    313  1.3  christos 	    default_window_size_skip_client, sx, sy, xpixel, ypixel)) {
    314  1.3  christos 		value = options_get_string(s->options, "default-size");
    315  1.3  christos 		if (sscanf(value, "%ux%u", sx, sy) != 2) {
    316  1.3  christos 			*sx = 80;
    317  1.3  christos 			*sy = 24;
    318  1.3  christos 		}
    319  1.4  christos 		log_debug("%s: using %ux%u from default-size", __func__, *sx,
    320  1.4  christos 		    *sy);
    321  1.1      jmmv 	}
    322  1.1      jmmv 
    323  1.2  christos done:
    324  1.3  christos 	/* Make sure the limits are enforced. */
    325  1.2  christos 	if (*sx < WINDOW_MINIMUM)
    326  1.2  christos 		*sx = WINDOW_MINIMUM;
    327  1.2  christos 	if (*sx > WINDOW_MAXIMUM)
    328  1.2  christos 		*sx = WINDOW_MAXIMUM;
    329  1.2  christos 	if (*sy < WINDOW_MINIMUM)
    330  1.2  christos 		*sy = WINDOW_MINIMUM;
    331  1.2  christos 	if (*sy > WINDOW_MAXIMUM)
    332  1.2  christos 		*sy = WINDOW_MAXIMUM;
    333  1.4  christos 	log_debug("%s: resulting size is %ux%u", __func__, *sx, *sy);
    334  1.2  christos }
    335  1.1      jmmv 
    336  1.3  christos static int
    337  1.3  christos recalculate_size_skip_client(struct client *loop, __unused int type,
    338  1.3  christos     int current, __unused struct session *s, struct window *w)
    339  1.3  christos {
    340  1.3  christos 	/*
    341  1.3  christos 	 * If the current flag is set, then skip any client where this window
    342  1.3  christos 	 * is not the current window - this is used for aggressive-resize.
    343  1.3  christos 	 * Otherwise skip any session that doesn't contain the window.
    344  1.3  christos 	 */
    345  1.5       wiz 	if (loop->session->curw == NULL)
    346  1.5       wiz 		return (1);
    347  1.3  christos 	if (current)
    348  1.3  christos 		return (loop->session->curw->window != w);
    349  1.3  christos 	return (session_has(loop->session, w) == 0);
    350  1.3  christos }
    351  1.3  christos 
    352  1.2  christos void
    353  1.3  christos recalculate_size(struct window *w, int now)
    354  1.2  christos {
    355  1.3  christos 	u_int	sx, sy, xpixel = 0, ypixel = 0;
    356  1.3  christos 	int	type, current, changed;
    357  1.2  christos 
    358  1.3  christos 	/*
    359  1.3  christos 	 * Do not attempt to resize windows which have no pane, they must be on
    360  1.3  christos 	 * the way to destruction.
    361  1.3  christos 	 */
    362  1.2  christos 	if (w->active == NULL)
    363  1.2  christos 		return;
    364  1.5       wiz 	log_debug("%s: @%u is %ux%u", __func__, w->id, w->sx, w->sy);
    365  1.2  christos 
    366  1.3  christos 	/*
    367  1.3  christos 	 * Type is manual, smallest, largest, latest. Current is the
    368  1.3  christos 	 * aggressive-resize option (do not resize based on clients where the
    369  1.3  christos 	 * window is not the current window).
    370  1.3  christos 	 */
    371  1.2  christos 	type = options_get_number(w->options, "window-size");
    372  1.2  christos 	current = options_get_number(w->options, "aggressive-resize");
    373  1.2  christos 
    374  1.3  christos 	/* Look for a suitable client and get the new size. */
    375  1.4  christos 	changed = clients_calculate_size(type, current, NULL, NULL, w,
    376  1.3  christos 	    recalculate_size_skip_client, &sx, &sy, &xpixel, &ypixel);
    377  1.2  christos 
    378  1.3  christos 	/*
    379  1.3  christos 	 * Make sure the size has actually changed. If the window has already
    380  1.3  christos 	 * got a resize scheduled, then use the new size; otherwise the old.
    381  1.3  christos 	 */
    382  1.3  christos 	if (w->flags & WINDOW_RESIZE) {
    383  1.3  christos 		if (!now && changed && w->new_sx == sx && w->new_sy == sy)
    384  1.2  christos 			changed = 0;
    385  1.3  christos 	} else {
    386  1.3  christos 		if (!now && changed && w->sx == sx && w->sy == sy)
    387  1.2  christos 			changed = 0;
    388  1.2  christos 	}
    389  1.1      jmmv 
    390  1.3  christos 	/*
    391  1.3  christos 	 * If the size hasn't changed, update the window offset but not the
    392  1.3  christos 	 * size.
    393  1.3  christos 	 */
    394  1.2  christos 	if (!changed) {
    395  1.5       wiz 		log_debug("%s: @%u no size change", __func__, w->id);
    396  1.2  christos 		tty_update_window_offset(w);
    397  1.2  christos 		return;
    398  1.1      jmmv 	}
    399  1.3  christos 
    400  1.3  christos 	/*
    401  1.3  christos 	 * If the now flag is set or if the window is sized manually, change
    402  1.3  christos 	 * the size immediately. Otherwise set the flag and it will be done
    403  1.3  christos 	 * later.
    404  1.3  christos 	 */
    405  1.5       wiz 	log_debug("%s: @%u new size %ux%u", __func__, w->id, sx, sy);
    406  1.3  christos 	if (now || type == WINDOW_SIZE_MANUAL)
    407  1.3  christos 		resize_window(w, sx, sy, xpixel, ypixel);
    408  1.3  christos 	else {
    409  1.3  christos 		w->new_sx = sx;
    410  1.3  christos 		w->new_sy = sy;
    411  1.3  christos 		w->new_xpixel = xpixel;
    412  1.3  christos 		w->new_ypixel = ypixel;
    413  1.3  christos 
    414  1.3  christos 		w->flags |= WINDOW_RESIZE;
    415  1.3  christos 		tty_update_window_offset(w);
    416  1.3  christos 	}
    417  1.2  christos }
    418  1.2  christos 
    419  1.2  christos void
    420  1.2  christos recalculate_sizes(void)
    421  1.2  christos {
    422  1.3  christos 	recalculate_sizes_now(0);
    423  1.3  christos }
    424  1.3  christos 
    425  1.3  christos void
    426  1.3  christos recalculate_sizes_now(int now)
    427  1.3  christos {
    428  1.2  christos 	struct session	*s;
    429  1.2  christos 	struct client	*c;
    430  1.2  christos 	struct window	*w;
    431  1.2  christos 
    432  1.2  christos 	/*
    433  1.2  christos 	 * Clear attached count and update saved status line information for
    434  1.2  christos 	 * each session.
    435  1.2  christos 	 */
    436  1.2  christos 	RB_FOREACH(s, sessions, &sessions) {
    437  1.2  christos 		s->attached = 0;
    438  1.2  christos 		status_update_cache(s);
    439  1.2  christos 	}
    440  1.2  christos 
    441  1.2  christos 	/*
    442  1.2  christos 	 * Increment attached count and check the status line size for each
    443  1.2  christos 	 * client.
    444  1.2  christos 	 */
    445  1.2  christos 	TAILQ_FOREACH(c, &clients, entry) {
    446  1.2  christos 		s = c->session;
    447  1.2  christos 		if (s != NULL && !(c->flags & CLIENT_UNATTACHEDFLAGS))
    448  1.2  christos 			s->attached++;
    449  1.2  christos 		if (ignore_client_size(c))
    450  1.2  christos 			continue;
    451  1.2  christos 		if (c->tty.sy <= s->statuslines || (c->flags & CLIENT_CONTROL))
    452  1.2  christos 			c->flags |= CLIENT_STATUSOFF;
    453  1.2  christos 		else
    454  1.2  christos 			c->flags &= ~CLIENT_STATUSOFF;
    455  1.2  christos 	}
    456  1.2  christos 
    457  1.2  christos 	/* Walk each window and adjust the size. */
    458  1.2  christos 	RB_FOREACH(w, windows, &windows)
    459  1.3  christos 		recalculate_size(w, now);
    460  1.1      jmmv }
    461