summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2007-06-07 03:21:18 +0000
committerDana Jansens <danakj@orodu.net>2007-06-07 03:21:18 +0000
commit571b09f999585c66e9781877c94807f663c2bd4c (patch)
tree0fec7a7de2797710ffd6f43dd6296605f8b9ce92 /openbox
parent9943a713e974473f52d951103efd9b6bda6dd753 (diff)
nice code cleanup that's been needed for a long time. add parents list to client, which you can iterate instead of going thru the group.
Diffstat (limited to 'openbox')
-rw-r--r--openbox/client.c325
-rw-r--r--openbox/client.h9
-rw-r--r--openbox/focus_cycle_popup.c23
-rw-r--r--openbox/place.c67
-rw-r--r--openbox/stacking.c4
5 files changed, 154 insertions, 274 deletions
diff --git a/openbox/client.c b/openbox/client.c
index bb3b53b2..a17f091b 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -93,6 +93,7 @@ static GSList *client_search_all_top_parents_internal(ObClient *self,
ObStackingLayer layer);
static void client_call_notifies(ObClient *self, GSList *list);
+
void client_startup(gboolean reconfig)
{
if (reconfig) return;
@@ -162,37 +163,6 @@ void client_set_list()
stacking_set_list();
}
-/*
- void client_foreach_transient(ObClient *self, ObClientForeachFunc func, gpointer data)
- {
- GSList *it;
-
- for (it = self->transients; it; it = g_slist_next(it)) {
- if (!func(it->data, data)) return;
- client_foreach_transient(it->data, func, data);
- }
- }
-
- void client_foreach_ancestor(ObClient *self, ObClientForeachFunc func, gpointer data)
- {
- if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP) {
- if (!func(self->transient_for, data)) return;
- client_foreach_ancestor(self->transient_for, func, data);
- } else {
- GSList *it;
-
- for (it = self->group->members; it; it = g_slist_next(it))
- if (it->data != self &&
- !((ObClient*)it->data)->transient_for) {
- if (!func(it->data, data)) return;
- client_foreach_ancestor(it->data, func, data);
- }
- }
- }
- }
-*/
-
void client_manage_all()
{
guint i, j, nchild;
@@ -682,22 +652,16 @@ void client_unmanage(ObClient *self)
client_call_notifies(self, client_destroy_notifies);
/* tell our parent(s) that we're gone */
- if (self->transient_for == OB_TRAN_GROUP) { /* transient of group */
- for (it = self->group->members; it; it = g_slist_next(it))
- if (it->data != self)
- ((ObClient*)it->data)->transients =
- g_slist_remove(((ObClient*)it->data)->transients,self);
- } else if (self->transient_for) { /* transient of window */
- self->transient_for->transients =
- g_slist_remove(self->transient_for->transients, self);
- }
+ for (it = self->parents; it; it = g_slist_next(it))
+ ((ObClient*)it->data)->transients =
+ g_slist_remove(((ObClient*)it->data)->transients,self);
/* tell our transients that we're gone */
for (it = self->transients; it; it = g_slist_next(it)) {
- if (((ObClient*)it->data)->transient_for != OB_TRAN_GROUP) {
- ((ObClient*)it->data)->transient_for = NULL;
- client_calc_layer(it->data);
- }
+ ((ObClient*)it->data)->parents =
+ g_slist_remove(((ObClient*)it->data)->parents, self);
+ /* we could be keeping our children in a higher layer */
+ client_calc_layer(it->data);
}
/* remove from its group */
@@ -1141,38 +1105,30 @@ static void client_get_desktop(ObClient *self)
gboolean trdesk = FALSE;
if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP) {
- if (self->transient_for->desktop != DESKTOP_ALL) {
- self->desktop = self->transient_for->desktop;
- trdesk = TRUE;
- }
- } else {
- /* if all the group is on one desktop, then open it on the
- same desktop */
- GSList *it;
- gboolean first = TRUE;
- guint all = screen_num_desktops; /* not a valid value */
-
- for (it = self->group->members; it; it = g_slist_next(it)) {
- ObClient *c = it->data;
-
- if (c->desktop == DESKTOP_ALL) continue;
-
- if (c != self) {
- if (first) {
- all = c->desktop;
- first = FALSE;
- }
- else if (all != c->desktop)
- all = screen_num_desktops; /* make it invalid */
- }
- }
- if (all != screen_num_desktops) {
- self->desktop = all;
- trdesk = TRUE;
+ /* if they are all on one desktop, then open it on the
+ same desktop */
+ GSList *it;
+ gboolean first = TRUE;
+ guint all = screen_num_desktops; /* not a valid value */
+
+ for (it = self->parents; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+
+ if (c->desktop == DESKTOP_ALL) continue;
+
+ if (first) {
+ all = c->desktop;
+ first = FALSE;
}
+ else if (all != c->desktop)
+ all = screen_num_desktops; /* make it invalid */
+ }
+ if (all != screen_num_desktops) {
+ self->desktop = all;
+ trdesk = TRUE;
}
}
+
if (!trdesk) {
/* try get from the startup-notification protocol */
if (sn_get_desktop(self->startup_id, &self->desktop)) {
@@ -1259,23 +1215,9 @@ void client_update_transient_for(ObClient *self)
target = NULL;
}
- /* THIS IS SO ANNOYING ! ! ! ! Let me explain.... have a seat..
-
- Setting the transient_for to Root is actually illegal, however
+ /* Setting the transient_for to Root is actually illegal, however
applications from time have done this to specify transient for
- their group.
-
- Now you can do that by being a TYPE_DIALOG and not setting
- the transient_for hint at all on your window. But people still
- use Root, and Kwin is very strange in this regard.
-
- KWin 3.0 will not consider windows with transient_for set to
- Root as transient for their group *UNLESS* they are also modal.
- In that case, it will make them transient for the group. This
- leads to all sorts of weird behavior from KDE apps which are
- only tested in KWin. I'd like to follow their behavior just to
- make this work right with KDE stuff, but that seems wrong.
- */
+ their group */
if (!target && self->group) {
/* not transient to a client, see if it is transient for a
group */
@@ -1323,13 +1265,14 @@ static void client_update_transient_tree(ObClient *self,
*/
if (oldparent != newparent &&
newparent != NULL && newparent != OB_TRAN_GROUP &&
- newgroup != NULL && newgroup == oldgroup)
+ newgroup != NULL && newgroup == oldgroup && client_normal(newparent))
{
ObClient *look = newparent;
do {
self->transients = g_slist_remove(self->transients, look);
+ look->parents = g_slist_remove(look->parents, self);
look = look->transient_for;
- } while (look != NULL && look != OB_TRAN_GROUP);
+ } while (look != NULL && look != OB_TRAN_GROUP && client_normal(look));
}
@@ -1344,8 +1287,10 @@ static void client_update_transient_tree(ObClient *self,
for (it = self->transients; it; it = next) {
next = g_slist_next(it);
c = it->data;
- if (c->group == oldgroup)
+ if (c->group == oldgroup && client_normal(self)) {
self->transients = g_slist_delete_link(self->transients, it);
+ c->parents = g_slist_remove(c->parents, self);
+ }
}
}
@@ -1355,19 +1300,25 @@ static void client_update_transient_tree(ObClient *self,
if (oldparent == OB_TRAN_GROUP && (oldgroup != newgroup ||
oldparent != newparent))
{
- for (it = oldgroup->members; it; it = g_slist_next(it)) {
+ for (it = self->parents; it; it = next) {
+ next = g_slist_next(it);
c = it->data;
- if (c != self && (!c->transient_for ||
- c->transient_for != OB_TRAN_GROUP))
+ if ((!c->transient_for || c->transient_for != OB_TRAN_GROUP) &&
+ client_normal(c))
+ {
c->transients = g_slist_remove(c->transients, self);
+ self->parents = g_slist_delete_link(self->parents, it);
+ }
}
}
/* If we used to be transient for a single window and we are no longer
transient for it, then we need to remove ourself from its children */
else if (oldparent != NULL && oldparent != OB_TRAN_GROUP &&
- oldparent != newparent)
+ oldparent != newparent && client_normal(oldparent))
+ {
oldparent->transients = g_slist_remove(oldparent->transients, self);
-
+ self->parents = g_slist_remove(self->parents, oldparent);
+ }
/** Re-add the client to the transient tree wherever it has changed **/
@@ -1378,9 +1329,14 @@ static void client_update_transient_tree(ObClient *self,
{
for (it = oldgroup->members; it; it = g_slist_next(it)) {
c = it->data;
- if (c != self && (!c->transient_for ||
- c->transient_for != OB_TRAN_GROUP))
+ if (c != self &&
+ (!c->transient_for ||
+ c->transient_for != OB_TRAN_GROUP) &&
+ client_normal(c))
+ {
c->transients = g_slist_prepend(c->transients, self);
+ self->parents = g_slist_prepend(self->parents, c);
+ }
}
}
/* If we are now transient for a single window which we weren't before,
@@ -1392,8 +1348,12 @@ static void client_update_transient_tree(ObClient *self,
else if (newparent != NULL && newparent != OB_TRAN_GROUP &&
newparent != oldparent &&
/* don't make ourself its child if it is already our child */
- !client_is_direct_child(self, newparent))
+ !client_is_direct_child(self, newparent) &&
+ client_normal(newparent))
+ {
newparent->transients = g_slist_prepend(newparent->transients, self);
+ self->parents = g_slist_prepend(self->parents, newparent);
+ }
/* If the group changed then we need to add any new group transient
windows to our children. But if we're transient for the group, then
@@ -1412,9 +1372,11 @@ static void client_update_transient_tree(ObClient *self,
c = it->data;
if (c != self && c->transient_for == OB_TRAN_GROUP &&
/* Don't make it our child if it is already our parent */
- !client_is_direct_child(c, self))
+ !client_is_direct_child(c, self) &&
+ client_normal(self))
{
self->transients = g_slist_prepend(self->transients, c);
+ c->parents = g_slist_prepend(c->parents, self);
}
}
}
@@ -2368,28 +2330,23 @@ ObClient *client_search_focus_tree(ObClient *self)
ObClient *client_search_focus_tree_full(ObClient *self)
{
- if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP) {
- return client_search_focus_tree_full(self->transient_for);
- } else {
- GSList *it;
-
- for (it = self->group->members; it; it = g_slist_next(it)) {
- if (it->data != self) {
- ObClient *c = it->data;
+ if (self->parents) {
+ GSList *it;
- if (client_focused(c)) return c;
- if ((c = client_search_focus_tree(it->data))) return c;
- }
- }
+ for (it = self->parents; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+ if ((c = client_search_focus_tree_full(it->data))) return c;
}
- }
- /* this function checks the whole tree, the client_search_focus_tree
- does not, so we need to check this window */
- if (client_focused(self))
- return self;
- return client_search_focus_tree(self);
+ return NULL;
+ }
+ else {
+ /* this function checks the whole tree, the client_search_focus_tree
+ does not, so we need to check this window */
+ if (client_focused(self))
+ return self;
+ return client_search_focus_tree(self);
+ }
}
ObClient *client_search_focus_group_full(ObClient *self)
@@ -2410,21 +2367,7 @@ ObClient *client_search_focus_group_full(ObClient *self)
gboolean client_has_parent(ObClient *self)
{
- if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP) {
- if (client_normal(self->transient_for))
- return TRUE;
- }
- else if (self->group) {
- GSList *it;
-
- for (it = self->group->members; it; it = g_slist_next(it)) {
- if (it->data != self && client_normal(it->data))
- return TRUE;
- }
- }
- }
- return FALSE;
+ return self->parents != NULL;
}
static ObStackingLayer calc_layer(ObClient *self)
@@ -3098,7 +3041,7 @@ void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk,
{
if (self->functions & OB_CLIENT_FUNC_ICONIFY || !iconic) {
/* move up the transient chain as far as possible first */
- self = client_search_top_normal_parent(self);
+ self = client_search_top_direct_parent(self);
client_iconify_recursive(self, iconic, curdesk, hide_animation);
}
}
@@ -3274,15 +3217,13 @@ void client_set_desktop_recursive(ObClient *self,
void client_set_desktop(ObClient *self, guint target, gboolean donthide)
{
- self = client_search_top_normal_parent(self);
+ self = client_search_top_direct_parent(self);
client_set_desktop_recursive(self, target, donthide);
}
gboolean client_is_direct_child(ObClient *parent, ObClient *child)
{
- while (child != parent &&
- child->transient_for && child->transient_for != OB_TRAN_GROUP)
- child = child->transient_for;
+ while (child != parent && (child = client_direct_parent(child)));
return child == parent;
}
@@ -3700,20 +3641,12 @@ static ObClientIcon* client_icon_recursive(ObClient *self, gint w, gint h)
if (!self->nicons) {
ObClientIcon *parent = NULL;
+ GSList *it;
- if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP)
- parent = client_icon_recursive(self->transient_for, w, h);
- else {
- GSList *it;
- for (it = self->group->members; it; it = g_slist_next(it)) {
- ObClient *c = it->data;
- if (c != self && !c->transient_for) {
- if ((parent = client_icon_recursive(c, w, h)))
- break;
- }
- }
- }
+ for (it = self->parents; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+ if ((parent = client_icon_recursive(c, w, h)))
+ break;
}
return parent;
@@ -3784,11 +3717,17 @@ guint client_monitor(ObClient *self)
return screen_find_monitor(&self->frame->area);
}
-ObClient *client_search_top_normal_parent(ObClient *self)
+ObClient *client_direct_parent(ObClient *self)
{
- while (self->transient_for && self->transient_for != OB_TRAN_GROUP &&
- client_normal(self->transient_for))
- self = self->transient_for;
+ if (!self->parents) return NULL;
+ if (self->transient_for == OB_TRAN_GROUP) return NULL;
+ return self->parents->data;
+}
+
+ObClient *client_search_top_direct_parent(ObClient *self)
+{
+ ObClient *p;
+ while ((p = client_direct_parent(self))) self = p;
return self;
}
@@ -3796,34 +3735,18 @@ static GSList *client_search_all_top_parents_internal(ObClient *self,
gboolean bylayer,
ObStackingLayer layer)
{
- GSList *ret = NULL;
+ GSList *ret;
+ ObClient *p;
/* move up the direct transient chain as far as possible */
- while (self->transient_for && self->transient_for != OB_TRAN_GROUP &&
- (!bylayer || self->transient_for->layer == layer) &&
- client_normal(self->transient_for))
- self = self->transient_for;
-
- if (!self->transient_for)
- ret = g_slist_prepend(ret, self);
- else {
- GSList *it;
-
- g_assert(self->group);
-
- for (it = self->group->members; it; it = g_slist_next(it)) {
- ObClient *c = it->data;
-
- if (!c->transient_for && client_normal(c) &&
- (!bylayer || c->layer == layer))
- {
- ret = g_slist_prepend(ret, c);
- }
- }
+ while ((p = client_direct_parent(self)) &&
+ (!bylayer || p->layer == layer))
+ self = p;
- if (ret == NULL) /* no group parents */
- ret = g_slist_prepend(ret, self);
- }
+ if (!self->parents)
+ ret = g_slist_prepend(NULL, self);
+ else
+ ret = g_slist_copy(self->parents);
return ret;
}
@@ -3840,46 +3763,20 @@ GSList *client_search_all_top_parents_layer(ObClient *self)
ObClient *client_search_focus_parent(ObClient *self)
{
- if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP) {
- if (client_focused(self->transient_for))
- return self->transient_for;
- } else {
- GSList *it;
-
- for (it = self->group->members; it; it = g_slist_next(it)) {
- ObClient *c = it->data;
+ GSList *it;
- /* checking transient_for prevents infinate loops! */
- if (c != self && !c->transient_for)
- if (client_focused(c))
- return c;
- }
- }
- }
+ for (it = self->parents; it; it = g_slist_next(it))
+ if (client_focused(it->data)) return it->data;
return NULL;
}
ObClient *client_search_parent(ObClient *self, ObClient *search)
{
- if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP) {
- if (self->transient_for == search)
- return search;
- } else {
- GSList *it;
-
- for (it = self->group->members; it; it = g_slist_next(it)) {
- ObClient *c = it->data;
+ GSList *it;
- /* checking transient_for prevents infinate loops! */
- if (c != self && !c->transient_for)
- if (c == search)
- return search;
- }
- }
- }
+ for (it = self->parents; it; it = g_slist_next(it))
+ if (it->data == search) return search;
return NULL;
}
diff --git a/openbox/client.h b/openbox/client.h
index f5b47ca4..a2cdea25 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -103,6 +103,8 @@ struct _ObClient
case.
*/
ObClient *transient_for;
+ /*! The client which are parents of this client */
+ GSList *parents;
/*! The clients which are transients (children) of this client */
GSList *transients;
/*! The desktop on which the window resides (0xffffffff for all
@@ -659,10 +661,15 @@ GSList *client_search_all_top_parents(ObClient *self);
*/
GSList *client_search_all_top_parents_layer(ObClient *self);
+/*! Returns the client's parent when it is transient for a direct window
+ rather than a group. If it has no parents, or is transient for the
+ group, this returns null */
+ObClient *client_direct_parent(ObClient *self);
+
/*! Returns a window's top level parent. This only counts direct parents,
not groups if it is transient for its group.
*/
-ObClient *client_search_top_normal_parent(ObClient *self);
+ObClient *client_search_top_direct_parent(ObClient *self);
/*! Is one client a direct child of another (i.e. not through the group.) */
gboolean client_is_direct_child(ObClient *parent, ObClient *child);
diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c
index 89468493..b827e524 100644
--- a/openbox/focus_cycle_popup.c
+++ b/openbox/focus_cycle_popup.c
@@ -211,31 +211,26 @@ static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets,
static gchar *popup_get_name(ObClient *c)
{
ObClient *p;
- gchar *title = NULL;
+ gchar *title;
const gchar *desk = NULL;
gchar *ret;
- /* find our highest direct parent, including non-normal windows */
- for (p = c; p->transient_for && p->transient_for != OB_TRAN_GROUP;
- p = p->transient_for);
+ /* find our highest direct parent */
+ p = client_search_top_direct_parent(c);
if (c->desktop != DESKTOP_ALL && c->desktop != screen_desktop)
desk = screen_desktop_names[c->desktop];
- /* use the transient's parent's title/icon if we don't have one */
- if (p != c && !strcmp("", (c->iconic ? c->icon_title : c->title)))
- title = g_strdup(p->iconic ? p->icon_title : p->title);
+ title = c->iconic ? c->icon_title : c->title;
- if (title == NULL)
- title = g_strdup(c->iconic ? c->icon_title : c->title);
+ /* use the transient's parent's title/icon if we don't have one */
+ if (p != c && title[0] == '\0')
+ title = p->iconic ? p->icon_title : p->title;
if (desk)
ret = g_strdup_printf("%s [%s]", title, desk);
- else {
- ret = title;
- title = NULL;
- }
- g_free(title);
+ else
+ ret = g_strdup(title);
return ret;
}
diff --git a/openbox/place.c b/openbox/place.c
index 5164675d..8f4726f6 100644
--- a/openbox/place.c
+++ b/openbox/place.c
@@ -62,6 +62,7 @@ static Rect **pick_head(ObClient *c)
guint *choice;
guint i;
gint px, py;
+ ObClient *p;
area = g_new(Rect*, screen_num_monitors);
choice = g_new(guint, screen_num_monitors);
@@ -69,12 +70,10 @@ static Rect **pick_head(ObClient *c)
choice[i] = screen_num_monitors; /* make them all invalid to start */
/* try direct parent first */
- if (c->transient_for && c->transient_for != OB_TRAN_GROUP &&
- client_normal(c->transient_for))
- {
- add_choice(choice, client_monitor(c->transient_for));
+ if ((p = client_direct_parent(c))) {
+ add_choice(choice, client_monitor(p));
ob_debug("placement adding choice %d for parent\n",
- client_monitor(c->transient_for));
+ client_monitor(p));
}
/* more than one window in its group (more than just this window) */
@@ -446,42 +445,24 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
static gboolean place_transient_splash(ObClient *client, gint *x, gint *y)
{
- if (client->transient_for && client->type == OB_CLIENT_TYPE_DIALOG) {
- if (client->transient_for != OB_TRAN_GROUP &&
- client_normal(client->transient_for) &&
- !client->iconic)
- {
- ObClient *c = client;
- ObClient *p = client->transient_for;
-
- if (client_normal(p)) {
- *x = (p->frame->area.width - c->frame->area.width) / 2 +
- p->frame->area.x;
- *y = (p->frame->area.height - c->frame->area.height) / 2 +
- p->frame->area.y;
- return TRUE;
- }
- } else {
- GSList *it;
- gboolean first = TRUE;
- gint l, r, t, b;
- for (it = client->group->members; it; it = g_slist_next(it)) {
- ObClient *m = it->data;
- if (!(m == client || m->transient_for) && client_normal(m) &&
- !m->iconic)
- {
- if (first) {
- l = RECT_LEFT(m->frame->area);
- t = RECT_TOP(m->frame->area);
- r = RECT_RIGHT(m->frame->area);
- b = RECT_BOTTOM(m->frame->area);
- first = FALSE;
- } else {
- l = MIN(l, RECT_LEFT(m->frame->area));
- t = MIN(t, RECT_TOP(m->frame->area));
- r = MAX(r, RECT_RIGHT(m->frame->area));
- b = MAX(b, RECT_BOTTOM(m->frame->area));
- }
+ if (client->type == OB_CLIENT_TYPE_DIALOG) {
+ GSList *it;
+ gboolean first = TRUE;
+ gint l, r, t, b;
+ for (it = client->parents; it; it = g_slist_next(it)) {
+ ObClient *m = it->data;
+ if (!m->iconic) {
+ if (first) {
+ l = RECT_LEFT(m->frame->area);
+ t = RECT_TOP(m->frame->area);
+ r = RECT_RIGHT(m->frame->area);
+ b = RECT_BOTTOM(m->frame->area);
+ first = FALSE;
+ } else {
+ l = MIN(l, RECT_LEFT(m->frame->area));
+ t = MIN(t, RECT_TOP(m->frame->area));
+ r = MAX(r, RECT_RIGHT(m->frame->area));
+ b = MAX(b, RECT_BOTTOM(m->frame->area));
}
}
if (!first) {
@@ -492,8 +473,8 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y)
}
}
- if ((client->transient && client->type == OB_CLIENT_TYPE_DIALOG)
- || client->type == OB_CLIENT_TYPE_SPLASH)
+ if (client->type == OB_CLIENT_TYPE_DIALOG ||
+ client->type == OB_CLIENT_TYPE_SPLASH)
{
Rect **areas;
diff --git a/openbox/stacking.c b/openbox/stacking.c
index 2c80ada0..0c7e38fd 100644
--- a/openbox/stacking.c
+++ b/openbox/stacking.c
@@ -169,7 +169,7 @@ static void restack_windows(ObClient *selected, gboolean raise)
GList *modals = NULL;
GList *trans = NULL;
- if (!raise && selected->transient_for) {
+ if (!raise && selected->parents) {
GSList *top, *top_it;
GSList *top_reorder = NULL;
@@ -371,7 +371,7 @@ static GList *find_highest_relative(ObClient *client)
{
GList *ret = NULL;
- if (client->transient_for) {
+ if (client->parents) {
GList *it;
GSList *top;