]> git.lizzy.rs Git - bspwm.git/commitdiff
Move a few functions from tree to desktop/monitor
authorBastien Dejean <nihilhill@gmail.com>
Fri, 20 Sep 2013 09:57:09 +0000 (11:57 +0200)
committerBastien Dejean <nihilhill@gmail.com>
Fri, 20 Sep 2013 09:57:09 +0000 (11:57 +0200)
12 files changed:
Sourcedeps
desktop.c
desktop.h
events.c
monitor.c
monitor.h
query.c
restore.c
rule.c
tree.c
tree.h
window.c

index 49a59f9ad73207fb1799b23b6b57eb997b099cb4..da5a36042463f26fc715b8e6bef7fcc7f426a032 100644 (file)
@@ -1,15 +1,15 @@
 bspc.o: bspc.c common.h helpers.h
 bspwm.o: bspwm.c bspwm.h common.h desktop.h events.h ewmh.h helpers.h messages.h monitor.h rule.h settings.h tree.h types.h window.h
-desktop.o: desktop.c bspwm.h desktop.h ewmh.h helpers.h history.h tree.h types.h window.h
+desktop.o: desktop.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h tree.h types.h window.h
 events.o: events.c bspwm.h events.h ewmh.h helpers.h monitor.h query.h settings.h tree.h types.h window.h
 ewmh.o: ewmh.c bspwm.h ewmh.h helpers.h settings.h tree.h types.h
 helpers.o: helpers.c bspwm.h helpers.h types.h
 history.o: history.c helpers.h query.h types.h
 messages.o: messages.c bspwm.h desktop.h events.h ewmh.h helpers.h messages.h monitor.h query.h restore.h rule.h settings.h tree.h types.h window.h
-monitor.o: monitor.c bspwm.h desktop.h ewmh.h helpers.h monitor.h tree.h types.h window.h
-query.o: query.c bspwm.h helpers.h history.h messages.h query.h tree.h types.h
+monitor.o: monitor.c bspwm.h desktop.h ewmh.h helpers.h monitor.h query.h settings.h tree.h types.h window.h
+query.o: query.c bspwm.h desktop.h helpers.h history.h messages.h monitor.h query.h tree.h types.h
 restore.o: restore.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h restore.h settings.h tree.h types.h
 rule.o: rule.c bspwm.h ewmh.h helpers.h query.h rule.h types.h window.h
 settings.o: settings.c bspwm.h helpers.h settings.h types.h
-tree.o: tree.c bspwm.h desktop.h ewmh.h helpers.h history.h query.h settings.h tree.h types.h window.h
-window.o: window.c bspwm.h ewmh.h helpers.h query.h rule.h settings.h tree.h types.h window.h
+tree.o: tree.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h tree.h types.h window.h
+window.o: window.c bspwm.h ewmh.h helpers.h monitor.h query.h rule.h settings.h tree.h types.h window.h
index d7dbccdd71c75460009b4309282ba19526d7ac2e..c6d6b3163d5d70166dbf72b9191752f6213e2a5e 100644 (file)
--- a/desktop.c
+++ b/desktop.c
@@ -2,11 +2,57 @@
 #include <string.h>
 #include "bspwm.h"
 #include "desktop.h"
+#include "monitor.h"
 #include "tree.h"
 #include "history.h"
 #include "window.h"
+#include "query.h"
 #include "ewmh.h"
 
+void select_desktop(monitor_t *m, desktop_t *d)
+{
+    select_monitor(m);
+
+    if (d == mon->desk)
+        return;
+
+    PRINTF("select desktop %s\n", d->name);
+
+    show_desktop(d);
+    hide_desktop(mon->desk);
+
+    mon->last_desk = mon->desk;
+    mon->desk = d;
+
+    ewmh_update_current_desktop();
+    put_status();
+}
+
+desktop_t *closest_desktop(monitor_t *m, desktop_t *d, cycle_dir_t dir, desktop_select_t sel)
+{
+    desktop_t *f = (dir == CYCLE_PREV ? d->prev : d->next);
+    if (f == NULL)
+        f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head);
+
+    while (f != d) {
+        if (desktop_matches(f, sel))
+            return f;
+        f = (dir == CYCLE_PREV ? f->prev : f->next);
+        if (f == NULL)
+            f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head);
+    }
+
+    return NULL;
+}
+
+void change_layout(monitor_t *m, desktop_t *d, layout_t l)
+{
+    d->layout = l;
+    arrange(m, d);
+    if (d == mon->desk)
+        put_status();
+}
+
 void transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
 {
     if (ms == md)
@@ -168,3 +214,11 @@ void hide_desktop(desktop_t *d)
     for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
         window_hide(n->client->window);
 }
