]> git.lizzy.rs Git - bspwm.git/blobdiff - tree.c
Remove window borders whenever possible
[bspwm.git] / tree.c
diff --git a/tree.c b/tree.c
index f2552804029c8e03560c5f515a379c62350b9fec..1a32782195ff75e72cd876d097e6da026b592b02 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -6,7 +6,7 @@
 #include <xcb/xcb_event.h>
 #include "settings.h"
 #include "helpers.h"
-#include "utils.h"
+#include "misc.h"
 #include "window.h"
 #include "types.h"
 #include "bspwm.h"
@@ -167,6 +167,34 @@ void rotate_tree(node_t *n, rotate_t rot)
     rotate_tree(n->second_child, rot);
 }
 
+void magnetise_tree(node_t *n, corner_t corner)
+{
+    if (n == NULL || is_leaf(n)) 
+        return;
+
+    PUTS("magnetise tree");
+
+    switch (n->split_type) {
+        case TYPE_HORIZONTAL:
+            if (corner == TOP_LEFT || corner == TOP_RIGHT)
+                change_split_ratio(n, CHANGE_DECREASE);
+            else
+                change_split_ratio(n, CHANGE_INCREASE);
+            break;
+        case TYPE_VERTICAL:
+            if (corner == TOP_LEFT || corner == BOTTOM_LEFT)
+                change_split_ratio(n, CHANGE_DECREASE);
+            else
+                change_split_ratio(n, CHANGE_INCREASE);
+            break;
+        default:
+            break;
+    }
+
+    magnetise_tree(n->first_child, corner);
+    magnetise_tree(n->second_child, corner);
+}
+
 void dump_tree(desktop_t *d, node_t *n, char *rsp, int depth)
 {
     if (n == NULL)
@@ -178,11 +206,9 @@ void dump_tree(desktop_t *d, node_t *n, char *rsp, int depth)
         strcat(rsp, "  ");
 
     if (is_leaf(n))
-        /* sprintf(line, "0x%X [%i %i %u %u]", n->client->window, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height); */ 
-        sprintf(line, "C %X [%i %i %u %u] (%s%s) [%i %i %u %u]", n->client->window, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height, (n->client->floating ? "f" : "-"), (n->client->transient ? "t" : "-"), n->client->rectangle.x, n->client->rectangle.y, n->client->rectangle.width, n->client->rectangle.height); 
+        sprintf(line, "%s %X %s%s%s%s%s", n->client->class_name, n->client->window, (n->client->floating ? "f" : "-"), (n->client->transient ? "t" : "-"), (n->client->fullscreen ? "F" : "-"), (n->client->urgent ? "u" : "-"), (n->client->locked ? "l" : "-")); 
     else
-        /* sprintf(line, "%s %.2f [%i %i %u %u]", (n->split_type == TYPE_HORIZONTAL ? "H" : "V"), n->split_ratio, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height); */
-        sprintf(line, "%s %.2f [%i %i %u %u]", (n->split_type == TYPE_HORIZONTAL ? "H" : "V"), n->split_ratio, n->rectangle.x, n->rectangle.y, n->rectangle.width, n->rectangle.height);
+        sprintf(line, "%s %.2f", (n->split_type == TYPE_HORIZONTAL ? "H" : "V"), n->split_ratio);
 
     strcat(rsp, line);
 
@@ -235,31 +261,34 @@ void apply_layout(desktop_t *d, node_t *n, xcb_rectangle_t rect)
     if (is_leaf(n)) {
         if (n->client->fullscreen)
             return;
+
+        if (n == d->root || (d->layout == LAYOUT_MONOCLE && !is_floating(n->client)))
+            n->client->border_width = 0;
+        else
+            n->client->border_width = border_width;
+
         xcb_rectangle_t r;
         if (is_tiled(n->client)) {
             if (d->layout == LAYOUT_TILED)
                 r = rect;
             else if (d->layout == LAYOUT_MONOCLE)
                 r = root_rect;
-            int bleed = window_gap + 2 * border_width;
-            r.width = (bleed < r.width ? r.width - bleed : MIN_WIDTH);
-            r.height = (bleed < r.height ? r.height - bleed : MIN_HEIGHT);
+            int bleed = window_gap + 2 * n->client->border_width;
+            r.width = (bleed < r.width ? r.width - bleed : 1);
+            r.height = (bleed < r.height ? r.height - bleed : 1);
+            n->client->tiled_rectangle = r;
         } else {
-            r = n->client->rectangle;
+            r = n->client->floating_rectangle;
         }
 
-        r.width = MAX(r.width, MIN_WIDTH);
-        r.height = MAX(r.height, MIN_HEIGHT);
-
         window_move_resize(n->client->window, r.x, r.y, r.width, r.height);
-        window_border_width(n->client->window, border_width);
-        draw_triple_border(n, (n == d->focus ? active_border_color_pxl : normal_border_color_pxl));
+        window_border_width(n->client->window, n->client->border_width);
+        window_draw_border(n, n == d->focus);
 
         if (d->layout == LAYOUT_MONOCLE && n == d->focus)
             window_raise(n->client->window);
 
     } else {
-
         xcb_rectangle_t first_rect;
         xcb_rectangle_t second_rect;
 
@@ -289,7 +318,7 @@ void insert_node(desktop_t *d, node_t *n)
     if (d == NULL || n == NULL)
         return;
 
-    PUTS("insert node\n");
+    PRINTF("insert node %X\n", n->client->window);
 
     node_t *focus = d->focus;
 
@@ -299,12 +328,16 @@ void insert_node(desktop_t *d, node_t *n)
         node_t *dad = make_node();
         node_t *fopar = focus->parent;
         n->parent = dad;
+        n->born_as = split_mode;
         switch (split_mode) {
             case MODE_AUTOMATIC:
                 if (fopar == NULL) {
                     dad->first_child = n;
                     dad->second_child = focus;
-                    dad->split_type = TYPE_VERTICAL;
+                    if (focus->rectangle.width > focus->rectangle.height)
+                        dad->split_type = TYPE_VERTICAL;
+                    else
+                        dad->split_type = TYPE_HORIZONTAL;
                     focus->parent = dad;
                     d->root = dad;
                 } else {
@@ -369,6 +402,8 @@ void insert_node(desktop_t *d, node_t *n)
                 split_mode = MODE_AUTOMATIC;
                 break;
         }
+        if (focus->vacant)
+            update_vacant_state(fopar);
     }
 }
 
@@ -377,19 +412,15 @@ void focus_node(desktop_t *d, node_t *n, bool is_mapped)
     if (n == NULL)
         return;
 
-    if (desk->focus != NULL && desk->focus->client->fullscreen)
-        return;
-
-    PRINTF("focus_node %x\n", n->client->window);
+    PRINTF("focus node %X\n", n->client->window);
 
     split_mode = MODE_AUTOMATIC;
-
-    select_desktop(d);
+    n->client->urgent = false;
 
     if (is_mapped) {
         if (d->focus != n) {
-            draw_triple_border(d->focus, normal_border_color_pxl);
-            draw_triple_border(n, active_border_color_pxl);
+            window_draw_border(d->focus, false);
+            window_draw_border(n, true);
         }
         xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, n->client->window, XCB_CURRENT_TIME);
     }
@@ -420,7 +451,7 @@ void unlink_node(desktop_t *d, node_t *n)
     if (d == NULL || n == NULL)
         return;
 
-    PUTS("unlink node\n");
+    PRINTF("unlink node %X\n", n->client->window);
 
     node_t *p = n->parent;
 
@@ -431,10 +462,16 @@ void unlink_node(desktop_t *d, node_t *n)
     } else {
         node_t *b;
         node_t *g = p->parent;
-        if (is_first_child(n))
+        bool n_first_child = is_first_child(n);
+        if (n_first_child) {
             b = p->second_child;
-        else
+            if (n->born_as == MODE_AUTOMATIC)
+                rotate_tree(b, ROTATE_COUNTER_CLOCKWISE);
+        } else {
             b = p->first_child;
+            if (n->born_as == MODE_AUTOMATIC)
+                rotate_tree(b, ROTATE_CLOCKWISE);
+        }
         b->parent = g;
         if (g != NULL) {
             if (is_first_child(p))
@@ -448,13 +485,17 @@ void unlink_node(desktop_t *d, node_t *n)
         n->parent = NULL;
         free(p);
 
-        if (n == d->focus) {
-            if (d->last_focus != NULL && d->last_focus != n)
+        if (n == d->last_focus) {
+            d->last_focus = NULL;
+        } else if (n == d->focus) {
+            if (d->last_focus != NULL)
                 d->focus = d->last_focus;
             else
-                d->focus = (is_first_child(b) ? second_extrema(b) : first_extrema(b));
+                d->focus = (n_first_child ? first_extrema(b) : second_extrema(b));
             d->last_focus = NULL;
         }
+
+        update_vacant_state(b->parent);
     }
 }
 
@@ -463,7 +504,7 @@ void remove_node(desktop_t *d, node_t *n)
     if (d == NULL || n == NULL)
         return;
 
-    PUTS("remove node\n");
+    PRINTF("remove node %X\n", n->client->window);
 
     unlink_node(d, n);
     free(n->client);
@@ -481,7 +522,7 @@ void swap_nodes(node_t *n1, node_t *n2)
     if (n1 == NULL || n2 == NULL || n1 == n2)
         return;
 
-    PUTS("swap nodes\n");
+    PUTS("swap nodes");
 
     /* (n1 and n2 are leaves) */
     node_t *pn1 = n1->parent;
@@ -512,15 +553,22 @@ void transfer_node(desktop_t *ds, desktop_t *dd, node_t *n)
     if (n == NULL || ds == NULL || dd == NULL || dd == ds)
         return;
 
-    PUTS("transfer node\n");
+    PRINTF("transfer node %X\n", n->client->window);
 
     unlink_node(ds, n);
-    if (ds == desk)
-        xcb_unmap_window(dpy, n->client->window);
+
+    if (ds == desk) {
+        window_hide(n->client->window);
+    }
 
     insert_node(dd, n);
-    if (dd == desk)
-        xcb_map_window(dpy, n->client->window);
+
+    if (dd == desk) {
+        window_show(n->client->window);
+        focus_node(dd, n, true);
+    } else {
+        focus_node(dd, n, false);
+    }
 
     if (ds == desk || dd == desk)
         update_current();
@@ -531,43 +579,34 @@ void select_desktop(desktop_t *d)
     if (d == NULL || d == desk)
         return;
 
-    PUTS("select desktop\n");
-
-    if (d->focus != NULL)
-        xcb_map_window(dpy, d->focus->client->window);
+    PRINTF("select desktop %s\n", d->name);
 
     node_t *n = first_extrema(d->root);
 
     while (n != NULL) {
-        if (n != d->focus)
-            xcb_map_window(dpy, n->client->window);
+        window_show(n->client->window);
         n = next_leaf(n);
     }
 
     n = first_extrema(desk->root);
 
     while (n != NULL) {
-        if (n != desk->focus)
-            xcb_unmap_window(dpy, n->client->window);
+        window_hide(n->client->window);
         n = next_leaf(n);
     }
 
-    if (desk->focus != NULL)
-        xcb_unmap_window(dpy, desk->focus->client->window);
-
     last_desk = desk;
     desk = d;
 
     update_current();
-
     ewmh_update_current_desktop();
 }
 
 void cycle_desktop(cycle_dir_t dir)
 {
-    if (dir == DIR_NEXT)
+    if (dir == CYCLE_NEXT)
         select_desktop((desk->next == NULL ? desk_head : desk->next));
-    else if (dir == DIR_PREV)
+    else if (dir == CYCLE_PREV)
         select_desktop((desk->prev == NULL ? desk_tail : desk->prev));
 }
 
@@ -576,41 +615,32 @@ void cycle_leaf(desktop_t *d, node_t *n, cycle_dir_t dir, skip_client_t skip)
     if (n == NULL)
         return;
 
-    PUTS("cycle leaf\n");
+    PUTS("cycle leaf");
 
-    node_t *f = (dir == DIR_PREV ? prev_leaf(n) : next_leaf(n));
+    node_t *f = (dir == CYCLE_PREV ? prev_leaf(n) : next_leaf(n));
+    if (f == NULL)
+        f = (dir == CYCLE_PREV ? second_extrema(d->root) : first_extrema(d->root));
 
-    while (f != NULL) {
+    while (f != n) {
         bool tiled = is_tiled(f->client);
-        if (skip == SKIP_NONE || (skip == SKIP_TILED && !tiled) || (skip == SKIP_FLOATING && tiled)) {
+        if (skip == SKIP_NONE || (skip == SKIP_TILED && !tiled) || (skip == SKIP_FLOATING && tiled)
+                || (skip == SKIP_CLASS_DIFFER && strcmp(f->client->class_name, n->client->class_name) == 0)
+                || (skip == SKIP_CLASS_EQUAL && strcmp(f->client->class_name, n->client->class_name) != 0)) {
             focus_node(d, f, true);
             return;
         }
-        f = (dir == DIR_PREV ? prev_leaf(f) : next_leaf(f));
+        f = (dir == CYCLE_PREV ? prev_leaf(f) : next_leaf(f));
+        if (f == NULL)
+            f = (dir == CYCLE_PREV ? second_extrema(d->root) : first_extrema(d->root));
     }
 }
 
-void toggle_floating(node_t *n)
-{
-    if (n == NULL || n->client->transient)
-        return;
-
-    PUTS("toggle floating\n");
-
-    client_t *c = n->client;
-    c->floating = !c->floating;
-    n->vacant = !n->vacant;
-    update_vacant_state(n->parent);
-    if (c->floating)
-        window_raise(c->window);
-}
-
 void update_vacant_state(node_t *n)
 {
     if (n == NULL)
         return;
 
-    PUTS("update vacant state\n");
+    PUTS("update vacant state");
 
     /* n is not a leaf */
     node_t *p = n;
@@ -642,13 +672,3 @@ void add_desktop(char *name)
     ewmh_update_number_of_desktops();
     ewmh_update_desktop_names();
 }
-
-void alternate_desktop(void)
-{
-    if (last_desk == NULL)
-        return;
-    desktop_t *tmp = desk;
-    desk = last_desk;
-    last_desk = tmp;
-    select_desktop(desk);
-}