]> git.lizzy.rs Git - bspwm.git/commitdiff
Split types.c into {monitor,desktop,history}.c
authorBastien Dejean <nihilhill@gmail.com>
Thu, 19 Sep 2013 13:02:49 +0000 (15:02 +0200)
committerBastien Dejean <nihilhill@gmail.com>
Thu, 19 Sep 2013 13:02:49 +0000 (15:02 +0200)
23 files changed:
Makefile
Sourcedeps
bspwm.c
bspwm.h
desktop.c [new file with mode: 0644]
desktop.h [new file with mode: 0644]
events.c
history.c [new file with mode: 0644]
history.h [new file with mode: 0644]
messages.c
monitor.c [new file with mode: 0644]
monitor.h [new file with mode: 0644]
query.c
query.h
restore.c
rules.c
rules.h
tree.c
tree.h
types.c [deleted file]
types.h
window.c
window.h

index c7633ff1daf3bb1a6c27ade7b1664b3cdc144cae..d68af405da834ce41ebee77d0ee7eb2bfb1ce89b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,8 @@ MANPREFIX = $(PREFIX)/share/man
 BASHCPL = $(PREFIX)/share/bash-completion/completions
 ZSHCPL = $(PREFIX)/share/zsh/site-functions
 
-WM_SRC = bspwm.c helpers.c settings.c types.c tree.c events.c window.c messages.c query.c restore.c rules.c ewmh.c
+WM_SRC = bspwm.c helpers.c settings.c monitor.c desktop.c tree.c history.c \
+        events.c window.c messages.c query.c restore.c rules.c ewmh.c
 WM_OBJ = $(WM_SRC:.c=.o)
 CL_SRC = bspc.c helpers.c
 CL_OBJ = $(CL_SRC:.c=.o)
index fe434a48318055c9172b38732780c332d1cab8ae..8b3a882b2d89fde3cd4dd2578bce6e5ecdf1d19d 100644 (file)
@@ -1,13 +1,15 @@
 bspc.o: bspc.c common.h helpers.h
-bspwm.o: bspwm.c bspwm.h common.h events.h ewmh.h helpers.h messages.h rules.h settings.h tree.h types.h window.h
-events.o: events.c bspwm.h events.h ewmh.h helpers.h query.h rules.h settings.h tree.h types.h window.h
+bspwm.o: bspwm.c bspwm.h common.h desktop.h events.h ewmh.h helpers.h messages.h monitor.h rules.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
+events.o: events.c bspwm.h events.h ewmh.h helpers.h monitor.h query.h rules.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
-messages.o: messages.c bspwm.h common.h events.h ewmh.h helpers.h messages.h query.h restore.h rules.h settings.h tree.h types.h window.h
-query.o: query.c bspwm.h helpers.h messages.h query.h settings.h tree.h types.h
-restore.o: restore.c bspwm.h ewmh.h helpers.h query.h restore.h settings.h tree.h types.h
+history.o: history.c helpers.h history.h query.h types.h
+messages.o: messages.c bspwm.h common.h desktop.h events.h ewmh.h helpers.h messages.h monitor.h query.h restore.h rules.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 settings.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
 rules.o: rules.c bspwm.h ewmh.h helpers.h query.h rules.h types.h window.h
 settings.o: settings.c bspwm.h common.h helpers.h settings.h types.h
-tree.o: tree.c bspwm.h ewmh.h helpers.h settings.h tree.h types.h window.h
-types.o: types.c bspwm.h ewmh.h helpers.h rules.h settings.h tree.h types.h window.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 rules.h settings.h tree.h types.h window.h
diff --git a/bspwm.c b/bspwm.c
index 7771e69b9e9a27ad41d2fed3a27b9ae2553029d2..d21cdd42778500ed6f05dd5737fb624bd81eba8c 100644 (file)
--- a/bspwm.c
+++ b/bspwm.c
@@ -13,6 +13,8 @@
 #include <xcb/xcb_ewmh.h>
 #include <xcb/randr.h>
 #include "types.h"
+#include "desktop.h"
+#include "monitor.h"
 #include "settings.h"
 #include "messages.h"
 #include "rules.h"
@@ -258,93 +260,6 @@ void register_events(void)
     }
 }
 