+
+bool is_urgent(desktop_t *d)
+{
+    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+        if (n->client->urgent)
+            return true;
+    return false;
+}
index 47e40fc5938d20e1e627241c8404256a3c2ed2c8..792d80e85ad9dcc6f4ef0991a5480a7a13b7933e 100644 (file)
--- a/desktop.h
+++ b/desktop.h
@@ -4,7 +4,10 @@
 #define DEFAULT_DESK_NAME    "Desktop"
 #define WINDOW_GAP           6
 
+void select_desktop(monitor_t *, desktop_t *);
+desktop_t *closest_desktop(monitor_t *, desktop_t *, cycle_dir_t, desktop_select_t);
 desktop_t *make_desktop(const char *);
+void change_layout(monitor_t *, desktop_t *, layout_t);
 void insert_desktop(monitor_t *, desktop_t *);
 void add_desktop(monitor_t *, desktop_t *);
 void empty_desktop(desktop_t *);
@@ -14,5 +17,6 @@ void swap_desktops(monitor_t *, desktop_t *, desktop_t *);
 void transfer_desktop(monitor_t *, monitor_t *, desktop_t *);
 void show_desktop(desktop_t *);
 void hide_desktop(desktop_t *);
+bool is_urgent(desktop_t *);
 
 #endif
index 7410850948c140cbd01ef8e1c9fa97505dd99532..1c2bbf7faf5314971d7c52dc2828709d94d54ca6 100644 (file)
--- a/events.c
+++ b/events.c
@@ -1,6 +1,4 @@
 #include <stdlib.h>
-#include <xcb/xcb_icccm.h>
-#include "types.h"
 #include "bspwm.h"
 #include "settings.h"
 #include "events.h"
index d93b9a3a3aad9bafb79948d508cbe49250dea1f0..ba3850546b5a0ca879b274abfd456a6361de35b8 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -1,11 +1,14 @@
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
+#include "settings.h"
 #include "bspwm.h"
 #include "tree.h"
-#include "monitor.h"
 #include "desktop.h"
 #include "window.h"
+#include "query.h"
 #include "ewmh.h"
+#include "monitor.h"
 
 monitor_t *make_monitor(xcb_rectangle_t rect)
 {
@@ -35,6 +38,38 @@ monitor_t *get_monitor_by_id(xcb_randr_output_t id)
     return NULL;
 }
 
+void fit_monitor(monitor_t *m, client_t *c)
+{
+    xcb_rectangle_t crect = c->floating_rectangle;
+    xcb_rectangle_t mrect = m->rectangle;
+    while (crect.x < mrect.x)
+        crect.x += mrect.width;
+    while (crect.x > (mrect.x + mrect.width - 1))
+        crect.x -= mrect.width;
+    while (crect.y < mrect.y)
+        crect.y += mrect.height;
+    while (crect.y > (mrect.y + mrect.height - 1))
+        crect.y -= mrect.height;
+    c->floating_rectangle = crect;
+}
+
+void select_monitor(monitor_t *m)
+{
+    if (mon == m)
+        return;
+
+    PRINTF("select monitor %s\n", m->name);
+
+    last_mon = mon;
+    mon = m;
+
+    if (pointer_follows_monitor)
+        center_pointer(m);
+
+    ewmh_update_current_desktop();
+    put_status();
+}
+
 monitor_t *add_monitor(xcb_rectangle_t rect)
 {
     monitor_t *m = make_monitor(rect);
@@ -134,6 +169,49 @@ void swap_monitors(monitor_t *m1, monitor_t *m2)
     put_status();
 }
 
+monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, desktop_select_t sel)
+{
+    monitor_t *f = (dir == CYCLE_PREV ? m->prev : m->next);
+    if (f == NULL)
+        f = (dir == CYCLE_PREV ? mon_tail : mon_head);
+
+    while (f != m) {
+        if (desktop_matches(f->desk, sel))
+            return f;
+        f = (dir == CYCLE_PREV ? m->prev : m->next);
+        if (f == NULL)
+            f = (dir == CYCLE_PREV ? mon_tail : mon_head);
+    }
+
+    return NULL;
+}
+
+monitor_t *nearest_monitor(monitor_t *m, direction_t dir, desktop_select_t sel)
+{
+    int dmin = INT_MAX;
+    monitor_t *nearest = NULL;
+    xcb_rectangle_t rect = m->rectangle;
+    for (monitor_t *f = mon_head; f != NULL; f = f->next) {
+        if (f == m)
+            continue;
+        if (!desktop_matches(f->desk, sel))
+            continue;
+        xcb_rectangle_t r = f->rectangle;
+        if ((dir == DIR_LEFT && r.x < rect.x) ||
+                (dir == DIR_RIGHT && r.x >= (rect.x + rect.width)) ||
+                (dir == DIR_UP && r.y < rect.y) ||
+                (dir == DIR_DOWN && r.y >= (rect.y + rect.height))) {
+            int d = abs((r.x + r.width / 2) - (rect.x + rect.width / 2)) +
+                abs((r.y + r.height / 2) - (rect.y + rect.height / 2));
+            if (d < dmin) {
+                dmin = d;
+                nearest = f;
+            }
+        }
+    }
+    return nearest;
+}
+
 bool import_monitors(void)
 {
     PUTS("import monitors");
index e2a9d3a0020a84e18a5f273b7d60e9e9ba1ecee2..0f05fedd1afa603e31243fa0e218c681b6e2e65a 100644 (file)
--- a/monitor.h
+++ b/monitor.h
@@ -5,7 +5,11 @@
 
 monitor_t *make_monitor(xcb_rectangle_t);
 monitor_t *find_monitor(char *);
+void fit_monitor(monitor_t *, client_t *);
 monitor_t *get_monitor_by_id(xcb_randr_output_t);
+void select_monitor(monitor_t *);
+monitor_t *nearest_monitor(monitor_t *, direction_t, desktop_select_t);
+monitor_t *closest_monitor(monitor_t *, cycle_dir_t, desktop_select_t);
 monitor_t *add_monitor(xcb_rectangle_t);
 void remove_monitor(monitor_t *);
 void merge_monitors(monitor_t *, monitor_t *);
diff --git a/query.c b/query.c
index a1e5f179b3e43b429172f4852f6100faaf109fbf..80a56b0a02ca9deaeea95d212f76b1cfa022b37c 100644 (file)
--- a/query.c
+++ b/query.c
@@ -2,6 +2,8 @@
 #include <stdio.h>
 #include "bspwm.h"
 #include "tree.h"
+#include "monitor.h"
+#include "desktop.h"
 #include "messages.h"
 #include "history.h"
 #include "query.h"
index 2b6fb80ad15fcd45086e52830ea68c764005da96..afb8f6a7e910dd36bf298c5cbd7eb9362a49e376 100644 (file)
--- a/restore.c
+++ b/restore.c
@@ -1,7 +1,6 @@
 #include <ctype.h>
 #include <string.h>
 #include "bspwm.h"
-#include "types.h"
 #include "monitor.h"
 #include "desktop.h"
 #include "tree.h"
diff --git a/rule.c b/rule.c
index 03039168078bf71f86e09f2c3ed64b11637c7cb9..1559e413ebc8f7e2c3fb7b0675add03056c0de55 100644 (file)
--- a/rule.c
+++ b/rule.c
@@ -1,6 +1,5 @@
 #include <stdio.h>
 #include <string.h>
-#include <xcb/xcb_icccm.h>
 #include "bspwm.h"
 #include "ewmh.h"
 #include "window.h"
diff --git a/tree.c b/tree.c
index a24c9890d67538fb739eb5c0102b6d06022e9650..f15941fccd367100c64422b11622f951f6483b94 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -8,9 +8,266 @@
 #include "ewmh.h"
 #include "tree.h"
 #include "desktop.h"
+#include "monitor.h"
 #include "history.h"
 #include "query.h"
 
+void arrange(monitor_t *m, desktop_t *d)
+{
+    if (d->root == NULL)
+        return;
+
+    PRINTF("arrange %s%s%s\n", (num_monitors > 1 ? m->name : ""), (num_monitors > 1 ? " " : ""), d->name);
+
+    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;
+    apply_layout(m, d, d->root, rect, rect);
+}
+
+void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect)
+{
+    if (n == NULL)
+        return;
+
+    n->rectangle = rect;
+
+    if (is_leaf(n)) {
+
+        if (is_floating(n->client) && n->client->border_width != border_width) {
+            int ds = 2 * (border_width - n->client->border_width);
+            n->client->floating_rectangle.width += ds;
+            n->client->floating_rectangle.height += ds;
+        }
+
+        if ((borderless_monocle && is_tiled(n->client) && d->layout == LAYOUT_MONOCLE) ||
+                n->client->fullscreen)
+            n->client->border_width = 0;
+        else
+            n->client->border_width = border_width;
+
+        xcb_rectangle_t r;
+        if (!n->client->fullscreen) {
+            if (!n->client->floating) {
+                /* tiled clients */
+                if (d->layout == LAYOUT_TILED)
+                    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);
+                n->client->tiled_rectangle = r;
+            } else {
+                /* floating clients */
+                r = n->client->floating_rectangle;
+            }
+        } else {
+            /* fullscreen clients */
+            r = m->rectangle;
+        }
+
+        window_move_resize(n->client->window, r.x, r.y, r.width, r.height);
+        window_border_width(n->client->window, n->client->border_width);
+        window_draw_border(n, n == d->focus, m == mon);
+
+    } else {
+        xcb_rectangle_t first_rect;
+        xcb_rectangle_t second_rect;
+
+        if (n->first_child->vacant || n->second_child->vacant) {
+            first_rect = second_rect = rect;
+        } else {
+            unsigned int fence;
+            if (n->split_type == TYPE_VERTICAL) {
+                fence = rect.width * n->split_ratio;
+                first_rect = (xcb_rectangle_t) {rect.x, rect.y, fence, rect.height};
+                second_rect = (xcb_rectangle_t) {rect.x + fence, rect.y, rect.width - fence, rect.height};
+            } else if (n->split_type == TYPE_HORIZONTAL) {
+                fence = rect.height * n->split_ratio;
+                first_rect = (xcb_rectangle_t) {rect.x, rect.y, rect.width, fence};
+                second_rect = (xcb_rectangle_t) {rect.x, rect.y + fence, rect.width, rect.height - fence};
+            }
+        }
+
+        apply_layout(m, d, n->first_child, first_rect, root_rect);
+        apply_layout(m, d, n->second_child, second_rect, root_rect);
+    }
+}
+
+void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
+{
+    if (d == NULL || n == NULL)
+        return;
+
+    PRINTF("insert node %X\n", n->client->window);
+
+    /* n: new leaf node */
+    /* c: new container node */
+    /* f: focus or insertion anchor */
+    /* p: parent of focus */
+    /* g: grand parent of focus */
+
+    if (f == NULL) {
+        d->root = n;
+    } else {
+        node_t *c = make_node();
+        node_t *p = f->parent;
+        n->parent = c;
+        c->birth_rotation = f->birth_rotation;
+        switch (f->split_mode) {
+            case MODE_AUTOMATIC:
+                if (p == NULL) {
+                    c->first_child = n;
+                    c->second_child = f;
+                    if (m->rectangle.width > m->rectangle.height)
+                        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;
+                    if (g != NULL) {
+                        if (is_first_child(p))
+                            g->first_child = c;
+                        else
+                            g->second_child = c;
+                    } else {
+                        d->root = c;
+                    }
+                    c->split_type = p->split_type;
+                    c->split_ratio = p->split_ratio;
+                    p->parent = c;
+                    int rot;
+                    if (is_first_child(f)) {
+                        c->first_child = n;
+                        c->second_child = p;
+                        rot = 90;
+                    } else {
+                        c->first_child = p;
+                        c->second_child = n;
+                        rot = 270;
+                    }
+                    if (!is_floating(n->client))
+                        rotate_tree(p, rot);
+                    n->birth_rotation = rot;
+                }
+                break;
+            case MODE_MANUAL:
+                if (p != NULL) {
+                    if (is_first_child(f))
+                        p->first_child = c;
+                    else
+                        p->second_child = c;
+                }
+                c->split_ratio = f->split_ratio;
+                c->parent = p;
+                f->parent = c;
+                f->birth_rotation = 0;
+                switch (f->split_dir) {
+                    case DIR_LEFT:
+                        c->split_type = TYPE_VERTICAL;
+                        c->first_child = n;
+                        c->second_child = f;
+                        break;
+                    case DIR_RIGHT:
+                        c->split_type = TYPE_VERTICAL;
+                        c->first_child = f;
+                        c->second_child = n;
+                        break;
+                    case DIR_UP:
+                        c->split_type = TYPE_HORIZONTAL;
+                        c->first_child = n;
+                        c->second_child = f;
+                        break;
+                    case DIR_DOWN:
+                        c->split_type = TYPE_HORIZONTAL;
+                        c->first_child = f;
+                        c->second_child = n;
+                        break;
+                }
+                if (d->root == f)
+                    d->root = c;
+                f->split_mode = MODE_AUTOMATIC;
+                break;
+        }
+        if (f->vacant)
+            update_vacant_state(p);
+    }
+    put_status();
+}
+
+void pseudo_focus(desktop_t *d, node_t *n)
+{
+    if (n == NULL || d->focus == n)
+        return;
+    d->focus = n;
+    history_add(d->history, n);
+    stack(d, n);
+}
+
+void focus_node(monitor_t *m, desktop_t *d, node_t *n)
+{
+    if (n == NULL && d->root != NULL)
+        return;
+
+    if (mon->desk != d)
+        clear_input_focus();
+
+    if (mon != m) {
+        for (desktop_t *cd = mon->desk_head; cd != NULL; cd = cd->next)
+            window_draw_border(cd->focus, true, false);
+        for (desktop_t *cd = m->desk_head; cd != NULL; cd = cd->next)
+            if (cd != d)
+                window_draw_border(cd->focus, true, true);
+        if (d->focus == n)
+            window_draw_border(n, true, true);
+    }
+
+    if (d->focus != n) {
+        window_draw_border(d->focus, false, true);
+        window_draw_border(n, true, true);
+    }
+
+    select_desktop(m, d);
+
+    if (n == NULL) {
+        ewmh_update_active_window();
+        return;
+    }
+
+    PRINTF("focus node %X\n", n->client->window);
+
+    n->client->urgent = false;
+
+    pseudo_focus(d, n);
+    set_input_focus(n);
+
+    if (focus_follows_pointer) {
+        xcb_window_t win = XCB_NONE;
+        query_pointer(&win, NULL);
+        if (win != n->client->window)
+            enable_motion_recorder();
+        else
+            disable_motion_recorder();
+    }
+
+    ewmh_update_active_window();
+}
+
+void update_current(void)
+{
+    focus_node(mon, mon->desk, mon->desk->focus);
+}
+
 node_t *make_node(void)
 {
     node_t *n = malloc(sizeof(node_t));
@@ -70,28 +327,12 @@ bool is_second_child(node_t *n)
     return (n != NULL && n->parent != NULL && n->parent->second_child == n);
 }
 
