From 4d3b05a17674d57216612dc7ececf9313a802ce9 Mon Sep 17 00:00:00 2001 From: jameh Date: Fri, 12 Jul 2013 19:14:44 -0400 Subject: [PATCH] Add valid key "first" to add/remove desktops. Add functionality to add/remove desktops of specific index; for consistency w ith configuration of MoveDesktop, configuration indices in rc.xml are 1-indexed. If AddDesktop with index higher than num_desktops, empty desktops are appende d 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. 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. Keys "last" and "current" should work exactly the same as before. --- openbox/actions/addremovedesktop.c | 34 ++++++++++++++------ openbox/screen.c | 66 ++++++++++++++++++++++---------------- openbox/screen.h | 4 +-- 3 files changed, 66 insertions(+), 38 deletions(-) diff --git a/openbox/actions/addremovedesktop.c b/openbox/actions/addremovedesktop.c index ff6767e..d1fafb5 100644 --- a/openbox/actions/addremovedesktop.c +++ b/openbox/actions/addremovedesktop.c @@ -3,7 +3,8 @@ #include typedef struct { - gboolean current; + /* index is 0-indexed */ + guint index; gboolean add; } Options; @@ -44,9 +45,24 @@ 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; + { + /* screen_num_desktops is 1-indexed */ + o->index = screen_num_desktops - 1; + } else if (!g_ascii_strcasecmp(s, "current")) - o->current = TRUE; + { + /* screen_desktop is 0-indexed */ + o->index = screen_desktop; + } + else if (!g_ascii_strcasecmp(s, "first")) + { + o->index = 0; + } + else if (atoi(s) >= 0) + { + /* configuration input is 1-indexed */ + o->index = atoi(s) - 1; + } g_free(s); } @@ -80,9 +96,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 +109,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 - 1; 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 - 1; return o; } diff --git a/openbox/screen.c b/openbox/screen.c index 33acb4a..5092897 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -740,22 +740,31 @@ 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) { + if (index > screen_num_desktops - 1) + { + /* simply appending desktops to the end of current array */ + /* create extra desktops; index is 0-indexed */ + screen_set_num_desktops(index + 1); + } + else + { + /* inserting a desktop between two existing desktops */ + /* add one desktop to the end */ + screen_set_num_desktops(screen_num_desktops + 1); GList *it; - + /* in all desktops of index >= param index, move their clients over + one desktop */ for (it = client_list; it; it = g_list_next(it)) { ObClient *c = it->data; - if (c->desktop != DESKTOP_ALL && c->desktop >= screen_desktop && + /* c->desktop is 0-indexed */ + if (c->desktop != DESKTOP_ALL && c->desktop >= 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,55 +773,57 @@ void screen_add_desktop(gboolean current) client_set_desktop(c, c->desktop+1, FALSE, TRUE); } } + /* if desktop inserted before current desktop, move screen_desktop one + over. screen_desktop is 0-indexed */ + if (index <= screen_desktop) + 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; GList *it, *stacking_copy; gulong ignore_start; + gboolean raise_client = FALSE; - if (screen_num_desktops <= 1) return; + if (screen_num_desktops <= 1 || index < 0 || index >= screen_num_desktops) + 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; - else - movedesktop = rmdesktop; - /* make a copy of the list cuz we're changing it */ stacking_copy = g_list_copy(stacking_list); for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) { if (WINDOW_IS_CLIENT(it->data)) { ObClient *c = it->data; - guint d = c->desktop; - if (d != DESKTOP_ALL && d >= movedesktop && + /* raise all the windows that are on the current desktop which + is being merged */ + if ((screen_desktop == index - 1 || + screen_desktop == index) && + (c->desktop == DESKTOP_ALL || c->desktop == screen_desktop)) + { + raise_client = TRUE; + } + if (c->desktop != DESKTOP_ALL && c->desktop > 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)) { + /* move clients to next down desktop */ ob_debug("moving window %s", c->title); client_set_desktop(c, c->desktop - 1, TRUE, TRUE); } - /* raise all the windows that are on the current desktop which - is being merged */ - if ((screen_desktop == rmdesktop - 1 || - screen_desktop == rmdesktop) && - (d == DESKTOP_ALL || d == screen_desktop)) + if (raise_client) { stacking_raise(CLIENT_AS_WINDOW(c)); ob_debug("raising window %s", c->title); + raise_client = FALSE; } + } } g_list_free(stacking_copy); @@ -823,6 +834,7 @@ void screen_remove_desktop(gboolean current) ob_debug("fake desktop change"); } + /* trim off last desktop */ screen_set_num_desktops(screen_num_desktops-1); event_end_ignore_all_enters(ignore_start); 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.2