-bool import_monitors(void)
-{
-    PUTS("import monitors");
-    xcb_randr_get_screen_resources_current_reply_t *sres = xcb_randr_get_screen_resources_current_reply(dpy, xcb_randr_get_screen_resources_current(dpy, root), NULL);
-    if (sres == NULL)
-        return false;
-
-    int len = xcb_randr_get_screen_resources_current_outputs_length(sres);
-    xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(sres);
-
-    xcb_randr_get_output_info_cookie_t cookies[len];
-    for (int i = 0; i < len; i++)
-        cookies[i] = xcb_randr_get_output_info(dpy, outputs[i], XCB_CURRENT_TIME);
-
-    for (monitor_t *m = mon_head; m != NULL; m = m->next)
-        m->wired = false;
-
-    monitor_t *mm = NULL;
-    unsigned int num = 0;
-
-    for (int i = 0; i < len; i++) {
-        xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(dpy, cookies[i], NULL);
-        if (info != NULL && info->crtc != XCB_NONE) {
-
-            xcb_randr_get_crtc_info_reply_t *cir = xcb_randr_get_crtc_info_reply(dpy, xcb_randr_get_crtc_info(dpy, info->crtc, XCB_CURRENT_TIME), NULL);
-            if (cir != NULL) {
-                xcb_rectangle_t rect = (xcb_rectangle_t) {cir->x, cir->y, cir->width, cir->height};
-                mm = get_monitor_by_id(outputs[i]);
-                if (mm != NULL) {
-                    mm->rectangle = rect;
-                    for (desktop_t *d = mm->desk_head; d != NULL; d = d->next)
-                        for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
-                            fit_monitor(mm, n->client);
-                    arrange(mm, mm->desk);
-                    mm->wired = true;
-                    PRINTF("update monitor %s (0x%X)\n", mm->name, mm->id);
-                } else {
-                    mm = add_monitor(rect);
-                    char *name = (char *)xcb_randr_get_output_info_name(info);
-                    size_t name_len = MIN(sizeof(mm->name), (size_t)xcb_randr_get_output_info_name_length(info));
-                    strncpy(mm->name, name, name_len);
-                    mm->name[name_len] = '\0';
-                    mm->id = outputs[i];
-                    PRINTF("add monitor %s (0x%X)\n", mm->name, mm->id);
-                }
-                num++;
-            }
-            free(cir);
-        }
-        free(info);
-    }
-
-    /* initially focus the primary monitor and add the first desktop to it */
-    xcb_randr_get_output_primary_reply_t *gpo = xcb_randr_get_output_primary_reply(dpy, xcb_randr_get_output_primary(dpy, root), NULL);
-    if (gpo != NULL) {
-        pri_mon = get_monitor_by_id(gpo->output);
-        if (!running && pri_mon != NULL) {
-            if (mon != pri_mon)
-                mon = pri_mon;
-            add_desktop(pri_mon, make_desktop(NULL));
-            ewmh_update_current_desktop();
-        }
-    }
-    free(gpo);
-
-    /* add one desktop to each new monitor */
-    for (monitor_t *m = mon_head; m != NULL; m = m->next)
-        if (m->desk == NULL && (running || pri_mon == NULL || m != pri_mon))
-            add_desktop(m, make_desktop(NULL));
-
-    /* merge and remove disconnected monitors */
-    monitor_t *m = mon_head;
-    while (m != NULL) {
-        monitor_t *next = m->next;
-        if (!m->wired) {
-            PRINTF("remove monitor %s (0x%X)\n", m->name, m->id);
-            merge_monitors(m, mm);
-            remove_monitor(m);
-        }
-        m = next;
-    }
-
-    free(sres);
-    update_motion_recorder();
-    return (num_monitors > 0);
-}
-
 void quit(void)
 {
     running = false;
diff --git a/bspwm.h b/bspwm.h
index 51b664e61affcf63bff8446a5f5c48928a079899..414a78c5909a627c1c3c0addea3b2872cf96f9c9 100644 (file)
--- a/bspwm.h
+++ b/bspwm.h
@@ -42,10 +42,9 @@ bool auto_raise;
 bool running;
 bool randr;
 
-void register_events(void);
-bool import_monitors(void);
 void init(void);
 void setup(void);
+void register_events(void);
 void put_status(void);
 void cleanup(void);
 void quit(void);
diff --git a/desktop.c b/desktop.c
new file mode 100644 (file)
index 0000000..49ccfea
--- /dev/null
+++ b/desktop.c
@@ -0,0 +1,171 @@
+#include <stdlib.h>
+#include <string.h>
+#include "bspwm.h"
+#include "types.h"
+#include "desktop.h"
+#include "history.h"
+#include "tree.h"
+#include "window.h"
+#include "ewmh.h"
+
+void transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
+{
+    if (ms == md)
+        return;
+
+    desktop_t *dd = ms->desk;
+    unlink_desktop(ms, d);
+    insert_desktop(md, d);
+
+    if (d == dd) {
+        if (ms->desk != NULL)
+            show_desktop(ms->desk);
+        if (md->desk != d)
+            hide_desktop(d);
+    }
+
+    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+        fit_monitor(md, n->client);
+    arrange(md, d);
+    if (d != dd && md->desk == d) {
+        show_desktop(d);
+    }
+
+    ewmh_update_wm_desktops();
+    ewmh_update_desktop_names();
+    ewmh_update_current_desktop();
+    put_status();
+}
+
+desktop_t *make_desktop(const char *name)
+{
+    desktop_t *d = malloc(sizeof(desktop_t));
+    if (name == NULL)
+        snprintf(d->name, sizeof(d->name), "%s%02d", DEFAULT_DESK_NAME, ++desktop_uid);
+    else
+        strncpy(d->name, name, sizeof(d->name));
+    d->layout = LAYOUT_TILED;
+    d->prev = d->next = NULL;
+    d->root = d->focus = NULL;
+    d->history = make_focus_history();
+    d->window_gap = WINDOW_GAP;
+    return d;
+}
+
+void insert_desktop(monitor_t *m, desktop_t *d)
+{
+    if (m->desk == NULL) {
+        m->desk = d;
+        m->desk_head = d;
+        m->desk_tail = d;
+    } else {
+        m->desk_tail->next = d;
+        d->prev = m->desk_tail;
+        m->desk_tail = d;
+    }
+}
+
+void add_desktop(monitor_t *m, desktop_t *d)
+{
+    PRINTF("add desktop %s\n", d->name);
+
+    insert_desktop(m, d);
+    num_desktops++;
+    ewmh_update_number_of_desktops();
+    ewmh_update_desktop_names();
+    put_status();
+}
+
+void empty_desktop(desktop_t *d)
+{
+    destroy_tree(d->root);
+    d->root = d->focus = NULL;
+    empty_history(d->history);
+}
+
+void unlink_desktop(monitor_t *m, desktop_t *d)
+{
+    desktop_t *prev = d->prev;
+    desktop_t *next = d->next;
+    if (prev != NULL)
+        prev->next = next;
+    if (next != NULL)
+        next->prev = prev;
+    if (m->desk_head == d)
+        m->desk_head = next;
+    if (m->desk_tail == d)
+        m->desk_tail = prev;
+    if (m->last_desk == d)
+        m->last_desk = NULL;
+    if (m->desk == d)
+        m->desk = (m->last_desk == NULL ? (prev == NULL ? next : prev) : m->last_desk);
+    d->prev = d->next = NULL;
+}
+
+void remove_desktop(monitor_t *m, desktop_t *d)
+{
+    PRINTF("remove desktop %s\n", d->name);
+
+    unlink_desktop(m, d);
+    empty_desktop(d);
+    free(d);
+    num_desktops--;
+    ewmh_update_number_of_desktops();
+    ewmh_update_desktop_names();
+    put_status();
+}
+
+void swap_desktops(monitor_t *m, desktop_t *d1, desktop_t *d2)
+{
+    if (d1 == NULL || d2 == NULL || d1 == d2)
+        return;
+
+    if (m->desk_head == d1)
+        m->desk_head = d2;
+    else if (m->desk_head == d2)
+        m->desk_head = d1;
+    if (m->desk_tail == d1)
+        m->desk_tail = d2;
+    else if (m->desk_tail == d2)
+        m->desk_tail = d1;
+
+    desktop_t *p1 = d1->prev;
+    desktop_t *n1 = d1->next;
+    desktop_t *p2 = d2->prev;
+    desktop_t *n2 = d2->next;
+
+    if (p1 != NULL && p1 != d2)
+        p1->next = d2;
+    if (n1 != NULL && n1 != d2)
+        n1->prev = d2;
+    if (p2 != NULL && p2 != d1)
+        p2->next = d1;
+    if (n2 != NULL && n2 != d1)
+        n2->prev = d1;
+
+    d1->prev = p2 == d1 ? d2 : p2;
+    d1->next = n2 == d1 ? d2 : n2;
+    d2->prev = p1 == d2 ? d1 : p1;
+    d2->next = n1 == d2 ? d1 : n1;
+
+    ewmh_update_wm_desktops();
+    ewmh_update_desktop_names();
+    ewmh_update_current_desktop();
+    put_status();
+}
+
+void show_desktop(desktop_t *d)
+{
+    if (!visible)
+        return;
+    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+        window_show(n->client->window);
+}
+
+void hide_desktop(desktop_t *d)
+{
+    if (!visible)
+        return;
+    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+        window_hide(n->client->window);
+}
diff --git a/desktop.h b/desktop.h
new file mode 100644 (file)
index 0000000..47e40fc
--- /dev/null
+++ b/desktop.h
@@ -0,0 +1,18 @@
+#ifndef _DESKTOP_H
+#define _DESKTOP_H
+
+#define DEFAULT_DESK_NAME    "Desktop"
+#define WINDOW_GAP           6
+
+desktop_t *make_desktop(const char *);
+void insert_desktop(monitor_t *, desktop_t *);
+void add_desktop(monitor_t *, desktop_t *);
+void empty_desktop(desktop_t *);
+void unlink_desktop(monitor_t *, desktop_t *);
+void remove_desktop(monitor_t *, desktop_t *);
+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 *);
+
+#endif
index 307861c6a717a862fa9c8a57d5d09280f58d2542..ec2794f30585db81f7845097739eddb82f0344cd 100644 (file)
--- a/events.c
+++ b/events.c
@@ -6,6 +6,7 @@
 #include <xcb/xcb_event.h>
 #include <xcb/xcb_icccm.h>
 #include "types.h"
