height, GitHub issue 2594.
-/* $OpenBSD: cmd-refresh-client.c,v 1.44 2021/08/21 10:28:05 nicm Exp $ */
+/* $OpenBSD: cmd-refresh-client.c,v 1.45 2021/08/27 17:15:57 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
free(copy);
}
+static enum cmd_retval
+cmd_refresh_client_control_client_size(struct cmd *self, struct cmdq_item *item)
+{
+ struct args *args = cmd_get_args(self);
+ struct client *tc = cmdq_get_target_client(item);
+ const char *size = args_get(args, 'C');
+ u_int w, x, y;
+ struct client_window *cw;
+
+ if (sscanf(size, "@%u:%ux%u", &w, &x, &y) == 3) {
+ if (x < WINDOW_MINIMUM || x > WINDOW_MAXIMUM ||
+ y < WINDOW_MINIMUM || y > WINDOW_MAXIMUM) {
+ cmdq_error(item, "size too small or too big");
+ return (CMD_RETURN_ERROR);
+ }
+ log_debug("%s: client %s window @%u: size %ux%u", __func__,
+ tc->name, w, x, y);
+ cw = server_client_add_client_window(tc, w);
+ cw->sx = x;
+ cw->sy = y;
+ tc->flags |= CLIENT_WINDOWSIZECHANGED;
+ recalculate_sizes_now(1);
+ return (CMD_RETURN_NORMAL);
+ }
+ if (sscanf(size, "@%u:", &w) == 1) {
+ cw = server_client_get_client_window(tc, w);
+ if (cw != NULL) {
+ log_debug("%s: client %s window @%u: no size", __func__,
+ tc->name, w);
+ cw->sx = 0;
+ cw->sy = 0;
+ recalculate_sizes_now(1);
+ }
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (sscanf(size, "%u,%u", &x, &y) != 2 &&
+ sscanf(size, "%ux%u", &x, &y) != 2) {
+ cmdq_error(item, "bad size argument");
+ return (CMD_RETURN_ERROR);
+ }
+ if (x < WINDOW_MINIMUM || x > WINDOW_MAXIMUM ||
+ y < WINDOW_MINIMUM || y > WINDOW_MAXIMUM) {
+ cmdq_error(item, "size too small or too big");
+ return (CMD_RETURN_ERROR);
+ }
+ tty_set_size(&tc->tty, x, y, 0, 0);
+ tc->flags |= CLIENT_SIZECHANGED;
+ recalculate_sizes_now(1);
+ return (CMD_RETURN_NORMAL);
+}
+
static void
cmd_refresh_client_update_offset(struct client *tc, const char *value)
{
struct client *tc = cmdq_get_target_client(item);
struct tty *tty = &tc->tty;
struct window *w;
- const char *size, *errstr;
- u_int x, y, adjust;
+ const char *errstr;
+ u_int adjust;
struct args_value *av;
if (args_has(args, 'c') ||
if (args_has(args, 'C')) {
if (~tc->flags & CLIENT_CONTROL)
goto not_control_client;
- size = args_get(args, 'C');
- if (sscanf(size, "%u,%u", &x, &y) != 2 &&
- sscanf(size, "%ux%u", &x, &y) != 2) {
- cmdq_error(item, "bad size argument");
- return (CMD_RETURN_ERROR);
- }
- if (x < WINDOW_MINIMUM || x > WINDOW_MAXIMUM ||
- y < WINDOW_MINIMUM || y > WINDOW_MAXIMUM) {
- cmdq_error(item, "size too small or too big");
- return (CMD_RETURN_ERROR);
- }
- tty_set_size(&tc->tty, x, y, 0, 0);
- tc->flags |= CLIENT_SIZECHANGED;
- recalculate_sizes_now(1);
- return (CMD_RETURN_NORMAL);
+ return (cmd_refresh_client_control_client_size(self, item));
}
if (args_has(args, 'S')) {
-/* $OpenBSD: cmd-resize-window.c,v 1.8 2021/08/21 10:28:05 nicm Exp $ */
+/* $OpenBSD: cmd-resize-window.c,v 1.9 2021/08/27 17:15:57 nicm Exp $ */
/*
* Copyright (c) 2018 Nicholas Marriott <nicholas.marriott@gmail.com>
}
options_set_number(w->options, "window-size", WINDOW_SIZE_MANUAL);
- resize_window(w, sx, sy, xpixel, ypixel);
+ w->manual_sx = sx;
+ w->manual_sy = sy;
+ recalculate_size(w, 1);
return (CMD_RETURN_NORMAL);
}
-/* $OpenBSD: resize.c,v 1.46 2021/08/25 10:18:01 nicm Exp $ */
+/* $OpenBSD: resize.c,v 1.47 2021/08/27 17:15:57 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
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);
}
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;
/*
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;
}
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
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);
-/* $OpenBSD: server-client.c,v 1.384 2021/08/22 13:48:29 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.385 2021/08/27 17:15:57 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
}
/* Get client window. */
-static struct client_window *
+struct client_window *
server_client_get_client_window(struct client *c, u_int id)
{
struct client_window cw = { .window = id };
return (RB_FIND(client_windows, &c->windows, &cw));
}
+/* Add client window. */
+struct client_window *
+server_client_add_client_window(struct client *c, u_int id)
+{
+ struct client_window *cw;
+
+ cw = server_client_get_client_window(c, id);
+ if (cw == NULL) {
+ cw = xcalloc(1, sizeof *cw);
+ cw->window = id;
+ RB_INSERT(client_windows, &c->windows, cw);
+ }
+ return cw;
+}
+
/* Get client active pane. */
struct window_pane *
server_client_get_pane(struct client *c)
if (s == NULL)
return;
- cw = server_client_get_client_window(c, s->curw->window->id);
- if (cw == NULL) {
- cw = xcalloc(1, sizeof *cw);
- cw->window = s->curw->window->id;
- RB_INSERT(client_windows, &c->windows, cw);
- }
+ cw = server_client_add_client_window(c, s->curw->window->id);
cw->pane = wp;
log_debug("%s pane now %%%u", c->name, wp->id);
}
-.\" $OpenBSD: tmux.1,v 1.854 2021/08/13 18:54:54 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.855 2021/08/27 17:15:57 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 13 2021 $
+.Dd $Mdocdate: August 27 2021 $
.Dt TMUX 1
.Os
.Sh NAME
.Op Fl cDlLRSU
.Op Fl A Ar pane:state
.Op Fl B Ar name:what:format
-.Op Fl C Ar XxY
+.Op Fl C Ar size
.Op Fl f Ar flags
.Op Fl t Ar target-client
.Op Ar adjustment
it.
.Pp
.Fl C
-sets the width and height of a control mode client.
+sets the width and height of a control mode client or of a window for a
+control mode client,
+.Ar size
+must be one of
+.Ql widthxheight
+or
+.Ql window ID:widthxheight ,
+for example
+.Ql 80x24
+or
+.Ql @0:80x24 .
.Fl A
allows a control mode client to trigger actions on a pane.
The argument is a pane ID (with leading
-/* $OpenBSD: tmux.h,v 1.1137 2021/08/25 08:51:55 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1138 2021/08/27 17:15:57 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
u_int sx;
u_int sy;
+ u_int manual_sx;
+ u_int manual_sy;
u_int xpixel;
u_int ypixel;
struct client_window {
u_int window;
struct window_pane *pane;
+
+ u_int sx;
+ u_int sy;
+
RB_ENTRY(client_window) entry;
};
RB_HEAD(client_windows, client_window);
#define CLIENT_ACTIVEPANE 0x80000000ULL
#define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL
#define CLIENT_CONTROL_WAITEXIT 0x200000000ULL
+#define CLIENT_WINDOWSIZECHANGED 0x400000000ULL
#define CLIENT_ALLREDRAWFLAGS \
(CLIENT_REDRAWWINDOW| \
CLIENT_REDRAWSTATUS| \
const char *server_client_get_cwd(struct client *, struct session *);
void server_client_set_flags(struct client *, const char *);
const char *server_client_get_flags(struct client *);
+struct client_window *server_client_get_client_window(struct client *, u_int);
+struct client_window *server_client_add_client_window(struct client *, u_int);
struct window_pane *server_client_get_pane(struct client *);
void server_client_set_pane(struct client *, struct window_pane *);
void server_client_remove_pane(struct window_pane *);
-/* $OpenBSD: window.c,v 1.275 2021/08/20 17:36:03 nicm Exp $ */
+/* $OpenBSD: window.c,v 1.276 2021/08/27 17:15:57 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
w->sx = sx;
w->sy = sy;
+ w->manual_sx = sx;
+ w->manual_sy = sy;
w->xpixel = xpixel;
w->ypixel = ypixel;