-bool is_urgent(desktop_t *d)
-{
-    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
-        if (n->client->urgent)
-            return true;
-    return false;
-}
-
 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 change_layout(monitor_t *m, desktop_t *d, layout_t l)
-{
-    d->layout = l;
-    arrange(m, d);
-    if (d == mon->desk)
-        put_status();
-}
-
 void reset_mode(coordinates_t *loc)
 {
     if (loc->node != NULL) {
@@ -336,369 +577,113 @@ node_t *find_biggest(desktop_t *d, node_t *c, client_select_t sel)
         return NULL;
 
     node_t *r = NULL;
-    int r_area = tiled_area(r);
-
-    for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
-        if (!is_tiled(f->client) || !node_matches(c, f, sel))
-            continue;
-        int f_area = tiled_area(f);
-        if (r == NULL) {
-            r = f;
-            r_area = f_area;
-        } else if (f_area > r_area) {
-            r = f;
-            r_area = f_area;
-        }
-    }
-
-    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)
-        return;
-
-    node_t *tmp;
-
-    if ((deg == 90 && n->split_type == TYPE_HORIZONTAL)
-            || (deg == 270 && n->split_type == TYPE_VERTICAL)
-            || deg == 180) {
-        tmp = n->first_child;
-        n->first_child = n->second_child;
-        n->second_child = tmp;
-        n->split_ratio = 1.0 - n->split_ratio;
-    }
-
-    if (deg != 180) {
-        if (n->split_type == TYPE_HORIZONTAL)
-            n->split_type = TYPE_VERTICAL;
-        else if (n->split_type == TYPE_VERTICAL)
-            n->split_type = TYPE_HORIZONTAL;
-    }
-
-    rotate_tree(n->first_child, deg);
-    rotate_tree(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))
-        return;
-
-    node_t *tmp;
-
-    if ((flp == FLIP_HORIZONTAL && n->split_type == TYPE_HORIZONTAL)
-            || (flp == FLIP_VERTICAL && n->split_type == TYPE_VERTICAL)) {
-        tmp = n->first_child;
-        n->first_child = n->second_child;
-        n->second_child = tmp;
-        n->split_ratio = 1.0 - n->split_ratio;
-    }
-
-    flip_tree(n->first_child, 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)
-{
-    if (d->root == NULL)
-        return;
-
-    PRINTF("arrange %s%s%s\n", (num_monitors > 1 ? m->name : ""), (num_monitors > 1 ? " " : ""), d->name);
-
-    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;
-    apply_layout(m, d, d->root, rect, rect);
-}
-
-void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect)
-{
-    if (n == NULL)
-        return;
-
-    n->rectangle = rect;
-
-    if (is_leaf(n)) {
-
-        if (is_floating(n->client) && n->client->border_width != border_width) {
-            int ds = 2 * (border_width - n->client->border_width);
-            n->client->floating_rectangle.width += ds;
-            n->client->floating_rectangle.height += ds;
-        }
-
-        if ((borderless_monocle && is_tiled(n->client) && d->layout == LAYOUT_MONOCLE) ||
-                n->client->fullscreen)
-            n->client->border_width = 0;
-        else
-            n->client->border_width = border_width;
-
-        xcb_rectangle_t r;
-        if (!n->client->fullscreen) {
-            if (!n->client->floating) {
-                /* tiled clients */
-                if (d->layout == LAYOUT_TILED)
-                    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);
-                n->client->tiled_rectangle = r;
-            } else {
-                /* floating clients */
-                r = n->client->floating_rectangle;
-            }
-        } else {
-            /* fullscreen clients */
-            r = m->rectangle;
-        }
-
-        window_move_resize(n->client->window, r.x, r.y, r.width, r.height);
-        window_border_width(n->client->window, n->client->border_width);
-        window_draw_border(n, n == d->focus, m == mon);
-
-    } else {
-        xcb_rectangle_t first_rect;
-        xcb_rectangle_t second_rect;
-
-        if (n->first_child->vacant || n->second_child->vacant) {
-            first_rect = second_rect = rect;
-        } else {
-            unsigned int fence;
-            if (n->split_type == TYPE_VERTICAL) {
-                fence = rect.width * n->split_ratio;
-                first_rect = (xcb_rectangle_t) {rect.x, rect.y, fence, rect.height};
-                second_rect = (xcb_rectangle_t) {rect.x + fence, rect.y, rect.width - fence, rect.height};
-            } else if (n->split_type == TYPE_HORIZONTAL) {
-                fence = rect.height * n->split_ratio;
-                first_rect = (xcb_rectangle_t) {rect.x, rect.y, rect.width, fence};
-                second_rect = (xcb_rectangle_t) {rect.x, rect.y + fence, rect.width, rect.height - fence};
-            }
-        }
-
-        apply_layout(m, d, n->first_child, first_rect, root_rect);
-        apply_layout(m, d, n->second_child, second_rect, root_rect);
-    }
-}
-
-void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
-{
-    if (d == NULL || n == NULL)
-        return;
-
-    PRINTF("insert node %X\n", n->client->window);
-
-    /* n: new leaf node */
-    /* c: new container node */
-    /* f: focus or insertion anchor */
-    /* p: parent of focus */
-    /* g: grand parent of focus */
+    int r_area = tiled_area(r);
 
-    if (f == NULL) {
-        d->root = n;
-    } else {
-        node_t *c = make_node();
-        node_t *p = f->parent;
-        n->parent = c;
-        c->birth_rotation = f->birth_rotation;
-        switch (f->split_mode) {
-            case MODE_AUTOMATIC:
-                if (p == NULL) {
-                    c->first_child = n;
-                    c->second_child = f;
-                    if (m->rectangle.width > m->rectangle.height)
-                        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;
-                    if (g != NULL) {
-                        if (is_first_child(p))
-                            g->first_child = c;
-                        else
-                            g->second_child = c;
-                    } else {
-                        d->root = c;
-                    }
-                    c->split_type = p->split_type;
-                    c->split_ratio = p->split_ratio;
-                    p->parent = c;
-                    int rot;
-                    if (is_first_child(f)) {
-                        c->first_child = n;
-                        c->second_child = p;
-                        rot = 90;
-                    } else {
-                        c->first_child = p;
-                        c->second_child = n;
-                        rot = 270;
-                    }
-                    if (!is_floating(n->client))
-                        rotate_tree(p, rot);
-                    n->birth_rotation = rot;
-                }
-                break;
-            case MODE_MANUAL:
-                if (p != NULL) {
-                    if (is_first_child(f))
-                        p->first_child = c;
-                    else
-                        p->second_child = c;
-                }
-                c->split_ratio = f->split_ratio;
-                c->parent = p;
-                f->parent = c;
-                f->birth_rotation = 0;
-                switch (f->split_dir) {
-                    case DIR_LEFT:
-                        c->split_type = TYPE_VERTICAL;
-                        c->first_child = n;
-                        c->second_child = f;
-                        break;
-                    case DIR_RIGHT:
-                        c->split_type = TYPE_VERTICAL;
-                        c->first_child = f;
-                        c->second_child = n;
-                        break;
-                    case DIR_UP:
-                        c->split_type = TYPE_HORIZONTAL;
-                        c->first_child = n;
-                        c->second_child = f;
-                        break;
-                    case DIR_DOWN:
-                        c->split_type = TYPE_HORIZONTAL;
-                        c->first_child = f;
-                        c->second_child = n;
-                        break;
-                }
-                if (d->root == f)
-                    d->root = c;
-                f->split_mode = MODE_AUTOMATIC;
-                break;
+    for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
+        if (!is_tiled(f->client) || !node_matches(c, f, sel))
+            continue;
+        int f_area = tiled_area(f);
+        if (r == NULL) {
+            r = f;
+            r_area = f_area;
+        } else if (f_area > r_area) {
+            r = f;
+            r_area = f_area;
         }
-        if (f->vacant)
-            update_vacant_state(p);
     }
-    put_status();
+
+    return r;
 }
 
-void pseudo_focus(desktop_t *d, node_t *n)
+void move_fence(node_t *n, direction_t dir, fence_move_t mov)
 {
-    if (n == NULL || d->focus == n)
+    if (n == NULL)
         return;
-    d->focus = n;
-    history_add(d->history, n);
-    stack(d, n);
+
+    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 focus_node(monitor_t *m, desktop_t *d, node_t *n)
+void rotate_tree(node_t *n, int deg)
 {
-    if (n == NULL && d->root != NULL)
+    if (n == NULL || is_leaf(n) || deg == 0)
         return;
 
-    if (mon->desk != d)
-        clear_input_focus();
+    node_t *tmp;
 
-    if (mon != m) {
-        for (desktop_t *cd = mon->desk_head; cd != NULL; cd = cd->next)
-            window_draw_border(cd->focus, true, false);
-        for (desktop_t *cd = m->desk_head; cd != NULL; cd = cd->next)
-            if (cd != d)
-                window_draw_border(cd->focus, true, true);
-        if (d->focus == n)
-            window_draw_border(n, true, true);
+    if ((deg == 90 && n->split_type == TYPE_HORIZONTAL)
+            || (deg == 270 && n->split_type == TYPE_VERTICAL)
+            || deg == 180) {
+        tmp = n->first_child;
+        n->first_child = n->second_child;
+        n->second_child = tmp;
+        n->split_ratio = 1.0 - n->split_ratio;
     }
 
-    if (d->focus != n) {
-        window_draw_border(d->focus, false, true);
-        window_draw_border(n, true, true);
+    if (deg != 180) {
+        if (n->split_type == TYPE_HORIZONTAL)
+            n->split_type = TYPE_VERTICAL;
+        else if (n->split_type == TYPE_VERTICAL)
+            n->split_type = TYPE_HORIZONTAL;
     }
 
-    select_desktop(m, d);
+    rotate_tree(n->first_child, deg);
+    rotate_tree(n->second_child, deg);
+}
 
-    if (n == NULL) {
-        ewmh_update_active_window();
+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);
+}
 
-    PRINTF("focus node %X\n", n->client->window);
+void unrotate_brother(node_t *n)
+{
+    unrotate_tree(brother_tree(n), n->birth_rotation);
+}
 
-    n->client->urgent = false;
+void flip_tree(node_t *n, flip_t flp)
+{
+    if (n == NULL || is_leaf(n))
+        return;
 
-    pseudo_focus(d, n);
-    set_input_focus(n);
+    node_t *tmp;
 
-    if (focus_follows_pointer) {
-        xcb_window_t win = XCB_NONE;
-        query_pointer(&win, NULL);
-        if (win != n->client->window)
-            enable_motion_recorder();
-        else
-            disable_motion_recorder();
+    if ((flp == FLIP_HORIZONTAL && n->split_type == TYPE_HORIZONTAL)
+            || (flp == FLIP_VERTICAL && n->split_type == TYPE_VERTICAL)) {
+        tmp = n->first_child;
+        n->first_child = n->second_child;
+        n->second_child = tmp;
+        n->split_ratio = 1.0 - n->split_ratio;
     }
 
-    ewmh_update_active_window();
+    flip_tree(n->first_child, flp);
+    flip_tree(n->second_child, flp);
 }
 
-void update_current(void)
+int balance_tree(node_t *n)
 {
-    focus_node(mon, mon->desk, mon->desk->focus);
+    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 unlink_node(desktop_t *d, node_t *n)
@@ -878,102 +863,6 @@ void transplant_node(monitor_t *m, desktop_t *d, node_t *n1, node_t *n2)
         pseudo_focus(d, n1);
 }
 
-void select_monitor(monitor_t *m)
-{
-    if (mon == m)
-        return;
-
-    PRINTF("select monitor %s\n", m->name);
-
-    last_mon = mon;
-    mon = m;
-
-    if (pointer_follows_monitor)
-        center_pointer(m);
-
-    ewmh_update_current_desktop();
-    put_status();
-}
-
-monitor_t *nearest_monitor(monitor_t *m, direction_t dir, desktop_select_t sel)
-{
-    int dmin = INT_MAX;
-    monitor_t *nearest = NULL;
-    xcb_rectangle_t rect = m->rectangle;
-    for (monitor_t *f = mon_head; f != NULL; f = f->next) {
-        if (f == m)
-            continue;
-        if (!desktop_matches(f->desk, sel))
-            continue;
-        xcb_rectangle_t r = f->rectangle;
-        if ((dir == DIR_LEFT && r.x < rect.x) ||
-                (dir == DIR_RIGHT && r.x >= (rect.x + rect.width)) ||
-                (dir == DIR_UP && r.y < rect.y) ||
-                (dir == DIR_DOWN && r.y >= (rect.y + rect.height))) {
-            int d = abs((r.x + r.width / 2) - (rect.x + rect.width / 2)) +
-                abs((r.y + r.height / 2) - (rect.y + rect.height / 2));
-            if (d < dmin) {
-                dmin = d;
-                nearest = f;
-            }
-        }
-    }
-    return nearest;
-}
-
-void select_desktop(monitor_t *m, desktop_t *d)
-{
-    select_monitor(m);
-
-    if (d == mon->desk)
-        return;
-
-    PRINTF("select desktop %s\n", d->name);
-
-    show_desktop(d);
-    hide_desktop(mon->desk);
-
-    mon->last_desk = mon->desk;
-    mon->desk = d;
-
-    ewmh_update_current_desktop();
-    put_status();
-}
-
-monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, desktop_select_t sel)
-{
-    monitor_t *f = (dir == CYCLE_PREV ? m->prev : m->next);
-    if (f == NULL)
-        f = (dir == CYCLE_PREV ? mon_tail : mon_head);
-
-    while (f != m) {
-        if (desktop_matches(f->desk, sel))
-            return f;
-        f = (dir == CYCLE_PREV ? m->prev : m->next);
-        if (f == NULL)
-            f = (dir == CYCLE_PREV ? mon_tail : mon_head);
-    }
-
-    return NULL;
-}
-
-desktop_t *closest_desktop(monitor_t *m, desktop_t *d, cycle_dir_t dir, desktop_select_t sel)
-{
-    desktop_t *f = (dir == CYCLE_PREV ? d->prev : d->next);
-    if (f == NULL)
-        f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head);
-
-    while (f != d) {
-        if (desktop_matches(f, sel))
-            return f;
-        f = (dir == CYCLE_PREV ? f->prev : f->next);
-        if (f == NULL)
-            f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head);
-    }
-
-    return NULL;
-}
-
 node_t *closest_node(desktop_t *d, node_t *n, cycle_dir_t dir, client_select_t sel)
 {
     if (n == NULL)
@@ -1026,18 +915,3 @@ void update_vacant_state(node_t *n)
         p = p->parent;
     }
 }
