add client_search_top_transient.
keep transients all on the same desktop together. use client_search_top_transient where possible in client.c
This commit is contained in:
parent
d2a628a487
commit
0719843c68
2 changed files with 128 additions and 98 deletions
132
openbox/client.c
132
openbox/client.c
|
@ -1494,8 +1494,8 @@ static StackLayer calc_layer(Client *self)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calc_recursive(Client *self, Client *orig, StackLayer l,
|
static void client_calc_layer_recursive(Client *self, Client *orig,
|
||||||
gboolean raised)
|
StackLayer l, gboolean raised)
|
||||||
{
|
{
|
||||||
StackLayer old, own;
|
StackLayer old, own;
|
||||||
GSList *it;
|
GSList *it;
|
||||||
|
@ -1505,7 +1505,8 @@ static void calc_recursive(Client *self, Client *orig, StackLayer l,
|
||||||
self->layer = l > own ? l : own;
|
self->layer = l > own ? l : own;
|
||||||
|
|
||||||
for (it = self->transients; it; it = it->next)
|
for (it = self->transients; it; it = it->next)
|
||||||
calc_recursive(it->data, orig, l, raised ? raised : l != old);
|
client_calc_layer_recursive(it->data, orig,
|
||||||
|
l, raised ? raised : l != old);
|
||||||
|
|
||||||
if (!raised && l != old)
|
if (!raised && l != old)
|
||||||
if (orig->frame) { /* only restack if the original window is managed */
|
if (orig->frame) { /* only restack if the original window is managed */
|
||||||
|
@ -1523,24 +1524,11 @@ void client_calc_layer(Client *self)
|
||||||
orig = self;
|
orig = self;
|
||||||
|
|
||||||
/* transients take on the layer of their parents */
|
/* transients take on the layer of their parents */
|
||||||
if (self->transient_for) {
|
self = client_search_top_transient(self);
|
||||||
if (self->transient_for != TRAN_GROUP) {
|
|
||||||
self = self->transient_for;
|
|
||||||
} else {
|
|
||||||
GSList *it;
|
|
||||||
|
|
||||||
for (it = self->group->members; it; it = it->next)
|
|
||||||
if (it->data != self &&
|
|
||||||
!((Client*)it->data)->transient_for) {
|
|
||||||
self = it->data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l = calc_layer(self);
|
l = calc_layer(self);
|
||||||
|
|
||||||
calc_recursive(self, orig, l, FALSE);
|
client_calc_layer_recursive(self, orig, l, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean client_should_show(Client *self)
|
gboolean client_should_show(Client *self)
|
||||||
|
@ -1883,49 +1871,34 @@ void client_fullscreen(Client *self, gboolean fs, gboolean savearea)
|
||||||
client_focus(self);
|
client_focus(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
|
static void client_iconify_recursive(Client *self,
|
||||||
|
gboolean iconic, gboolean curdesk)
|
||||||
{
|
{
|
||||||
GSList *it;
|
GSList *it;
|
||||||
|
gboolean changed = FALSE;
|
||||||
|
|
||||||
/* move up the transient chain as far as possible first */
|
|
||||||
if (self->transient_for) {
|
|
||||||
if (self->transient_for != TRAN_GROUP) {
|
|
||||||
if (self->transient_for->iconic != iconic) {
|
|
||||||
client_iconify(self->transient_for, iconic, curdesk);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GSList *it;
|
|
||||||
|
|
||||||
for (it = self->group->members; it; it = it->next) {
|
|
||||||
Client *c = it->data;
|
|
||||||
if (c != self && c->iconic != iconic &&
|
|
||||||
!c->transient_for) {
|
|
||||||
client_iconify(it->data, iconic, curdesk);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (it != NULL) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->iconic == iconic) return; /* nothing to do */
|
|
||||||
|
|
||||||
|
if (self->iconic != iconic) {
|
||||||
g_message("%sconifying window: 0x%lx", (iconic ? "I" : "Uni"),
|
g_message("%sconifying window: 0x%lx", (iconic ? "I" : "Uni"),
|
||||||
self->window);
|
self->window);
|
||||||
|
|
||||||
self->iconic = iconic;
|
self->iconic = iconic;
|
||||||
|
|
||||||
if (iconic) {
|
if (iconic) {
|
||||||
|
if (self->functions & Func_Iconify) {
|
||||||
self->wmstate = IconicState;
|
self->wmstate = IconicState;
|
||||||
self->ignore_unmaps++;
|
self->ignore_unmaps++;
|
||||||
/* we unmap the client itself so that we can get MapRequest events,
|
/* we unmap the client itself so that we can get MapRequest
|
||||||
and because the ICCCM tells us to! */
|
events, and because the ICCCM tells us to! */
|
||||||
XUnmapWindow(ob_display, self->window);
|
XUnmapWindow(ob_display, self->window);
|
||||||
|
|
||||||
/* update the focus lists.. iconic windows go to the bottom of the
|
/* update the focus lists.. iconic windows go to the bottom of
|
||||||
list, put the new iconic window at the 'top of the bottom'. */
|
the list, put the new iconic window at the 'top of the
|
||||||
|
bottom'. */
|
||||||
focus_order_to_top(self);
|
focus_order_to_top(self);
|
||||||
|
|
||||||
|
changed = TRUE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (curdesk)
|
if (curdesk)
|
||||||
client_set_desktop(self, screen_desktop, FALSE);
|
client_set_desktop(self, screen_desktop, FALSE);
|
||||||
|
@ -1936,21 +1909,38 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
|
||||||
focus_order_remove(self);
|
focus_order_remove(self);
|
||||||
focus_order_add_new(self);
|
focus_order_add_new(self);
|
||||||
|
|
||||||
/* this is here cuz with the VIDMODE extension, the viewport can change
|
/* this is here cuz with the VIDMODE extension, the viewport can
|
||||||
while a fullscreen window is iconic, and when it uniconifies, it
|
change while a fullscreen window is iconic, and when it
|
||||||
would be nice if it did so to the new position of the viewport */
|
uniconifies, it would be nice if it did so to the new position
|
||||||
|
of the viewport */
|
||||||
client_reconfigure(self);
|
client_reconfigure(self);
|
||||||
|
|
||||||
|
changed = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
client_change_state(self);
|
client_change_state(self);
|
||||||
client_showhide(self);
|
client_showhide(self);
|
||||||
screen_update_areas();
|
screen_update_areas();
|
||||||
|
|
||||||
dispatch_client(iconic ? Event_Client_Unmapped : Event_Client_Mapped,
|
dispatch_client(iconic ? Event_Client_Unmapped : Event_Client_Mapped,
|
||||||
self, 0, 0);
|
self, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* iconify all transients */
|
/* iconify all transients */
|
||||||
for (it = self->transients; it != NULL; it = it->next)
|
for (it = self->transients; it != NULL; it = it->next)
|
||||||
if (it->data != self) client_iconify(it->data, iconic, curdesk);
|
if (it->data != self) client_iconify_recursive(it->data,
|
||||||
|
iconic, curdesk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
|
||||||
|
{
|
||||||
|
/* move up the transient chain as far as possible first */
|
||||||
|
self = client_search_top_transient(self);
|
||||||
|
|
||||||
|
client_iconify_recursive(client_search_top_transient(self),
|
||||||
|
iconic, curdesk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
|
void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
|
||||||
|
@ -2101,11 +2091,13 @@ void client_kill(Client *self)
|
||||||
XKillClient(ob_display, self->window);
|
XKillClient(ob_display, self->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_set_desktop(Client *self, guint target, gboolean donthide)
|
void client_set_desktop_recursive(Client *self,
|
||||||
|
guint target, gboolean donthide)
|
||||||
{
|
{
|
||||||
guint old;
|
guint old;
|
||||||
|
GSList *it;
|
||||||
|
|
||||||
if (target == self->desktop) return;
|
if (target != self->desktop) {
|
||||||
|
|
||||||
g_message("Setting desktop %u", target+1);
|
g_message("Setting desktop %u", target+1);
|
||||||
|
|
||||||
|
@ -2136,6 +2128,18 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
|
||||||
dispatch_client(Event_Client_Desktop, self, target, old);
|
dispatch_client(Event_Client_Desktop, self, target, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* move all transients */
|
||||||
|
for (it = self->transients; it != NULL; it = it->next)
|
||||||
|
if (it->data != self) client_set_desktop_recursive(it->data,
|
||||||
|
target, donthide);
|
||||||
|
}
|
||||||
|
|
||||||
|
void client_set_desktop(Client *self, guint target, gboolean donthide)
|
||||||
|
{
|
||||||
|
client_set_desktop_recursive(client_search_top_transient(self),
|
||||||
|
target, donthide);
|
||||||
|
}
|
||||||
|
|
||||||
Client *client_search_modal_child(Client *self)
|
Client *client_search_modal_child(Client *self)
|
||||||
{
|
{
|
||||||
GSList *it;
|
GSList *it;
|
||||||
|
@ -2575,3 +2579,27 @@ guint client_xinerama_area(Client *self)
|
||||||
g_assert(i < screen_num_xin_areas);
|
g_assert(i < screen_num_xin_areas);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Client *client_search_top_transient(Client *self)
|
||||||
|
{
|
||||||
|
/* move up the transient chain as far as possible */
|
||||||
|
if (self->transient_for) {
|
||||||
|
if (self->transient_for != TRAN_GROUP) {
|
||||||
|
return client_search_top_transient(self->transient_for);
|
||||||
|
} else {
|
||||||
|
GSList *it;
|
||||||
|
|
||||||
|
for (it = self->group->members; it; it = it->next) {
|
||||||
|
Client *c = it->data;
|
||||||
|
|
||||||
|
/* checking transient_for prevents infinate loops! */
|
||||||
|
if (c != self && !c->transient_for)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (it)
|
||||||
|
return it->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
|
@ -496,6 +496,8 @@ Client *client_search_focus_tree_full(Client *self);
|
||||||
*/
|
*/
|
||||||
Client *client_search_modal_child(Client *self);
|
Client *client_search_modal_child(Client *self);
|
||||||
|
|
||||||
|
Client *client_search_top_transient(Client *self);
|
||||||
|
|
||||||
/*! Return the "closest" client in the given direction */
|
/*! Return the "closest" client in the given direction */
|
||||||
Client *client_find_directional(Client *c, Direction dir);
|
Client *client_find_directional(Client *c, Direction dir);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue