From 6e42b65bda1706887f3b2a7f9d79ba20f7611a06 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 16 May 2003 15:16:33 +0000 Subject: [PATCH] add anotehr stacking_add function. make stacking_add take care of raising also. make new windows that dont get focus also not raise above the focused window. --- openbox/client.c | 70 +++++++++++++++------------------- openbox/menu.c | 2 +- openbox/moveresize.c | 2 +- openbox/popup.c | 2 +- openbox/slit.c | 2 +- openbox/stacking.c | 89 +++++++++++++++++++++++++++++++++++++------- openbox/stacking.h | 3 +- 7 files changed, 112 insertions(+), 58 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index 0a2fd298..828b158c 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -178,6 +178,7 @@ void client_manage(Window window) XWindowAttributes attrib; XSetWindowAttributes attrib_set; XWMHints *wmhint; + gboolean activate = FALSE; grab_server(TRUE); @@ -241,30 +242,18 @@ void client_manage(Window window) client_apply_startup_state(self); grab_server(FALSE); - + + /* add to client list/map */ client_list = g_list_append(client_list, self); - stacking_add(self); - g_assert(!g_hash_table_lookup(client_map, &self->window)); g_hash_table_insert(client_map, &self->window, self); /* update the focus lists */ focus_order_add_new(self); - stacking_raise(CLIENT_AS_WINDOW(self)); - - screen_update_struts(); - - dispatch_client(Event_Client_New, self, 0, 0); - - client_showhide(self); - /* focus the new window? */ - if (ob_state != State_Starting) { - Client *parent; + if (ob_state != State_Starting && config_focus_new) { gboolean group_foc = FALSE; - parent = NULL; - if (self->group) { GSList *it; @@ -274,39 +263,42 @@ void client_manage(Window window) break; } } - if (!group_foc && self->transient_for) { - if (self->transient_for != TRAN_GROUP) {/* transient of a window */ - parent = self->transient_for; - } else { /* transient of a group */ - GSList *it; - - for (it = self->group->members; it; it = it->next) - if (it->data != self && - ((Client*)it->data)->transient_for != TRAN_GROUP) - parent = it->data; - } - } - /* note the check against Type_Normal, not client_normal(self), which - would also include dialog types. in this case we want more strict - rules for focus */ - if ((config_focus_new && - (self->type == Type_Normal || + /* note the check against Type_Normal/Dialog, not client_normal(self), + which would also include other types. in this case we want more + strict rules for focus */ + if (((self->type == Type_Normal || (self->type == Type_Dialog && (group_foc || - (!parent && (!self->group || - !self->group->members->next)))))) || - (parent && (client_focused(parent) || - client_search_focus_tree(parent)))) { - client_focus(self); + (!self->transient_for && (!self->group || + !self->group->members->next)))))) || + client_search_focus_tree_full(self) || + !focus_client || + !client_normal(focus_client)) { + /* activate the window */ + stacking_add(CLIENT_AS_WINDOW(self)); + activate = TRUE; + } else { + /* try to not get in the way */ + stacking_add_nonintrusive(CLIENT_AS_WINDOW(self)); } + } else { + stacking_add(CLIENT_AS_WINDOW(self)); } - /* update the list hints */ - client_set_list(); + screen_update_struts(); /* make sure the window is visible */ client_move_onscreen(self); + dispatch_client(Event_Client_New, self, 0, 0); + + client_showhide(self); + + if (activate) client_activate(self); + + /* update the list hints */ + client_set_list(); + dispatch_client(Event_Client_Mapped, self, 0, 0); g_message("Managed window 0x%lx", window); diff --git a/openbox/menu.c b/openbox/menu.c index 425a7537..17f96b47 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -200,7 +200,7 @@ Menu *menu_new_full(char *label, char *name, Menu *parent, g_hash_table_insert(menu_map, &self->items, self); g_hash_table_insert(menu_hash, g_strdup(name), self); - stacking_add(self); + stacking_add(MENU_AS_WINDOW(self)); stacking_raise(MENU_AS_WINDOW(self)); return self; diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 9a1b4319..871e9653 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -55,7 +55,7 @@ void moveresize_startup() opaque_window.win = XCreateWindow(ob_display, ob_root, 0, 0, 1, 1, 0, render_depth, InputOutput, render_visual, CWSaveUnder, &attrib); - stacking_add(&opaque_window); + stacking_add(INTERNAL_AS_WINDOW(&opaque_window)); stacking_raise(INTERNAL_AS_WINDOW(&opaque_window)); /* a GC to invert stuff */ diff --git a/openbox/popup.c b/openbox/popup.c index 17462d39..efde0758 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -34,7 +34,7 @@ Popup *popup_new(gboolean hasicon) self->gravity = NorthWestGravity; self->x = self->y = self->w = self->h = 0; self->mapped = FALSE; - stacking_add(self); + stacking_add(INTERNAL_AS_WINDOW(self)); stacking_raise(INTERNAL_AS_WINDOW(self)); return self; } diff --git a/openbox/slit.c b/openbox/slit.c index 311cd6ac..81f0b897 100644 --- a/openbox/slit.c +++ b/openbox/slit.c @@ -48,7 +48,7 @@ void slit_startup() XSetWindowBorderWidth(ob_display, slit[i].frame, theme_bwidth); g_hash_table_insert(slit_map, &slit[i].frame, &slit[i]); - stacking_add(&slit[i]); + stacking_add(SLIT_AS_WINDOW(&slit[i])); stacking_raise(SLIT_AS_WINDOW(&slit[i])); } } diff --git a/openbox/stacking.c b/openbox/stacking.c index 0dda3a00..eac4025c 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -113,9 +113,10 @@ void stacking_raise(ObWindow *window) if (WINDOW_IS_CLIENT(window)) { Client *client = WINDOW_AS_CLIENT(window); /* move up the transient chain as far as possible first */ - while (client->transient_for) { + if (client->transient_for) { if (client->transient_for != TRAN_GROUP) { - client = client->transient_for; + stacking_raise(CLIENT_AS_WINDOW(client->transient_for)); + return; } else { GSList *it; @@ -125,15 +126,12 @@ void stacking_raise(ObWindow *window) for (it = client->group->members; it; it = it->next) { Client *c = it->data; - if (c != client && c->transient_for != TRAN_GROUP) { - client = it->data; - break; - } + if (c != client && c->transient_for != TRAN_GROUP) + stacking_raise(it->data); } - if (it == NULL) break; + if (it == NULL) return; } } - window = CLIENT_AS_WINDOW(client); } raise_recursive(window); @@ -180,7 +178,8 @@ void stacking_lower(ObWindow *window) /* move up the transient chain as far as possible first */ while (client->transient_for) { if (client->transient_for != TRAN_GROUP) { - client = client->transient_for; + stacking_lower(CLIENT_AS_WINDOW(client->transient_for)); + return; } else { GSList *it; @@ -190,12 +189,10 @@ void stacking_lower(ObWindow *window) for (it = client->group->members; it; it = it->next) { Client *c = it->data; - if (c != client && c->transient_for != TRAN_GROUP) { - client = it->data; - break; - } + if (c != client && c->transient_for != TRAN_GROUP) + stacking_lower(it->data); } - if (it == NULL) break; + if (it == NULL) return; } } window = CLIENT_AS_WINDOW(client); @@ -205,3 +202,67 @@ void stacking_lower(ObWindow *window) stacking_set_list(); } + +void stacking_add(ObWindow *win) +{ + stacking_list = g_list_append(stacking_list, win); + stacking_raise(win); +} + +void stacking_add_nonintrusive(ObWindow *win) +{ + Window wins[2]; /* only ever restack 2 windows. */ + + if (!WINDOW_IS_CLIENT(win)) + stacking_add(win); /* no special rules for others */ + else { + Client *client = WINDOW_AS_CLIENT(win); + Client *parent = NULL; + GList *it_before = NULL; + + /* insert above its highest parent */ + if (client->transient_for) { + if (client->transient_for != TRAN_GROUP) { + parent = client->transient_for; + } else { + GSList *sit; + GList *it; + + /* the check for TRAN_GROUP is to prevent an infinate loop with + 2 transients of the same group at the head of the group's + members list */ + for (it = stacking_list; !parent && it; it = it->next) { + for (sit = client->group->members; !parent && sit; + sit = sit->next) { + Client *c = sit->data; + if (sit->data == it->data && + c->transient_for != TRAN_GROUP) + parent = it->data; + } + } + } + } + + if (!(it_before = g_list_find(stacking_list, parent))) { + /* no parent to put above, try find the focused client to go + under */ + if ((it_before = g_list_find(stacking_list, focus_client))) + it_before = it_before->next; + else { + /* out of ideas, just add it normally... */ + stacking_add(win); + return; + } + } + stacking_list = g_list_insert_before(stacking_list, it_before, win); + + it_before = g_list_find(stacking_list, win)->prev; + if (!it_before) + wins[0] = focus_backup; + else + wins[0] = window_top(it_before->data); + wins[1] = window_top(win); + + XRestackWindows(ob_display, wins, 2); + } +} diff --git a/openbox/stacking.h b/openbox/stacking.h index 118cc5c3..d27e8c0c 100644 --- a/openbox/stacking.h +++ b/openbox/stacking.h @@ -24,7 +24,8 @@ extern GList *stacking_list; stacking_list */ void stacking_set_list(); -#define stacking_add(win) stacking_list = g_list_append(stacking_list, win); +void stacking_add(ObWindow *win); +void stacking_add_nonintrusive(ObWindow *win); #define stacking_remove(win) stacking_list = g_list_remove(stacking_list, win); /*! Raises a window above all others in its stacking layer -- 2.45.2