aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/container.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r--sway/tree/container.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 23b6c997..4c573e83 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -1630,3 +1630,65 @@ bool container_is_sticky(struct sway_container *con) {
1630bool container_is_sticky_or_child(struct sway_container *con) { 1630bool container_is_sticky_or_child(struct sway_container *con) {
1631 return container_is_sticky(container_toplevel_ancestor(con)); 1631 return container_is_sticky(container_toplevel_ancestor(con));
1632} 1632}
1633
1634static bool is_parallel(enum sway_container_layout first,
1635 enum sway_container_layout second) {
1636 switch (first) {
1637 case L_TABBED:
1638 case L_HORIZ:
1639 return second == L_TABBED || second == L_HORIZ;
1640 case L_STACKED:
1641 case L_VERT:
1642 return second == L_STACKED || second == L_VERT;
1643 default:
1644 return false;
1645 }
1646}
1647
1648static bool container_is_squashable(struct sway_container *con,
1649 struct sway_container *child) {
1650 enum sway_container_layout gp_layout = container_parent_layout(con);
1651 return (con->layout == L_HORIZ || con->layout == L_VERT) &&
1652 (child->layout == L_HORIZ || child->layout == L_VERT) &&
1653 !is_parallel(con->layout, child->layout) &&
1654 is_parallel(gp_layout, child->layout);
1655}
1656
1657static void container_squash_children(struct sway_container *con) {
1658 for (int i = 0; i < con->children->length; i++) {
1659 struct sway_container *child = con->children->items[i];
1660 i += container_squash(child);
1661 }
1662}
1663
1664int container_squash(struct sway_container *con) {
1665 if (!con->children) {
1666 return 0;
1667 }
1668 if (con->children->length != 1) {
1669 container_squash_children(con);
1670 return 0;
1671 }
1672 struct sway_container *child = con->children->items[0];
1673 int idx = container_sibling_index(con);
1674 int change = 0;
1675 if (container_is_squashable(con, child)) {
1676 // con and child are a redundant H/V pair. Destroy them.
1677 while (child->children->length) {
1678 struct sway_container *current = child->children->items[0];
1679 container_detach(current);
1680 if (con->parent) {
1681 container_insert_child(con->parent, current, idx);
1682 } else {
1683 workspace_insert_tiling_direct(con->workspace, current, idx);
1684 }
1685 change++;
1686 }
1687 // This will also destroy con because child was its only child
1688 container_reap_empty(child);
1689 change--;
1690 } else {
1691 container_squash_children(con);
1692 }
1693 return change;
1694}