mirror of
https://github.com/swaywm/sway.git
synced 2026-04-23 06:46:27 -04:00
introduce workspace_squash
workspace_squash is container_flatten in the reverse
direction. Instead of eliminating redundant splits that are
parents of the target container, it eliminates pairs of
redundant H/V splits that are children of the workspace.
Splits are redundant if a con and its grandchild have the
same layout, and the immediate child has the opposite split.
For example, layouts are transformed like:
H[V[H[app1 app2]] app3] -> H[app1 app2 app3]
i3 uses this operation to simplify the tree after moving
heavily nested containers to a higher level in the tree via
an orthogonal move.
This commit is contained in:
parent
e95c299f0a
commit
8eb0c54693
4 changed files with 109 additions and 7 deletions
|
|
@ -1630,3 +1630,65 @@ bool container_is_sticky(struct sway_container *con) {
|
|||
bool container_is_sticky_or_child(struct sway_container *con) {
|
||||
return container_is_sticky(container_toplevel_ancestor(con));
|
||||
}
|
||||
|
||||
static bool is_parallel(enum sway_container_layout first,
|
||||
enum sway_container_layout second) {
|
||||
switch (first) {
|
||||
case L_TABBED:
|
||||
case L_HORIZ:
|
||||
return second == L_TABBED || second == L_HORIZ;
|
||||
case L_STACKED:
|
||||
case L_VERT:
|
||||
return second == L_STACKED || second == L_VERT;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool container_is_squashable(struct sway_container *con,
|
||||
struct sway_container *child) {
|
||||
enum sway_container_layout gp_layout = container_parent_layout(con);
|
||||
return (con->layout == L_HORIZ || con->layout == L_VERT) &&
|
||||
(child->layout == L_HORIZ || child->layout == L_VERT) &&
|
||||
!is_parallel(con->layout, child->layout) &&
|
||||
is_parallel(gp_layout, child->layout);
|
||||
}
|
||||
|
||||
static void container_squash_children(struct sway_container *con) {
|
||||
for (int i = 0; i < con->children->length; i++) {
|
||||
struct sway_container *child = con->children->items[i];
|
||||
i += container_squash(child);
|
||||
}
|
||||
}
|
||||
|
||||
int container_squash(struct sway_container *con) {
|
||||
if (!con->children) {
|
||||
return 0;
|
||||
}
|
||||
if (con->children->length != 1) {
|
||||
container_squash_children(con);
|
||||
return 0;
|
||||
}
|
||||
struct sway_container *child = con->children->items[0];
|
||||
int idx = container_sibling_index(con);
|
||||
int change = 0;
|
||||
if (container_is_squashable(con, child)) {
|
||||
// con and child are a redundant H/V pair. Destroy them.
|
||||
while (child->children->length) {
|
||||
struct sway_container *current = child->children->items[0];
|
||||
container_detach(current);
|
||||
if (con->parent) {
|
||||
container_insert_child(con->parent, current, idx);
|
||||
} else {
|
||||
workspace_insert_tiling_direct(con->workspace, current, idx);
|
||||
}
|
||||
change++;
|
||||
}
|
||||
// This will also destroy con because child was its only child
|
||||
container_reap_empty(child);
|
||||
change--;
|
||||
} else {
|
||||
container_squash_children(con);
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue