]> git.lizzy.rs Git - bspwm.git/blobdiff - tree.c
Handle min/max window size hints
[bspwm.git] / tree.c
diff --git a/tree.c b/tree.c
index 0dc6aec4039d609708bd8ec9c99521bfd0199335..f18b6d9fba4aa90f91b41ff6b3bf51e058518104 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -24,7 +24,6 @@
 
 #include <float.h>
 #include <limits.h>
-#include <math.h>
 #include "bspwm.h"
 #include "desktop.h"
 #include "ewmh.h"
@@ -45,10 +44,10 @@ void arrange(monitor_t *m, desktop_t *d)
 
     xcb_rectangle_t rect = m->rectangle;
     int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
-    rect.x += m->left_padding + wg;
-    rect.y += m->top_padding + wg;
-    rect.width -= m->left_padding + m->right_padding + wg;
-    rect.height -= m->top_padding + m->bottom_padding + wg;
+    rect.x += m->left_padding + d->left_padding + wg;
+    rect.y += m->top_padding + d->top_padding + wg;
+    rect.width -= m->left_padding + d->left_padding + d->right_padding + m->right_padding + wg;
+    rect.height -= m->top_padding + d->top_padding + d->bottom_padding + m->bottom_padding + wg;
     apply_layout(m, d, d->root, rect, rect);
 }
 
@@ -62,8 +61,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
     if (is_leaf(n)) {
 
         if ((borderless_monocle && is_tiled(n->client) && d->layout == LAYOUT_MONOCLE)
-                || n->client->fullscreen
-                || n->client->frame)
+                || n->client->fullscreen)
             n->client->border_width = 0;
         else
             n->client->border_width = d->border_width;
@@ -71,17 +69,18 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
         xcb_rectangle_t r;
         if (!n->client->fullscreen) {
             if (!n->client->floating) {
-                /* tiled clients */
-                if (d->layout == LAYOUT_TILED)
+                if (n->client->pseudo_tiled) {
+                /* pseudo-tiled clients */
+                    r = n->client->floating_rectangle;
+                    center_rectangle(&r, rect);
+                } else {
+                    /* tiled clients */
                     r = rect;
-                else if (d->layout == LAYOUT_MONOCLE)
-                    r = root_rect;
-                else
-                    return;
-                int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
-                int bleed = wg + 2 * n->client->border_width;
-                r.width = (bleed < r.width ? r.width - bleed : 1);
-                r.height = (bleed < r.height ? r.height - bleed : 1);
+                    int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
+                    int bleed = wg + 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 {
                 /* floating clients */
@@ -100,7 +99,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
         xcb_rectangle_t first_rect;
         xcb_rectangle_t second_rect;
 
-        if (n->first_child->vacant || n->second_child->vacant) {
+        if (d->layout == LAYOUT_MONOCLE || n->first_child->vacant || n->second_child->vacant) {
             first_rect = second_rect = rect;
         } else {
             unsigned int fence;
@@ -262,11 +261,16 @@ void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
     put_status();
 }
 
-void pseudo_focus(desktop_t *d, node_t *n)
+void pseudo_focus(monitor_t *m, desktop_t *d, node_t *n)
 {
-    d->focus = n;
-    if (n != NULL)
+    if (n != NULL) {
         stack(n, STACK_ABOVE);
+        if (d->focus != n) {
+            window_draw_border(d->focus, false, m == mon);
+            window_draw_border(n, true, m == mon);
+        }
+    }
+    d->focus = n;
 }
 
 void focus_node(monitor_t *m, desktop_t *d, node_t *n)
@@ -309,12 +313,15 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n)
     }
 
     focus_desktop(m, d);
-    pseudo_focus(d, n);
+
+    d->focus = n;
 
     if (n == NULL) {
         history_add(m, d, NULL);
         ewmh_update_active_window();
         return;
+    } else {
+        stack(n, STACK_ABOVE);
     }
 
     PRINTF("focus node %X\n", n->client->window);
@@ -358,11 +365,12 @@ node_t *make_node(void)
 client_t *make_client(xcb_window_t win)
 {
     client_t *c = malloc(sizeof(client_t));
+    c->window = win;
     snprintf(c->class_name, sizeof(c->class_name), "%s", MISSING_VALUE);
+    snprintf(c->instance_name, sizeof(c->instance_name), "%s", MISSING_VALUE);
     c->border_width = BORDER_WIDTH;
-    c->window = win;
-    c->floating = c->transient = c->fullscreen = c->locked = c->sticky = c->urgent = false;
-    c->frame = c->private = c->icccm_focus = false;
+    c->pseudo_tiled = c->floating = c->fullscreen = false;
+    c->locked = c->sticky = c->urgent = c->private = c->icccm_focus = false;
     xcb_icccm_get_wm_protocols_reply_t protocols;
     if (xcb_icccm_get_wm_protocols_reply(dpy, xcb_icccm_get_wm_protocols(dpy, win, ewmh->WM_PROTOCOLS), &protocols, NULL) == 1) {
         if (has_proto(WM_TAKE_FOCUS, &protocols))
@@ -408,12 +416,6 @@ bool is_second_child(node_t *n)
     return (n != NULL && n->parent != NULL && n->parent->second_child == n);
 }
 
-void change_split_ratio(node_t *n, value_change_t chg)
-{
-    n->split_ratio = pow(n->split_ratio,
-            (chg == CHANGE_INCREASE ? (1 / growth_factor) : growth_factor));
-}
-
 void reset_mode(coordinates_t *loc)
 {
     if (loc->node != NULL) {
@@ -727,18 +729,6 @@ node_t *find_biggest(monitor_t *m, desktop_t *d, node_t *n, client_select_t sel)
     return r;
 }
 
-void move_fence(node_t *n, direction_t dir, fence_move_t mov)
-{
-    if (n == NULL)
-        return;
-
-    if ((mov == MOVE_PUSH && (dir == DIR_RIGHT || dir == DIR_DOWN))
-            || (mov == MOVE_PULL && (dir == DIR_LEFT || dir == DIR_UP)))
-        change_split_ratio(n, CHANGE_INCREASE);
-    else
-        change_split_ratio(n, CHANGE_DECREASE);
-}
-
 void rotate_tree(node_t *n, int deg)
 {
     if (n == NULL || is_leaf(n) || deg == 0)
@@ -802,6 +792,17 @@ void flip_tree(node_t *n, flip_t flp)
     flip_tree(n->second_child, flp);
 }
 
+void equalize_tree(node_t *n)
+{
+    if (n == NULL || n->vacant) {
+        return;
+    } else {
+        n->split_ratio = split_ratio;
+        equalize_tree(n->first_child);
+        equalize_tree(n->second_child);
+    }
+}
+
 int balance_tree(node_t *n)
 {
     if (n == NULL || n->vacant) {
@@ -831,12 +832,6 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
         d->root = NULL;
         d->focus = NULL;
     } else {
-        if (n == d->focus) {
-            d->focus = history_get_node(d, n);
-            if (d->focus == NULL)
-                d->focus = first_extrema(d->root);
-        }
-
         if (n->client->private)
             update_privacy_level(n, false);
 
@@ -868,6 +863,13 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
         n->parent = NULL;
         free(p);
         update_vacant_state(b->parent);
+
+        if (n == d->focus) {
+            d->focus = history_get_node(d, n);
+            // fallback to the first extrema (`n` is not reachable)
+            if (d->focus == NULL)
+                d->focus = first_extrema(d->root);
+        }
     }
     if (n->client->sticky)
         m->num_sticky--;
@@ -901,8 +903,10 @@ void destroy_tree(node_t *n)
         return;
     node_t *first_tree = n->first_child;
     node_t *second_tree = n->second_child;
-    if (n->client != NULL)
+    if (n->client != NULL) {
         free(n->client);
+        num_clients--;
+    }
     free(n);
     destroy_tree(first_tree);
     destroy_tree(second_tree);
@@ -1026,7 +1030,7 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
         if (focused)
             focus_node(md, dd, ns);
         else if (active)
-            pseudo_focus(dd, ns);
+            pseudo_focus(md, dd, ns);
     } else {
         if (focused)
             update_current();