From 5f42ecfacbbf0bcfe43137c51a20b60d8ea368e3 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 7 Apr 2003 05:47:20 +0000 Subject: [PATCH] track window groups iconify all its transients when a window is iconified --- openbox/client.c | 25 ++++++++++++++++++++----- openbox/client.h | 4 ++-- openbox/group.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ openbox/group.h | 25 +++++++++++++++++++++++++ openbox/openbox.c | 3 +++ 5 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 openbox/group.c create mode 100644 openbox/group.h diff --git a/openbox/client.c b/openbox/client.c index 1b1fedad..2c6082bd 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -9,6 +9,7 @@ #include "focus.h" #include "stacking.h" #include "dispatch.h" +#include "group.h" #include #include @@ -319,6 +320,10 @@ void client_unmanage(Client *client) 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 @@ static void client_get_all(Client *self) 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 @@ void client_update_wmhints(Client *self) 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 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk) 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) diff --git a/openbox/client.h b/openbox/client.h index 89bdb518..1e801dc4 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -7,7 +7,7 @@ #include struct Frame; - +struct Group; /*! Holds an icon in ARGB format */ typedef struct Icon { @@ -114,7 +114,7 @@ typedef struct Client { 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. */ diff --git a/openbox/group.c b/openbox/group.c new file mode 100644 index 00000000..69d2ccb2 --- /dev/null +++ b/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); + } +} diff --git a/openbox/group.h b/openbox/group.h new file mode 100644 index 00000000..dfc6e883 --- /dev/null +++ b/openbox/group.h @@ -0,0 +1,25 @@ +#ifndef __group_h +#define __group_h + +#include +#include + +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 diff --git a/openbox/openbox.c b/openbox/openbox.c index 3d4db6f9..74f8164c 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -12,6 +12,7 @@ #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 @@ int main(int argc, char **argv) engine_load(); screen_startup(); + group_startup(); client_startup(); /* call startup for all the plugins */ @@ -189,6 +191,7 @@ int main(int argc, char **argv) plugin_shutdown(); /* calls all the plugins' shutdown functions */ client_shutdown(); + group_shutdown(); screen_shutdown(); focus_shutdown(); engine_shutdown(); -- 2.39.2