+#include "monitor.h"
 #include "bspwm.h"
 #include "settings.h"
 #include "helpers.h"
diff --git a/history.c b/history.c
new file mode 100644 (file)
index 0000000..6334a67
--- /dev/null
+++ b/history.c
@@ -0,0 +1,120 @@
+#include <stdlib.h>
+#include "types.h"
+#include "query.h"
+#include "history.h"
+
+focus_history_t *make_focus_history(void)
+{
+    focus_history_t *f = malloc(sizeof(focus_history_t));
+    f->head = f->tail = NULL;
+    return f;
+}
+
+node_list_t *make_node_list(void)
+{
+    node_list_t *n = malloc(sizeof(node_list_t));
+    n->node = NULL;
+    n->prev = n->next = NULL;
+    n->latest = true;
+    return n;
+}
+
+void history_add(focus_history_t *f, node_t *n)
+{
+    node_list_t *a = make_node_list();
+    a->node = n;
+    if (f->head == NULL) {
+        f->head = f->tail = a;
+    } else if (f->head->node != n) {
+        for (node_list_t *b = f->head; b != NULL; b = b->next)
+            if (b->node == n)
+                b->latest = false;
+        f->head->prev = a;
+        a->next = f->head;
+        f->head = a;
+    } else {
+        free(a);
+    }
+}
+
+void history_remove(focus_history_t *f, node_t *n)
+{
+    /* in order to maintain the `latest` node list state,
+       we remove node lists from head to tail */
+    node_list_t *b = f->head;
+    while (b != NULL) {
+        if (b->node == n) {
+            node_list_t *a = b->prev;
+            node_list_t *c = b->next;
+            if (a != NULL) {
+                /* remove duplicate entries */
+                while (c != NULL && c->node == a->node) {
+                    node_list_t *d = c->next;
+                    if (f->tail == c)
+                        f->tail = f->head;
+                    free(c);
+                    c = d;
+                }
+                a->next = c;
+            }
+            if (c != NULL)
+                c->prev = a;
+            if (f->head == b)
+                f->head = c;
+            if (f->tail == b)
+                f->tail = a;
+            free(b);
+            b = c;
+        } else {
+            b = b->next;
+        }
+    }
+}
+
+void empty_history(focus_history_t *f)
+{
+    node_list_t *a = f->head;
+    while (a != NULL) {
+        node_list_t *b = a->next;
+        free(a);
+        a = b;
+    }
+    f->head = f->tail = NULL;
+}
+
+node_t *history_get(focus_history_t *f, int i)
+{
+    node_list_t *a = f->head;
+    while (a != NULL && i > 0) {
+        a = a->next;
+        i--;
+    }
+    if (a == NULL)
+        return NULL;
+    else
+        return a->node;
+}
+
+node_t *history_last(focus_history_t *f, node_t *n, client_select_t sel)
+{
+    for (node_list_t *a = f->head; a != NULL; a = a->next) {
+        if (!a->latest || a->node == n || !node_matches(n, a->node, sel))
+            continue;
+        return a->node;
+    }
+    return NULL;
+}
+
+int history_rank(focus_history_t *f, node_t *n)
+{
+    int i = 0;
+    node_list_t *a = f->head;
+    while (a != NULL && (!a->latest || a->node != n)) {
+        a = a->next;
+        i++;
+    }
+    if (a == NULL)
+        return -1;
+    else
+        return i;
+}
diff --git a/history.h b/history.h
new file mode 100644 (file)
index 0000000..00da5b1
--- /dev/null
+++ b/history.h
@@ -0,0 +1,15 @@
+#ifndef _HISTORY_H
+#define _HISTORY_H
+
+#include "types.h"
+
+focus_history_t *make_focus_history(void);
+node_list_t *make_node_list(void);
+void history_add(focus_history_t *, node_t *);
+void history_remove(focus_history_t *, node_t *);
+void empty_history(focus_history_t *);
+node_t *history_get(focus_history_t *, int);
+node_t *history_last(focus_history_t *, node_t *, client_select_t);
+int history_rank(focus_history_t *, node_t *);
+
+#endif
index 38b1ee7190cca6dce98b1bcda0ea4feecb7f3b85..2370dbda52c72baf63da5e1b82c0e7176ac60784 100644 (file)
@@ -8,6 +8,8 @@
 #include "restore.h"
 #include "common.h"
 #include "types.h"
+#include "desktop.h"
+#include "monitor.h"
 #include "bspwm.h"
 #include "ewmh.h"
 #include "helpers.h"
@@ -286,7 +288,7 @@ bool cmd_desktop(char **args, int num)
             if (trg.desktop->root == NULL
                     && trg.monitor->desk_head != trg.monitor->desk_tail) {
                 remove_desktop(trg.monitor, trg.desktop);
-                desktop_show(trg.monitor->desk);
+                show_desktop(trg.monitor->desk);
                 update_current();
                 return true;
             } else {
@@ -384,7 +386,7 @@ bool cmd_monitor(char **args, int num)
                 coordinates_t dst;
                 if (locate_desktop(*args, &dst) && dst.monitor->desk_head != dst.monitor->desk_tail && dst.desktop->root == NULL) {
                     remove_desktop(dst.monitor, dst.desktop);
-                    desktop_show(dst.monitor->desk);
+                    show_desktop(dst.monitor->desk);
                 }
                 num--, args++;
             }
