Add hidden panes and a "show desktop" button to the pane list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Michael Grant
2026-10-01 08:24:16 +01:00
parent 291c043080
commit d6cf5e0e4d
14 changed files with 281 additions and 48 deletions

View File

@@ -75,6 +75,7 @@ struct layout_parse_cell_ctx {
int index;
int zindex;
int zoomed;
int hidden;
};
/* Layout parse context. */
@@ -221,7 +222,7 @@ layout_parse_free_ctx(struct layout_parse_ctx *pctx)
/* Add a cell context to the parse context. */
static void
layout_parse_add_cctx(struct layout_parse_ctx *pctx, struct layout_cell *lc,
int active, int last, int index, int zindex, int zoomed)
int active, int last, int index, int zindex, int zoomed, int hidden)
{
struct layout_parse_cell_ctx *cctx;
@@ -238,6 +239,7 @@ layout_parse_add_cctx(struct layout_parse_ctx *pctx, struct layout_cell *lc,
cctx->index = index;
cctx->zindex = zindex;
cctx->zoomed = zoomed;
cctx->hidden = hidden;
}
/* Remove a cell context from the parse context. Does not preserve ordering. */
@@ -429,6 +431,8 @@ layout_append_v2(struct layout_cell *lc, struct layout_string *ls)
layout_string_write(ls, ",\"i\":%u", i);
if (wp->flags & PANE_ZOOMED)
layout_string_write(ls, ",\"Z\":true");
if (wp->flags & PANE_HIDDEN)
layout_string_write(ls, ",\"H\":true");
if (lc->flags & LAYOUT_CELL_FLOATING) {
z = layout_cell_zindex(lc);
layout_string_write(ls, ",\"z\":%u", z);
@@ -481,18 +485,23 @@ layout_append_v1(struct layout_cell *lc, struct layout_string *ls)
}
/*
* Copies the tiled part of a layout. Only populates what is necessary to dump a
* V1 layout string.
* Copies the part of a layout that is shown, which leaves out hidden tiled
* panes and, unless asked to keep them, floating panes. Only populates what is
* necessary to dump a layout string.
*/
static struct layout_cell *
layout_custom_copy_layout(struct layout_cell *lc)
layout_custom_copy_layout(struct layout_cell *lc, int keep_floating)
{
struct layout_cell *lcchild, *lcnewchild, *lconly;
struct layout_cell *lcnew;
if (lc->type == LAYOUT_WINDOWPANE &&
(lc->flags & LAYOUT_CELL_FLOATING))
return (NULL);
if (lc->type == LAYOUT_WINDOWPANE) {
if (lc->flags & LAYOUT_CELL_FLOATING) {
if (!keep_floating)
return (NULL);
} else if (lc->wp != NULL && (lc->wp->flags & PANE_HIDDEN))
return (NULL);
}
lcnew = layout_create_cell(NULL);
@@ -508,7 +517,8 @@ layout_custom_copy_layout(struct layout_cell *lc)
case LAYOUT_TOPBOTTOM:
case LAYOUT_LEFTRIGHT:
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
lcnewchild = layout_custom_copy_layout(lcchild);
lcnewchild = layout_custom_copy_layout(lcchild,
keep_floating);
if (lcnewchild == NULL)
continue;
TAILQ_INSERT_TAIL(&lcnew->cells, lcnewchild, entry);
@@ -534,11 +544,11 @@ layout_custom_copy_layout(struct layout_cell *lc)
/* Create a compatibility layout for dumping a V1 layout string. */
static struct layout_cell *
layout_custom_create_compat(struct layout_cell *lcroot)
layout_custom_create_compat(struct layout_cell *lcroot, int keep_floating)
{
struct layout_cell *lccompat;
lccompat = layout_custom_copy_layout(lcroot);
lccompat = layout_custom_copy_layout(lcroot, keep_floating);
if (lccompat != NULL && layout_cell_is_tiled(lccompat)) {
lccompat->g.xoff = 0;
lccompat->g.yoff = 0;
@@ -586,11 +596,18 @@ layout_append(struct layout_cell *lcroot, struct layout_string *ls, int flags)
if (!layout_cell_is_tiled(lcroot) &&
!layout_cell_has_tiled_child(lcroot))
return (-1);
lccompat = layout_custom_create_compat(lcroot);
lccompat = layout_custom_create_compat(lcroot, 0);
result = layout_append_v1(lccompat, ls);
layout_custom_free_compat(lccompat);
} else
result = layout_append_v2(lcroot, ls);
} else {
lccompat = layout_custom_create_compat(lcroot, 1);
if (lccompat == NULL)
result = layout_append_v2(lcroot, ls);
else {
result = layout_append_v2(lccompat, ls);
layout_custom_free_compat(lccompat);
}
}
return (result);
}
@@ -743,6 +760,12 @@ layout_parse(struct window *w, const char *input, char **cause)
}
}
/* Hidden tiled panes are in the new layout like the rest. */
TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_is_floating(wp))
wp->flags &= ~(PANE_HIDDEN|PANE_HIDDENALL);
}
/* Destroy the old layout and swap to the new. */
layout_free_cell(w->layout_root, 0);
w->layout_root = lc;
@@ -1018,7 +1041,7 @@ layout_parse_json_layout(struct json_node *node, struct layout_cell *lcparent,
int64_t num;
char **cause = pctx->cause;
int boolean, index, zindex, active = -1;
int last = -1, zoomed = 0;
int last = -1, zoomed, hidden;
if (json_find_string(node, "t", &str, cause) != 0)
goto fail;
@@ -1108,14 +1131,20 @@ layout_parse_json_layout(struct json_node *node, struct layout_cell *lcparent,
} else
zindex = INT_MAX;
zoomed = hidden = 0;
if (json_find(node, "Z") != NULL) {
if (json_find_boolean(node, "Z", &boolean, cause) != 0)
goto fail;
zoomed = boolean;
}
if (json_find(node, "H") != NULL) {
if (json_find_boolean(node, "H", &boolean, cause) != 0)
goto fail;
hidden = boolean;
}
layout_parse_add_cctx(pctx, lc, active, last, index, zindex,
zoomed);
zoomed, hidden);
} else {
if (json_find_array(node, "c", &array, cause) != 0)
goto fail;
@@ -1225,11 +1254,18 @@ layout_parse_apply_ctx(struct window *w, struct layout_parse_ctx *pctx)
TAILQ_INSERT_HEAD(&w->z_index, wp, zentry);
}
/* Zoom panes. */
/* Zoom and hide panes. */
for (i = 0; i < pctx->size; i++) {
cctx = &pctx->cctxs[i];
wp = cctx->lc->wp;
if (cctx->zoomed)
window_zoom(cctx->lc->wp);
window_zoom(wp);
}
for (i = 0; i < pctx->size; i++) {
cctx = &pctx->cctxs[i];
wp = cctx->lc->wp;
if (cctx->hidden && window_pane_is_floating(wp))
window_hide_pane(wp);
}
/* Set the active pane. */