Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-07-07 09:15:06 +01:00
9 changed files with 234 additions and 235 deletions

View File

@@ -51,10 +51,9 @@ cmd_break_pane_float(struct cmdq_item *item, struct args *args,
struct window *w, struct window_pane *wp)
{
struct layout_cell *lc = wp->layout_cell;
u_int sx = lc->saved_sx, sy = lc->saved_sy;
int ox = lc->saved_xoff, oy = lc->saved_yoff;
char *cause = NULL;
enum pane_lines lines = window_get_pane_lines(w);
struct layout_geometry *fg = &lc->fg;
if (window_pane_is_floating(wp)) {
cmdq_error(item, "pane is already floating");
@@ -65,14 +64,13 @@ cmd_break_pane_float(struct cmdq_item *item, struct args *args,
return (CMD_RETURN_ERROR);
}
if (layout_floating_args_parse(item, args, lines, w, &sx, &sy, &ox, &oy,
&cause) != 0) {
if (layout_floating_args_parse(item, args, lines, w, fg, &cause) != 0) {
cmdq_error(item, "failed to float pane: %s", cause);
free(cause);
return (CMD_RETURN_ERROR);
}
layout_remove_tile(w, lc);
layout_set_size(lc, sx, sy, ox, oy);
layout_set_size(lc, fg->sx, fg->sy, fg->xoff, fg->yoff);
lc->flags |= LAYOUT_CELL_FLOATING;
TAILQ_REMOVE(&w->z_index, wp, zentry);

View File

@@ -71,8 +71,9 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl,
struct window *w = wl->window;
struct layout_cell *lc = wp->layout_cell;
struct window_pane *owp;
int wx = w->sx, wy = w->sy, px = lc->sx;
int py = lc->sy, xoff = lc->xoff, yoff = lc->yoff;
int wx = w->sx, wy = w->sy;
int px = lc->g.sx, py = lc->g.sy;
int xoff = lc->g.xoff, yoff = lc->g.yoff;
int border = 1;
if (window_pane_get_pane_lines(wp) == PANE_LINES_NONE)
@@ -180,9 +181,9 @@ cmd_join_pane_place(struct cmdq_item *item, struct winlink *wl,
return (CMD_RETURN_ERROR);
}
if (xoff != lc->xoff || yoff != lc->yoff) {
lc->xoff = xoff;
lc->yoff = yoff;
if (xoff != lc->g.xoff || yoff != lc->g.yoff) {
lc->g.xoff = xoff;
lc->g.yoff = yoff;
layout_fix_panes(w, NULL);
}
notify_window("window-layout-changed", w);
@@ -200,7 +201,7 @@ cmd_join_pane_move(struct cmdq_item *item, struct args *args,
const char *errstr, *argval;
const char flags[] = { 'U', 'D', 'L', 'R' };
char *cause = NULL, flag;
int xoff = lc->xoff, yoff = lc->yoff, adjust;
int xoff = lc->g.xoff, yoff = lc->g.yoff, adjust;
u_int i;
enum pane_lines lines = window_pane_get_pane_lines(wp);
@@ -251,9 +252,9 @@ cmd_join_pane_move(struct cmdq_item *item, struct args *args,
xoff += adjust;
}
if (xoff != lc->xoff || yoff != lc->yoff) {
lc->xoff = xoff;
lc->yoff = yoff;
if (xoff != lc->g.xoff || yoff != lc->g.yoff) {
lc->g.xoff = xoff;
lc->g.yoff = yoff;
layout_fix_panes(w, NULL);
notify_window("window-layout-changed", w);
server_redraw_window(w);
@@ -319,8 +320,8 @@ cmd_join_pane_mouse_move(struct client *c, struct mouse_event *m)
ly = m->statusat - 1;
if (x != lx || y != ly) {
lc->xoff += x - lx;
lc->yoff += y - ly;
lc->g.xoff += x - lx;
lc->g.yoff += y - ly;
layout_fix_panes(w, NULL);
server_redraw_window(w);
server_redraw_window_borders(w);
@@ -378,10 +379,11 @@ cmd_join_pane_tile(struct cmdq_item *item, struct args *args, struct window *w,
return (CMD_RETURN_ERROR);
}
lc->saved_sx = lc->sx;
lc->saved_sy = lc->sy;
lc->saved_xoff = lc->xoff;
lc->saved_yoff = lc->yoff;
lc->fg.sx = lc->g.sx;
lc->fg.sy = lc->g.sy;
lc->fg.xoff = lc->g.xoff;
lc->fg.yoff = lc->g.yoff;
if (layout_insert_tile(w, lc) != 0) {
cmdq_error(item, "no space for a new pane");
return (CMD_RETURN_ERROR);

View File

@@ -270,10 +270,10 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
if ((lx == left || lx == left + 1) && ly == wp->yoff - 1) {
/* Top left corner. */
new_sx = lc->sx + (lx - x);
new_sx = lc->g.sx + (lx - x);
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = lc->sy + (ly - y);
new_sy = lc->g.sy + (ly - y);
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
new_xoff = x + 1; /* because mouse is on border at xoff - 1 */
@@ -283,65 +283,65 @@ cmd_resize_pane_mouse_resize_move_floating(struct client *c,
} else if ((lx == right + 1 || lx == right) &&
ly == wp->yoff - 1) {
/* Top right corner. */
new_sx = x - lc->xoff;
new_sx = x - lc->g.xoff;
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = lc->sy + (ly - y);
new_sy = lc->g.sy + (ly - y);
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
new_yoff = y + 1;
layout_set_size(lc, new_sx, new_sy, lc->xoff, new_yoff);
layout_set_size(lc, new_sx, new_sy, lc->g.xoff, new_yoff);
resizes++;
} else if ((lx == left || lx == left + 1) &&
ly == wp->yoff + sy) {
/* Bottom left corner. */
new_sx = lc->sx + (lx - x);
new_sx = lc->g.sx + (lx - x);
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = y - lc->yoff;
new_sy = y - lc->g.yoff;
if (new_sy < PANE_MINIMUM)
return;
new_xoff = x + 1;
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->yoff);
layout_set_size(lc, new_sx, new_sy, new_xoff, lc->g.yoff);
resizes++;
} else if ((lx == right + 1 || lx == right) &&
ly == wp->yoff + sy) {
/* Bottom right corner. */
new_sx = x - lc->xoff;
new_sx = x - lc->g.xoff;
if (new_sx < PANE_MINIMUM)
new_sx = PANE_MINIMUM;
new_sy = y - lc->yoff;
new_sy = y - lc->g.yoff;
if (new_sy < PANE_MINIMUM)
new_sy = PANE_MINIMUM;
layout_set_size(lc, new_sx, new_sy, lc->xoff, lc->yoff);
layout_set_size(lc, new_sx, new_sy, lc->g.xoff, lc->g.yoff);
resizes++;
} else if (lx == right) {
/* Right border. */
new_sx = x - lc->xoff;
new_sx = x - lc->g.xoff;
if (new_sx < PANE_MINIMUM)
return;
layout_set_size(lc, new_sx, lc->sy, lc->xoff, lc->yoff);
layout_set_size(lc, new_sx, lc->g.sy, lc->g.xoff, lc->g.yoff);
resizes++;
} else if (lx == left) {
/* Left border. */
new_sx = lc->sx + (lx - x);
new_sx = lc->g.sx + (lx - x);
if (new_sx < PANE_MINIMUM)
return;
new_xoff = x + 1;
layout_set_size(lc, new_sx, lc->sy, new_xoff, lc->yoff);
layout_set_size(lc, new_sx, lc->g.sy, new_xoff, lc->g.yoff);
resizes++;
} else if (ly == wp->yoff + sy) {
/* Bottom border. */
new_sy = y - lc->yoff;
new_sy = y - lc->g.yoff;
if (new_sy < PANE_MINIMUM)
return;
layout_set_size(lc, lc->sx, new_sy, lc->xoff, lc->yoff);
layout_set_size(lc, lc->g.sx, new_sy, lc->g.xoff, lc->g.yoff);
resizes++;
} else if (ly == wp->yoff - 1) {
/* Top border (move instead of resize). */
new_xoff = lc->xoff + (x - lx);
new_xoff = lc->g.xoff + (x - lx);
new_yoff = y + 1;
layout_set_size(lc, lc->sx, lc->sy, new_xoff, new_yoff);
layout_set_size(lc, lc->g.sx, lc->g.sy, new_xoff, new_yoff);
resizes++;
}
if (resizes != 0) {

View File

@@ -101,10 +101,10 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
return (0);
if (lc->wp != NULL) {
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d,%u",
lc->sx, lc->sy, lc->xoff, lc->yoff, lc->wp->id);
lc->g.sx, lc->g.sy, lc->g.xoff, lc->g.yoff, lc->wp->id);
} else {
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d",
lc->sx, lc->sy, lc->xoff, lc->yoff);
lc->g.sx, lc->g.sy, lc->g.xoff, lc->g.yoff);
}
if (tmplen > (sizeof tmp) - 1)
return (-1);
@@ -145,24 +145,24 @@ layout_check(struct layout_cell *lc)
break;
case LAYOUT_LEFTRIGHT:
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (lcchild->sy != lc->sy)
if (lcchild->g.sy != lc->g.sy)
return (0);
if (!layout_check(lcchild))
return (0);
n += lcchild->sx + 1;
n += lcchild->g.sx + 1;
}
if (n - 1 != lc->sx)
if (n - 1 != lc->g.sx)
return (0);
break;
case LAYOUT_TOPBOTTOM:
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (lcchild->sx != lc->sx)
if (lcchild->g.sx != lc->g.sx)
return (0);
if (!layout_check(lcchild))
return (0);
n += lcchild->sy + 1;
n += lcchild->g.sy + 1;
}
if (n - 1 != lc->sy)
if (n - 1 != lc->g.sy)
return (0);
break;
}
@@ -237,21 +237,21 @@ layout_parse(struct window *w, const char *layout, char **cause)
break;
case LAYOUT_LEFTRIGHT:
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
sy = lcchild->sy + 1;
sx += lcchild->sx + 1;
sy = lcchild->g.sy + 1;
sx += lcchild->g.sx + 1;
}
break;
case LAYOUT_TOPBOTTOM:
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
sx = lcchild->sx + 1;
sy += lcchild->sy + 1;
sx = lcchild->g.sx + 1;
sy += lcchild->g.sy + 1;
}
break;
}
if (tiled_lc->type != LAYOUT_WINDOWPANE &&
(tiled_lc->sx != sx || tiled_lc->sy != sy)) {
(tiled_lc->g.sx != sx || tiled_lc->g.sy != sy)) {
layout_print_cell(tiled_lc, __func__, 0);
tiled_lc->sx = sx - 1; tiled_lc->sy = sy - 1;
tiled_lc->g.sx = sx - 1; tiled_lc->g.sy = sy - 1;
}
/* Check the new layout. */
@@ -262,7 +262,7 @@ layout_parse(struct window *w, const char *layout, char **cause)
/* Resize window to the layout size. */
if (sx != 0 && sy != 0)
window_resize(w, tiled_lc->sx, tiled_lc->sy, -1, -1);
window_resize(w, tiled_lc->g.sx, tiled_lc->g.sy, -1, -1);
/* Destroy the old layout and swap to the new. */
layout_free_cell(w->layout_root, 0);
@@ -358,10 +358,10 @@ layout_construct_cell(struct layout_cell *lcparent, const char **layout)
}
lc = layout_create_cell(lcparent);
lc->sx = sx;
lc->sy = sy;
lc->xoff = xoff;
lc->yoff = yoff;
lc->g.sx = sx;
lc->g.sy = sy;
lc->g.xoff = xoff;
lc->g.yoff = yoff;
return (lc);
}

