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)
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
#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"
}
}
-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;
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);
--- /dev/null
+#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);
+}
--- /dev/null
+#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
#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"
--- /dev/null
+#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;
+}
--- /dev/null
+#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
#include "restore.h"
#include "common.h"
#include "types.h"
+#include "desktop.h"
+#include "monitor.h"
#include "bspwm.h"
#include "ewmh.h"
#include "helpers.h"
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 {
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++;
}
--- /dev/null
+#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);
+}
--- /dev/null
+#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
#include <stdio.h>
#include "bspwm.h"
#include "tree.h"
+#include "history.h"
#include "settings.h"
#include "messages.h"
#include "query.h"
}
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;
+}
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
#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"
#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) {
#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);
#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);
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))
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;
#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 *);
+++ /dev/null
-#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;
-}
#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,
MODE_MANUAL
} split_mode_t;
-typedef enum {
- LAYOUT_TILED,
- LAYOUT_MONOCLE
-} layout_t;
-
typedef enum {
MOVE_PULL,
MOVE_PUSH
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
CIRCULATE_BACKWARD
} circulate_dir_t;
-typedef enum {
- FLIP_HORIZONTAL,
- FLIP_VERTICAL
-} flip_t;
-
typedef enum {
DIR_RIGHT,
DIR_DOWN,
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];
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
#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)
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");
#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);
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);