diff --git a/monitor.c b/monitor.c
new file mode 100644 (file)
index 0000000..35d1e24
--- /dev/null
+++ b/monitor.c
@@ -0,0 +1,223 @@
+#include <stdlib.h>
+#include <string.h>
+#include "bspwm.h"
+#include "types.h"
+#include "desktop.h"
+#include "tree.h"
+#include "monitor.h"
+#include "window.h"
+#include "ewmh.h"
+
+monitor_t *make_monitor(xcb_rectangle_t rect)
+{
+    monitor_t *m = malloc(sizeof(monitor_t));
+    snprintf(m->name, sizeof(m->name), "%s%02d", DEFAULT_MON_NAME, ++monitor_uid);
+    m->prev = m->next = NULL;
+    m->desk = m->last_desk = NULL;
+    m->rectangle = rect;
+    m->top_padding = m->right_padding = m->bottom_padding = m->left_padding = 0;
+    m->wired = true;
+    return m;
+}
+
+monitor_t *find_monitor(char *name)
+{
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        if (streq(m->name, name))
+            return m;
+    return NULL;
+}
+
+monitor_t *get_monitor_by_id(xcb_randr_output_t id)
+{
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        if (m->id == id)
+            return m;
+    return NULL;
+}
+
+monitor_t *add_monitor(xcb_rectangle_t rect)
+{
+    monitor_t *m = make_monitor(rect);
+    if (mon == NULL) {
+        mon = m;
+        mon_head = m;
+        mon_tail = m;
+    } else {
+        mon_tail->next = m;
+        m->prev = mon_tail;
+        mon_tail = m;
+    }
+    num_monitors++;
+    return m;
+}
+
+void remove_monitor(monitor_t *m)
+{
+    while (m->desk_head != NULL)
+        remove_desktop(m, m->desk_head);
+    monitor_t *prev = m->prev;
+    monitor_t *next = m->next;
+    if (prev != NULL)
+        prev->next = next;
+    if (next != NULL)
+        next->prev = prev;
+    if (mon_head == m)
+        mon_head = next;
+    if (mon_tail == m)
+        mon_tail = prev;
+    if (last_mon == m)
+        last_mon = NULL;
+    if (pri_mon == m)
+        pri_mon = NULL;
+    if (mon == m) {
+        monitor_t *mm = (last_mon == NULL ? (prev == NULL ? next : prev) : last_mon);
+        if (mm != NULL) {
+            focus_node(mm, mm->desk, mm->desk->focus);
+            last_mon = NULL;
+        } else {
+            mon = NULL;
+        }
+    }
+    free(m);
+    num_monitors--;
+    put_status();
+}
+
+void merge_monitors(monitor_t *ms, monitor_t *md)
+{
+    PRINTF("merge %s into %s\n", ms->name, md->name);
+
+    desktop_t *d = ms->desk_head;
+    while (d != NULL) {
+        desktop_t *next = d->next;
+        transfer_desktop(ms, md, d);
+        d = next;
+    }
+}
+
+void swap_monitors(monitor_t *m1, monitor_t *m2)
+{
+    if (m1 == NULL || m2 == NULL || m1 == m2)
+        return;
+
+    if (mon_head == m1)
+        mon_head = m2;
+    else if (mon_head == m2)
+        mon_head = m1;
+    if (mon_tail == m1)
+        mon_tail = m2;
+    else if (mon_tail == m2)
+        mon_tail = m1;
+
+    monitor_t *p1 = m1->prev;
+    monitor_t *n1 = m1->next;
+    monitor_t *p2 = m2->prev;
+    monitor_t *n2 = m2->next;
+
+    if (p1 != NULL && p1 != m2)
+        p1->next = m2;
+    if (n1 != NULL && n1 != m2)
+        n1->prev = m2;
+    if (p2 != NULL && p2 != m1)
+        p2->next = m1;
+    if (n2 != NULL && n2 != m1)
+        n2->prev = m1;
+
+    m1->prev = p2 == m1 ? m2 : p2;
+    m1->next = n2 == m1 ? m2 : n2;
+    m2->prev = p1 == m2 ? m1 : p1;
+    m2->next = n1 == m2 ? m1 : n1;
+
+    ewmh_update_wm_desktops();
+    ewmh_update_desktop_names();
+    ewmh_update_current_desktop();
+    put_status();
+}
+
+bool import_monitors(void)
+{
+    PUTS("import monitors");
+    xcb_randr_get_screen_resources_current_reply_t *sres = xcb_randr_get_screen_resources_current_reply(dpy, xcb_randr_get_screen_resources_current(dpy, root), NULL);
+    if (sres == NULL)
+        return false;
+
+    int len = xcb_randr_get_screen_resources_current_outputs_length(sres);
+    xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(sres);
+
+    xcb_randr_get_output_info_cookie_t cookies[len];
+    for (int i = 0; i < len; i++)
+        cookies[i] = xcb_randr_get_output_info(dpy, outputs[i], XCB_CURRENT_TIME);
+
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        m->wired = false;
+
+    monitor_t *mm = NULL;
+    unsigned int num = 0;
+
+    for (int i = 0; i < len; i++) {
+        xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(dpy, cookies[i], NULL);
+        if (info != NULL && info->crtc != XCB_NONE) {
+
+            xcb_randr_get_crtc_info_reply_t *cir = xcb_randr_get_crtc_info_reply(dpy, xcb_randr_get_crtc_info(dpy, info->crtc, XCB_CURRENT_TIME), NULL);
+            if (cir != NULL) {
+                xcb_rectangle_t rect = (xcb_rectangle_t) {cir->x, cir->y, cir->width, cir->height};
+                mm = get_monitor_by_id(outputs[i]);
+                if (mm != NULL) {
+                    mm->rectangle = rect;
+                    for (desktop_t *d = mm->desk_head; d != NULL; d = d->next)
+                        for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+                            fit_monitor(mm, n->client);
+                    arrange(mm, mm->desk);
+                    mm->wired = true;
+                    PRINTF("update monitor %s (0x%X)\n", mm->name, mm->id);
+                } else {
+                    mm = add_monitor(rect);
+                    char *name = (char *)xcb_randr_get_output_info_name(info);
+                    size_t name_len = MIN(sizeof(mm->name), (size_t)xcb_randr_get_output_info_name_length(info));
+                    strncpy(mm->name, name, name_len);
+                    mm->name[name_len] = '\0';
+                    mm->id = outputs[i];
+                    PRINTF("add monitor %s (0x%X)\n", mm->name, mm->id);
+                }
+                num++;
+            }
+            free(cir);
+        }
+        free(info);
+    }
+
+    /* initially focus the primary monitor and add the first desktop to it */
+    xcb_randr_get_output_primary_reply_t *gpo = xcb_randr_get_output_primary_reply(dpy, xcb_randr_get_output_primary(dpy, root), NULL);
+    if (gpo != NULL) {
+        pri_mon = get_monitor_by_id(gpo->output);
+        if (!running && pri_mon != NULL) {
+            if (mon != pri_mon)
+                mon = pri_mon;
+            add_desktop(pri_mon, make_desktop(NULL));
+            ewmh_update_current_desktop();
+        }
+    }
+    free(gpo);
+
+    /* add one desktop to each new monitor */
+    for (monitor_t *m = mon_head; m != NULL; m = m->next)
+        if (m->desk == NULL && (running || pri_mon == NULL || m != pri_mon))
+            add_desktop(m, make_desktop(NULL));
+
+    /* merge and remove disconnected monitors */
+    monitor_t *m = mon_head;
+    while (m != NULL) {
+        monitor_t *next = m->next;
+        if (!m->wired) {
+            PRINTF("remove monitor %s (0x%X)\n", m->name, m->id);
+            merge_monitors(m, mm);
+            remove_monitor(m);
+        }
+        m = next;
+    }
+
+    free(sres);
+    update_motion_recorder();
+    return (num_monitors > 0);
+}
diff --git a/monitor.h b/monitor.h
new file mode 100644 (file)
index 0000000..e2a9d3a
--- /dev/null
+++ b/monitor.h
@@ -0,0 +1,15 @@
+#ifndef _MONITOR_H
+#define _MONITOR_H
+
+#define DEFAULT_MON_NAME     "Monitor"
+
+monitor_t *make_monitor(xcb_rectangle_t);
+monitor_t *find_monitor(char *);
+monitor_t *get_monitor_by_id(xcb_randr_output_t);
+monitor_t *add_monitor(xcb_rectangle_t);
+void remove_monitor(monitor_t *);
+void merge_monitors(monitor_t *, monitor_t *);
+void swap_monitors(monitor_t *, monitor_t *);
+bool import_monitors(void);
+
+#endif
diff --git a/query.c b/query.c
index a25e53f7faddad3d773d6c61c49c2950470f483a..15eb548e48eee57d72fe2980c612121e935ce8a7 100644 (file)
--- a/query.c
+++ b/query.c
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include "bspwm.h"
 #include "tree.h"
+#include "history.h"
 #include "settings.h"
 #include "messages.h"
 #include "query.h"
@@ -331,3 +332,58 @@ bool monitor_from_index(int i, coordinates_t *loc)
         }
     return false;
 }
