summaryrefslogtreecommitdiffstats
path: root/resize.c
diff options
context:
space:
mode:
authornicm <nicm>2021-08-27 17:15:57 +0000
committernicm <nicm>2021-08-27 17:15:57 +0000
commitfd756a150b43d319d08ac4117f34edef9e0438c4 (patch)
tree003f77b6051466412eba1fa0260b9e95c89e3923 /resize.c
parent24636be42b4b0463afe5c72e1d982f28729a0579 (diff)
Allow control mode clients to set a hard limit on the window width and
height, GitHub issue 2594.
Diffstat (limited to 'resize.c')
-rw-r--r--resize.c93
1 files changed, 76 insertions, 17 deletions
diff --git a/resize.c b/resize.c
index f321e7d2..8416ad6a 100644
--- a/resize.c
+++ b/resize.c
@@ -87,7 +87,9 @@ ignore_client_size(struct client *c)
return (1);
}
}
- if ((c->flags & CLIENT_CONTROL) && (~c->flags & CLIENT_SIZECHANGED))
+ if ((c->flags & CLIENT_CONTROL) &&
+ (~c->flags & CLIENT_SIZECHANGED) &&
+ (~c->flags & CLIENT_WINDOWSIZECHANGED))
return (1);
return (0);
}
@@ -113,23 +115,25 @@ clients_calculate_size(int type, int current, struct client *c,
int, int, struct session *, struct window *), u_int *sx, u_int *sy,
u_int *xpixel, u_int *ypixel)
{
- struct client *loop;
- u_int cx, cy, n = 0;
-
- /* Manual windows do not have their size changed based on a client. */
- if (type == WINDOW_SIZE_MANUAL) {
- log_debug("%s: type is manual", __func__);
- return (0);
- }
+ struct client *loop;
+ struct client_window *cw;
+ u_int cx, cy, n = 0;
/*
* Start comparing with 0 for largest and UINT_MAX for smallest or
* latest.
*/
- if (type == WINDOW_SIZE_LARGEST)
- *sx = *sy = 0;
- else
- *sx = *sy = UINT_MAX;
+ if (type == WINDOW_SIZE_LARGEST) {
+ *sx = 0;
+ *sy = 0;
+ } else if (type == WINDOW_SIZE_MANUAL) {
+ *sx = w->manual_sx;
+ *sy = w->manual_sy;
+ log_debug("%s: manual size %ux%u", __func__, *sx, *sy);
+ } else {
+ *sx = UINT_MAX;
+ *sy = UINT_MAX;
+ }
*xpixel = *ypixel = 0;
/*
@@ -139,14 +143,18 @@ clients_calculate_size(int type, int current, struct client *c,
if (type == WINDOW_SIZE_LATEST && w != NULL)
n = clients_with_window(w);
+ /* Skip setting the size if manual */
+ if (type == WINDOW_SIZE_MANUAL)
+ goto skip;
+
/* Loop over the clients and work out the size. */
TAILQ_FOREACH(loop, &clients, entry) {
if (loop != c && ignore_client_size(loop)) {
- log_debug("%s: ignoring %s", __func__, loop->name);
+ log_debug("%s: ignoring %s (1)", __func__, loop->name);
continue;
}
if (loop != c && skip_client(loop, type, current, s, w)) {
- log_debug("%s: skipping %s", __func__, loop->name);
+ log_debug("%s: skipping %s (1)", __func__, loop->name);
continue;
}
@@ -160,9 +168,23 @@ clients_calculate_size(int type, int current, struct client *c,
continue;
}
+ /*
+ * If the client has a per-window size, use this instead if it is
+ * smaller.
+ */
+ if (w != NULL)
+ cw = server_client_get_client_window(loop, w->id);
+ else
+ cw = NULL;
+
/* Work out this client's size. */
- cx = loop->tty.sx;
- cy = loop->tty.sy - status_line_size(loop);
+ if (cw != NULL) {
+ cx = cw->sx;
+ cy = cw->sy;
+ } else {
+ cx = loop->tty.sx;
+ cy = loop->tty.sy - status_line_size(loop);
+ }
/*
* If it is larger or smaller than the best so far, update the
@@ -191,7 +213,44 @@ clients_calculate_size(int type, int current, struct client *c,
else
log_debug("%s: no calculated size", __func__);
+skip:
+ /*
+ * Do not allow any size to be larger than the per-client window size
+ * if one exists.
+ */
+ if (w != NULL) {
+ TAILQ_FOREACH(loop, &clients, entry) {
+ if (loop != c && ignore_client_size(loop))
+ continue;
+ if (loop != c && skip_client(loop, type, current, s, w))
+ continue;
+
+ /* Look up per-window size if any. */
+ if (~loop->flags & CLIENT_WINDOWSIZECHANGED)
+ continue;
+ cw = server_client_get_client_window(loop, w->id);
+ if (cw == NULL)
+ continue;
+
+ /* Clamp the size. */
+ log_debug("%s: %s size for @%u is %ux%u", __func__,
+ loop->name, w->id, cw->sx, cw->sy);
+ if (cw->sx != 0 && *sx > cw->sx)
+ *sx = cw->sx;
+ if (cw->sy != 0 && *sy > cw->sy)
+ *sy = cw->sy;
+ }
+ }
+ if (*sx != UINT_MAX && *sy != UINT_MAX)
+ log_debug("%s: calculated size %ux%u", __func__, *sx, *sy);
+ else
+ log_debug("%s: no calculated size", __func__);
+
/* Return whether a suitable size was found. */
+ if (type == WINDOW_SIZE_MANUAL) {
+ log_debug("%s: type is manual", __func__);
+ return (1);
+ }
if (type == WINDOW_SIZE_LARGEST) {
log_debug("%s: type is largest", __func__);
return (*sx != 0 && *sy != 0);