track window groups iconify all its transients when a window is iconified
Dana Jansens danakj@orodu.net
5 files changed,
96 insertions(+),
7 deletions(-)
M
openbox/client.c
→
openbox/client.c
@@ -9,6 +9,7 @@ #include "grab.h"
#include "focus.h" #include "stacking.h" #include "dispatch.h" +#include "group.h" #include <glib.h> #include <X11/Xutil.h>@@ -319,6 +320,10 @@ if (client->iconic)
XMapWindow(ob_display, client->window); } + /* remoev from its group */ + if (client->group) + group_remove(client->group, client); + /* free all data allocated in the client struct */ g_slist_free(client->transients); for (j = 0; j < client->nicons; ++j)@@ -420,7 +425,7 @@ self->layer = -1;
self->urgent = FALSE; self->positioned = FALSE; self->disabled_decorations = 0; - self->group = None; + self->group = NULL; self->nicons = 0; client_get_area(self);@@ -940,10 +945,12 @@ if (hints->flags & XUrgencyHint)
ur = TRUE; if (hints->flags & WindowGroupHint) { - if (hints->window_group != self->group) { - /* XXX: remove from the old group if there was one */ - self->group = hints->window_group; - /* XXX: do stuff with the group */ + if (hints->window_group != + (self->group ? self->group->leader : None)) { + /* remove from the old group if there was one */ + if (self->group != NULL) + group_remove(self->group, self); + self->group = group_add(hints->window_group, self); } } else /* no group! */ self->group = None;@@ -1554,6 +1561,14 @@ screen_update_struts();
dispatch_client(iconic ? Event_Client_Unmapped : Event_Client_Mapped, self, 0, 0); + + /* iconify all transients */ + if (self->transients) { + GSList *it; + + for (it = self->transients; it != NULL; it = it->next) + if (it->data != self) client_iconify(it->data, iconic, curdesk); + } } void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
M
openbox/client.h
→
openbox/client.h
@@ -7,7 +7,7 @@ #include <glib.h>
#include <X11/Xlib.h> struct Frame; - +struct Group; /*! Holds an icon in ARGB format */ typedef struct Icon {@@ -114,7 +114,7 @@ /*! The number of unmap events to ignore on the window */
int ignore_unmaps; /*! The id of the group the window belongs to */ - Window group; + struct Group *group; /*! Whether or not the client is a transient window. This is guaranteed to be TRUE if transient_for != NULL, but not guaranteed to be FALSE if transient_for == NULL. */
A
openbox/group.c
@@ -0,0 +1,46 @@
+#include "group.h" +#include "client.h" + +GHashTable *group_map = NULL; + +static guint map_hash(Window *w) { return *w; } +static gboolean map_key_comp(Window *w1, Window *w2) { return *w1 == *w2; } + +void group_startup() +{ + group_map = g_hash_table_new((GHashFunc)map_hash, + (GEqualFunc)map_key_comp); +} + +void group_shutdown() +{ + g_hash_table_destroy(group_map); +} + +Group *group_add(Window leader, Client *client) +{ + Group *self; + + self = g_hash_table_lookup(group_map, &leader); + if (self == NULL) { + self = g_new(Group, 1); + self->leader = leader; + self->members = NULL; + g_hash_table_insert(group_map, &self->leader, self); + g_message("NEW GROUP FOR %lx", leader); + } else + g_message("REUSING GROUP FOR %lx", leader); + + self->members = g_slist_append(self->members, client); + + return self; +} + +void group_remove(Group *self, Client *client) +{ + self->members = g_slist_remove(self->members, client); + if (self->members == NULL) { + g_hash_table_remove(group_map, &self->leader); + g_free(self); + } +}
A
openbox/group.h
@@ -0,0 +1,25 @@
+#ifndef __group_h +#define __group_h + +#include <X11/Xlib.h> +#include <glib.h> + +struct Client; + +typedef struct Group { + Window leader; + + /* list of clients */ + GSList *members; +} Group; + +extern GHashTable *group_map; + +void group_startup(); +void group_shutdown(); + +Group *group_add(Window leader, struct Client *client); + +void group_remove(Group *self, struct Client *client); + +#endif
M
openbox/openbox.c
→
openbox/openbox.c
@@ -12,6 +12,7 @@ #include "grab.h"
#include "engine.h" #include "plugin.h" #include "timer.h" +#include "group.h" #include "gettext.h" #include "../render/render.h" #include "../render/font.h"@@ -172,6 +173,7 @@ /* load the engine specified in the rc */
engine_load(); screen_startup(); + group_startup(); client_startup(); /* call startup for all the plugins */@@ -189,6 +191,7 @@ client_unmanage_all();
plugin_shutdown(); /* calls all the plugins' shutdown functions */ client_shutdown(); + group_shutdown(); screen_shutdown(); focus_shutdown(); engine_shutdown();