+
+/**
+ * Check if the specified node matches the selection criteria.
+ *
+ * Arguments:
+ *  node_t *c           - the active node
+ *  node_t *t           - the node to test
+ *  client_sel_t sel    - the selection criteria
+ *
+ * Returns true if the node matches.
+ **/
+bool node_matches(node_t *c, node_t *t, client_select_t sel)
+{
+    if (sel.type != CLIENT_TYPE_ALL &&
+            is_tiled(t->client)
+            ? sel.type == CLIENT_TYPE_FLOATING
+            : sel.type == CLIENT_TYPE_TILED
+       ) return false;
+
+    if (sel.class != CLIENT_CLASS_ALL &&
+            streq(c->client->class_name, t->client->class_name)
+            ? sel.class == CLIENT_CLASS_DIFFER
+            : sel.class == CLIENT_CLASS_EQUAL
+       ) return false;
+
+    if (sel.mode != CLIENT_MODE_ALL &&
+            t->split_mode == MODE_MANUAL
+            ? sel.mode == CLIENT_MODE_AUTOMATIC
+            : sel.mode == CLIENT_MODE_MANUAL)
+        return false;
+
+    if (sel.urgency != CLIENT_URGENCY_ALL &&
+            t->client->urgent
+            ? sel.urgency == CLIENT_URGENCY_OFF
+            : sel.urgency == CLIENT_URGENCY_ON
+       ) return false;
+
+    return true;
+}
+
+bool desktop_matches(desktop_t *t, desktop_select_t sel) {
+    if (sel.status != DESKTOP_STATUS_ALL &&
+            t->root == NULL
+            ? sel.status == DESKTOP_STATUS_OCCUPIED
+            : sel.status == DESKTOP_STATUS_FREE
+       ) return false;
+
+    if (sel.urgency != DESKTOP_URGENCY_ALL &&
+            is_urgent(t)
+            ? sel.urgency == DESKTOP_URGENCY_OFF
+            : sel.urgency == DESKTOP_URGENCY_ON
+       ) return false;
+
+    return true;
+}
diff --git a/query.h b/query.h
index 1c345e11e4c1848f1531dc984b5202c120a0482a..7ad2afe601c51c467582f487aae37f56d3ede102 100644 (file)
--- a/query.h
+++ b/query.h
@@ -22,5 +22,7 @@ bool desktop_from_desc(char *, coordinates_t *, coordinates_t *);
 bool monitor_from_desc(char *, coordinates_t *, coordinates_t *);
 bool desktop_from_index(int, coordinates_t *);
 bool monitor_from_index(int, coordinates_t *);
+bool node_matches(node_t *, node_t *, client_select_t);
+bool desktop_matches(desktop_t *, desktop_select_t);
 
 #endif
index a7f136e9dd7a8c3a98b70b96b554dbfc65d3c127..b007e163ea13c362f802517e3a9e81774dab4cbc 100644 (file)
--- a/restore.c
+++ b/restore.c
@@ -1,6 +1,9 @@
 #include <ctype.h>
 #include <string.h>
 #include "types.h"
+#include "desktop.h"
+#include "monitor.h"
+#include "history.h"
 #include "tree.h"
 #include "settings.h"
 #include "ewmh.h"
diff --git a/rules.c b/rules.c
index 99b2a3f96d512630d5a6800b8677e1e0494d47e3..5fb776b0d86dfac0edfca5d4ce7cdf2fb47bf31d 100644 (file)
--- a/rules.c
+++ b/rules.c
@@ -9,6 +9,21 @@
 #include "rules.h"
 #include "query.h"
 
+rule_t *make_rule(void)
+{
+    rule_t *r = malloc(sizeof(rule_t));
+    r->uid = ++rule_uid;
+    r->effect.floating = false;
+    r->effect.follow = false;
+    r->effect.focus = false;
+    r->effect.unmanage = false;
+    r->one_shot = false;
+    r->effect.desc[0] = '\0';
+    r->prev = NULL;
+    r->next = NULL;
+    return r;
+}
+
 void add_rule(rule_t *r)
 {
     if (rule_head == NULL) {
diff --git a/rules.h b/rules.h
index ff6ec1b957726ab29d715fd8b54ea98fddd6e59c..286c1259f156604fadaa618fda549f365091decc 100644 (file)
--- a/rules.h
+++ b/rules.h
@@ -3,6 +3,7 @@
 
 #define MATCH_ALL  "*"
 
+rule_t *make_rule(void);
 void add_rule(rule_t *);
 void remove_rule(rule_t *);
 void remove_rule_by_uid(unsigned int);
diff --git a/tree.c b/tree.c
index d57c24f5c972f0db972aa159e2ba4a31e6ee9ce4..22d5cfb5264d4928f8c6bdd28036f561207be051 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -6,10 +6,43 @@
 #include "helpers.h"
 #include "window.h"
 #include "types.h"
+#include "desktop.h"
+#include "history.h"
+#include "query.h"
 #include "bspwm.h"
 #include "ewmh.h"
 #include "tree.h"
 
+node_t *make_node(void)
+{
+    node_t *n = malloc(sizeof(node_t));
+    n->parent = n->first_child = n->second_child = NULL;
+    n->split_ratio = split_ratio;
+    n->split_mode = MODE_AUTOMATIC;
+    n->split_type = TYPE_VERTICAL;
+    n->birth_rotation = 0;
+    n->client = NULL;
+    n->vacant = false;
+    return n;
+}
+
+client_t *make_client(xcb_window_t win)
+{
+    client_t *c = malloc(sizeof(client_t));
+    strncpy(c->class_name, MISSING_VALUE, sizeof(c->class_name));
+    c->border_width = border_width;
+    c->window = win;
+    c->floating = c->transient = c->fullscreen = c->locked = c->urgent = false;
+    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))
+            c->icccm_focus = true;
+        xcb_icccm_get_wm_protocols_reply_wipe(&protocols);
+    }
+    return c;
+}
+
 bool is_leaf(node_t *n)
 {
     return (n != NULL && n->first_child == NULL && n->second_child == NULL);
@@ -39,61 +72,6 @@ bool is_second_child(node_t *n)
     return (n != NULL && n->parent != NULL && n->parent->second_child == n);
 }
 
