+ g_assert(!oldgtran || oldgroup);
+ g_assert(!newgtran || newgroup);
+ g_assert((!oldgtran && !oldparent) ||
+ (oldgtran && !oldparent) ||
+ (!oldgtran && oldparent));
+ g_assert((!newgtran && !newparent) ||
+ (newgtran && !newparent) ||
+ (!newgtran && newparent));
+
+ /* * *
+ Group transient windows are not allowed to have other group
+ transient windows as their children.
+ * * */
+
+
+ /* No change has occured */
+ if (oldgroup == newgroup &&
+ oldgtran == newgtran &&
+ oldparent == newparent) return;
+
+ /** Remove the client from the transient tree wherever it has changed **/
+
+ /* If the window is becoming a direct transient for a window in its group
+ then any group transients which were our children and are now becoming
+ our parents need to stop being our children.
+
+ Group transients can't be children of group transients already, but
+ we could have any number of direct parents above up, any of which could
+ be transient for the group, and we need to remove it from our children.
+ */
+ if (!oldgtran && oldparent != newparent && newparent != NULL &&
+ newgroup != NULL && newgroup == oldgroup &&
+ client_normal(newparent))
+ {
+ ObClient *look = client_search_top_direct_parent(newparent);
+ self->transients = g_slist_remove(self->transients, look);
+ look->parents = g_slist_remove(look->parents, self);
+ }
+
+
+ /* If the group changed, or if we are just becoming transient for the
+ group, then we need to remove any old group transient windows
+ from our children. But if we were already transient for the group, then
+ other group transients are not our children. */
+ if ((oldgroup != newgroup || (newgtran && oldgtran != newgtran)) &&
+ oldgroup != NULL && !oldgtran)
+ {
+ for (it = self->transients; it; it = next) {
+ next = g_slist_next(it);
+ c = it->data;
+ if (c->group == oldgroup && client_normal(self)) {
+ self->transients = g_slist_delete_link(self->transients, it);
+ c->parents = g_slist_remove(c->parents, self);
+ }
+ }
+ }
+
+ /* If we used to be transient for a group and now we are not, or we're
+ transient for a new group, then we need to remove ourselves from all
+ our ex-parents */
+ if (oldgtran && (oldgroup != newgroup || oldgtran != newgtran))
+ {
+ for (it = self->parents; it; it = next) {
+ next = g_slist_next(it);
+ c = it->data;
+ if (!c->transient_for_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 && 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 **/
+
+ /* If we're now transient for a group and we weren't transient for it
+ before then we need to add ourselves to all our new parents */
+ if (newgtran && (oldgroup != newgroup || oldgtran != newgtran))
+ {
+ for (it = oldgroup->members; it; it = g_slist_next(it)) {
+ c = it->data;
+ if (c != self && !c->transient_for_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,
+ we need to add ourselves to its children
+
+ WARNING: Cyclical transient ness is possible if two windows are
+ transient for eachother.
+ */
+ else if (newparent && newparent != oldparent &&
+ /* don't make ourself its child if it is already our child */
+ !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);
+ }