-
-void fit_monitor(monitor_t *m, client_t *c)
-{
-    xcb_rectangle_t crect = c->floating_rectangle;
-    xcb_rectangle_t mrect = m->rectangle;
-    while (crect.x < mrect.x)
-        crect.x += mrect.width;
-    while (crect.x > (mrect.x + mrect.width - 1))
-        crect.x -= mrect.width;
-    while (crect.y < mrect.y)
-        crect.y += mrect.height;
-    while (crect.y > (mrect.y + mrect.height - 1))
-        crect.y -= mrect.height;
-    c->floating_rectangle = crect;
-}
diff --git a/tree.h b/tree.h
index 3d7a6d53cfb7e9fe3732fb84e61ab8260cf4cdf4..42e471f05b694c5ec47f752ff99002d556b5e577 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -24,9 +24,7 @@ bool is_tiled(client_t *);
 bool is_floating(client_t *);
 bool is_first_child(node_t *);
 bool is_second_child(node_t *);
-bool is_urgent(desktop_t *);
 void change_split_ratio(node_t *, value_change_t);
-void change_layout(monitor_t *, desktop_t *, layout_t);
 void reset_mode(coordinates_t *);
 node_t *brother_tree(node_t *);
 node_t *first_extrema(node_t *);
@@ -44,15 +42,9 @@ void unrotate_brother(node_t *);
 void flip_tree(node_t *, flip_t);
 int balance_tree(node_t *);
 void destroy_tree(node_t *);
-void fit_monitor(monitor_t *, client_t *);
 void transfer_node(monitor_t *, desktop_t *, monitor_t *, desktop_t *, node_t *);
 void transplant_node(monitor_t *, desktop_t *, node_t *, node_t *);
-void select_monitor(monitor_t *);
-void select_desktop(monitor_t *, desktop_t *);
-monitor_t *nearest_monitor(monitor_t *, direction_t, desktop_select_t);
 node_t *closest_node(desktop_t *, node_t *, cycle_dir_t, client_select_t);
-desktop_t *closest_desktop(monitor_t *, desktop_t *, cycle_dir_t, desktop_select_t);
-monitor_t *closest_monitor(monitor_t *, cycle_dir_t, desktop_select_t);
 void circulate_leaves(monitor_t *, desktop_t *, circulate_dir_t);
 void update_vacant_state(node_t *);
 
index 71a85f120bcc7f178ba6fe0ccd99b512cd00c649..6aa184f7e751a40429e4e8787c257682536183ff 100644 (file)
--- a/window.c
+++ b/window.c
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "types.h"
+#include "monitor.h"
 #include "tree.h"
 #include "bspwm.h"
 #include "settings.h"