-/**
- * Check if the specified node matches the selection criteria.
- *
- * Arguments:
- *  node_t *c           - the active node
- *  node_t *t           - the node to test
- *  client_sel_t sel    - the selection criteria
- *
- * Returns true if the node matches.
- **/
-bool node_matches(node_t *c, node_t *t, client_select_t sel)
-{
-    if (sel.type != CLIENT_TYPE_ALL &&
-            is_tiled(t->client)
-            ? sel.type == CLIENT_TYPE_FLOATING
-            : sel.type == CLIENT_TYPE_TILED
-       ) return false;
-
-    if (sel.class != CLIENT_CLASS_ALL &&
-            streq(c->client->class_name, t->client->class_name)
-            ? sel.class == CLIENT_CLASS_DIFFER
-            : sel.class == CLIENT_CLASS_EQUAL
-       ) return false;
-
-    if (sel.mode != CLIENT_MODE_ALL &&
-            t->split_mode == MODE_MANUAL
-            ? sel.mode == CLIENT_MODE_AUTOMATIC
-            : sel.mode == CLIENT_MODE_MANUAL)
-        return false;
-
-    if (sel.urgency != CLIENT_URGENCY_ALL &&
-            t->client->urgent
-            ? sel.urgency == CLIENT_URGENCY_OFF
-            : sel.urgency == CLIENT_URGENCY_ON
-       ) return false;
-
-    return true;
-}
-
-bool desktop_matches(desktop_t *t, desktop_select_t sel) {
-    if (sel.status != DESKTOP_STATUS_ALL &&
-            t->root == NULL
-            ? sel.status == DESKTOP_STATUS_OCCUPIED
-            : sel.status == DESKTOP_STATUS_FREE
-       ) return false;
-
-    if (sel.urgency != DESKTOP_URGENCY_ALL &&
-            is_urgent(t)
-            ? sel.urgency == DESKTOP_URGENCY_OFF
-            : sel.urgency == DESKTOP_URGENCY_ON
-       ) return false;
-
-    return true;
-}
-
 bool is_urgent(desktop_t *d)
 {
     for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
@@ -954,8 +932,8 @@ void select_desktop(monitor_t *m, desktop_t *d)
 
     PRINTF("select desktop %s\n", d->name);
 
-    desktop_show(d);
-    desktop_hide(mon->desk);
+    show_desktop(d);
+    hide_desktop(mon->desk);
 
     mon->last_desk = mon->desk;
     mon->desk = d;
diff --git a/tree.h b/tree.h
index 92fd06d0a0b63e2e21e38b02a88d9448f7c08ebb..3d7a6d53cfb7e9fe3732fb84e61ab8260cf4cdf4 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -3,8 +3,8 @@
 
 #define GROWTH_FACTOR  1.1
 
-bool node_matches(node_t *, node_t *, client_select_t);
-bool desktop_matches(desktop_t *, desktop_select_t);
+node_t *make_node(void);
+client_t *make_client(xcb_window_t);
 void arrange(monitor_t *, desktop_t *);
 void apply_layout(monitor_t *, desktop_t *, node_t *, xcb_rectangle_t, xcb_rectangle_t);
 void focus_node(monitor_t *, desktop_t *, node_t *);
diff --git a/types.c b/types.c
deleted file mode 100644 (file)
index 96a3891..0000000
--- a/types.c
+++ /dev/null
@@ -1,456 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <xcb/xcb.h>
-#include <xcb/xcb_event.h>
-#include "bspwm.h"
-#include "window.h"
-#include "rules.h"
-#include "ewmh.h"
-#include "settings.h"
-#include "types.h"
-#include "tree.h"
-
-node_t *make_node(void)
-{
-    node_t *n = malloc(sizeof(node_t));
-    n->parent = n->first_child = n->second_child = NULL;
-    n->split_ratio = split_ratio;
-    n->split_mode = MODE_AUTOMATIC;
-    n->split_type = TYPE_VERTICAL;
-    n->birth_rotation = 0;
-    n->client = NULL;
-    n->vacant = false;
-    return n;
-}
-
-monitor_t *make_monitor(xcb_rectangle_t rect)
-{
-    monitor_t *m = malloc(sizeof(monitor_t));
-    snprintf(m->name, sizeof(m->name), "%s%02d", DEFAULT_MON_NAME, ++monitor_uid);
-    m->prev = m->next = NULL;
-    m->desk = m->last_desk = NULL;
-    m->rectangle = rect;
-    m->top_padding = m->right_padding = m->bottom_padding = m->left_padding = 0;
-    m->wired = true;
-    return m;
-}
-
-monitor_t *find_monitor(char *name)
-{
-    for (monitor_t *m = mon_head; m != NULL; m = m->next)
-        if (streq(m->name, name))
-            return m;
-    return NULL;
-}
-
-monitor_t *get_monitor_by_id(xcb_randr_output_t id)
-{
-    for (monitor_t *m = mon_head; m != NULL; m = m->next)
-        if (m->id == id)
-            return m;
-    return NULL;
-}
-
-monitor_t *add_monitor(xcb_rectangle_t rect)
-{
-    monitor_t *m = make_monitor(rect);
-    if (mon == NULL) {
-        mon = m;
-        mon_head = m;
-        mon_tail = m;
-    } else {
-        mon_tail->next = m;
-        m->prev = mon_tail;
-        mon_tail = m;
-    }
-    num_monitors++;
-    return m;
-}
-
-void remove_monitor(monitor_t *m)
-{
-    while (m->desk_head != NULL)
-        remove_desktop(m, m->desk_head);
-    monitor_t *prev = m->prev;
-    monitor_t *next = m->next;
-    if (prev != NULL)
-        prev->next = next;
-    if (next != NULL)
-        next->prev = prev;
-    if (mon_head == m)
-        mon_head = next;
-    if (mon_tail == m)
-        mon_tail = prev;
-    if (last_mon == m)
-        last_mon = NULL;
-    if (pri_mon == m)
-        pri_mon = NULL;
-    if (mon == m) {
-        monitor_t *mm = (last_mon == NULL ? (prev == NULL ? next : prev) : last_mon);
-        if (mm != NULL) {
-            focus_node(mm, mm->desk, mm->desk->focus);
-            last_mon = NULL;
-        } else {
-            mon = NULL;
-        }
-    }
-    free(m);
-    num_monitors--;
-    put_status();
-}
-
-void transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
-{
-    if (ms == md)
-        return;
-
-    desktop_t *dd = ms->desk;
-    unlink_desktop(ms, d);
-    insert_desktop(md, d);
-
-    if (d == dd) {
-        if (ms->desk != NULL)
-            desktop_show(ms->desk);
-        if (md->desk != d)
-            desktop_hide(d);
-    }
-
-    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
-        fit_monitor(md, n->client);
-    arrange(md, d);
-    if (d != dd && md->desk == d) {
-        desktop_show(d);
-    }
-
-    ewmh_update_wm_desktops();
-    ewmh_update_desktop_names();
-    ewmh_update_current_desktop();
-    put_status();
-}
-
-void merge_monitors(monitor_t *ms, monitor_t *md)
-{
-    PRINTF("merge %s into %s\n", ms->name, md->name);
-
-    desktop_t *d = ms->desk_head;
-    while (d != NULL) {
-        desktop_t *next = d->next;
-        transfer_desktop(ms, md, d);
-        d = next;
-    }
-}
-
-void swap_monitors(monitor_t *m1, monitor_t *m2)
-{
-    if (m1 == NULL || m2 == NULL || m1 == m2)
-        return;
-
-    if (mon_head == m1)
-        mon_head = m2;
-    else if (mon_head == m2)
-        mon_head = m1;
-    if (mon_tail == m1)
-        mon_tail = m2;
-    else if (mon_tail == m2)
-        mon_tail = m1;
-
-    monitor_t *p1 = m1->prev;
-    monitor_t *n1 = m1->next;
-    monitor_t *p2 = m2->prev;
-    monitor_t *n2 = m2->next;
-
-    if (p1 != NULL && p1 != m2)
-        p1->next = m2;
-    if (n1 != NULL && n1 != m2)
-        n1->prev = m2;
-    if (p2 != NULL && p2 != m1)
-        p2->next = m1;
-    if (n2 != NULL && n2 != m1)
-        n2->prev = m1;
-
-    m1->prev = p2 == m1 ? m2 : p2;
-    m1->next = n2 == m1 ? m2 : n2;
-    m2->prev = p1 == m2 ? m1 : p1;
-    m2->next = n1 == m2 ? m1 : n1;
-
-    ewmh_update_wm_desktops();
-    ewmh_update_desktop_names();
-    ewmh_update_current_desktop();
-    put_status();
-}
-
-desktop_t *make_desktop(const char *name)
-{
-    desktop_t *d = malloc(sizeof(desktop_t));
-    if (name == NULL)
-        snprintf(d->name, sizeof(d->name), "%s%02d", DEFAULT_DESK_NAME, ++desktop_uid);
-    else
-        strncpy(d->name, name, sizeof(d->name));
-    d->layout = LAYOUT_TILED;
-    d->prev = d->next = NULL;
-    d->root = d->focus = NULL;
-    d->history = make_focus_history();
-    d->window_gap = WINDOW_GAP;
-    return d;
-}
-
-void insert_desktop(monitor_t *m, desktop_t *d)
-{
-    if (m->desk == NULL) {
-        m->desk = d;
-        m->desk_head = d;
-        m->desk_tail = d;
-    } else {
-        m->desk_tail->next = d;
-        d->prev = m->desk_tail;
-        m->desk_tail = d;
-    }
-}
-
-void add_desktop(monitor_t *m, desktop_t *d)
-{
-    PRINTF("add desktop %s\n", d->name);
-
-    insert_desktop(m, d);
-    num_desktops++;
-    ewmh_update_number_of_desktops();
-    ewmh_update_desktop_names();
-    put_status();
-}
-
-void empty_desktop(desktop_t *d)
-{
-    destroy_tree(d->root);
-    d->root = d->focus = NULL;
-    empty_history(d->history);
-}
-
-void unlink_desktop(monitor_t *m, desktop_t *d)
-{
-    desktop_t *prev = d->prev;
-    desktop_t *next = d->next;
-    if (prev != NULL)
-        prev->next = next;
-    if (next != NULL)
-        next->prev = prev;
-    if (m->desk_head == d)
-        m->desk_head = next;
-    if (m->desk_tail == d)
-        m->desk_tail = prev;
-    if (m->last_desk == d)
-        m->last_desk = NULL;
-    if (m->desk == d)
-        m->desk = (m->last_desk == NULL ? (prev == NULL ? next : prev) : m->last_desk);
-    d->prev = d->next = NULL;
-}
-
-void remove_desktop(monitor_t *m, desktop_t *d)
-{
-    PRINTF("remove desktop %s\n", d->name);
-
-    unlink_desktop(m, d);
-    empty_desktop(d);
-    free(d);
-    num_desktops--;
-    ewmh_update_number_of_desktops();
-    ewmh_update_desktop_names();
-    put_status();
-}
-
-void swap_desktops(monitor_t *m, desktop_t *d1, desktop_t *d2)
-{
-    if (d1 == NULL || d2 == NULL || d1 == d2)
-        return;
-
-    if (m->desk_head == d1)
-        m->desk_head = d2;
-    else if (m->desk_head == d2)
-        m->desk_head = d1;
-    if (m->desk_tail == d1)
-        m->desk_tail = d2;
-    else if (m->desk_tail == d2)
-        m->desk_tail = d1;
-
-    desktop_t *p1 = d1->prev;
-    desktop_t *n1 = d1->next;
-    desktop_t *p2 = d2->prev;
-    desktop_t *n2 = d2->next;
-
-    if (p1 != NULL && p1 != d2)
-        p1->next = d2;
-    if (n1 != NULL && n1 != d2)
-        n1->prev = d2;
-    if (p2 != NULL && p2 != d1)
-        p2->next = d1;
-    if (n2 != NULL && n2 != d1)
-        n2->prev = d1;
-
-    d1->prev = p2 == d1 ? d2 : p2;
-    d1->next = n2 == d1 ? d2 : n2;
-    d2->prev = p1 == d2 ? d1 : p1;
-    d2->next = n1 == d2 ? d1 : n1;
-
-    ewmh_update_wm_desktops();
-    ewmh_update_desktop_names();
-    ewmh_update_current_desktop();
-    put_status();
-}
-
-client_t *make_client(xcb_window_t win)
-{
-    client_t *c = malloc(sizeof(client_t));
-    strncpy(c->class_name, MISSING_VALUE, sizeof(c->class_name));
-    c->border_width = border_width;
-    c->window = win;
-    c->floating = c->transient = c->fullscreen = c->locked = c->urgent = false;
-    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))
-            c->icccm_focus = true;
-        xcb_icccm_get_wm_protocols_reply_wipe(&protocols);
-    }
-    return c;
-}
-
-rule_t *make_rule(void)
-{
-    rule_t *r = malloc(sizeof(rule_t));
-    r->uid = ++rule_uid;
-    r->effect.floating = false;
-    r->effect.follow = false;
-    r->effect.focus = false;
-    r->effect.unmanage = false;
-    r->one_shot = false;
-    r->effect.desc[0] = '\0';
-    r->prev = NULL;
-    r->next = NULL;
-    return r;
-}
-
-pointer_state_t *make_pointer_state(void)
-{
-    pointer_state_t *p = malloc(sizeof(pointer_state_t));
-    p->monitor = NULL;
-    p->desktop = NULL;
-    p->node = p->vertical_fence = p->horizontal_fence = NULL;
-    p->client = NULL;
-    p->window = XCB_NONE;
-    return p;
-}
-
-focus_history_t *make_focus_history(void)
-{
-    focus_history_t *f = malloc(sizeof(focus_history_t));
-    f->head = f->tail = NULL;
-    return f;
-}
-
-node_list_t *make_node_list(void)
-{
-    node_list_t *n = malloc(sizeof(node_list_t));
-    n->node = NULL;
-    n->prev = n->next = NULL;
-    n->latest = true;
-    return n;
-}
-
-void history_add(focus_history_t *f, node_t *n)
-{
-    node_list_t *a = make_node_list();
-    a->node = n;
-    if (f->head == NULL) {
-        f->head = f->tail = a;
-    } else if (f->head->node != n) {
-        for (node_list_t *b = f->head; b != NULL; b = b->next)
-            if (b->node == n)
-                b->latest = false;
-        f->head->prev = a;
-        a->next = f->head;
-        f->head = a;
-    } else {
-        free(a);
-    }
-}
-
-void history_remove(focus_history_t *f, node_t *n)
-{
-    /* in order to maintain the `latest` node list state,
-       we remove node lists from head to tail */
-    node_list_t *b = f->head;
-    while (b != NULL) {
-        if (b->node == n) {
-            node_list_t *a = b->prev;
-            node_list_t *c = b->next;
-            if (a != NULL) {
-                /* remove duplicate entries */
-                while (c != NULL && c->node == a->node) {
-                    node_list_t *d = c->next;
-                    if (f->tail == c)
-                        f->tail = f->head;
-                    free(c);
-                    c = d;
-                }
-                a->next = c;
-            }
-            if (c != NULL)
-                c->prev = a;
-            if (f->head == b)
-                f->head = c;
-            if (f->tail == b)
-                f->tail = a;
-            free(b);
-            b = c;
-        } else {
-            b = b->next;
-        }
-    }
-}
-
-void empty_history(focus_history_t *f)
-{
-    node_list_t *a = f->head;
-    while (a != NULL) {
-        node_list_t *b = a->next;
-        free(a);
-        a = b;
-    }
-    f->head = f->tail = NULL;
-}
-
-node_t *history_get(focus_history_t *f, int i)
-{
-    node_list_t *a = f->head;
-    while (a != NULL && i > 0) {
-        a = a->next;
-        i--;
-    }
-    if (a == NULL)
-        return NULL;
-    else
-        return a->node;
-}
-
-node_t *history_last(focus_history_t *f, node_t *n, client_select_t sel)
-{
-    for (node_list_t *a = f->head; a != NULL; a = a->next) {
-        if (!a->latest || a->node == n || !node_matches(n, a->node, sel))
-            continue;
-        return a->node;
-    }
-    return NULL;
-}
-
-int history_rank(focus_history_t *f, node_t *n)
-{
-    int i = 0;
-    node_list_t *a = f->head;
-    while (a != NULL && (!a->latest || a->node != n)) {
-        a = a->next;
-        i++;
-    }
-    if (a == NULL)
-        return -1;
-    else
-        return i;
-}
diff --git a/types.h b/types.h
index bb1e21a8926e34d38f7dc448fea629dc3320634a..77df40903bdb7d6756ea9ada4f3ed76d74cc7fdf 100644 (file)
--- a/types.h
+++ b/types.h
@@ -7,10 +7,7 @@
 #include <xcb/xcb_event.h>
 #include "helpers.h"
 
