]> git.lizzy.rs Git - bspwm.git/blobdiff - types.c
Remove `--float-upcoming` from `control`
[bspwm.git] / types.c
diff --git a/types.c b/types.c
index 202619389d7d01248bda352fa67a57a929d0f76b..96a389186019babb13baaced8cfca306392ac281 100644 (file)
--- a/types.c
+++ b/types.c
@@ -15,23 +15,21 @@ 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 = ROTATE_IDENTITY;
+    n->birth_rotation = 0;
     n->client = NULL;
     n->vacant = false;
     return n;
 }
 
-monitor_t *make_monitor(xcb_rectangle_t *rect)
+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;
-    if (rect != NULL)
-        m->rectangle = *rect;
-    else
-        warn("no rectangle was given for monitor '%s'\n", m->name);
+    m->rectangle = rect;
     m->top_padding = m->right_padding = m->bottom_padding = m->left_padding = 0;
     m->wired = true;
     return m;
@@ -40,7 +38,7 @@ monitor_t *make_monitor(xcb_rectangle_t *rect)
 monitor_t *find_monitor(char *name)
 {
     for (monitor_t *m = mon_head; m != NULL; m = m->next)
-        if (strcmp(m->name, name) == 0)
+        if (streq(m->name, name))
             return m;
     return NULL;
 }
@@ -53,7 +51,7 @@ monitor_t *get_monitor_by_id(xcb_randr_output_t id)
     return NULL;
 }
 
-monitor_t *add_monitor(xcb_rectangle_t *rect)
+monitor_t *add_monitor(xcb_rectangle_t rect)
 {
     monitor_t *m = make_monitor(rect);
     if (mon == NULL) {
@@ -85,26 +83,55 @@ void remove_monitor(monitor_t *m)
         mon_tail = prev;
     if (last_mon == m)
         last_mon = NULL;
-    if (mon == m)
-        mon = (last_mon == NULL ? mon_head : last_mon);
+    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 monitor %s into %s\n", ms->name, md->name);
+    PRINTF("merge %s into %s\n", ms->name, md->name);
 
-    if (visible) {
-        for (node_t *n = first_extrema(ms->desk->root); n != NULL; n = next_leaf(n, ms->desk->root))
-            window_hide(n->client->window);
-    }
     desktop_t *d = ms->desk_head;
     while (d != NULL) {
         desktop_t *next = d->next;
@@ -113,6 +140,45 @@ void merge_monitors(monitor_t *ms, monitor_t *md)
     }
 }
 
+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));
@@ -124,6 +190,7 @@ desktop_t *make_desktop(const char *name)
     d->prev = d->next = NULL;
     d->root = d->focus = NULL;
     d->history = make_focus_history();
+    d->window_gap = WINDOW_GAP;
     return d;
 }
 
@@ -173,7 +240,7 @@ void unlink_desktop(monitor_t *m, desktop_t *d)
     if (m->last_desk == d)
         m->last_desk = NULL;
     if (m->desk == d)
-        m->desk = (m->last_desk == NULL ? m->desk_head : m->last_desk);
+        m->desk = (m->last_desk == NULL ? (prev == NULL ? next : prev) : m->last_desk);
     d->prev = d->next = NULL;
 }
 
@@ -181,7 +248,6 @@ void remove_desktop(monitor_t *m, desktop_t *d)
 {
     PRINTF("remove desktop %s\n", d->name);
 
-    prune_rules(d);
     unlink_desktop(m, d);
     empty_desktop(d);
     free(d);
@@ -191,14 +257,59 @@ void remove_desktop(monitor_t *m, desktop_t *d)
     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->uid = ++client_uid;
     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;
 }
 
@@ -208,8 +319,10 @@ rule_t *make_rule(void)
     r->uid = ++rule_uid;
     r->effect.floating = false;
     r->effect.follow = false;
-    r->effect.monitor = NULL;
-    r->effect.desktop = NULL;
+    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;
@@ -317,3 +430,27 @@ node_t *history_get(focus_history_t *f, int i)
     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;
+}