]> git.lizzy.rs Git - bspwm.git/blobdiff - src/tree.c
Add automatic insertion scheme: alternate
[bspwm.git] / src / tree.c
index 4e9929f003df1d6dbe8060f720180b5ea6c02313..bf5d3965f8e6ebe49f447d2dd496e769c10d79dc 100644 (file)
@@ -48,17 +48,22 @@ void arrange(monitor_t *m, desktop_t *d)
 
        layout_t l = d->layout;
 
-       if (single_monocle && tiled_count(d->root) <= 1) {
+       if (single_monocle && tiled_count(d->root, true) <= 1) {
                l = LAYOUT_MONOCLE;
        }
 
        xcb_rectangle_t rect = m->rectangle;
 
-       if (!paddingless_monocle || l != LAYOUT_MONOCLE) {
-               rect.x += m->padding.left + d->padding.left;
-               rect.y += m->padding.top + d->padding.top;
-               rect.width -= m->padding.left + d->padding.left + d->padding.right + m->padding.right;
-               rect.height -= m->padding.top + d->padding.top + d->padding.bottom + m->padding.bottom;
+       rect.x += m->padding.left + d->padding.left;
+       rect.y += m->padding.top + d->padding.top;
+       rect.width -= m->padding.left + d->padding.left + d->padding.right + m->padding.right;
+       rect.height -= m->padding.top + d->padding.top + d->padding.bottom + m->padding.bottom;
+
+       if (l == LAYOUT_MONOCLE) {
+               rect.x += monocle_padding.left;
+               rect.y += monocle_padding.top;
+               rect.width -= monocle_padding.left + monocle_padding.right;
+               rect.height -= monocle_padding.top + monocle_padding.bottom;
        }
 
        if (!gapless_monocle || l != LAYOUT_MONOCLE) {
@@ -79,13 +84,6 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectang
 
        n->rectangle = rect;
 
-       if (pointer_follows_focus && mon->desk->focus == n) {
-               xcb_rectangle_t r = rect;
-               r.width -= d->window_gap;
-               r.height -= d->window_gap;
-               center_pointer(r);
-       }
-
        if (n->presel != NULL) {
                draw_presel_feedback(m, d, n);
        }
@@ -329,14 +327,21 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
                                presel_dir(m, d, f, (rect.width >= rect.height ? DIR_EAST : DIR_SOUTH));
                        }
                }
-               while (f->presel == NULL && p != NULL && (f->vacant || brother_tree(f)->vacant)) {
-                       f = p;
-                       p = f->parent;
-               }
                n->parent = c;
-               c->birth_rotation = f->birth_rotation;
                if (f->presel == NULL) {
-                       if (p == NULL) {
+                       bool single_tiled = f->client != NULL && IS_TILED(f->client) && tiled_count(d->root, true) == 1;
+                       if (p == NULL || automatic_scheme != SCHEME_SPIRAL || single_tiled) {
+                               if (p != NULL) {
+                                       if (is_first_child(f)) {
+                                               p->first_child = c;
+                                       } else {
+                                               p->second_child = c;
+                                       }
+                               } else {
+                                       d->root = c;
+                               }
+                               c->parent = p;
+                               f->parent = c;
                                if (initial_polarity == FIRST_CHILD) {
                                        c->first_child = n;
                                        c->second_child = f;
@@ -344,13 +349,19 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
                                        c->first_child = f;
                                        c->second_child = n;
                                }
-                               if (m->rectangle.width > m->rectangle.height) {
-                                       c->split_type = TYPE_VERTICAL;
+                               if (p == NULL || automatic_scheme == SCHEME_LONGEST_SIDE || single_tiled) {
+                                       if (f->rectangle.width > f->rectangle.height) {
+                                               c->split_type = TYPE_VERTICAL;
+                                       } else {
+                                               c->split_type = TYPE_HORIZONTAL;
+                                       }
                                } else {
-                                       c->split_type = TYPE_HORIZONTAL;
+                                       if (p->split_type == TYPE_HORIZONTAL) {
+                                               c->split_type = TYPE_VERTICAL;
+                                       } else {
+                                               c->split_type = TYPE_HORIZONTAL;
+                                       }
                                }
-                               f->parent = c;
-                               d->root = c;
                        } else {
                                node_t *g = p->parent;
                                c->parent = g;
@@ -376,7 +387,6 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
                                        c->second_child = n;
                                        rot = 270;
                                }
-                               n->birth_rotation = rot;
                                if (!n->vacant) {
                                        rotate_tree(p, rot);
                                }
@@ -392,7 +402,6 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
                        c->split_ratio = f->presel->split_ratio;
                        c->parent = p;
                        f->parent = c;
-                       f->birth_rotation = 0;
                        switch (f->presel->split_dir) {
                                case DIR_WEST:
                                        c->split_type = TYPE_VERTICAL;
@@ -441,7 +450,10 @@ void insert_receptacle(monitor_t *m, desktop_t *d, node_t *n)
 bool activate_node(monitor_t *m, desktop_t *d, node_t *n)
 {
        if (n == NULL && d->root != NULL) {
-               n = history_last_node(d, NULL);
+               n = d->focus;
+               if (n == NULL) {
+                       n = history_last_node(d, NULL);
+               }
                if (n == NULL) {
                        n = first_focusable_leaf(d->root);
                }
@@ -480,28 +492,31 @@ bool activate_node(monitor_t *m, desktop_t *d, node_t *n)
        return true;
 }
 
-void transfer_sticky_nodes(monitor_t *m, desktop_t *ds, desktop_t *dd, node_t *n)
+void transfer_sticky_nodes(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd, node_t *n)
 {
        if (n == NULL) {
                return;
        } else if (n->sticky) {
                sticky_still = false;
-               transfer_node(m, ds, n, m, dd, dd->focus, false);
+               transfer_node(ms, ds, n, md, dd, dd->focus, false);
                sticky_still = true;
        } else {
                /* we need references to the children because n might be freed after
                 * the first recursive call */
                node_t *first_child = n->first_child;
                node_t *second_child = n->second_child;
-               transfer_sticky_nodes(m, ds, dd, first_child);
-               transfer_sticky_nodes(m, ds, dd, second_child);
+               transfer_sticky_nodes(ms, ds, md, dd, first_child);
+               transfer_sticky_nodes(ms, ds, md, dd, second_child);
        }
 }
 
 bool focus_node(monitor_t *m, desktop_t *d, node_t *n)
 {
        if (m == NULL) {
-               m = history_last_monitor(NULL);
+               m = mon;
+               if (m == NULL) {
+                       m = history_last_monitor(NULL);
+               }
                if (m == NULL) {
                        m = mon_head;
                }
@@ -512,7 +527,10 @@ bool focus_node(monitor_t *m, desktop_t *d, node_t *n)
        }
 
        if (d == NULL) {
-               d = history_last_desktop(m, NULL);
+               d = m->desk;
+               if (d == NULL) {
+                       d = history_last_desktop(m, NULL);
+               }
                if (d == NULL) {
                        d = m->desk_head;
                }
@@ -525,7 +543,10 @@ bool focus_node(monitor_t *m, desktop_t *d, node_t *n)
        bool guess = (n == NULL);
 
        if (n == NULL && d->root != NULL) {
-               n = history_last_node(d, NULL);
+               n = d->focus;
+               if (n == NULL) {
+                       n = history_last_node(d, NULL);
+               }
                if (n == NULL) {
                        n = first_focusable_leaf(d->root);
                }
@@ -539,12 +560,12 @@ bool focus_node(monitor_t *m, desktop_t *d, node_t *n)
                clear_input_focus();
        }
 
-       if (m->sticky_count > 0 && d != m->desk) {
+       if (m->sticky_count > 0 && m->desk != NULL && d != m->desk) {
                if (guess && m->desk->focus != NULL && m->desk->focus->sticky) {
                        n = m->desk->focus;
                }
 
-               transfer_sticky_nodes(m, m->desk, d, m->desk->root);
+               transfer_sticky_nodes(m, m->desk, m, d, m->desk->root);
 
                if (n == NULL && d->focus != NULL) {
                        n = d->focus;
@@ -614,7 +635,7 @@ bool focus_node(monitor_t *m, desktop_t *d, node_t *n)
 
 void hide_node(desktop_t *d, node_t *n)
 {
-       if (n == NULL) {
+       if (n == NULL || (!hide_sticky && n->sticky)) {
                return;
        } else {
                if (!n->hidden) {
@@ -665,7 +686,6 @@ node_t *make_node(uint32_t id)
        n->vacant = n->hidden = n->sticky = n->private = n->locked = n->marked = false;
        n->split_ratio = split_ratio;
        n->split_type = TYPE_VERTICAL;
-       n->birth_rotation = 0;
        n->constraints = (constraints_t) {MIN_WIDTH, MIN_HEIGHT};
        n->presel = NULL;
        n->client = NULL;
@@ -1029,14 +1049,15 @@ unsigned int node_area(desktop_t *d, node_t *n)
        return area(get_rectangle(NULL, d, n));
 }
 
-int tiled_count(node_t *n)
+int tiled_count(node_t *n, bool include_receptacles)
 {
        if (n == NULL) {
                return 0;
        }
        int cnt = 0;
        for (node_t *f = first_extrema(n); f != NULL; f = next_leaf(f, n)) {
-               if (!f->hidden && f->client != NULL && IS_TILED(f->client)) {
+               if (!f->hidden && ((include_receptacles && f->client == NULL) ||
+                                  (f->client != NULL && IS_TILED(f->client)))) {
                        cnt++;
                }
        }
@@ -1104,24 +1125,6 @@ void rotate_tree_rec(node_t *n, int deg)
        rotate_tree_rec(n->second_child, deg);
 }
 
-void rotate_brother(node_t *n)
-{
-       rotate_tree(brother_tree(n), n->birth_rotation);
-}
-
-void unrotate_tree(node_t *n, int rot)
-{
-       if (rot == 0) {
-               return;
-       }
-       rotate_tree(n, 360 - rot);
-}
-
-void unrotate_brother(node_t *n)
-{
-       unrotate_tree(brother_tree(n), n->birth_rotation);
-}
-
 void flip_tree(node_t *n, flip_t flp)
 {
        if (n == NULL || is_leaf(n)) {
@@ -1195,10 +1198,6 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
                node_t *b = brother_tree(n);
                node_t *g = p->parent;
 
-               if (!n->vacant) {
-                       unrotate_tree(b, n->birth_rotation);
-               }
-
                b->parent = g;
 
                if (g != NULL) {
@@ -1211,7 +1210,23 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
                        d->root = b;
                }
 
-               b->birth_rotation = p->birth_rotation;
+               if (!n->vacant && removal_adjustment) {
+                       if (automatic_scheme == SCHEME_LONGEST_SIDE || g == NULL) {
+                               if (p != NULL) {
+                                       if (p->rectangle.width > p->rectangle.height) {
+                                               b->split_type = TYPE_VERTICAL;
+                                       } else {
+                                               b->split_type = TYPE_HORIZONTAL;
+                                       }
+                               }
+                       } else if (automatic_scheme == SCHEME_ALTERNATE) {
+                               if (g->split_type == TYPE_HORIZONTAL) {
+                                       b->split_type = TYPE_VERTICAL;
+                               } else {
+                                       b->split_type = TYPE_HORIZONTAL;
+                               }
+                       }
+               }
 
                free(p);
                n->parent = NULL;
@@ -1309,8 +1324,6 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
        node_t *pn2 = n2->parent;
        bool n1_first_child = is_first_child(n1);
        bool n2_first_child = is_first_child(n2);
-       int br1 = n1->birth_rotation;
-       int br2 = n2->birth_rotation;
        bool n1_held_focus = is_descendant(d1->focus, n1);
        bool n2_held_focus = is_descendant(d2->focus, n2);
        node_t *last_d1_focus = d1->focus;
@@ -1334,8 +1347,6 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
 
        n1->parent = pn2;
        n2->parent = pn1;
-       n1->birth_rotation = br2;
-       n2->birth_rotation = br1;
 
        propagate_flags_upward(m2, d2, n1);
        propagate_flags_upward(m1, d1, n2);
@@ -1452,11 +1463,6 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
                if (ns->client == NULL || monitor_from_client(ns->client) != md) {
                        adapt_geometry(&ms->rectangle, &md->rectangle, ns);
                }
-
-               if (ms->sticky_count > 0 && sticky_count(ns) > 0) {
-                       ms->sticky_count -= sticky_count(ns);
-                       md->sticky_count += sticky_count(ns);
-               }
        }
 
        if (ds != dd) {
@@ -1559,7 +1565,7 @@ bool find_closest_node(coordinates_t *ref, coordinates_t *dst, cycle_dir_t dir,
 
 void circulate_leaves(monitor_t *m, desktop_t *d, node_t *n, circulate_dir_t dir)
 {
-       if (tiled_count(n) < 2) {
+       if (tiled_count(n, false) < 2) {
                return;
        }
        node_t *p = d->focus->parent;
@@ -1612,10 +1618,7 @@ void set_vacant_local(monitor_t *m, desktop_t *d, node_t *n, bool value)
        n->vacant = value;
 
        if (value) {
-               unrotate_brother(n);
                cancel_presel(m, d, n);
-       } else {
-               rotate_brother(n);
        }
 }
 
@@ -2005,13 +2008,6 @@ void set_urgent(monitor_t *m, desktop_t *d, node_t *n, bool value)
        put_status(SBSC_MASK_REPORT);
 }
 
-/* Returns true if a contains b */
-bool contains(xcb_rectangle_t a, xcb_rectangle_t b)
-{
-       return (a.x <= b.x && (a.x + a.width) >= (b.x + b.width) &&
-               a.y <= b.y && (a.y + a.height) >= (b.y + b.height));
-}
-
 xcb_rectangle_t get_rectangle(monitor_t *m, desktop_t *d, node_t *n)
 {
        if (n == NULL) {