-#define DEFAULT_DESK_NAME    "Desktop"
-#define DEFAULT_MON_NAME     "Monitor"
 #define MISSING_VALUE        "N/A"
-#define WINDOW_GAP           6
 
 typedef enum {
     TYPE_HORIZONTAL,
@@ -22,11 +19,6 @@ typedef enum {
     MODE_MANUAL
 } split_mode_t;
 
-typedef enum {
-    LAYOUT_TILED,
-    LAYOUT_MONOCLE
-} layout_t;
-
 typedef enum {
     MOVE_PULL,
     MOVE_PUSH
@@ -74,23 +66,6 @@ typedef enum {
     ALTER_SET
 } state_alter_t;
 
-typedef enum {
-    DESKTOP_STATUS_ALL,
-    DESKTOP_STATUS_FREE,
-    DESKTOP_STATUS_OCCUPIED
-} desktop_status_t;
-
-typedef enum {
-    DESKTOP_URGENCY_ALL,
-    DESKTOP_URGENCY_ON,
-    DESKTOP_URGENCY_OFF
-} desktop_urgency_t;
-
-typedef struct {
-    desktop_status_t status;
-    desktop_urgency_t urgency;
-} desktop_select_t;
-
 typedef enum {
     CYCLE_NEXT,
     CYCLE_PREV
@@ -101,11 +76,6 @@ typedef enum {
     CIRCULATE_BACKWARD
 } circulate_dir_t;
 
-typedef enum {
-    FLIP_HORIZONTAL,
-    FLIP_VERTICAL
-} flip_t;
-
 typedef enum {
     DIR_RIGHT,
     DIR_DOWN,
@@ -135,6 +105,33 @@ typedef enum {
     ACTION_RESIZE_CORNER
 } pointer_action_t;
 
+typedef enum {
+    LAYOUT_TILED,
+    LAYOUT_MONOCLE
+} layout_t;
+
+typedef enum {
+    FLIP_HORIZONTAL,
+    FLIP_VERTICAL
+} flip_t;
+
+typedef enum {
+    DESKTOP_STATUS_ALL,
+    DESKTOP_STATUS_FREE,
+    DESKTOP_STATUS_OCCUPIED
+} desktop_status_t;
+
+typedef enum {
+    DESKTOP_URGENCY_ALL,
+    DESKTOP_URGENCY_ON,
+    DESKTOP_URGENCY_OFF
+} desktop_urgency_t;
+
+typedef struct {
+    desktop_status_t status;
+    desktop_urgency_t urgency;
+} desktop_select_t;
+
 typedef struct {
     xcb_window_t window;
     char class_name[MAXLEN];
@@ -260,32 +257,4 @@ typedef struct {
     unsigned int distance;
 } fence_distance_t;
 
-node_t *make_node(void);
-monitor_t *make_monitor(xcb_rectangle_t);
-monitor_t *find_monitor(char *);
-monitor_t *get_monitor_by_id(xcb_randr_output_t);
-monitor_t *add_monitor(xcb_rectangle_t);
-void remove_monitor(monitor_t *);
-void merge_monitors(monitor_t *, monitor_t *);
-void swap_monitors(monitor_t *, monitor_t *);
-desktop_t *make_desktop(const char *);
-void insert_desktop(monitor_t *, desktop_t *);
-void add_desktop(monitor_t *, desktop_t *);
-void empty_desktop(desktop_t *);
-void unlink_desktop(monitor_t *, desktop_t *);
-void remove_desktop(monitor_t *, desktop_t *);
-void swap_desktops(monitor_t *, desktop_t *, desktop_t *);
-void transfer_desktop(monitor_t *, monitor_t *, desktop_t *);
-rule_t *make_rule(void);
-pointer_state_t *make_pointer_state(void);
-client_t *make_client(xcb_window_t);
-focus_history_t *make_focus_history(void);
-node_list_t *make_node_list(void);
-void history_add(focus_history_t *, node_t *);
-void history_remove(focus_history_t *, node_t *);
-void empty_history(focus_history_t *);
-node_t *history_get(focus_history_t *, int);
-node_t *history_last(focus_history_t *, node_t *, client_select_t);
-int history_rank(focus_history_t *, node_t *);
-
 #endif
index afd0fe1b1e00d1db1b82fe080cca3c149cdf7f36..61055d4eb111b709f4d23c29508c7466338292de 100644 (file)
--- a/window.c
+++ b/window.c
 #include "query.h"
 #include "window.h"
 
+pointer_state_t *make_pointer_state(void)
+{
+    pointer_state_t *p = malloc(sizeof(pointer_state_t));
+    p->monitor = NULL;
+    p->desktop = NULL;
+    p->node = p->vertical_fence = p->horizontal_fence = NULL;
+    p->client = NULL;
+    p->window = XCB_NONE;
+    return p;
+}
+
 void center(xcb_rectangle_t a, xcb_rectangle_t *b)
 {
     if (b->width < a.width)
@@ -561,22 +572,6 @@ void toggle_visibility(void)
         update_input_focus();
 }
 
-void desktop_show(desktop_t *d)
-{
-    if (!visible)
-        return;
-    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
-        window_show(n->client->window);
-}
-
-void desktop_hide(desktop_t *d)
-{
-    if (!visible)
-        return;
-    for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
-        window_hide(n->client->window);
-}
-
 void enable_motion_recorder(void)
 {
     PUTS("enable motion recorder");
index c79e97aab956a1dd8efae0bc0ebac450b03748f7..0413a33b7958b46d41f477e54ec12dcb0079b0f6 100644 (file)
--- a/window.h
+++ b/window.h
@@ -7,6 +7,7 @@
 #include <xcb/xcb_event.h>
 #include "types.h"
 
+pointer_state_t *make_pointer_state(void);
 void center(xcb_rectangle_t, xcb_rectangle_t *);
 bool contains(xcb_rectangle_t, xcb_rectangle_t);
 bool is_inside(monitor_t *, xcb_point_t);
@@ -45,8 +46,6 @@ void window_set_visibility(xcb_window_t, bool);
 void window_hide(xcb_window_t);
 void window_show(xcb_window_t);
 void toggle_visibility(void);
-void desktop_show(desktop_t *);
-void desktop_hide(desktop_t *);
 void enable_motion_recorder(void);
 void disable_motion_recorder(void);
 void update_motion_recorder(void);