aboutsummaryrefslogtreecommitdiff
path: root/resize.c
diff options
context:
space:
mode:
Diffstat (limited to 'resize.c')
-rw-r--r--resize.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/resize.c b/resize.c
new file mode 100644
index 00000000..50e12fb0
--- /dev/null
+++ b/resize.c
@@ -0,0 +1,138 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <string.h>
+
+#include "tmux.h"
+
+/*
+ * Recalculate window and session sizes.
+ *
+ * Every session has the size of the smallest client it is attached to and
+ * every window the size of the smallest session it is attached to.
+ *
+ * So, when a client is resized or a session attached to or detached from a
+ * client, the window sizes must be recalculated. For each session, find the
+ * smallest client it is attached to, and resize it to that size. Then for
+ * every window, find the smallest session it is attached to, resize it to that
+ * size and clear and redraw every client with it as the current window.
+ *
+ * This is quite inefficient - better/additional data structures are needed
+ * to make it better.
+ *
+ * As a side effect, this function updates the SESSION_UNATTACHED flag. This
+ * flag is necessary to make sure unattached sessions do not limit the size of
+ * windows that are attached both to them and to other (attached) sessions.
+ */
+
+void
+recalculate_sizes(void)
+{
+ struct session *s;
+ struct client *c;
+ struct window *w;
+ u_int i, j, ssx, ssy, has, limit;
+ int flag;
+
+ for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
+ s = ARRAY_ITEM(&sessions, i);
+ if (s == NULL)
+ continue;
+
+ ssx = ssy = UINT_MAX;
+ for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
+ c = ARRAY_ITEM(&clients, j);
+ if (c == NULL)
+ continue;
+ if (c->session == s) {
+ if (c->tty.sx < ssx)
+ ssx = c->tty.sx;
+ if (c->tty.sy < ssy)
+ ssy = c->tty.sy;
+ }
+ }
+ if (ssx == UINT_MAX || ssy == UINT_MAX) {
+ s->flags |= SESSION_UNATTACHED;
+ continue;
+ }
+ s->flags &= ~SESSION_UNATTACHED;
+
+ if (options_get_number(&s->options, "status")) {
+ if (ssy == 0)
+ ssy = 1;
+ else
+ ssy--;
+ }
+ if (s->sx == ssx && s->sy == ssy)
+ continue;
+
+ log_debug(
+ "session size %u,%u (was %u,%u)", ssx, ssy, s->sx, s->sy);
+
+ s->sx = ssx;
+ s->sy = ssy;
+ }
+
+ for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
+ w = ARRAY_ITEM(&windows, i);
+ if (w == NULL)
+ continue;
+ flag = options_get_number(&w->options, "aggressive-resize");
+
+ ssx = ssy = UINT_MAX;
+ for (j = 0; j < ARRAY_LENGTH(&sessions); j++) {
+ s = ARRAY_ITEM(&sessions, j);
+ if (s == NULL || s->flags & SESSION_UNATTACHED)
+ continue;
+ if (flag)
+ has = s->curw->window == w;
+ else
+ has = session_has(s, w);
+ if (has) {
+ if (s->sx < ssx)
+ ssx = s->sx;
+ if (s->sy < ssy)
+ ssy = s->sy;
+ }
+ }
+ if (ssx == UINT_MAX || ssy == UINT_MAX) {
+ w->flags |= WINDOW_HIDDEN;
+ continue;
+ }
+ w->flags &= ~WINDOW_HIDDEN;
+
+ limit = options_get_number(&w->options, "force-width");
+ if (limit != 0 && ssx > limit)
+ ssx = limit;
+ limit = options_get_number(&w->options, "force-height");
+ if (limit != 0 && ssy > limit)
+ ssy = limit;
+
+ if (w->sx == ssx && w->sy == ssy)
+ continue;
+
+ log_debug(
+ "window size %u,%u (was %u,%u)", ssx, ssy, w->sx, w->sy);
+
+ window_resize(w, ssx, ssy);
+ server_redraw_window(w);
+ layout_refresh(w, 0);
+ }
+}