mirror of
https://github.com/tmux/tmux.git
synced 2026-05-30 14:16:18 +00:00
Bring over some of layout and positioning code for floating panes, by
Michael Grant.
This commit is contained in:
@@ -73,7 +73,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
}
|
}
|
||||||
server_unzoom_window(w);
|
server_unzoom_window(w);
|
||||||
|
|
||||||
if (window_count_panes(w) == 1) {
|
if (window_count_panes(w, 1) == 1) {
|
||||||
if (server_link_window(src_s, wl, dst_s, idx, 0,
|
if (server_link_window(src_s, wl, dst_s, idx, 0,
|
||||||
!args_has(args, 'd'), &cause) != 0) {
|
!args_has(args, 'd'), &cause) != 0) {
|
||||||
cmdq_error(item, "%s", cause);
|
cmdq_error(item, "%s", cause);
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
} else
|
} else
|
||||||
server_status_session(dst_s);
|
server_status_session(dst_s);
|
||||||
|
|
||||||
if (window_count_panes(src_w) == 0)
|
if (window_count_panes(src_w, 1) == 0)
|
||||||
server_kill_window(src_w, 1);
|
server_kill_window(src_w, 1);
|
||||||
else
|
else
|
||||||
notify_window("window-layout-changed", src_w);
|
notify_window("window-layout-changed", src_w);
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
* spawned without being visited (for example split-window -d).
|
* spawned without being visited (for example split-window -d).
|
||||||
*/
|
*/
|
||||||
lastwp = TAILQ_FIRST(&w->last_panes);
|
lastwp = TAILQ_FIRST(&w->last_panes);
|
||||||
if (lastwp == NULL && window_count_panes(w) == 2) {
|
if (lastwp == NULL && window_count_panes(w, 1) == 2) {
|
||||||
lastwp = TAILQ_PREV(w->active, window_panes, entry);
|
lastwp = TAILQ_PREV(w->active, window_panes, entry);
|
||||||
if (lastwp == NULL)
|
if (lastwp == NULL)
|
||||||
lastwp = TAILQ_NEXT(w->active, entry);
|
lastwp = TAILQ_NEXT(w->active, entry);
|
||||||
|
|||||||
10
format.c
10
format.c
@@ -2046,7 +2046,7 @@ static void *
|
|||||||
format_cb_pane_bottom(struct format_tree *ft)
|
format_cb_pane_bottom(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->wp != NULL)
|
if (ft->wp != NULL)
|
||||||
return (format_printf("%u", ft->wp->yoff + ft->wp->sy - 1));
|
return (format_printf("%d", ft->wp->yoff + ft->wp->sy - 1));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2205,7 +2205,7 @@ static void *
|
|||||||
format_cb_pane_left(struct format_tree *ft)
|
format_cb_pane_left(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->wp != NULL)
|
if (ft->wp != NULL)
|
||||||
return (format_printf("%u", ft->wp->xoff));
|
return (format_printf("%d", ft->wp->xoff));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2329,7 +2329,7 @@ static void *
|
|||||||
format_cb_pane_right(struct format_tree *ft)
|
format_cb_pane_right(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->wp != NULL)
|
if (ft->wp != NULL)
|
||||||
return (format_printf("%u", ft->wp->xoff + ft->wp->sx - 1));
|
return (format_printf("%d", ft->wp->xoff + ft->wp->sx - 1));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2371,7 +2371,7 @@ static void *
|
|||||||
format_cb_pane_top(struct format_tree *ft)
|
format_cb_pane_top(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->wp != NULL)
|
if (ft->wp != NULL)
|
||||||
return (format_printf("%u", ft->wp->yoff));
|
return (format_printf("%d", ft->wp->yoff));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2918,7 +2918,7 @@ static void *
|
|||||||
format_cb_window_panes(struct format_tree *ft)
|
format_cb_window_panes(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
if (ft->w != NULL)
|
if (ft->w != NULL)
|
||||||
return (format_printf("%u", window_count_panes(ft->w)));
|
return (format_printf("%u", window_count_panes(ft->w, 1)));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
174
layout-custom.c
174
layout-custom.c
@@ -27,10 +27,11 @@ static struct layout_cell *layout_find_bottomright(struct layout_cell *);
|
|||||||
static u_short layout_checksum(const char *);
|
static u_short layout_checksum(const char *);
|
||||||
static int layout_append(struct layout_cell *, char *,
|
static int layout_append(struct layout_cell *, char *,
|
||||||
size_t);
|
size_t);
|
||||||
static struct layout_cell *layout_construct(struct layout_cell *,
|
static int layout_construct(struct layout_cell *,
|
||||||
const char **);
|
const char **, struct layout_cell **,
|
||||||
|
struct layout_cell **);
|
||||||
static void layout_assign(struct window_pane **,
|
static void layout_assign(struct window_pane **,
|
||||||
struct layout_cell *);
|
struct layout_cell *, int);
|
||||||
|
|
||||||
/* Find the bottom-right cell. */
|
/* Find the bottom-right cell. */
|
||||||
static struct layout_cell *
|
static struct layout_cell *
|
||||||
@@ -58,14 +59,30 @@ layout_checksum(const char *layout)
|
|||||||
|
|
||||||
/* Dump layout as a string. */
|
/* Dump layout as a string. */
|
||||||
char *
|
char *
|
||||||
layout_dump(__unused struct window *w, struct layout_cell *root)
|
layout_dump(struct window *w, struct layout_cell *root)
|
||||||
{
|
{
|
||||||
char layout[8192], *out;
|
char layout[8192], *out;
|
||||||
|
int bracket = 0;
|
||||||
|
struct window_pane *wp;
|
||||||
|
|
||||||
*layout = '\0';
|
*layout = '\0';
|
||||||
if (layout_append(root, layout, sizeof layout) != 0)
|
if (layout_append(root, layout, sizeof layout) != 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||||
|
if (~wp->flags & PANE_FLOATING)
|
||||||
|
break;
|
||||||
|
if (!bracket) {
|
||||||
|
strlcat(layout, "<", sizeof layout);
|
||||||
|
bracket = 1;
|
||||||
|
}
|
||||||
|
if (layout_append(wp->layout_cell, layout, sizeof layout) != 0)
|
||||||
|
return (NULL);
|
||||||
|
strlcat(layout, ",", sizeof layout);
|
||||||
|
}
|
||||||
|
if (bracket)
|
||||||
|
layout[strlen(layout) - 1] = '>';
|
||||||
|
|
||||||
xasprintf(&out, "%04hx,%s", layout_checksum(layout), layout);
|
xasprintf(&out, "%04hx,%s", layout_checksum(layout), layout);
|
||||||
return (out);
|
return (out);
|
||||||
}
|
}
|
||||||
@@ -81,12 +98,13 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
|
|||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
if (lc == NULL)
|
||||||
|
return (0);
|
||||||
if (lc->wp != NULL) {
|
if (lc->wp != NULL) {
|
||||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%u,%u,%u",
|
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d,%u",
|
||||||
lc->sx, lc->sy, lc->xoff, lc->yoff, lc->wp->id);
|
lc->sx, lc->sy, lc->xoff, lc->yoff, lc->wp->id);
|
||||||
} else {
|
} else {
|
||||||
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%u,%u",
|
tmplen = xsnprintf(tmp, sizeof tmp, "%ux%u,%d,%d",
|
||||||
lc->sx, lc->sy, lc->xoff, lc->yoff);
|
lc->sx, lc->sy, lc->xoff, lc->yoff);
|
||||||
}
|
}
|
||||||
if (tmplen > (sizeof tmp) - 1)
|
if (tmplen > (sizeof tmp) - 1)
|
||||||
@@ -109,6 +127,7 @@ layout_append(struct layout_cell *lc, char *buf, size_t len)
|
|||||||
}
|
}
|
||||||
buf[strlen(buf) - 1] = brackets[0];
|
buf[strlen(buf) - 1] = brackets[0];
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -124,6 +143,7 @@ layout_check(struct layout_cell *lc)
|
|||||||
u_int n = 0;
|
u_int n = 0;
|
||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
break;
|
break;
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
@@ -156,7 +176,7 @@ layout_check(struct layout_cell *lc)
|
|||||||
int
|
int
|
||||||
layout_parse(struct window *w, const char *layout, char **cause)
|
layout_parse(struct window *w, const char *layout, char **cause)
|
||||||
{
|
{
|
||||||
struct layout_cell *lc, *lcchild;
|
struct layout_cell *lcchild, *tiled_lc = NULL, *floating_lc = NULL;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int npanes, ncells, sx = 0, sy = 0;
|
u_int npanes, ncells, sx = 0, sy = 0;
|
||||||
u_short csum;
|
u_short csum;
|
||||||
@@ -174,20 +194,27 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Build the layout. */
|
/* Build the layout. */
|
||||||
lc = layout_construct(NULL, &layout);
|
if (layout_construct(NULL, &layout, &tiled_lc, &floating_lc) != 0) {
|
||||||
if (lc == NULL) {
|
|
||||||
*cause = xstrdup("invalid layout");
|
*cause = xstrdup("invalid layout");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
if (tiled_lc == NULL) {
|
||||||
|
/* A stub layout cell for an empty window. */
|
||||||
|
tiled_lc = layout_create_cell(NULL);
|
||||||
|
tiled_lc->type = LAYOUT_LEFTRIGHT;
|
||||||
|
layout_set_size(tiled_lc, w->sx, w->sy, 0, 0);
|
||||||
|
}
|
||||||
if (*layout != '\0') {
|
if (*layout != '\0') {
|
||||||
*cause = xstrdup("invalid layout");
|
*cause = xstrdup("invalid layout");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check this window will fit into the layout. */
|
/* Check this window will fit into the layout. */
|
||||||
|
npanes = window_count_panes(w, 1);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
npanes = window_count_panes(w);
|
ncells = layout_count_cells(tiled_lc);
|
||||||
ncells = layout_count_cells(lc);
|
if (floating_lc != NULL)
|
||||||
|
ncells += layout_count_cells(floating_lc);
|
||||||
if (npanes > ncells) {
|
if (npanes > ncells) {
|
||||||
xasprintf(cause, "have %u panes but need %u", npanes,
|
xasprintf(cause, "have %u panes but need %u", npanes,
|
||||||
ncells);
|
ncells);
|
||||||
@@ -196,9 +223,17 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
if (npanes == ncells)
|
if (npanes == ncells)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Fewer panes than cells - close the bottom right. */
|
/*
|
||||||
lcchild = layout_find_bottomright(lc);
|
* Fewer panes than cells - close floating panes first
|
||||||
layout_destroy_cell(w, lcchild, &lc);
|
* then close the bottom right until none remain.
|
||||||
|
*/
|
||||||
|
if (floating_lc != NULL && !TAILQ_EMPTY(&floating_lc->cells)) {
|
||||||
|
lcchild = TAILQ_FIRST(&floating_lc->cells);
|
||||||
|
layout_destroy_cell(w, lcchild, &floating_lc);
|
||||||
|
} else {
|
||||||
|
lcchild = layout_find_bottomright(tiled_lc);
|
||||||
|
layout_destroy_cell(w, lcchild, &tiled_lc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -206,91 +241,108 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
* an incorrect top cell size - if it is larger than the top child then
|
* an incorrect top cell size - if it is larger than the top child then
|
||||||
* correct that (if this is still wrong the check code will catch it).
|
* correct that (if this is still wrong the check code will catch it).
|
||||||
*/
|
*/
|
||||||
switch (lc->type) {
|
|
||||||
|
switch (tiled_lc->type) {
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
break;
|
break;
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
|
||||||
sy = lcchild->sy + 1;
|
sy = lcchild->sy + 1;
|
||||||
sx += lcchild->sx + 1;
|
sx += lcchild->sx + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &tiled_lc->cells, entry) {
|
||||||
sx = lcchild->sx + 1;
|
sx = lcchild->sx + 1;
|
||||||
sy += lcchild->sy + 1;
|
sy += lcchild->sy + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
*cause = xstrdup("invalid layout");
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
if (lc->type != LAYOUT_WINDOWPANE && (lc->sx != sx || lc->sy != sy)) {
|
if (tiled_lc->type != LAYOUT_WINDOWPANE &&
|
||||||
log_debug("fix layout %u,%u to %u,%u", lc->sx, lc->sy, sx,sy);
|
(tiled_lc->sx != sx || tiled_lc->sy != sy)) {
|
||||||
layout_print_cell(lc, __func__, 0);
|
layout_print_cell(tiled_lc, __func__, 0);
|
||||||
lc->sx = sx - 1; lc->sy = sy - 1;
|
tiled_lc->sx = sx - 1; tiled_lc->sy = sy - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the new layout. */
|
/* Check the new layout. */
|
||||||
if (!layout_check(lc)) {
|
if (!layout_check(tiled_lc)) {
|
||||||
*cause = xstrdup("size mismatch after applying layout");
|
*cause = xstrdup("size mismatch after applying layout");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize to the layout size. */
|
/* Resize window to the layout size. */
|
||||||
window_resize(w, lc->sx, lc->sy, -1, -1);
|
if (sx != 0 && sy != 0)
|
||||||
|
window_resize(w, tiled_lc->sx, tiled_lc->sy, -1, -1);
|
||||||
|
|
||||||
/* Destroy the old layout and swap to the new. */
|
/* Destroy the old layout and swap to the new. */
|
||||||
layout_free_cell(w->layout_root);
|
layout_free_cell(w->layout_root);
|
||||||
w->layout_root = lc;
|
w->layout_root = tiled_lc;
|
||||||
|
|
||||||
/* Assign the panes into the cells. */
|
/* Assign the panes into the cells. */
|
||||||
wp = TAILQ_FIRST(&w->panes);
|
wp = TAILQ_FIRST(&w->panes);
|
||||||
layout_assign(&wp, lc);
|
if (tiled_lc != NULL)
|
||||||
|
layout_assign(&wp, tiled_lc, 0);
|
||||||
|
if (floating_lc != NULL)
|
||||||
|
layout_assign(&wp, floating_lc, PANE_FLOATING);
|
||||||
|
|
||||||
/* Update pane offsets and sizes. */
|
/* Update pane offsets and sizes. */
|
||||||
layout_fix_offsets(w);
|
layout_fix_offsets(w);
|
||||||
layout_fix_panes(w, NULL);
|
layout_fix_panes(w, NULL);
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
|
layout_print_cell(tiled_lc, __func__, 0);
|
||||||
|
|
||||||
layout_print_cell(lc, __func__, 0);
|
/* Free the floating layout cell, no longer needed. */
|
||||||
|
if (floating_lc != NULL)
|
||||||
|
layout_free_cell(floating_lc);
|
||||||
|
|
||||||
notify_window("window-layout-changed", w);
|
notify_window("window-layout-changed", w);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
layout_free_cell(lc);
|
layout_free_cell(tiled_lc);
|
||||||
|
layout_free_cell(floating_lc);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign panes into cells. */
|
/* Assign panes into cells. */
|
||||||
static void
|
static void
|
||||||
layout_assign(struct window_pane **wp, struct layout_cell *lc)
|
layout_assign(struct window_pane **wp, struct layout_cell *lc, int flags)
|
||||||
{
|
{
|
||||||
struct layout_cell *lcchild;
|
struct layout_cell *lcchild;
|
||||||
|
|
||||||
|
if (lc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
layout_make_leaf(lc, *wp);
|
layout_make_leaf(lc, *wp);
|
||||||
|
(*wp)->flags |= flags;
|
||||||
*wp = TAILQ_NEXT(*wp, entry);
|
*wp = TAILQ_NEXT(*wp, entry);
|
||||||
return;
|
return;
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||||
layout_assign(wp, lcchild);
|
layout_assign(wp, lcchild, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct a cell from all or part of a layout tree. */
|
|
||||||
static struct layout_cell *
|
static struct layout_cell *
|
||||||
layout_construct(struct layout_cell *lcparent, const char **layout)
|
layout_construct_cell(struct layout_cell *lcparent, const char **layout)
|
||||||
{
|
{
|
||||||
struct layout_cell *lc, *lcchild;
|
struct layout_cell *lc;
|
||||||
u_int sx, sy, xoff, yoff;
|
u_int sx, sy;
|
||||||
|
int xoff, yoff;
|
||||||
const char *saved;
|
const char *saved;
|
||||||
|
|
||||||
if (!isdigit((u_char) **layout))
|
if (!isdigit((u_char) **layout))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if (sscanf(*layout, "%ux%u,%u,%u", &sx, &sy, &xoff, &yoff) != 4)
|
if (sscanf(*layout, "%ux%u,%d,%d", &sx, &sy, &xoff, &yoff) != 4)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
while (isdigit((u_char) **layout))
|
while (isdigit((u_char) **layout))
|
||||||
@@ -325,17 +377,41 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
|||||||
lc->xoff = xoff;
|
lc->xoff = xoff;
|
||||||
lc->yoff = yoff;
|
lc->yoff = yoff;
|
||||||
|
|
||||||
|
return (lc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a character string layout, recursively construct cells.
|
||||||
|
* Possible return values:
|
||||||
|
* lc LAYOUT_WINDOWPANE, no children
|
||||||
|
* lc LAYOUT_LEFTRIGHT or LAYOUT_TOPBOTTOM, with children
|
||||||
|
* floating_lc LAYOUT_FLOATING, with children
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
layout_construct(struct layout_cell *lcparent, const char **layout,
|
||||||
|
struct layout_cell **lc, struct layout_cell **floating_lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcchild, *saved_lc;
|
||||||
|
|
||||||
|
*lc = layout_construct_cell(lcparent, layout);
|
||||||
|
|
||||||
switch (**layout) {
|
switch (**layout) {
|
||||||
case ',':
|
case ',':
|
||||||
case '}':
|
case '}':
|
||||||
case ']':
|
case ']':
|
||||||
|
case '>':
|
||||||
case '\0':
|
case '\0':
|
||||||
return (lc);
|
return (0);
|
||||||
case '{':
|
case '{':
|
||||||
lc->type = LAYOUT_LEFTRIGHT;
|
(*lc)->type = LAYOUT_LEFTRIGHT;
|
||||||
break;
|
break;
|
||||||
case '[':
|
case '[':
|
||||||
lc->type = LAYOUT_TOPBOTTOM;
|
(*lc)->type = LAYOUT_TOPBOTTOM;
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
saved_lc = *lc;
|
||||||
|
*lc = layout_create_cell(lcparent);
|
||||||
|
(*lc)->type = LAYOUT_FLOATING;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -343,13 +419,12 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
(*layout)++;
|
(*layout)++;
|
||||||
lcchild = layout_construct(lc, layout);
|
if (layout_construct(*lc, layout, &lcchild, floating_lc) != 0)
|
||||||
if (lcchild == NULL)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
TAILQ_INSERT_TAIL(&lc->cells, lcchild, entry);
|
TAILQ_INSERT_TAIL(&(*lc)->cells, lcchild, entry);
|
||||||
} while (**layout == ',');
|
} while (**layout == ',');
|
||||||
|
|
||||||
switch (lc->type) {
|
switch ((*lc)->type) {
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
if (**layout != '}')
|
if (**layout != '}')
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -358,14 +433,21 @@ layout_construct(struct layout_cell *lcparent, const char **layout)
|
|||||||
if (**layout != ']')
|
if (**layout != ']')
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
if (**layout != '>')
|
||||||
|
goto fail;
|
||||||
|
*floating_lc = *lc;
|
||||||
|
*lc = saved_lc;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
(*layout)++;
|
(*layout)++;
|
||||||
|
|
||||||
return (lc);
|
return (0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
layout_free_cell(lc);
|
layout_free_cell(*lc);
|
||||||
return (NULL);
|
layout_free_cell(*floating_lc);
|
||||||
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|||||||
12
layout-set.c
12
layout-set.c
@@ -133,7 +133,7 @@ layout_set_even(struct window *w, enum layout_type type)
|
|||||||
layout_print_cell(w->layout_root, __func__, 1);
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
/* Get number of panes. */
|
/* Get number of panes. */
|
||||||
n = window_count_panes(w);
|
n = window_count_panes(w, 0);
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ layout_set_main_h(struct window *w)
|
|||||||
layout_print_cell(w->layout_root, __func__, 1);
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
/* Get number of panes. */
|
/* Get number of panes. */
|
||||||
n = window_count_panes(w);
|
n = window_count_panes(w, 0);
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
return;
|
return;
|
||||||
n--; /* take off main pane */
|
n--; /* take off main pane */
|
||||||
@@ -299,7 +299,7 @@ layout_set_main_h_mirrored(struct window *w)
|
|||||||
layout_print_cell(w->layout_root, __func__, 1);
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
/* Get number of panes. */
|
/* Get number of panes. */
|
||||||
n = window_count_panes(w);
|
n = window_count_panes(w, 0);
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
return;
|
return;
|
||||||
n--; /* take off main pane */
|
n--; /* take off main pane */
|
||||||
@@ -397,7 +397,7 @@ layout_set_main_v(struct window *w)
|
|||||||
layout_print_cell(w->layout_root, __func__, 1);
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
/* Get number of panes. */
|
/* Get number of panes. */
|
||||||
n = window_count_panes(w);
|
n = window_count_panes(w, 0);
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
return;
|
return;
|
||||||
n--; /* take off main pane */
|
n--; /* take off main pane */
|
||||||
@@ -495,7 +495,7 @@ layout_set_main_v_mirrored(struct window *w)
|
|||||||
layout_print_cell(w->layout_root, __func__, 1);
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
/* Get number of panes. */
|
/* Get number of panes. */
|
||||||
n = window_count_panes(w);
|
n = window_count_panes(w, 0);
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
return;
|
return;
|
||||||
n--; /* take off main pane */
|
n--; /* take off main pane */
|
||||||
@@ -593,7 +593,7 @@ layout_set_tiled(struct window *w)
|
|||||||
layout_print_cell(w->layout_root, __func__, 1);
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
/* Get number of panes. */
|
/* Get number of panes. */
|
||||||
n = window_count_panes(w);
|
n = window_count_panes(w, 0);
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
95
layout.c
95
layout.c
@@ -46,7 +46,10 @@ static int layout_set_size_check(struct window *, struct layout_cell *,
|
|||||||
enum layout_type, int);
|
enum layout_type, int);
|
||||||
static void layout_resize_child_cells(struct window *,
|
static void layout_resize_child_cells(struct window *,
|
||||||
struct layout_cell *);
|
struct layout_cell *);
|
||||||
|
void layout_redistribute_cells(struct window *, struct layout_cell *,
|
||||||
|
enum layout_type);
|
||||||
|
|
||||||
|
/* Create a new layout cell. */
|
||||||
struct layout_cell *
|
struct layout_cell *
|
||||||
layout_create_cell(struct layout_cell *lcparent)
|
layout_create_cell(struct layout_cell *lcparent)
|
||||||
{
|
{
|
||||||
@@ -61,14 +64,15 @@ layout_create_cell(struct layout_cell *lcparent)
|
|||||||
lc->sx = UINT_MAX;
|
lc->sx = UINT_MAX;
|
||||||
lc->sy = UINT_MAX;
|
lc->sy = UINT_MAX;
|
||||||
|
|
||||||
lc->xoff = UINT_MAX;
|
lc->xoff = INT_MAX;
|
||||||
lc->yoff = UINT_MAX;
|
lc->yoff = INT_MAX;
|
||||||
|
|
||||||
lc->wp = NULL;
|
lc->wp = NULL;
|
||||||
|
|
||||||
return (lc);
|
return (lc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free a layout cell. */
|
||||||
void
|
void
|
||||||
layout_free_cell(struct layout_cell *lc)
|
layout_free_cell(struct layout_cell *lc)
|
||||||
{
|
{
|
||||||
@@ -83,21 +87,40 @@ layout_free_cell(struct layout_cell *lc)
|
|||||||
layout_free_cell(lcchild);
|
layout_free_cell(lcchild);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
/*
|
||||||
|
* A floating layout cell is only used temporarily while
|
||||||
|
* select-layout constructs a layout. Remove the children from
|
||||||
|
* the temporary layout, then free temporary floating layout
|
||||||
|
* cell. Each floating pane has stub layout.
|
||||||
|
*/
|
||||||
|
while (!TAILQ_EMPTY(&lc->cells)) {
|
||||||
|
lcchild = TAILQ_FIRST(&lc->cells);
|
||||||
|
TAILQ_REMOVE(&lc->cells, lcchild, entry);
|
||||||
|
lcchild->parent = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
if (lc->wp != NULL)
|
if (lc->wp != NULL) {
|
||||||
|
lc->wp->layout_cell->parent = NULL;
|
||||||
lc->wp->layout_cell = NULL;
|
lc->wp->layout_cell = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(lc);
|
free(lc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Log a cell. */
|
||||||
void
|
void
|
||||||
layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
||||||
{
|
{
|
||||||
struct layout_cell *lcchild;
|
struct layout_cell *lcchild;
|
||||||
const char *type;
|
const char *type;
|
||||||
|
|
||||||
|
if (lc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
type = "LEFTRIGHT";
|
type = "LEFTRIGHT";
|
||||||
@@ -105,6 +128,9 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
|||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
type = "TOPBOTTOM";
|
type = "TOPBOTTOM";
|
||||||
break;
|
break;
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
|
type = "FLOATING";
|
||||||
|
break;
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
type = "WINDOWPANE";
|
type = "WINDOWPANE";
|
||||||
break;
|
break;
|
||||||
@@ -112,12 +138,13 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
|||||||
type = "UNKNOWN";
|
type = "UNKNOWN";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
log_debug("%s:%*s%p type %s [parent %p] wp=%p [%u,%u %ux%u]", hdr, n,
|
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, type, lc->parent, lc->wp, lc->xoff, lc->yoff, lc->sx,
|
||||||
lc->sy);
|
lc->sy);
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||||
layout_print_cell(lcchild, hdr, n + 1);
|
layout_print_cell(lcchild, hdr, n + 1);
|
||||||
break;
|
break;
|
||||||
@@ -126,14 +153,17 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Search for a cell by the border position. */
|
||||||
struct layout_cell *
|
struct layout_cell *
|
||||||
layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
||||||
{
|
{
|
||||||
struct layout_cell *lcchild, *last = NULL;
|
struct layout_cell *lcchild, *last = NULL;
|
||||||
|
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
if (x >= lcchild->xoff && x < lcchild->xoff + lcchild->sx &&
|
if ((int)x >= lcchild->xoff &&
|
||||||
y >= lcchild->yoff && y < lcchild->yoff + lcchild->sy) {
|
(int)x < lcchild->xoff + (int)lcchild->sx &&
|
||||||
|
(int)y >= lcchild->yoff &&
|
||||||
|
(int)y < lcchild->yoff + (int)lcchild->sy) {
|
||||||
/* Inside the cell - recurse. */
|
/* Inside the cell - recurse. */
|
||||||
return (layout_search_by_border(lcchild, x, y));
|
return (layout_search_by_border(lcchild, x, y));
|
||||||
}
|
}
|
||||||
@@ -145,14 +175,17 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
|||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
if (x < lcchild->xoff && x >= last->xoff + last->sx)
|
if ((int)x < lcchild->xoff &&
|
||||||
|
(int)x >= last->xoff + (int)last->sx)
|
||||||
return (last);
|
return (last);
|
||||||
break;
|
break;
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
if (y < lcchild->yoff && y >= last->yoff + last->sy)
|
if ((int)y < lcchild->yoff &&
|
||||||
|
(int)y >= last->yoff + (int)last->sy)
|
||||||
return (last);
|
return (last);
|
||||||
break;
|
break;
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
|
case LAYOUT_FLOATING:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,9 +195,9 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set cell size. */
|
||||||
void
|
void
|
||||||
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, u_int xoff,
|
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, int xoff, int yoff)
|
||||||
u_int yoff)
|
|
||||||
{
|
{
|
||||||
lc->sx = sx;
|
lc->sx = sx;
|
||||||
lc->sy = sy;
|
lc->sy = sy;
|
||||||
@@ -173,6 +206,7 @@ layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, u_int xoff,
|
|||||||
lc->yoff = yoff;
|
lc->yoff = yoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a cell a leaf cell. */
|
||||||
void
|
void
|
||||||
layout_make_leaf(struct layout_cell *lc, struct window_pane *wp)
|
layout_make_leaf(struct layout_cell *lc, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@@ -184,6 +218,7 @@ layout_make_leaf(struct layout_cell *lc, struct window_pane *wp)
|
|||||||
lc->wp = wp;
|
lc->wp = wp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a cell a node cell. */
|
||||||
void
|
void
|
||||||
layout_make_node(struct layout_cell *lc, enum layout_type type)
|
layout_make_node(struct layout_cell *lc, enum layout_type type)
|
||||||
{
|
{
|
||||||
@@ -203,7 +238,7 @@ static void
|
|||||||
layout_fix_offsets1(struct layout_cell *lc)
|
layout_fix_offsets1(struct layout_cell *lc)
|
||||||
{
|
{
|
||||||
struct layout_cell *lcchild;
|
struct layout_cell *lcchild;
|
||||||
u_int xoff, yoff;
|
int xoff, yoff;
|
||||||
|
|
||||||
if (lc->type == LAYOUT_LEFTRIGHT) {
|
if (lc->type == LAYOUT_LEFTRIGHT) {
|
||||||
xoff = lc->xoff;
|
xoff = lc->xoff;
|
||||||
@@ -246,6 +281,8 @@ layout_cell_is_top(struct window *w, struct layout_cell *lc)
|
|||||||
|
|
||||||
while (lc != w->layout_root) {
|
while (lc != w->layout_root) {
|
||||||
next = lc->parent;
|
next = lc->parent;
|
||||||
|
if (next == NULL)
|
||||||
|
return (0);
|
||||||
if (next->type == LAYOUT_TOPBOTTOM &&
|
if (next->type == LAYOUT_TOPBOTTOM &&
|
||||||
lc != TAILQ_FIRST(&next->cells))
|
lc != TAILQ_FIRST(&next->cells))
|
||||||
return (0);
|
return (0);
|
||||||
@@ -262,6 +299,8 @@ layout_cell_is_bottom(struct window *w, struct layout_cell *lc)
|
|||||||
|
|
||||||
while (lc != w->layout_root) {
|
while (lc != w->layout_root) {
|
||||||
next = lc->parent;
|
next = lc->parent;
|
||||||
|
if (next == NULL)
|
||||||
|
return (0);
|
||||||
if (next->type == LAYOUT_TOPBOTTOM &&
|
if (next->type == LAYOUT_TOPBOTTOM &&
|
||||||
lc != TAILQ_LAST(&next->cells, layout_cells))
|
lc != TAILQ_LAST(&next->cells, layout_cells))
|
||||||
return (0);
|
return (0);
|
||||||
@@ -307,7 +346,8 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
|
|||||||
sx = lc->sx;
|
sx = lc->sx;
|
||||||
sy = lc->sy;
|
sy = lc->sy;
|
||||||
|
|
||||||
if (layout_add_horizontal_border(w, lc, status)) {
|
if ((~wp->flags & PANE_FLOATING) &&
|
||||||
|
layout_add_horizontal_border(w, lc, status)) {
|
||||||
if (status == PANE_STATUS_TOP)
|
if (status == PANE_STATUS_TOP)
|
||||||
wp->yoff++;
|
wp->yoff++;
|
||||||
sy--;
|
sy--;
|
||||||
@@ -346,14 +386,14 @@ u_int
|
|||||||
layout_count_cells(struct layout_cell *lc)
|
layout_count_cells(struct layout_cell *lc)
|
||||||
{
|
{
|
||||||
struct layout_cell *lcchild;
|
struct layout_cell *lcchild;
|
||||||
u_int count;
|
u_int count = 0;
|
||||||
|
|
||||||
switch (lc->type) {
|
switch (lc->type) {
|
||||||
case LAYOUT_WINDOWPANE:
|
case LAYOUT_WINDOWPANE:
|
||||||
return (1);
|
return (1);
|
||||||
case LAYOUT_LEFTRIGHT:
|
case LAYOUT_LEFTRIGHT:
|
||||||
case LAYOUT_TOPBOTTOM:
|
case LAYOUT_TOPBOTTOM:
|
||||||
count = 0;
|
case LAYOUT_FLOATING:
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||||
count += layout_count_cells(lcchild);
|
count += layout_count_cells(lcchild);
|
||||||
return (count);
|
return (count);
|
||||||
@@ -470,13 +510,22 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
|||||||
struct layout_cell *lcother, *lcparent;
|
struct layout_cell *lcother, *lcparent;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If no parent, this is the last pane so window close is imminent and
|
* If no parent, this is either a floating pane or the last
|
||||||
* there is no need to resize anything.
|
* pane so window close is imminent and there is no need to
|
||||||
|
* resize anything.
|
||||||
*/
|
*/
|
||||||
lcparent = lc->parent;
|
lcparent = lc->parent;
|
||||||
if (lcparent == NULL) {
|
if (lcparent == NULL) {
|
||||||
layout_free_cell(lc);
|
if (lc->wp != NULL && ~lc->wp->flags & PANE_FLOATING)
|
||||||
*lcroot = NULL;
|
*lcroot = NULL;
|
||||||
|
layout_free_cell(lc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A floating cell need only be removed from the parent. */
|
||||||
|
if (lcparent->type == LAYOUT_FLOATING) {
|
||||||
|
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||||
|
layout_free_cell(lc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,12 +548,13 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
|||||||
* replace it by that cell.
|
* replace it by that cell.
|
||||||
*/
|
*/
|
||||||
lc = TAILQ_FIRST(&lcparent->cells);
|
lc = TAILQ_FIRST(&lcparent->cells);
|
||||||
if (TAILQ_NEXT(lc, entry) == NULL) {
|
if (lc != NULL && TAILQ_NEXT(lc, entry) == NULL) {
|
||||||
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||||
|
|
||||||
lc->parent = lcparent->parent;
|
lc->parent = lcparent->parent;
|
||||||
if (lc->parent == NULL) {
|
if (lc->parent == NULL) {
|
||||||
lc->xoff = 0; lc->yoff = 0;
|
lc->xoff = 0;
|
||||||
|
lc->yoff = 0;
|
||||||
*lcroot = lc;
|
*lcroot = lc;
|
||||||
} else
|
} else
|
||||||
TAILQ_REPLACE(&lc->parent->cells, lcparent, lc, entry);
|
TAILQ_REPLACE(&lc->parent->cells, lcparent, lc, entry);
|
||||||
@@ -513,6 +563,7 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize layout for pane. */
|
||||||
void
|
void
|
||||||
layout_init(struct window *w, struct window_pane *wp)
|
layout_init(struct window *w, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@@ -524,6 +575,7 @@ layout_init(struct window *w, struct window_pane *wp)
|
|||||||
layout_fix_panes(w, NULL);
|
layout_fix_panes(w, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free layout for pane. */
|
||||||
void
|
void
|
||||||
layout_free(struct window *w)
|
layout_free(struct window *w)
|
||||||
{
|
{
|
||||||
@@ -741,7 +793,7 @@ layout_resize_pane_shrink(struct window *w, struct layout_cell *lc,
|
|||||||
return (size);
|
return (size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign window pane to newly split cell. */
|
/* Assign window pane to new cell. */
|
||||||
void
|
void
|
||||||
layout_assign_pane(struct layout_cell *lc, struct window_pane *wp,
|
layout_assign_pane(struct layout_cell *lc, struct window_pane *wp,
|
||||||
int do_not_resize)
|
int do_not_resize)
|
||||||
@@ -1085,6 +1137,9 @@ layout_close_pane(struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
struct window *w = wp->window;
|
struct window *w = wp->window;
|
||||||
|
|
||||||
|
if (wp->layout_cell == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Remove the cell. */
|
/* Remove the cell. */
|
||||||
layout_destroy_cell(w, wp->layout_cell, &w->layout_root);
|
layout_destroy_cell(w, wp->layout_cell, &w->layout_root);
|
||||||
|
|
||||||
|
|||||||
2
log.c
2
log.c
@@ -150,6 +150,7 @@ fatal(const char *msg, ...)
|
|||||||
log_vwrite(msg, ap, tmp);
|
log_vwrite(msg, ap, tmp);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
abort ();//XXX
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,5 +164,6 @@ fatalx(const char *msg, ...)
|
|||||||
log_vwrite(msg, ap, "fatal: ");
|
log_vwrite(msg, ap, "fatal: ");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
|
abort ();//XXX
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ server_kill_pane(struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
struct window *w = wp->window;
|
struct window *w = wp->window;
|
||||||
|
|
||||||
if (window_count_panes(w) == 1) {
|
if (window_count_panes(w, 1) == 1) {
|
||||||
server_kill_window(w, 1);
|
server_kill_window(w, 1);
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
22
tmux.h
22
tmux.h
@@ -1302,9 +1302,11 @@ struct window_pane {
|
|||||||
|
|
||||||
TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */
|
TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */
|
||||||
TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */
|
TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */
|
||||||
|
TAILQ_ENTRY(window_pane) zentry; /* z-index link in list of all panes */
|
||||||
RB_ENTRY(window_pane) tree_entry;
|
RB_ENTRY(window_pane) tree_entry;
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(window_panes, window_pane);
|
TAILQ_HEAD(window_panes, window_pane);
|
||||||
|
TAILQ_HEAD(window_panes_zindex, window_pane);
|
||||||
RB_HEAD(window_pane_tree, window_pane);
|
RB_HEAD(window_pane_tree, window_pane);
|
||||||
|
|
||||||
/* Window structure. */
|
/* Window structure. */
|
||||||
@@ -1324,6 +1326,7 @@ struct window {
|
|||||||
|
|
||||||
struct window_pane *active;
|
struct window_pane *active;
|
||||||
struct window_panes last_panes;
|
struct window_panes last_panes;
|
||||||
|
struct window_panes z_index;
|
||||||
struct window_panes panes;
|
struct window_panes panes;
|
||||||
|
|
||||||
int lastlayout;
|
int lastlayout;
|
||||||
@@ -1417,6 +1420,7 @@ TAILQ_HEAD(winlink_stack, winlink);
|
|||||||
enum layout_type {
|
enum layout_type {
|
||||||
LAYOUT_LEFTRIGHT,
|
LAYOUT_LEFTRIGHT,
|
||||||
LAYOUT_TOPBOTTOM,
|
LAYOUT_TOPBOTTOM,
|
||||||
|
LAYOUT_FLOATING,
|
||||||
LAYOUT_WINDOWPANE
|
LAYOUT_WINDOWPANE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1432,8 +1436,8 @@ struct layout_cell {
|
|||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
|
||||||
u_int xoff;
|
int xoff;
|
||||||
u_int yoff;
|
int yoff;
|
||||||
|
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
struct layout_cells cells;
|
struct layout_cells cells;
|
||||||
@@ -1710,10 +1714,10 @@ struct tty_ctx {
|
|||||||
u_int orlower;
|
u_int orlower;
|
||||||
|
|
||||||
/* Target region (usually pane) offset and size. */
|
/* Target region (usually pane) offset and size. */
|
||||||
u_int xoff;
|
int xoff;
|
||||||
u_int yoff;
|
int yoff;
|
||||||
u_int rxoff;
|
int rxoff;
|
||||||
u_int ryoff;
|
int ryoff;
|
||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
|
||||||
@@ -2284,6 +2288,7 @@ struct spawn_context {
|
|||||||
#define SPAWN_FULLSIZE 0x20
|
#define SPAWN_FULLSIZE 0x20
|
||||||
#define SPAWN_EMPTY 0x40
|
#define SPAWN_EMPTY 0x40
|
||||||
#define SPAWN_ZOOM 0x80
|
#define SPAWN_ZOOM 0x80
|
||||||
|
#define SPAWN_FLOATING 0x100
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Paste buffer. */
|
/* Paste buffer. */
|
||||||
@@ -3362,7 +3367,7 @@ struct window_pane *window_pane_next_by_number(struct window *,
|
|||||||
struct window_pane *window_pane_previous_by_number(struct window *,
|
struct window_pane *window_pane_previous_by_number(struct window *,
|
||||||
struct window_pane *, u_int);
|
struct window_pane *, u_int);
|
||||||
int window_pane_index(struct window_pane *, u_int *);
|
int window_pane_index(struct window_pane *, u_int *);
|
||||||
u_int window_count_panes(struct window *);
|
u_int window_count_panes(struct window *, int);
|
||||||
void window_destroy_panes(struct window *);
|
void window_destroy_panes(struct window *);
|
||||||
struct window_pane *window_pane_find_by_id_str(const char *);
|
struct window_pane *window_pane_find_by_id_str(const char *);
|
||||||
struct window_pane *window_pane_find_by_id(u_int);
|
struct window_pane *window_pane_find_by_id(u_int);
|
||||||
@@ -3430,8 +3435,7 @@ void layout_destroy_cell(struct window *, struct layout_cell *,
|
|||||||
void layout_resize_layout(struct window *, struct layout_cell *,
|
void layout_resize_layout(struct window *, struct layout_cell *,
|
||||||
enum layout_type, int, int);
|
enum layout_type, int, int);
|
||||||
struct layout_cell *layout_search_by_border(struct layout_cell *, u_int, u_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, u_int,
|
void layout_set_size(struct layout_cell *, u_int, u_int, int, int);
|
||||||
u_int);
|
|
||||||
void layout_make_leaf(struct layout_cell *, struct window_pane *);
|
void layout_make_leaf(struct layout_cell *, struct window_pane *);
|
||||||
void layout_make_node(struct layout_cell *, enum layout_type);
|
void layout_make_node(struct layout_cell *, enum layout_type);
|
||||||
void layout_fix_offsets(struct window *);
|
void layout_fix_offsets(struct window *);
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ window_tree_build(void *modedata, struct sort_criteria *sort_crit,
|
|||||||
*tag = (uint64_t)data->fs.wl;
|
*tag = (uint64_t)data->fs.wl;
|
||||||
break;
|
break;
|
||||||
case WINDOW_TREE_PANE:
|
case WINDOW_TREE_PANE:
|
||||||
if (window_count_panes(data->fs.wl->window) == 1)
|
if (window_count_panes(data->fs.wl->window, 1) == 1)
|
||||||
*tag = (uint64_t)data->fs.wl;
|
*tag = (uint64_t)data->fs.wl;
|
||||||
else
|
else
|
||||||
*tag = (uint64_t)data->fs.wp;
|
*tag = (uint64_t)data->fs.wp;
|
||||||
@@ -578,7 +578,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s,
|
|||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
struct options *oo;
|
struct options *oo;
|
||||||
|
|
||||||
total = window_count_panes(w);
|
total = window_count_panes(w, 1);
|
||||||
|
|
||||||
if (sx / total < 24) {
|
if (sx / total < 24) {
|
||||||
visible = sx / 24;
|
visible = sx / 24;
|
||||||
|
|||||||
84
window.c
84
window.c
@@ -73,7 +73,7 @@ static struct window_pane *window_pane_create(struct window *, u_int, u_int,
|
|||||||
u_int);
|
u_int);
|
||||||
static void window_pane_destroy(struct window_pane *);
|
static void window_pane_destroy(struct window_pane *);
|
||||||
static void window_pane_full_size_offset(struct window_pane *wp,
|
static void window_pane_full_size_offset(struct window_pane *wp,
|
||||||
u_int *xoff, u_int *yoff, u_int *sx, u_int *sy);
|
int *xoff, int *yoff, u_int *sx, u_int *sy);
|
||||||
|
|
||||||
RB_GENERATE(windows, window, entry, window_cmp);
|
RB_GENERATE(windows, window, entry, window_cmp);
|
||||||
RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
|
RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
|
||||||
@@ -308,6 +308,7 @@ window_create(u_int sx, u_int sy, u_int xpixel, u_int ypixel)
|
|||||||
w->flags = 0;
|
w->flags = 0;
|
||||||
|
|
||||||
TAILQ_INIT(&w->panes);
|
TAILQ_INIT(&w->panes);
|
||||||
|
TAILQ_INIT(&w->z_index);
|
||||||
TAILQ_INIT(&w->last_panes);
|
TAILQ_INIT(&w->last_panes);
|
||||||
w->active = NULL;
|
w->active = NULL;
|
||||||
|
|
||||||
@@ -523,6 +524,8 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
|
|||||||
|
|
||||||
if (wp == w->active)
|
if (wp == w->active)
|
||||||
return (0);
|
return (0);
|
||||||
|
if (w->flags & WINDOW_ZOOMED)
|
||||||
|
window_unzoom(w, 1);
|
||||||
lastwp = w->active;
|
lastwp = w->active;
|
||||||
|
|
||||||
window_pane_stack_remove(&w->last_panes, wp);
|
window_pane_stack_remove(&w->last_panes, wp);
|
||||||
@@ -665,7 +668,7 @@ window_zoom(struct window_pane *wp)
|
|||||||
if (w->flags & WINDOW_ZOOMED)
|
if (w->flags & WINDOW_ZOOMED)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (window_count_panes(w) == 1)
|
if (window_count_panes(w, 1) == 1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (w->active != wp)
|
if (w->active != wp)
|
||||||
@@ -852,14 +855,15 @@ window_pane_index(struct window_pane *wp, u_int *i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u_int
|
u_int
|
||||||
window_count_panes(struct window *w)
|
window_count_panes(struct window *w, int with_floating)
|
||||||
{
|
{
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int n;
|
u_int n = 0;
|
||||||
|
|
||||||
n = 0;
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
TAILQ_FOREACH(wp, &w->panes, entry)
|
if (with_floating || ~wp->flags & PANE_FLOATING)
|
||||||
n++;
|
n++;
|
||||||
|
}
|
||||||
return (n);
|
return (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1377,7 +1381,7 @@ window_pane_choose_best(struct window_pane **list, u_int size)
|
|||||||
* scrollbars if they were visible but not including the border(s).
|
* scrollbars if they were visible but not including the border(s).
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
window_pane_full_size_offset(struct window_pane *wp, u_int *xoff, u_int *yoff,
|
window_pane_full_size_offset(struct window_pane *wp, int *xoff, int *yoff,
|
||||||
u_int *sx, u_int *sy)
|
u_int *sx, u_int *sy)
|
||||||
{
|
{
|
||||||
struct window *w = wp->window;
|
struct window *w = wp->window;
|
||||||
@@ -1411,9 +1415,9 @@ window_pane_find_up(struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *next, *best, **list;
|
struct window_pane *next, *best, **list;
|
||||||
u_int edge, left, right, end, size;
|
int edge, left, right, end, status, found;
|
||||||
int status, found;
|
int xoff, yoff;
|
||||||
u_int xoff, yoff, sx, sy;
|
u_int size, sx, sy;
|
||||||
|
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -1428,25 +1432,25 @@ window_pane_find_up(struct window_pane *wp)
|
|||||||
edge = yoff;
|
edge = yoff;
|
||||||
if (status == PANE_STATUS_TOP) {
|
if (status == PANE_STATUS_TOP) {
|
||||||
if (edge == 1)
|
if (edge == 1)
|
||||||
edge = w->sy + 1;
|
edge = (int)w->sy + 1;
|
||||||
} else if (status == PANE_STATUS_BOTTOM) {
|
} else if (status == PANE_STATUS_BOTTOM) {
|
||||||
if (edge == 0)
|
if (edge == 0)
|
||||||
edge = w->sy;
|
edge = (int)w->sy;
|
||||||
} else {
|
} else {
|
||||||
if (edge == 0)
|
if (edge == 0)
|
||||||
edge = w->sy + 1;
|
edge = (int)w->sy + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
left = xoff;
|
left = xoff;
|
||||||
right = xoff + sx;
|
right = xoff + (int)sx;
|
||||||
|
|
||||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||||
if (next == wp)
|
if (next == wp)
|
||||||
continue;
|
continue;
|
||||||
if (yoff + sy + 1 != edge)
|
if (yoff + (int)sy + 1 != edge)
|
||||||
continue;
|
continue;
|
||||||
end = xoff + sx - 1;
|
end = xoff + (int)sx - 1;
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
if (xoff < left && end > right)
|
if (xoff < left && end > right)
|
||||||
@@ -1472,9 +1476,9 @@ window_pane_find_down(struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *next, *best, **list;
|
struct window_pane *next, *best, **list;
|
||||||
u_int edge, left, right, end, size;
|
int edge, left, right, end, status, found;
|
||||||
int status, found;
|
int xoff, yoff;
|
||||||
u_int xoff, yoff, sx, sy;
|
u_int size, sx, sy;
|
||||||
|
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -1486,20 +1490,20 @@ window_pane_find_down(struct window_pane *wp)
|
|||||||
|
|
||||||
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
||||||
|
|
||||||
edge = yoff + sy + 1;
|
edge = yoff + (int)sy + 1;
|
||||||
if (status == PANE_STATUS_TOP) {
|
if (status == PANE_STATUS_TOP) {
|
||||||
if (edge >= w->sy)
|
if (edge >= (int)w->sy)
|
||||||
edge = 1;
|
edge = 1;
|
||||||
} else if (status == PANE_STATUS_BOTTOM) {
|
} else if (status == PANE_STATUS_BOTTOM) {
|
||||||
if (edge >= w->sy - 1)
|
if (edge >= (int)w->sy - 1)
|
||||||
edge = 0;
|
edge = 0;
|
||||||
} else {
|
} else {
|
||||||
if (edge >= w->sy)
|
if (edge >= (int)w->sy)
|
||||||
edge = 0;
|
edge = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
left = wp->xoff;
|
left = wp->xoff;
|
||||||
right = wp->xoff + wp->sx;
|
right = wp->xoff + (int)wp->sx;
|
||||||
|
|
||||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||||
@@ -1507,7 +1511,7 @@ window_pane_find_down(struct window_pane *wp)
|
|||||||
continue;
|
continue;
|
||||||
if (yoff != edge)
|
if (yoff != edge)
|
||||||
continue;
|
continue;
|
||||||
end = xoff + sx - 1;
|
end = xoff + (int)sx - 1;
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
if (xoff < left && end > right)
|
if (xoff < left && end > right)
|
||||||
@@ -1533,9 +1537,9 @@ window_pane_find_left(struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *next, *best, **list;
|
struct window_pane *next, *best, **list;
|
||||||
u_int edge, top, bottom, end, size;
|
int edge, top, bottom, end, found;
|
||||||
int found;
|
int xoff, yoff;
|
||||||
u_int xoff, yoff, sx, sy;
|
u_int size, sx, sy;
|
||||||
|
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -1548,18 +1552,18 @@ window_pane_find_left(struct window_pane *wp)
|
|||||||
|
|
||||||
edge = xoff;
|
edge = xoff;
|
||||||
if (edge == 0)
|
if (edge == 0)
|
||||||
edge = w->sx + 1;
|
edge = (int)w->sx + 1;
|
||||||
|
|
||||||
top = yoff;
|
top = yoff;
|
||||||
bottom = yoff + sy;
|
bottom = yoff + (int)sy;
|
||||||
|
|
||||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||||
if (next == wp)
|
if (next == wp)
|
||||||
continue;
|
continue;
|
||||||
if (xoff + sx + 1 != edge)
|
if (xoff + (int)sx + 1 != edge)
|
||||||
continue;
|
continue;
|
||||||
end = yoff + sy - 1;
|
end = yoff + (int)sy - 1;
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
if (yoff < top && end > bottom)
|
if (yoff < top && end > bottom)
|
||||||
@@ -1585,9 +1589,9 @@ window_pane_find_right(struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct window_pane *next, *best, **list;
|
struct window_pane *next, *best, **list;
|
||||||
u_int edge, top, bottom, end, size;
|
int edge, top, bottom, end, found;
|
||||||
int found;
|
int xoff, yoff;
|
||||||
u_int xoff, yoff, sx, sy;
|
u_int size, sx, sy;
|
||||||
|
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
@@ -1598,12 +1602,12 @@ window_pane_find_right(struct window_pane *wp)
|
|||||||
|
|
||||||
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
window_pane_full_size_offset(wp, &xoff, &yoff, &sx, &sy);
|
||||||
|
|
||||||
edge = xoff + sx + 1;
|
edge = xoff + (int)sx + 1;
|
||||||
if (edge >= w->sx)
|
if (edge >= (int)w->sx)
|
||||||
edge = 0;
|
edge = 0;
|
||||||
|
|
||||||
top = wp->yoff;
|
top = wp->yoff;
|
||||||
bottom = wp->yoff + wp->sy;
|
bottom = wp->yoff + (int)wp->sy;
|
||||||
|
|
||||||
TAILQ_FOREACH(next, &w->panes, entry) {
|
TAILQ_FOREACH(next, &w->panes, entry) {
|
||||||
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
window_pane_full_size_offset(next, &xoff, &yoff, &sx, &sy);
|
||||||
@@ -1611,7 +1615,7 @@ window_pane_find_right(struct window_pane *wp)
|
|||||||
continue;
|
continue;
|
||||||
if (xoff != edge)
|
if (xoff != edge)
|
||||||
continue;
|
continue;
|
||||||
end = yoff + sy - 1;
|
end = yoff + (int)sy - 1;
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
if (yoff < top && end > bottom)
|
if (yoff < top && end > bottom)
|
||||||
@@ -1631,6 +1635,7 @@ window_pane_find_right(struct window_pane *wp)
|
|||||||
return (best);
|
return (best);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add window to stack. */
|
||||||
void
|
void
|
||||||
window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
|
window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
@@ -1641,6 +1646,7 @@ window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove window from stack. */
|
||||||
void
|
void
|
||||||
window_pane_stack_remove(struct window_panes *stack, struct window_pane *wp)
|
window_pane_stack_remove(struct window_panes *stack, struct window_pane *wp)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user