]> git.lizzy.rs Git - bspwm.git/blobdiff - tree.c
New message: `balance`
[bspwm.git] / tree.c
diff --git a/tree.c b/tree.c
index 6d41fb665e2781b292ac95b702e9d16044a76337..3a51c16abc35e3ae0339725371b6a13e62c12b67 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -140,40 +140,6 @@ void move_fence(node_t *n, direction_t dir, fence_move_t mov)
         change_split_ratio(fence, CHANGE_DECREASE);
 }
 
-unsigned int distance_to_fence(xcb_point_t pt, node_t *fence)
-{
-    xcb_rectangle_t rect = fence->rectangle;
-    if (fence->split_type == TYPE_VERTICAL) {
-        int fx = rect.x + fence->split_ratio * rect.width - window_gap / 2;
-        return ABS(pt.x - fx);
-    } else {
-        int fy = rect.y + fence->split_ratio * rect.height - window_gap / 2;
-        return ABS(pt.y - fy);
-    }
-}
-
-fence_distance_t nearest_fence(xcb_point_t pt, node_t *tree)
-{
-    fence_distance_t fd;
-    if (tree == NULL || is_leaf(tree)) {
-        fd.fence = NULL;
-    } else {
-        fd.fence = tree;
-        fd.distance = distance_to_fence(pt, tree);
-        fence_distance_t first_fd = nearest_fence(pt, tree->first_child);
-        fence_distance_t second_fd = nearest_fence(pt, tree->second_child);
-        if (first_fd.fence != NULL && fd.distance > first_fd.distance) {
-            fd.fence = first_fd.fence;
-            fd.distance = first_fd.distance;
-        }
-        if (second_fd.fence != NULL && fd.distance > second_fd.distance) {
-            fd.fence = second_fd.fence;
-            fd.distance = second_fd.distance;
-        }
-    }
-    return fd;
-}
-
 void rotate_tree(node_t *n, rotate_t rot)
 {
     if (n == NULL || is_leaf(n))
@@ -220,6 +186,22 @@ void flip_tree(node_t *n, flip_t flp)
     flip_tree(n->second_child, flp);
 }
 
+int balance_tree(node_t *n)
+{
+    if (n == NULL || n->vacant) {
+        return 0;
+    } else if (is_leaf(n)) {
+        return 1;
+    } else {
+        int b1 = balance_tree(n->first_child);
+        int b2 = balance_tree(n->second_child);
+        int b = b1 + b2;
+        if (b1 > 0 && b2 > 0)
+            n->split_ratio = (double) b1 / b;
+        return b;
+    }
+}
+
 void arrange(monitor_t *m, desktop_t *d)
 {
     PRINTF("arrange %s%s%s\n", (num_monitors > 1 ? m->name : ""), (num_monitors > 1 ? " " : ""), d->name);
@@ -230,8 +212,6 @@ void arrange(monitor_t *m, desktop_t *d)
     rect.y += m->top_padding + wg;
     rect.width -= m->left_padding + m->right_padding + wg;
     rect.height -= m->top_padding + m->bottom_padding + wg;
-    if (focus_follows_pointer)
-        save_pointer_position(&last_pointer_position);
     apply_layout(m, d, d->root, rect, rect);
 }
 
@@ -423,16 +403,12 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n, bool is_mapped)
     }
 
     if (focus_follows_pointer) {
-        save_pointer_position(&last_pointer_position);
-        if (n != mon->desk->focus) {
-            if (last_focused_window != XCB_NONE) {
-                uint32_t values[] = {CLIENT_EVENT_MASK_FFP};
-                xcb_change_window_attributes(dpy, last_focused_window, XCB_CW_EVENT_MASK, values);
-            }
-            uint32_t values[] = {CLIENT_EVENT_MASK};
-            xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
-            last_focused_window = n->client->window;
-        }
+        xcb_window_t win = XCB_NONE;
+        query_pointer(&win, NULL);
+        if (win != n->client->window)
+            enable_motion_recorder();
+        else
+            disable_motion_recorder();
     }
 
     if (!is_tiled(n->client)) {
@@ -544,7 +520,7 @@ void destroy_tree(node_t *n)
     destroy_tree(second_tree);
 }
 
-void swap_nodes(node_t *n1, node_t *n2)
+void swap_nodes(desktop_t *d1, node_t *n1, desktop_t *d2, node_t *n2)
 {
     if (n1 == NULL || n2 == NULL || n1 == n2)
         return;
@@ -578,6 +554,21 @@ void swap_nodes(node_t *n1, node_t *n2)
         update_vacant_state(n1->parent);
         update_vacant_state(n2->parent);
     }
+
+    if (d1 != d2) {
+        if (d1->root == n1)
+            d1->root = n2;
+        if (d1->focus == n1)
+            d1->focus = n2;
+        if (d1->last_focus == n1)
+            d1->last_focus = n2;
+        if (d2->root == n2)
+            d2->root = n1;
+        if (d2->focus == n2)
+            d2->focus = n1;
+        if (d2->last_focus == n2)
+            d2->last_focus = n1;
+    }
 }
 
 void transfer_node(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd, node_t *n)
@@ -741,10 +732,10 @@ void circulate_leaves(monitor_t *m, desktop_t *d, circulate_dir_t dir) {
     bool focus_first_child = is_first_child(d->focus);
     if (dir == CIRCULATE_FORWARD)
         for (node_t *s = second_extrema(d->root), *f = prev_leaf(s); f != NULL; s = prev_leaf(f), f = prev_leaf(s))
-            swap_nodes(f, s);
+            swap_nodes(d, f, d, s);
     else
         for (node_t *f = first_extrema(d->root), *s = next_leaf(f); s != NULL; f = next_leaf(s), s = next_leaf(f))
-            swap_nodes(f, s);
+            swap_nodes(d, f, d, s);
     if (focus_first_child)
         focus_node(m, d, par->first_child, true);
     else