View File

@@ -170,8 +170,8 @@ layout_set_even(struct window *w, enum layout_type type)
TAILQ_INSERT_TAIL(&lcroot->cells, lcchild, entry);
lcchild->parent = lcroot;
if (layout_cell_is_tiled(lcchild)) {
lcchild->sx = w->sx;
lcchild->sy = w->sy;
lcchild->g.sx = w->sx;
lcchild->g.sy = w->sy;
}
}
@@ -182,7 +182,7 @@ layout_set_even(struct window *w, enum layout_type type)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
notify_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -291,7 +291,7 @@ layout_set_main_h(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
notify_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -388,7 +388,7 @@ layout_set_main_h_mirrored(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
notify_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -485,7 +485,7 @@ layout_set_main_v(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
notify_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -583,7 +583,7 @@ layout_set_main_v_mirrored(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
notify_window("window-layout-changed", w);
server_redraw_window(w);
}
@@ -705,7 +705,7 @@ layout_set_tiled(struct window *w)
layout_print_cell(w->layout_root, __func__, 1);
window_resize(w, lcroot->sx, lcroot->sy, -1, -1);
window_resize(w, lcroot->g.sx, lcroot->g.sy, -1, -1);
notify_window("window-layout-changed", w);
server_redraw_window(w);
}

274
layout.c
View File

@@ -56,6 +56,16 @@ static int layout_set_size_check(struct window *, struct layout_cell *,
static void layout_resize_child_cells(struct window *,
struct layout_cell *);
/* Initializes cell geometry to sentinel values. */
static void
layout_geometry_init(struct layout_geometry *lg)
{
lg->sx = UINT_MAX;
lg->sy = UINT_MAX;
lg->xoff = INT_MAX;
lg->yoff = INT_MAX;
}
/* Create a new layout cell. */
struct layout_cell *
layout_create_cell(struct layout_cell *lcparent)
@@ -67,17 +77,8 @@ layout_create_cell(struct layout_cell *lcparent)
lc->parent = lcparent;
TAILQ_INIT(&lc->cells);
lc->sx = UINT_MAX;
lc->sy = UINT_MAX;
lc->xoff = INT_MAX;
lc->yoff = INT_MAX;
lc->saved_sx = UINT_MAX;
lc->saved_sy = UINT_MAX;
lc->saved_xoff = INT_MAX;
lc->saved_yoff = INT_MAX;
layout_geometry_init(&lc->g);
layout_geometry_init(&lc->fg);
return (lc);
}
@@ -140,8 +141,8 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
break;
}
log_debug("%s:%*s%p type %s [parent %p] wp=%p [%d,%d %ux%u]", hdr, n,
" ", lc, type, lc->parent, lc->wp, lc->xoff, lc->yoff, lc->sx,
lc->sy);
" ", lc, type, lc->parent, lc->wp, lc->g.xoff, lc->g.yoff, lc->g.sx,
lc->g.sy);
switch (lc->type) {
case LAYOUT_LEFTRIGHT:
case LAYOUT_TOPBOTTOM:
@@ -160,10 +161,10 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
struct layout_cell *lcchild, *last = NULL;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if ((int)x >= lcchild->xoff &&
(int)x < lcchild->xoff + (int)lcchild->sx &&
(int)y >= lcchild->yoff &&
(int)y < lcchild->yoff + (int)lcchild->sy) {
if ((int)x >= lcchild->g.xoff &&
(int)x < lcchild->g.xoff + (int)lcchild->g.sx &&
(int)y >= lcchild->g.yoff &&
(int)y < lcchild->g.yoff + (int)lcchild->g.sy) {
/* Inside the cell - recurse. */
return (layout_search_by_border(lcchild, x, y));
}
@@ -175,13 +176,13 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
switch (lc->type) {
case LAYOUT_LEFTRIGHT:
if ((int)x < lcchild->xoff &&
(int)x >= last->xoff + (int)last->sx)
if ((int)x < lcchild->g.xoff &&
(int)x >= last->g.xoff + (int)last->g.sx)
return (last);
break;
case LAYOUT_TOPBOTTOM:
if ((int)y < lcchild->yoff &&
(int)y >= last->yoff + (int)last->sy)
if ((int)y < lcchild->g.yoff &&
(int)y >= last->g.yoff + (int)last->g.sy)
return (last);
break;
case LAYOUT_WINDOWPANE:
@@ -198,11 +199,11 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
void
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, int xoff, int yoff)
{
lc->sx = sx;
lc->sy = sy;
lc->g.sx = sx;
lc->g.sy = sy;
lc->xoff = xoff;
lc->yoff = yoff;
lc->g.xoff = xoff;
lc->g.yoff = yoff;
}
/* Make a cell a leaf cell. */
@@ -327,28 +328,28 @@ layout_fix_offsets1(struct layout_cell *lc)
int xoff, yoff;
if (lc->type == LAYOUT_LEFTRIGHT) {
xoff = lc->xoff;
xoff = lc->g.xoff;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (!layout_cell_is_tiled(lcchild) &&
!layout_cell_has_tiled_child(lcchild))
continue;
lcchild->xoff = xoff;
lcchild->yoff = lc->yoff;
lcchild->g.xoff = xoff;
lcchild->g.yoff = lc->g.yoff;
if (lcchild->type != LAYOUT_WINDOWPANE)
layout_fix_offsets1(lcchild);
xoff += lcchild->sx + 1;
xoff += lcchild->g.sx + 1;
}
} else {
yoff = lc->yoff;
yoff = lc->g.yoff;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (!layout_cell_is_tiled(lcchild) &&
!layout_cell_has_tiled_child(lcchild))
continue;
lcchild->xoff = lc->xoff;
lcchild->yoff = yoff;
lcchild->g.xoff = lc->g.xoff;
lcchild->g.yoff = yoff;
if (lcchild->type != LAYOUT_WINDOWPANE)
layout_fix_offsets1(lcchild);
yoff += lcchild->sy + 1;
yoff += lcchild->g.sy + 1;
}
}
}
@@ -363,8 +364,8 @@ layout_fix_offsets(struct window *w)
if (lc->flags & LAYOUT_CELL_FLOATING)
return;
lc->xoff = 0;
lc->yoff = 0;
lc->g.xoff = 0;
lc->g.yoff = 0;
layout_fix_offsets1(lc);
}
@@ -448,10 +449,10 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
old_sx = wp->sx;
old_sy = wp->sy;
wp->xoff = lc->xoff;
wp->yoff = lc->yoff;
sx = lc->sx;
sy = lc->sy;
wp->xoff = lc->g.xoff;
wp->yoff = lc->g.yoff;
sx = lc->g.sx;
sy = lc->g.sy;
if (!window_pane_is_floating(wp) &&
layout_add_horizontal_border(w, lc, status)) {
@@ -532,14 +533,14 @@ layout_resize_check(struct window *w, struct layout_cell *lc,
if (lc->type == LAYOUT_WINDOWPANE) {
/* Space available in this cell only. */
if (type == LAYOUT_LEFTRIGHT) {
available = lc->sx;
available = lc->g.sx;
if (w->sb == PANE_SCROLLBARS_ALWAYS)
minimum = PANE_MINIMUM + sb_style->width +
sb_style->pad;
else
minimum = PANE_MINIMUM;
} else {
available = lc->sy;
available = lc->g.sy;
if (layout_add_horizontal_border(w, lc, status))
minimum = PANE_MINIMUM + 1;
else
@@ -581,9 +582,9 @@ layout_resize_adjust(struct window *w, struct layout_cell *lc,
/* Adjust the cell size. */
if (type == LAYOUT_LEFTRIGHT)
lc->sx += change;
lc->g.sx += change;
else
lc->sy += change;
lc->g.sy += change;
/* If this is a leaf cell, that is all that is necessary. */
if (type == LAYOUT_WINDOWPANE)
@@ -643,9 +644,9 @@ layout_resize_set_size(struct window *w, struct layout_cell *lc,
int change;
if (type == LAYOUT_LEFTRIGHT)
change = size - lc->sx;
change = size - lc->g.sx;
else
change = size - lc->sy;
change = size - lc->g.sy;
layout_resize_adjust(w, lc, type, change);
}
@@ -719,9 +720,9 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
lcother = layout_cell_get_neighbour(lc);
if (lcother != NULL) {
if (lcparent->type == LAYOUT_LEFTRIGHT)
change = lc->sx + 1;
change = lc->g.sx + 1;
else
change = lc->sy + 1;
change = lc->g.sy + 1;
layout_resize_adjust(w, lcother, lcparent->type, change);
} else
layout_remove_tile(w, lcparent);
@@ -742,8 +743,8 @@ out:
lc->parent = lcparent->parent;
if (lc->parent == NULL) {
if (layout_cell_is_tiled(lc)) {
lc->xoff = 0;
lc->yoff = 0;
lc->g.xoff = 0;
lc->g.yoff = 0;
}
*lcroot = lc;
} else
@@ -794,29 +795,29 @@ layout_resize(struct window *w, u_int sx, u_int sy)
*/
if (lc->type == LAYOUT_WINDOWPANE && (lc->flags & LAYOUT_CELL_FLOATING))
return;
xchange = sx - lc->sx;
xchange = sx - lc->g.sx;
xlimit = layout_resize_check(w, lc, LAYOUT_LEFTRIGHT);
if (xchange < 0 && xchange < -xlimit)
xchange = -xlimit;
if (xlimit == 0) {
if (sx <= lc->sx) /* lc->sx is minimum possible */
if (sx <= lc->g.sx) /* lc->g.sx is minimum possible */
xchange = 0;
else
xchange = sx - lc->sx;
xchange = sx - lc->g.sx;
}
if (xchange != 0)
layout_resize_adjust(w, lc, LAYOUT_LEFTRIGHT, xchange);
/* Adjust vertically in a similar fashion. */
ychange = sy - lc->sy;
ychange = sy - lc->g.sy;
ylimit = layout_resize_check(w, lc, LAYOUT_TOPBOTTOM);
if (ychange < 0 && ychange < -ylimit)
ychange = -ylimit;
if (ylimit == 0) {
if (sy <= lc->sy) /* lc->sy is minimum possible */
if (sy <= lc->g.sy) /* lc->g.sy is minimum possible */
ychange = 0;
else
ychange = sy - lc->sy;
ychange = sy - lc->g.sy;
}
if (ychange != 0)
layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, ychange);
@@ -847,9 +848,9 @@ layout_resize_pane_to(struct window_pane *wp, enum layout_type type,
/* Work out the size adjustment. */
if (type == LAYOUT_LEFTRIGHT)
size = lc->sx;
size = lc->g.sx;
else
size = lc->sy;
size = lc->g.sy;
if (lc == TAILQ_LAST(&lcparent->cells, layout_cells))
change = size - new_size;
else
@@ -880,13 +881,13 @@ layout_resize_floating_pane_to(struct window_pane *wp, enum layout_type type,
}
if (type == LAYOUT_TOPBOTTOM) {
if (lc->sy == size)
if (lc->g.sy == size)
return (0);
lc->sy = size;
lc->g.sy = size;
} else {
if (lc->sx == size)
if (lc->g.sx == size)
return (0);
lc->sx = size;
lc->g.sx = size;
}
redraw_invalidate_scene(wp->window);
return (0);
@@ -908,23 +909,23 @@ layout_resize_floating_pane(struct window_pane *wp, enum layout_type type,
return (0);
if (type == LAYOUT_TOPBOTTOM) {
size = lc->sy + change;
size = lc->g.sy + change;
if (size < PANE_MINIMUM || size > PANE_MAXIMUM) {
*cause = xstrdup("change is too big or too small");
return (-1);
}
lc->sy = size;
lc->g.sy = size;
if (opposite)
lc->yoff -= change;
lc->g.yoff -= change;
} else {
size = lc->sx + change;
size = lc->g.sx + change;
if (size < PANE_MINIMUM || size > PANE_MAXIMUM) {
*cause = xstrdup("change is too big or too small");
return (-1);
}
lc->sx = size;
lc->g.sx = size;
if (opposite)
lc->xoff -= change;
lc->g.xoff -= change;
}
redraw_invalidate_scene(wp->window);
return (0);
@@ -1090,13 +1091,13 @@ layout_new_pane_size(struct window *w, u_int previous, struct layout_cell *lc,
*/
min = (PANE_MINIMUM + 1) * (count_left - 1);
if (type == LAYOUT_LEFTRIGHT) {
if (lc->sx - available > min)
min = lc->sx - available;
new_size = (lc->sx * size) / previous;
if (lc->g.sx - available > min)
min = lc->g.sx - available;
new_size = (lc->g.sx * size) / previous;
} else {
if (lc->sy - available > min)
min = lc->sy - available;
new_size = (lc->sy * size) / previous;
if (lc->g.sy - available > min)
min = lc->g.sy - available;
new_size = (lc->g.sy * size) / previous;
}
/* Check against the maximum and minimum size. */
@@ -1132,9 +1133,9 @@ layout_set_size_check(struct window *w, struct layout_cell *lc,
return (0);
if (type == LAYOUT_LEFTRIGHT)
previous = lc->sx;
previous = lc->g.sx;
else
previous = lc->sy;
previous = lc->g.sy;
idx = 0;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
@@ -1170,32 +1171,32 @@ static void
layout_resize_child_cells(struct window *w, struct layout_cell *lc)
{
struct layout_cell *lcchild;
u_int previous, available, count, idx;
u_int prev, available, count, idx;
if (lc->type == LAYOUT_WINDOWPANE)
return;
/* What is the current size used? */
count = 0;
previous = 0;
prev = 0;
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
if (!layout_cell_is_tiled(lcchild) &&
!layout_cell_has_tiled_child(lcchild))
continue;
count++;
if (lc->type == LAYOUT_LEFTRIGHT)
previous += lcchild->sx;
prev += lcchild->g.sx;
else if (lc->type == LAYOUT_TOPBOTTOM)
previous += lcchild->sy;
prev += lcchild->g.sy;
}
previous += (count - 1);
prev += (count - 1);
/* And how much is available? */
available = 0;
if (lc->type == LAYOUT_LEFTRIGHT)
available = lc->sx;
available = lc->g.sx;
else if (lc->type == LAYOUT_TOPBOTTOM)
available = lc->sy;
available = lc->g.sy;
/* Resize children into the new size. */
idx = 0;
@@ -1204,20 +1205,20 @@ layout_resize_child_cells(struct window *w, struct layout_cell *lc)
!layout_cell_has_tiled_child(lcchild))
continue;
if (lc->type == LAYOUT_TOPBOTTOM) {
lcchild->sx = lc->sx;
lcchild->xoff = lc->xoff;
lcchild->g.sx = lc->g.sx;
lcchild->g.xoff = lc->g.xoff;
} else {
lcchild->sx = layout_new_pane_size(w, previous, lcchild,
lc->type, lc->sx, count - idx, available);
available -= (lcchild->sx + 1);
lcchild->g.sx = layout_new_pane_size(w, prev, lcchild,
lc->type, lc->g.sx, count - idx, available);
available -= (lcchild->g.sx + 1);
}
if (lc->type == LAYOUT_LEFTRIGHT) {
lcchild->sy = lc->sy;
lcchild->yoff = lc->yoff;
lcchild->g.sy = lc->g.sy;
lcchild->g.yoff = lc->g.yoff;
} else {
lcchild->sy = layout_new_pane_size(w, previous, lcchild,
lc->type, lc->sy, count - idx, available);
available -= (lcchild->sy + 1);
lcchild->g.sy = layout_new_pane_size(w, prev, lcchild,
lc->type, lc->g.sy, count - idx, available);
available -= (lcchild->g.sy + 1);
}
layout_resize_child_cells(w, lcchild);
idx++;
@@ -1237,7 +1238,7 @@ layout_replace_with_node(struct window *w, struct layout_cell *lc,
lcparent = layout_create_cell(lc->parent);
layout_make_node(lcparent, type);
layout_set_size(lcparent, lc->sx, lc->sy, lc->xoff, lc->yoff);
layout_set_size(lcparent, lc->g.sx, lc->g.sy, lc->g.xoff, lc->g.yoff);
if (lc->parent == NULL)
w->layout_root = lcparent;
else
@@ -1256,7 +1257,7 @@ layout_split_check_space(struct window_pane *wp, struct layout_cell *lc,
enum layout_type type)
{
struct style *sb_style = &wp->scrollbar_style;
u_int minimum, sx = lc->sx, sy = lc->sy;
u_int minimum, sx = lc->g.sx, sy = lc->g.sy;
int status;
if (lc->flags & LAYOUT_CELL_FLOATING)
@@ -1295,7 +1296,7 @@ layout_split_sizes(struct layout_cell *lc, int size, int before,
enum layout_type type, u_int *size1, u_int *size2, u_int *saved_size)
{
u_int s1, s2, ss;
u_int sx = lc->sx, sy = lc->sy;
u_int sx = lc->g.sx, sy = lc->g.sy;
if (type == LAYOUT_LEFTRIGHT)
ss = sx;
@@ -1342,10 +1343,10 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
lc = wp->layout_cell;
/* Copy the old cell size. */
sx = lc->sx;
sy = lc->sy;
xoff = lc->xoff;
yoff = lc->yoff;
sx = lc->g.sx;
sy = lc->g.sy;
xoff = lc->g.xoff;
yoff = lc->g.yoff;
/* Check there is enough space for the two new panes. */
if (!layout_split_check_space(wp, lc, type))
@@ -1386,13 +1387,13 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
* must be resized before inserting the new cell.
*/
if (lc->type == LAYOUT_LEFTRIGHT) {
lc->sx = new_size;
lc->g.sx = new_size;
layout_resize_child_cells(wp->window, lc);
lc->sx = saved_size;
lc->g.sx = saved_size;
} else if (lc->type == LAYOUT_TOPBOTTOM) {
lc->sy = new_size;
lc->g.sy = new_size;
layout_resize_child_cells(wp->window, lc);
lc->sy = saved_size;
lc->g.sy = saved_size;
}
resize_first = 1;
@@ -1436,10 +1437,10 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
*/
if (!resize_first && type == LAYOUT_LEFTRIGHT) {
layout_set_size(lc1, size1, sy, xoff, yoff);
layout_set_size(lc2, size2, sy, xoff + lc1->sx + 1, yoff);
layout_set_size(lc2, size2, sy, xoff + lc1->g.sx + 1, yoff);
} else if (!resize_first && type == LAYOUT_TOPBOTTOM) {
layout_set_size(lc1, sx, size1, xoff, yoff);
layout_set_size(lc2, sx, size2, xoff, yoff + lc1->sy + 1);
layout_set_size(lc2, sx, size2, xoff, yoff + lc1->g.sy + 1);
}
if (full_size) {
if (!resize_first)
@@ -1456,8 +1457,8 @@ layout_split_pane(struct window_pane *wp, enum layout_type type, int size,
* layout_assign_pane before much else happens!
*/
struct layout_cell *
layout_floating_pane(struct window *w, struct window_pane *wp, u_int sx,
u_int sy, int ox, int oy)
layout_floating_pane(struct window *w, struct window_pane *wp,
struct layout_geometry *lg)
{
struct layout_cell *lc, *lcnew, *lcparent;
@@ -1469,16 +1470,16 @@ layout_floating_pane(struct window *w, struct window_pane *wp, u_int sx,
if (lcparent == NULL) {
/*
* Adding a pane to a root that isn't node. Must create and
* insert a new root.
*/
* Adding a pane to a root that isn't a node. Must create and
* insert a new root.
*/
lcparent = layout_replace_with_node(w, lc, LAYOUT_TOPBOTTOM);
}
lcnew = layout_create_cell(lcparent);
TAILQ_INSERT_AFTER(&lcparent->cells, lc, lcnew, entry);
lcnew->flags |= LAYOUT_CELL_FLOATING;
layout_set_size(lcnew, sx, sy, ox, oy);
layout_set_size(lcnew, lg->sx, lg->sy, lg->xoff, lg->yoff);
return (lcnew);
}
@@ -1521,12 +1522,12 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
status = window_get_pane_status(w);
if (parent->type == LAYOUT_LEFTRIGHT)
size = parent->sx;
size = parent->g.sx;
else if (parent->type == LAYOUT_TOPBOTTOM) {
if (layout_add_horizontal_border(w, parent, status))
size = parent->sy - 1;
size = parent->g.sy - 1;
else
size = parent->sy;
size = parent->g.sy;
} else
return (0);
if (size < number - 1)
@@ -1547,7 +1548,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
continue;
change = 0;
if (parent->type == LAYOUT_LEFTRIGHT) {
change = each - (int)lc->sx;
change = each - (int)lc->g.sx;
if (remainder > 0) {
change++;
remainder--;
@@ -1562,7 +1563,7 @@ layout_spread_cell(struct window *w, struct layout_cell *parent)
this++;
remainder--;
}
change = this - (int)lc->sy;
change = this - (int)lc->g.sy;
layout_resize_adjust(w, lc, LAYOUT_TOPBOTTOM, change);
}
if (change != 0)
@@ -1659,30 +1660,29 @@ layout_get_floating_cell(struct cmdq_item *item, struct args *args,
char **cause)
{
struct layout_cell *lcnew;
u_int sx = UINT_MAX, sy = UINT_MAX;
int ox = INT_MAX, oy = INT_MAX;
struct layout_geometry fg;
if (layout_floating_args_parse(item, args, lines, w, &sx, &sy, &ox, &oy,
cause) != 0)
layout_geometry_init(&fg);
if (layout_floating_args_parse(item, args, lines, w, &fg, cause) != 0)
return (NULL);
window_push_zoom(wp->window, 1, args_has(args, 'Z'));
lcnew = layout_floating_pane(w, wp, sx, sy, ox, oy);
lcnew = layout_floating_pane(w, wp, &fg);
return (lcnew);
}
int
layout_floating_args_parse(struct cmdq_item *item, struct args *args,
enum pane_lines lines, struct window *w, u_int *sxp, u_int *syp, int *oxp,
int *oyp, char **cause)
enum pane_lines lines, struct window *w, struct layout_geometry *lg,
char **cause)
{
int sx, sy, ox, oy;
char *error = NULL;
sx = *sxp == UINT_MAX ? w->sx / 2 : *sxp;
sy = *syp == UINT_MAX ? w->sy / 4 : *syp;
ox = *oxp == INT_MAX ? INT_MAX : *oxp;
oy = *oyp == INT_MAX ? INT_MAX : *oyp;
sx = lg->sx == UINT_MAX ? w->sx / 2 : lg->sx;
sy = lg->sy == UINT_MAX ? w->sy / 4 : lg->sy;
ox = lg->xoff;
oy = lg->yoff;
if (args_has(args, 'x')) {
sx = args_percentage_and_expand(args, 'x', 0, PANE_MAXIMUM,
@@ -1759,10 +1759,10 @@ layout_floating_args_parse(struct cmdq_item *item, struct args *args,
return (-1);
}
*sxp = sx;
*syp = sy;
*oxp = ox;
*oyp = oy;
lg->sx = sx;
lg->sy = sy;
lg->xoff = ox;
lg->yoff = oy;
return (0);
}
@@ -1791,9 +1791,9 @@ layout_remove_tile(struct window *w, struct layout_cell *lc)
* neighbour.
*/
if (type == LAYOUT_TOPBOTTOM)
change = lc->sy + 1;
change = lc->g.sy + 1;
else
change = lc->sx + 1;
change = lc->g.sx + 1;
layout_resize_adjust(w, lcneighbour, type, change);
}
@@ -1839,9 +1839,9 @@ layout_insert_tile(struct window *w, struct layout_cell *lc)
*/
layout_insert_tile(w, lcparent);
if (type == LAYOUT_LEFTRIGHT)
size1 = lcparent->sx;
size1 = lcparent->g.sx;
else
size1 = lcparent->sy;
size1 = lcparent->g.sy;
layout_resize_set_size(w, lc, type, size1);
} else {
/*
@@ -1859,10 +1859,10 @@ layout_insert_tile(struct window *w, struct layout_cell *lc)
/* Setting opposite of the 'split' size to that of the parent. */
if (lcparent->type == LAYOUT_LEFTRIGHT) {
size1 = lcparent->sy;
size1 = lcparent->g.sy;
type = LAYOUT_TOPBOTTOM;
} else {
size1 = lcparent->sx;
size1 = lcparent->g.sx;
type = LAYOUT_LEFTRIGHT;
}
layout_resize_set_size(w, lc, type, size1);

View File

@@ -46,13 +46,13 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
layout_resize(w, sx, sy);
/* Resize the window, it can be no smaller than the layout. */
if (sx < w->layout_root->sx)
sx = w->layout_root->sx;
if (sy < w->layout_root->sy)
sy = w->layout_root->sy;
if (sx < w->layout_root->g.sx)
sx = w->layout_root->g.sx;
if (sy < w->layout_root->g.sy)
sy = w->layout_root->g.sy;
window_resize(w, sx, sy, xpixel, ypixel);
log_debug("%s: @%u resized to %ux%u; layout %ux%u", __func__, w->id,
sx, sy, w->layout_root->sx, w->layout_root->sy);
sx, sy, w->layout_root->g.sx, w->layout_root->g.sy);
/* Restore the window zoom state. */
if (zoomed)

12
spawn.c
View File

@@ -632,13 +632,13 @@ spawn_editor(struct client *c, const char *buf, size_t len,
struct window *w = wl->window;
struct window_pane *wp;
struct layout_cell *lc;
struct layout_geometry lg;
struct environ *env;
FILE *f;
char *cmd, *cause = NULL;
char path[] = _PATH_TMP "tmux.XXXXXXXX";
const char *editor;
int fd;
u_int px, py, sx, sy;
editor = options_get_string(global_options, "editor");
fd = mkstemp(path);
@@ -662,12 +662,12 @@ spawn_editor(struct client *c, const char *buf, size_t len,
es->cb = cb;
es->arg = arg;
sx = w->sx * 9 / 10;
sy = w->sy * 9 / 10;
px = w->sx / 2 - sx / 2;
py = w->sy / 2 - sy / 2;
lg.sx = w->sx * 9 / 10;
lg.sy = w->sy * 9 / 10;
lg.xoff = w->sx / 2 - lg.sx / 2;
lg.yoff = w->sy / 2 - lg.sy / 2;
window_push_zoom(w, 1, 0);
lc = layout_floating_pane(w, NULL, sx, sy, px, py);
lc = layout_floating_pane(w, NULL, &lg);
if (lc == NULL) {
spawn_editor_free(es);
return (NULL);

41
tmux.h
View File

@@ -1505,32 +1505,31 @@ enum layout_type {
LAYOUT_WINDOWPANE
};
/* Layout cell sizes and position. */
struct layout_geometry {
u_int sx;
u_int sy;
int xoff;
int yoff;
};
/* Layout cells queue. */
TAILQ_HEAD(layout_cells, layout_cell);
/* Layout cell. */
struct layout_cell {
enum layout_type type;
enum layout_type type;
int flags;
#define LAYOUT_CELL_FLOATING 0x1
int flags;
struct layout_cell *parent;
struct layout_cell *parent;
u_int sx;
u_int sy;
struct layout_geometry g;
struct layout_geometry fg; /* saved floating pane */
int xoff;
int yoff;
u_int saved_sx;
u_int saved_sy;
int saved_xoff;
int saved_yoff;
struct window_pane *wp;
struct layout_cells cells;
struct window_pane *wp;
struct layout_cells cells;
TAILQ_ENTRY(layout_cell) entry;
};
@@ -3719,7 +3718,7 @@ void layout_destroy_cell(struct window *, struct layout_cell *,
void layout_resize_layout(struct window *, struct layout_cell *,
enum layout_type, int, int);
struct layout_cell *layout_search_by_border(struct layout_cell *, u_int, u_int);
void layout_set_size(struct layout_cell *, u_int, u_int, int, int);
void layout_set_size(struct layout_cell *, u_int, u_int, int, int);
void layout_make_leaf(struct layout_cell *, struct window_pane *);
void layout_make_node(struct layout_cell *, enum layout_type);
void layout_fix_zindexes(struct window *, struct layout_cell *);
@@ -3753,7 +3752,7 @@ struct layout_cell *layout_replace_with_node(struct window *,
struct layout_cell *layout_split_pane(struct window_pane *, enum layout_type,
int, int);
struct layout_cell *layout_floating_pane(struct window *, struct window_pane *,
u_int, u_int, int, int);
struct layout_geometry *);
void layout_close_pane(struct window_pane *);
int layout_spread_cell(struct window *, struct layout_cell *);
void layout_spread_out(struct window_pane *);
@@ -3761,10 +3760,10 @@ struct layout_cell *layout_get_tiled_cell(struct cmdq_item *, struct args *,
struct window *, struct window_pane *, int, char **);
struct layout_cell *layout_get_floating_cell(struct cmdq_item *, struct args *,
enum pane_lines, struct window *, struct window_pane *,
char **cause);
char **);
int layout_floating_args_parse(struct cmdq_item *, struct args *,
enum pane_lines, struct window *, u_int *, u_int *, int *,
int *, char **);
enum pane_lines, struct window *, struct layout_geometry *,
char **);
int layout_remove_tile(struct window *, struct layout_cell *);
int layout_insert_tile(struct window *, struct layout_cell *);