summaryrefslogtreecommitdiffstats
path: root/sway/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/layout.c')
-rw-r--r--sway/layout.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/sway/layout.c b/sway/layout.c
index 377dad47..5f8da9e6 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -1503,3 +1503,96 @@ enum swayc_layouts default_layout(swayc_t *output) {
1503bool is_auto_layout(enum swayc_layouts layout) { 1503bool is_auto_layout(enum swayc_layouts layout) {
1504 return (layout >= L_AUTO_FIRST) && (layout <= L_AUTO_LAST); 1504 return (layout >= L_AUTO_FIRST) && (layout <= L_AUTO_LAST);
1505} 1505}
1506
1507/**
1508 * Return the number of children in the slave groups. This corresponds to the children
1509 * that are not members of the master group.
1510 */
1511static inline size_t auto_slave_count(swayc_t *container) {
1512 return container->children->length - container->nb_master;
1513}
1514
1515/**
1516 * given the index of a container's child, return the index of the first child of the group
1517 * which index is a member of.
1518 */
1519int auto_group_start_index(swayc_t *container, int index) {
1520 if (index < 0 || ! is_auto_layout(container->layout)
1521 || (size_t) index < container->nb_master) {
1522 return 0;
1523 } else {
1524 size_t grp_sz = auto_slave_count(container) / container->nb_slave_groups;
1525 size_t remainder = auto_slave_count(container) % container->nb_slave_groups;
1526 int start_idx;
1527 int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master;
1528 if (index < idx2) {
1529 start_idx = ((index - container->nb_master) / grp_sz) * grp_sz + container->nb_master;
1530 } else {
1531 start_idx = idx2 + ((index - idx2) / (grp_sz + 1)) * (grp_sz + 1);
1532 }
1533 return MIN(start_idx, container->children->length);
1534 }
1535}
1536
1537/**
1538 * given the index of a container's child, return the index of the first child of the group
1539 * that follows the one which index is a member of.
1540 * This makes the function usable to walk through the groups in a container.
1541 */
1542int auto_group_end_index(swayc_t *container, int index) {
1543 if (index < 0 || ! is_auto_layout(container->layout)) {
1544 return container->children->length;
1545 } else {
1546 int nxt_idx;
1547 if ((size_t)index < container->nb_master) {
1548 nxt_idx = container->nb_master;
1549 } else {
1550 size_t grp_sz = auto_slave_count(container) / container->nb_slave_groups;
1551 size_t remainder = auto_slave_count(container) % container->nb_slave_groups;
1552 int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master;
1553 if (index < idx2) {
1554 nxt_idx = ((index - container->nb_master) / grp_sz + 1) * grp_sz + container->nb_master;
1555 } else {
1556 nxt_idx = idx2 + ((index - idx2) / (grp_sz + 1) + 1) * (grp_sz + 1);
1557 }
1558 }
1559 return MIN(nxt_idx, container->children->length);
1560 }
1561}
1562
1563/**
1564 * Return the combined number of master and slave groups in the container.
1565 */
1566size_t auto_group_count(swayc_t *container) {
1567 return MIN(container->nb_slave_groups, auto_slave_count(container)) + (container->nb_master ? 1 : 0);
1568}
1569
1570/**
1571 * return the index of the Group containing <index>th child of <container>.
1572 * The index is the order of the group along the container's major axis (starting at 0).
1573 */
1574size_t auto_group_index(swayc_t *container, int index) {
1575 if (index < 0) {
1576 return 0;
1577 }
1578 bool master_first = (container->layout == L_AUTO_LEFT || container->layout == L_AUTO_TOP);
1579 int nb_slaves = auto_slave_count(container);
1580 if ((size_t) index < container->nb_master) {
1581 if (master_first || nb_slaves <= 0) {
1582 return 0;
1583 } else {
1584 return MIN(container->nb_slave_groups, nb_slaves);
1585 }
1586 } else {
1587 size_t grp_sz = auto_slave_count(container) / container->nb_slave_groups;
1588 size_t remainder = auto_slave_count(container) % container->nb_slave_groups;
1589 size_t grp_idx;
1590 int idx2 = (container->nb_slave_groups - remainder) * grp_sz + container->nb_master;
1591 if (index < idx2) {
1592 grp_idx = (index - container->nb_master) / grp_sz;
1593 } else {
1594 grp_idx = (container->nb_slave_groups - remainder) + (index - idx2) / (grp_sz + 1) ;
1595 }
1596 return grp_idx + (master_first ? 1 : 0);
1597 }
1598}