<div dir="ltr"><div><div><div><div>Hello, I made a small patch to add the functionality of adding/removing desktops from given indices.  It's on bugzilla here: <a href="https://bugzilla.icculus.org/show_bug.cgi?id=5974">https://bugzilla.icculus.org/show_bug.cgi?id=5974</a> . <br>
<br></div>The patch allows for indices in rc.xml AddDesktop and RemoveDesktop action blocks in the same way that exists currently for GoToDesktop and SendToDesktop.<br><br></div><div>e.g.<br><keybind key="C-8"><br>
  <action name="AddDesktop"><br>    <where>8</where><br>  </action><br></keybind><br></div><div><br></div>I would appreciate review and testing :)<br></div><div><br></div>Herein follows the commit message, which explains the intended changes and the diff from master branch at git://<a href="http://git.openbox.org/dana/openbox">git.openbox.org/dana/openbox</a><br>
```<br>    Add valid key "first" to add/remove desktops.<br>    Add functionality to add/remove desktops of specific index; for consistency with configuration of MoveDesktop, configuration indices in rc.xml are 1-indexed.<br>
    <br>    If AddDesktop with index higher than num_desktops, empty desktops are appended until that index. If AddDesktop with index between 1 and num_desktops-1, empty desktop is inserted between previous desktop index-1 and desktop index.<br>
    <br>    If RemoveDesktop with index higher than num_desktops, nothing happens. If RemoveDesktop with index between 1 and num_desktops-1, that desktop is merged up, keeping current windows focused. If RemoveDesktop with index num_desktops, last desktop is merged down, keeping current windows focused.<br>
    <br>    Keys "last" and "current" should work exactly the same as before.<br>```<br></div>BEGIN DIFF:<br>```<br>diff --git a/openbox/actions/addremovedesktop.c b/openbox/actions/addremovedesktop.c<br>
index ff6767e..d1fafb5 100644<br>--- a/openbox/actions/addremovedesktop.c<br>+++ b/openbox/actions/addremovedesktop.c<br>@@ -3,7 +3,8 @@<br> #include <glib.h><br> <br> typedef struct {<br>-    gboolean current;<br>+    /* index is 0-indexed */<br>
+    guint index;<br>     gboolean add;<br> } Options;<br> <br>@@ -44,9 +45,24 @@ static gpointer setup_func(xmlNodePtr node)<br>     if ((n = obt_xml_find_node(node, "where"))) {<br>         gchar *s = obt_xml_node_string(n);<br>
         if (!g_ascii_strcasecmp(s, "last"))<br>-            o->current = FALSE;<br>+        {<br>+            /* screen_num_desktops is 1-indexed */<br>+            o->index = screen_num_desktops - 1;<br>
+        }<br>         else if (!g_ascii_strcasecmp(s, "current"))<br>-            o->current = TRUE;<br>+        {<br>+            /* screen_desktop is 0-indexed */<br>+            o->index = screen_desktop;<br>
+        }<br>+        else if (!g_ascii_strcasecmp(s, "first"))<br>+        {<br>+            o->index = 0;<br>+        }<br>+        else if (atoi(s) >= 0)<br>+        {<br>+            /* configuration input is 1-indexed */<br>
+            o->index = atoi(s) - 1;<br>+        }<br>         g_free(s);<br>     }<br> <br>@@ -80,9 +96,9 @@ static gboolean run_func(ObActionsData *data, gpointer options)<br>     actions_client_move(data, TRUE);<br>
 <br>     if (o->add)<br>-        screen_add_desktop(o->current);<br>+        screen_add_desktop(o->index);<br>     else<br>-        screen_remove_desktop(o->current);<br>+        screen_remove_desktop(o->index);<br>
 <br>     actions_client_move(data, FALSE);<br> <br>@@ -93,27 +109,27 @@ static gboolean run_func(ObActionsData *data, gpointer options)<br> static gpointer setup_addcurrent_func(xmlNodePtr node)<br> {<br>     Options *o = setup_add_func(node);<br>
-    o->current = TRUE;<br>+    o->index = screen_desktop;<br>     return o;<br> }<br> <br> static gpointer setup_addlast_func(xmlNodePtr node)<br> {<br>     Options *o = setup_add_func(node);<br>-    o->current = FALSE;<br>
+    o->index = screen_num_desktops - 1;<br>     return o;<br> }<br> <br> static gpointer setup_removecurrent_func(xmlNodePtr node)<br> {<br>     Options *o = setup_remove_func(node);<br>-    o->current = TRUE;<br>+    o->index = screen_desktop;<br>
     return o;<br> }<br> <br> static gpointer setup_removelast_func(xmlNodePtr node)<br> {<br>     Options *o = setup_remove_func(node);<br>-    o->current = FALSE;<br>+    o->index = screen_num_desktops - 1;<br>     return o;<br>
 }<br>diff --git a/openbox/screen.c b/openbox/screen.c<br>index 33acb4a..5092897 100644<br>--- a/openbox/screen.c<br>+++ b/openbox/screen.c<br>@@ -740,22 +740,31 @@ void screen_set_desktop(guint num, gboolean dofocus)<br>
         screen_desktop_user_time = event_source_time();<br> }<br> <br>-void screen_add_desktop(gboolean current)<br>+void screen_add_desktop(guint index)<br> {<br>     gulong ignore_start;<br> <br>     /* ignore enter events caused by this */<br>
     ignore_start = event_start_ignore_all_enters();<br> <br>-    screen_set_num_desktops(screen_num_desktops+1);<br>-<br>-    /* move all the clients over */<br>-    if (current) {<br>+    if (index > screen_num_desktops - 1)<br>
+    {<br>+        /* simply appending desktops to the end of current array */<br>+        /* create extra desktops; index is 0-indexed */<br>+        screen_set_num_desktops(index + 1);<br>+    }<br>+    else<br>+    {<br>
+        /* inserting a desktop between two existing desktops */<br>+        /* add one desktop to the end */<br>+        screen_set_num_desktops(screen_num_desktops + 1);<br>         GList *it;<br>-<br>+        /* in all desktops of index >= param index, move their clients over <br>
+           one desktop */<br>         for (it = client_list; it; it = g_list_next(it)) {<br>             ObClient *c = it->data;<br>-            if (c->desktop != DESKTOP_ALL && c->desktop >= screen_desktop &&<br>
+            /* c->desktop is 0-indexed */<br>+            if (c->desktop != DESKTOP_ALL && c->desktop >= index &&<br>                 /* don't move direct children, they'll be moved with their<br>
                    parent - which will have to be on the same desktop */<br>                 !client_direct_parent(c))<br>@@ -764,55 +773,57 @@ void screen_add_desktop(gboolean current)<br>                 client_set_desktop(c, c->desktop+1, FALSE, TRUE);<br>
             }<br>         }<br>+        /* if desktop inserted before current desktop, move screen_desktop one <br>+           over. screen_desktop is 0-indexed */<br>+        if (index <= screen_desktop)<br>+            screen_set_desktop(screen_desktop+1, TRUE);<br>
     }<br> <br>+    /* end ignore */<br>     event_end_ignore_all_enters(ignore_start);<br> }<br> <br>-void screen_remove_desktop(gboolean current)<br>+void screen_remove_desktop(guint index)<br> {<br>-    guint rmdesktop, movedesktop;<br>
     GList *it, *stacking_copy;<br>     gulong ignore_start;<br>+    gboolean raise_client = FALSE;<br> <br>-    if (screen_num_desktops <= 1) return;<br>+    if (screen_num_desktops <= 1 || index < 0 || index >= screen_num_desktops)<br>
+        return;<br> <br>     /* ignore enter events caused by this */<br>     ignore_start = event_start_ignore_all_enters();<br> <br>-    /* what desktop are we removing and moving to? */<br>-    if (current)<br>-        rmdesktop = screen_desktop;<br>
-    else<br>-        rmdesktop = screen_num_desktops - 1;<br>-    if (rmdesktop < screen_num_desktops - 1)<br>-        movedesktop = rmdesktop + 1;<br>-    else<br>-        movedesktop = rmdesktop;<br>-<br>     /* make a copy of the list cuz we're changing it */<br>
     stacking_copy = g_list_copy(stacking_list);<br>     for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) {<br>         if (WINDOW_IS_CLIENT(it->data)) {<br>             ObClient *c = it->data;<br>
-            guint d = c->desktop;<br>-            if (d != DESKTOP_ALL && d >= movedesktop &&<br>+            /* raise all the windows that are on the current desktop which<br>+               is being merged */<br>
+            if ((screen_desktop == index - 1 ||<br>+                 screen_desktop == index) &&<br>+                (c->desktop == DESKTOP_ALL || c->desktop == screen_desktop))<br>+            {<br>+                raise_client = TRUE;<br>
+            }<br>+            if (c->desktop != DESKTOP_ALL && c->desktop > index &&<br>                 /* don't move direct children, they'll be moved with their<br>                    parent - which will have to be on the same desktop */<br>
                 !client_direct_parent(c))<br>             {<br>+                /* move clients to next down desktop */<br>                 ob_debug("moving window %s", c->title);<br>                 client_set_desktop(c, c->desktop - 1, TRUE, TRUE);<br>
             }<br>-            /* raise all the windows that are on the current desktop which<br>-               is being merged */<br>-            if ((screen_desktop == rmdesktop - 1 ||<br>-                 screen_desktop == rmdesktop) &&<br>
-                (d == DESKTOP_ALL || d == screen_desktop))<br>+            if (raise_client)<br>             {<br>                 stacking_raise(CLIENT_AS_WINDOW(c));<br>                 ob_debug("raising window %s", c->title);<br>
+                raise_client = FALSE;<br>             }<br>+            <br>         }<br>     }<br>     g_list_free(stacking_copy);<br>@@ -823,6 +834,7 @@ void screen_remove_desktop(gboolean current)<br>         ob_debug("fake desktop change");<br>
     }<br> <br>+    /* trim off last desktop */<br>     screen_set_num_desktops(screen_num_desktops-1);<br> <br>     event_end_ignore_all_enters(ignore_start);<br>diff --git a/openbox/screen.h b/openbox/screen.h<br>index a6a3995..f541530 100644<br>
--- a/openbox/screen.h<br>+++ b/openbox/screen.h<br>@@ -68,9 +68,9 @@ void screen_set_num_desktops(guint num);<br> /*! Change the current desktop */<br> void screen_set_desktop(guint num, gboolean dofocus);<br> /*! Add a new desktop either at the end or inserted at the current desktop */<br>
-void screen_add_desktop(gboolean current);<br>+void screen_add_desktop(guint index);<br> /*! Remove a desktop, either at the end or the current desktop */<br>-void screen_remove_desktop(gboolean current);<br>+void screen_remove_desktop(guint index);<br>
 <br> guint screen_find_desktop(guint from, ObDirection dir,<br>                           gboolean wrap, gboolean linear);<br>```<br></div>