]> git.lizzy.rs Git - bspwm.git/blobdiff - src/desktop.c
bspwm: port rounded corners patch to latest version
[bspwm.git] / src / desktop.c
index 4ffb83ae9cea1200045efa53198e581f8041aca2..b622e8d40439de06e1d10834ed7a83aad0acb38c 100644 (file)
 #include "subscribe.h"
 #include "settings.h"
 
-void focus_desktop(monitor_t *m, desktop_t *d)
-{
-       bool changed = (m != mon || m->desk != d);
-
-       focus_monitor(m);
-
-       if (m->desk != d) {
-               show_desktop(d);
-               hide_desktop(m->desk);
-               m->desk = d;
-       }
-
-       if (changed) {
-               ewmh_update_current_desktop();
-               put_status(SBSC_MASK_DESKTOP_FOCUS, "desktop_focus 0x%08X 0x%08X\n", m->id, d->id);
-       }
-}
-
 bool activate_desktop(monitor_t *m, desktop_t *d)
 {
        if (d != NULL && m == mon) {
@@ -61,18 +43,21 @@ bool activate_desktop(monitor_t *m, desktop_t *d)
        }
 
        if (d == NULL) {
-               d = history_last_desktop(m, NULL);
+               d = m->desk;
+               if (d == NULL) {
+                       d = history_last_desktop(m, NULL);
+               }
                if (d == NULL) {
                        d = m->desk_head;
                }
        }
 
-       if (d == NULL) {
+       if (d == NULL || d == m->desk) {
                return false;
        }
 
-       if (m->sticky_count > 0) {
-               transfer_sticky_nodes(m, m->desk, d, m->desk->root);
+       if (m->sticky_count > 0 && m->desk != NULL) {
+               transfer_sticky_nodes(m, m->desk, m, d, m->desk->root);
        }
 
        show_desktop(d);
@@ -80,13 +65,15 @@ bool activate_desktop(monitor_t *m, desktop_t *d)
 
        m->desk = d;
 
+       history_add(m, d, NULL, false);
+
        put_status(SBSC_MASK_DESKTOP_ACTIVATE, "desktop_activate 0x%08X 0x%08X\n", m->id, d->id);
        put_status(SBSC_MASK_REPORT);
 
        return true;
 }
 
-bool find_closest_desktop(coordinates_t *ref, coordinates_t *dst, cycle_dir_t dir, desktop_select_t sel)
+bool find_closest_desktop(coordinates_t *ref, coordinates_t *dst, cycle_dir_t dir, desktop_select_t *sel)
 {
        monitor_t *m = ref->monitor;
        desktop_t *d = ref->desktop;
@@ -116,22 +103,50 @@ bool find_closest_desktop(coordinates_t *ref, coordinates_t *dst, cycle_dir_t di
        return false;
 }
 
-bool set_layout(monitor_t *m, desktop_t *d, layout_t l)
+bool find_any_desktop(coordinates_t *ref, coordinates_t *dst, desktop_select_t *sel)
+{
+       for (monitor_t *m = mon_head; m != NULL; m = m->next) {
+               for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
+                       coordinates_t loc = {m, d, NULL};
+                       if (desktop_matches(&loc, ref, sel)) {
+                               *dst = loc;
+                               return true;
+                       }
+               }
+       }
+       return false;
+}
+
+bool set_layout(monitor_t *m, desktop_t *d, layout_t l, bool user)
 {
-       if (d->layout == l) {
+       if ((user && d->user_layout == l) || (!user && d->layout == l)) {
                return false;
        }
 
-       d->layout = l;
+       layout_t old_layout = d->layout;
+
+       if (user) {
+               d->user_layout = l;
+       } else {
+               d->layout = l;
+       }
+
+       if (user && (!single_monocle || tiled_count(d->root, true) > 1)) {
+               d->layout = l;
+       }
 
-       handle_presel_feedbacks(m, d);
+       if (d->layout != old_layout) {
+               handle_presel_feedbacks(m, d);
 
-       arrange(m, d);
+               if (user) {
+                       arrange(m, d);
+               }
 
-       put_status(SBSC_MASK_DESKTOP_LAYOUT, "desktop_layout 0x%08X 0x%08X %s\n", m->id, d->id, LAYOUT_STR(l));
+               put_status(SBSC_MASK_DESKTOP_LAYOUT, "desktop_layout 0x%08X 0x%08X %s\n", m->id, d->id, LAYOUT_STR(d->layout));
 
-       if (d == m->desk) {
-               put_status(SBSC_MASK_REPORT);
+               if (d == m->desk) {
+                       put_status(SBSC_MASK_REPORT);
+               }
        }
 
        return true;
@@ -157,14 +172,19 @@ bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d, bool follow)
 
        bool d_was_active = (d == ms->desk);
        bool ms_was_focused = (ms == mon);
+       unsigned int sc = (ms->sticky_count > 0 && d_was_active) ? sticky_count(d->root) : 0;
 
        unlink_desktop(ms, d);
+       ms->sticky_count -= sc;
 
        if ((!follow || !d_was_active || !ms_was_focused) && md->desk != NULL) {
+               hide_sticky = false;
                hide_desktop(d);
+               hide_sticky = true;
        }
 
        insert_desktop(md, d);
+       md->sticky_count += sc;
        history_remove(d, NULL, false);
 
        if (d_was_active) {
@@ -184,8 +204,12 @@ bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d, bool follow)
                }
        }
 
-       if (ms->sticky_count > 0 && d_was_active) {
-               transfer_sticky_nodes(ms, d, ms->desk, d->root);
+       if (sc > 0) {
+               if (ms->desk != NULL) {
+                       transfer_sticky_nodes(md, d, ms, ms->desk, d->root);
+               } else if (d != md->desk) {
+                       transfer_sticky_nodes(md, d, md, md->desk, d->root);
+               }
        }
 
        adapt_geometry(&ms->rectangle, &md->rectangle, d->root);
@@ -219,7 +243,8 @@ desktop_t *make_desktop(const char *name, uint32_t id)
        }
        d->prev = d->next = NULL;
        d->root = d->focus = NULL;
-       d->layout = LAYOUT_TILED;
+       d->user_layout = LAYOUT_TILED;
+       d->layout = single_monocle ? LAYOUT_MONOCLE : LAYOUT_TILED;
        d->padding = (padding_t) PADDING;
        d->window_gap = window_gap;
        d->border_width = border_width;
@@ -252,11 +277,12 @@ void insert_desktop(monitor_t *m, desktop_t *d)
 
 void add_desktop(monitor_t *m, desktop_t *d)
 {
-       put_status(SBSC_MASK_DESKTOP_ADD, "desktop_add 0x%08X %s 0x%08X\n", d->id, d->name, m->id);
+       put_status(SBSC_MASK_DESKTOP_ADD, "desktop_add 0x%08X 0x%08X %s\n", m->id, d->id, d->name);
 
        d->border_width = m->border_width;
        d->window_gap = m->window_gap;
        insert_desktop(m, d);
+       ewmh_update_current_desktop();
        ewmh_update_number_of_desktops();
        ewmh_update_desktop_names();
        ewmh_update_desktop_viewport();
@@ -340,14 +366,13 @@ void merge_desktops(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd)
        if (ds == NULL || dd == NULL || ds == dd) {
                return;
        }
+       /* TODO: Handle sticky nodes. */
        transfer_node(ms, ds, ds->root, md, dd, dd->focus, false);
 }
 
 bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2, bool follow)
 {
-       if (d1 == NULL || d2 == NULL || d1 == d2 ||
-           (m1->desk == d1 && m1->sticky_count > 0) ||
-           (m2->desk == d2 && m2->sticky_count > 0)) {
+       if (d1 == NULL || d2 == NULL || d1 == d2) {
                return false;
        }
 
@@ -357,6 +382,20 @@ bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2, b
        bool d2_was_active = (m2->desk == d2);
        bool d1_was_focused = (mon->desk == d1);
        bool d2_was_focused = (mon->desk == d2);
+       desktop_t *d1_stickies = NULL;
+       desktop_t *d2_stickies = NULL;
+
+       if (m1->sticky_count > 0 && d1 == m1->desk && sticky_count(d1->root) > 0) {
+               d1_stickies = make_desktop(NULL, XCB_NONE);
+               insert_desktop(m1, d1_stickies);
+               transfer_sticky_nodes(m1, d1, m1, d1_stickies, d1->root);
+       }
+
+       if (m2->sticky_count > 0 && d2 == m2->desk && sticky_count(d2->root) > 0) {
+               d2_stickies = make_desktop(NULL, XCB_NONE);
+               insert_desktop(m2, d2_stickies);
+               transfer_sticky_nodes(m2, d2, m2, d2_stickies, d2->root);
+       }
 
        if (m1 != m2) {
                if (m1->desk == d1) {
@@ -427,6 +466,18 @@ bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2, b
                arrange(m2, d1);
        }
 
+       if (d1_stickies != NULL) {
+               transfer_sticky_nodes(m1, d1_stickies, m1, d2, d1_stickies->root);
+               unlink_desktop(m1, d1_stickies);
+               free(d1_stickies);
+       }
+
+       if (d2_stickies != NULL) {
+               transfer_sticky_nodes(m2, d2_stickies, m2, d1, d2_stickies->root);
+               unlink_desktop(m2, d2_stickies);
+               free(d2_stickies);
+       }
+
        if (d1_was_active && !d2_was_active) {
                if ((!follow && m1 != m2) || !d1_was_focused) {
                        hide_desktop(d1);