mirror of
https://github.com/tmux/tmux.git
synced 2026-06-20 17:25:57 +00:00
Add layout_cell_is_tiled and layout_cell_has_tiled_child helper
functions, from Dane Jensen.
This commit is contained in:
93
layout.c
93
layout.c
@@ -26,11 +26,18 @@
|
|||||||
/*
|
/*
|
||||||
* The window layout is a tree of cells each of which can be one of: a
|
* The window layout is a tree of cells each of which can be one of: a
|
||||||
* left-right container for a list of cells, a top-bottom container for a list
|
* left-right container for a list of cells, a top-bottom container for a list
|
||||||
* of cells, or a container for a window pane.
|
* of cells, or a container for a window pane. 'Node' will be used to refer to
|
||||||
|
* a cell which contains a list of cells, and 'leaf' to refer to a cell that
|
||||||
|
* contains a window pane. A leaf is considered to be 'tiled' if it is to be
|
||||||
|
* drawn as a part of the tiled layout. A 'neighbour' is a sibling that is also
|
||||||
|
* tiled. A cell's 'split' size refers to the side that is shortened when
|
||||||
|
* splitting it, determined by the parent's type.
|
||||||
*
|
*
|
||||||
* Each window has a pointer to the root of its layout tree (containing its
|
* Each window has a pointer to the root of its layout tree (containing its
|
||||||
* panes), every pane has a pointer back to the cell containing it, and each
|
* panes), every pane has a pointer back to the cell containing it, and each
|
||||||
* cell a pointer to its parent cell.
|
* cell a pointer to its parent cell. Every cell has a position in the root
|
||||||
|
* layout tree. This position is retained through cell state changes such as
|
||||||
|
* floating or hiding.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static u_int layout_resize_check(struct window *, struct layout_cell *,
|
static u_int layout_resize_check(struct window *, struct layout_cell *,
|
||||||
@@ -240,6 +247,49 @@ layout_fix_zindexes(struct window *w, struct layout_cell *lc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
layout_cell_is_tiled(struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
int is_leaf = lc->type == LAYOUT_WINDOWPANE;
|
||||||
|
int is_floating = lc->flags & LAYOUT_CELL_FLOATING;
|
||||||
|
|
||||||
|
return is_leaf && !is_floating;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
layout_cell_has_tiled_child(struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcchild;
|
||||||
|
|
||||||
|
if (lc->type == LAYOUT_WINDOWPANE)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
|
if (layout_cell_is_tiled(lcchild) ||
|
||||||
|
layout_cell_has_tiled_child(lcchild))
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
layout_cell_is_first_tiled(struct layout_cell *lc)
|
||||||
|
{
|
||||||
|
struct layout_cell *lcchild, *lcparent = lc->parent;
|
||||||
|
|
||||||
|
if (lcparent == NULL)
|
||||||
|
return (layout_cell_is_tiled(lc));
|
||||||
|
|
||||||
|
TAILQ_FOREACH(lcchild, &lcparent->cells, entry) {
|
||||||
|
if (layout_cell_is_tiled(lcchild) ||
|
||||||
|
layout_cell_has_tiled_child(lcchild))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (lcchild == lc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fix cell offsets for a child cell. */
|
/* Fix cell offsets for a child cell. */
|
||||||
static void
|
static void
|
||||||
layout_fix_offsets1(struct layout_cell *lc)
|
layout_fix_offsets1(struct layout_cell *lc)
|
||||||
@@ -250,7 +300,8 @@ layout_fix_offsets1(struct layout_cell *lc)
|
|||||||
if (lc->type == LAYOUT_LEFTRIGHT) {
|
if (lc->type == LAYOUT_LEFTRIGHT) {
|
||||||
xoff = lc->xoff;
|
xoff = lc->xoff;
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
if (lcchild->flags & LAYOUT_CELL_FLOATING)
|
if (!layout_cell_is_tiled(lcchild) &&
|
||||||
|
!layout_cell_has_tiled_child(lcchild))
|
||||||
continue;
|
continue;
|
||||||
lcchild->xoff = xoff;
|
lcchild->xoff = xoff;
|
||||||
lcchild->yoff = lc->yoff;
|
lcchild->yoff = lc->yoff;
|
||||||
@@ -261,7 +312,8 @@ layout_fix_offsets1(struct layout_cell *lc)
|
|||||||
} else {
|
} else {
|
||||||
yoff = lc->yoff;
|
yoff = lc->yoff;
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
if (lcchild->flags & LAYOUT_CELL_FLOATING)
|
if (!layout_cell_is_tiled(lcchild) &&
|
||||||
|
!layout_cell_has_tiled_child(lcchild))
|
||||||
continue;
|
continue;
|
||||||
lcchild->xoff = lc->xoff;
|
lcchild->xoff = lc->xoff;
|
||||||
lcchild->yoff = yoff;
|
lcchild->yoff = yoff;
|
||||||
@@ -292,22 +344,15 @@ layout_fix_offsets(struct window *w)
|
|||||||
static int
|
static int
|
||||||
layout_cell_is_top(struct window *w, struct layout_cell *lc)
|
layout_cell_is_top(struct window *w, struct layout_cell *lc)
|
||||||
{
|
{
|
||||||
struct layout_cell *next, *edge;
|
struct layout_cell *next;
|
||||||
|
|
||||||
while (lc != w->layout_root) {
|
while (lc != w->layout_root) {
|
||||||
next = lc->parent;
|
next = lc->parent;
|
||||||
if (next == NULL)
|
if (next == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
if (next->type == LAYOUT_TOPBOTTOM) {
|
if (next->type == LAYOUT_TOPBOTTOM &&
|
||||||
edge = TAILQ_FIRST(&next->cells);
|
!layout_cell_is_first_tiled(lc))
|
||||||
while (edge != NULL) {
|
|
||||||
if (~edge->flags & LAYOUT_CELL_FLOATING)
|
|
||||||
break;
|
|
||||||
edge = TAILQ_NEXT(edge, entry);
|
|
||||||
}
|
|
||||||
if (lc != edge)
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
|
||||||
lc = next;
|
lc = next;
|
||||||
}
|
}
|
||||||
return (1);
|
return (1);
|
||||||
@@ -505,13 +550,20 @@ layout_resize_adjust(struct window *w, struct layout_cell *lc,
|
|||||||
/* Child cell runs in a different direction. */
|
/* Child cell runs in a different direction. */
|
||||||
if (lc->type != type) {
|
if (lc->type != type) {
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
if (lcchild->flags & LAYOUT_CELL_FLOATING)
|
if (!layout_cell_is_tiled(lcchild) &&
|
||||||
|
!layout_cell_has_tiled_child(lcchild))
|
||||||
continue;
|
continue;
|
||||||
layout_resize_adjust(w, lcchild, type, change);
|
layout_resize_adjust(w, lcchild, type, change);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a node doesn't contain any tiled cells, there is nothing to do.
|
||||||
|
*/
|
||||||
|
if (!layout_cell_has_tiled_child(lc))
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Child cell runs in the same direction. Adjust each child equally
|
* Child cell runs in the same direction. Adjust each child equally
|
||||||
* until no further change is possible.
|
* until no further change is possible.
|
||||||
@@ -520,7 +572,8 @@ layout_resize_adjust(struct window *w, struct layout_cell *lc,
|
|||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
if (change == 0)
|
if (change == 0)
|
||||||
break;
|
break;
|
||||||
if (lcchild->flags & LAYOUT_CELL_FLOATING)
|
if (!layout_cell_is_tiled(lcchild) &&
|
||||||
|
!layout_cell_has_tiled_child(lcchild))
|
||||||
continue;
|
continue;
|
||||||
if (change > 0) {
|
if (change > 0) {
|
||||||
layout_resize_adjust(w, lcchild, type, 1);
|
layout_resize_adjust(w, lcchild, type, 1);
|
||||||
@@ -582,7 +635,7 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
|||||||
|
|
||||||
lc->parent = lcparent->parent;
|
lc->parent = lcparent->parent;
|
||||||
if (lc->parent == NULL) {
|
if (lc->parent == NULL) {
|
||||||
if (~lc->flags & LAYOUT_CELL_FLOATING) {
|
if (!layout_cell_is_tiled(lc)) {
|
||||||
lc->xoff = 0;
|
lc->xoff = 0;
|
||||||
lc->yoff = 0;
|
lc->yoff = 0;
|
||||||
}
|
}
|
||||||
@@ -1009,7 +1062,8 @@ layout_resize_child_cells(struct window *w, struct layout_cell *lc)
|
|||||||
count = 0;
|
count = 0;
|
||||||
previous = 0;
|
previous = 0;
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
if (lcchild->flags & LAYOUT_CELL_FLOATING)
|
if (!layout_cell_is_tiled(lc) &&
|
||||||
|
!layout_cell_has_tiled_child(lc))
|
||||||
continue;
|
continue;
|
||||||
count++;
|
count++;
|
||||||
if (lc->type == LAYOUT_LEFTRIGHT)
|
if (lc->type == LAYOUT_LEFTRIGHT)
|
||||||
@@ -1029,7 +1083,8 @@ layout_resize_child_cells(struct window *w, struct layout_cell *lc)
|
|||||||
/* Resize children into the new size. */
|
/* Resize children into the new size. */
|
||||||
idx = 0;
|
idx = 0;
|
||||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||||
if (lcchild->flags & LAYOUT_CELL_FLOATING)
|
if (!layout_cell_is_tiled(lc) &&
|
||||||
|
!layout_cell_has_tiled_child(lc))
|
||||||
continue;
|
continue;
|
||||||
if (lc->type == LAYOUT_TOPBOTTOM) {
|
if (lc->type == LAYOUT_TOPBOTTOM) {
|
||||||
lcchild->sx = lc->sx;
|
lcchild->sx = lc->sx;
|
||||||
|
|||||||
Reference in New Issue
Block a user