From 3e147773eff37627e132e5a1d912be5d509abaab Mon Sep 17 00:00:00 2001 From: Jamie Macdonald Date: Fri, 21 Jun 2013 02:44:56 -0400 Subject: [PATCH] Add functionality to add/remove workspaces at given indices. Example usage in rc.xml: ... 4 ... will add a desktop in position 4 (one-indexed), shifting windows from higher desktop indices up one desktop. If there are less than 3 desktops currently, the in between desktops will also be created. ... 3 ... will remove desktop at position 3 (one-indexed), moving its windows to desktop 4. If there are exactly 3 desktops, the windows are moved to desktop 2. If there are less than 3 desktops, nothing happens. API changes: screen.c: screen_add_desktop(gboolean current); // is now screen_add_desktop(guint index); screen_remove_desktop(gboolean current); // is now screen_remove_desktop(guint index); This should be fully backwards compatible with previous scheme due to the changes made to openbox/actions/addremovedesktop.c --- openbox/actions/addremovedesktop.c | 20 +++++++++------- openbox/screen.c | 49 ++++++++++++++++++++++---------------- openbox/screen.h | 4 ++-- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/openbox/actions/addremovedesktop.c b/openbox/actions/addremovedesktop.c index ff6767e..198994b 100644 --- a/openbox/actions/addremovedesktop.c +++ b/openbox/actions/addremovedesktop.c @@ -3,7 +3,7 @@ #include typedef struct { - gboolean current; + guint index; gboolean add; } Options; @@ -44,9 +44,11 @@ static gpointer setup_func(xmlNodePtr node) if ((n = obt_xml_find_node(node, "where"))) { gchar *s = obt_xml_node_string(n); if (!g_ascii_strcasecmp(s, "last")) - o->current = FALSE; + o->index = screen_num_desktops; else if (!g_ascii_strcasecmp(s, "current")) - o->current = TRUE; + o->index = screen_desktop; + else if (atoi(s) > 0) + o->index = atoi(s); g_free(s); } @@ -80,9 +82,9 @@ static gboolean run_func(ObActionsData *data, gpointer options) actions_client_move(data, TRUE); if (o->add) - screen_add_desktop(o->current); + screen_add_desktop(o->index); else - screen_remove_desktop(o->current); + screen_remove_desktop(o->index); actions_client_move(data, FALSE); @@ -93,27 +95,27 @@ static gboolean run_func(ObActionsData *data, gpointer options) static gpointer setup_addcurrent_func(xmlNodePtr node) { Options *o = setup_add_func(node); - o->current = TRUE; + o->index = screen_desktop; return o; } static gpointer setup_addlast_func(xmlNodePtr node) { Options *o = setup_add_func(node); - o->current = FALSE; + o->index = screen_num_desktops; return o; } static gpointer setup_removecurrent_func(xmlNodePtr node) { Options *o = setup_remove_func(node); - o->current = TRUE; + o->index = screen_desktop; return o; } static gpointer setup_removelast_func(xmlNodePtr node) { Options *o = setup_remove_func(node); - o->current = FALSE; + o->index = screen_num_desktops; return o; } diff --git a/openbox/screen.c b/openbox/screen.c index 33acb4a..df9f062 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -740,22 +740,29 @@ void screen_set_desktop(guint num, gboolean dofocus) screen_desktop_user_time = event_source_time(); } -void screen_add_desktop(gboolean current) +void screen_add_desktop(guint index) { gulong ignore_start; /* ignore enter events caused by this */ ignore_start = event_start_ignore_all_enters(); - screen_set_num_desktops(screen_num_desktops+1); - - /* move all the clients over */ - if (current) { + /* create extra desktops */ + if (index > screen_num_desktops) + { + /* no moving clients is needed */ + screen_set_num_desktops(index); + } else { + /* add one desktop to the end */ + screen_set_num_desktops(screen_num_desktops + 1); GList *it; - + /* move over the clients in desktops higher than index + to make it look like the new desktop is at index */ for (it = client_list; it; it = g_list_next(it)) { ObClient *c = it->data; - if (c->desktop != DESKTOP_ALL && c->desktop >= screen_desktop && + /* NOTE: ObClient.data.desktop is zero-indexed and + index is one-indexed */ + if (c->desktop != DESKTOP_ALL && c->desktop + 1 >= index && /* don't move direct children, they'll be moved with their parent - which will have to be on the same desktop */ !client_direct_parent(c)) @@ -764,31 +771,33 @@ void screen_add_desktop(gboolean current) client_set_desktop(c, c->desktop+1, FALSE, TRUE); } } + /* Follow current windows */ + screen_set_desktop(screen_desktop+1, TRUE); } - + /* end ignore */ event_end_ignore_all_enters(ignore_start); } -void screen_remove_desktop(gboolean current) +void screen_remove_desktop(guint index) { - guint rmdesktop, movedesktop; + guint movedesktop; GList *it, *stacking_copy; gulong ignore_start; - if (screen_num_desktops <= 1) return; + if ((index > screen_num_desktops) || (screen_num_desktops == 1)) return; /* ignore enter events caused by this */ ignore_start = event_start_ignore_all_enters(); /* what desktop are we removing and moving to? */ - if (current) - rmdesktop = screen_desktop; - else - rmdesktop = screen_num_desktops - 1; - if (rmdesktop < screen_num_desktops - 1) - movedesktop = rmdesktop + 1; + // if (current) + // rmdesktop = screen_desktop; + // else + // rmdesktop = screen_num_desktops - 1; + if (index < screen_num_desktops - 1) + movedesktop = index + 1; else - movedesktop = rmdesktop; + movedesktop = index; /* make a copy of the list cuz we're changing it */ stacking_copy = g_list_copy(stacking_list); @@ -806,8 +815,8 @@ void screen_remove_desktop(gboolean current) } /* raise all the windows that are on the current desktop which is being merged */ - if ((screen_desktop == rmdesktop - 1 || - screen_desktop == rmdesktop) && + if ((screen_desktop == index - 1 || + screen_desktop == index) && (d == DESKTOP_ALL || d == screen_desktop)) { stacking_raise(CLIENT_AS_WINDOW(c)); diff --git a/openbox/screen.h b/openbox/screen.h index a6a3995..f541530 100644 --- a/openbox/screen.h +++ b/openbox/screen.h @@ -68,9 +68,9 @@ void screen_set_num_desktops(guint num); /*! Change the current desktop */ void screen_set_desktop(guint num, gboolean dofocus); /*! Add a new desktop either at the end or inserted at the current desktop */ -void screen_add_desktop(gboolean current); +void screen_add_desktop(guint index); /*! Remove a desktop, either at the end or the current desktop */ -void screen_remove_desktop(gboolean current); +void screen_remove_desktop(guint index); guint screen_find_desktop(guint from, ObDirection dir, gboolean wrap, gboolean linear); -- 1.8.3.1