diff options
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r-- | sway/tree/container.c | 62 |
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) { | |||
1630 | bool container_is_sticky_or_child(struct sway_container *con) { | 1630 | bool 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 | |||
1634 | static 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 | |||
1648 | static 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 | |||
1657 | static 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 | |||
1664 | int 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 | } | ||