X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=abc9a1e38778ef16631c00ca8c7c9408b036f949;hb=0b5f6589ba42869d4d1bdac61b3128dbc762424d;hp=6cd8454b062247b0186765e2b4e728e6e72be55e;hpb=58cfbb7f8419e084af6b6b8b00c88ed270c29e88;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index 6cd8454b..abc9a1e3 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1,5 +1,5 @@ #include "client.h" -#include "slit.h" +#include "dock.h" #include "startup.h" #include "screen.h" #include "moveresize.h" @@ -26,7 +26,6 @@ ButtonMotionMask) GList *client_list = NULL; -GHashTable *client_map = NULL; static void client_get_all(Client *self); static void client_toggle_border(Client *self, gboolean show); @@ -41,20 +40,13 @@ static void client_change_allowed_actions(Client *self); static void client_change_state(Client *self); static void client_apply_startup_state(Client *self); -static guint map_hash(Window *w) { return *w; } -static gboolean map_key_comp(Window *w1, Window *w2) { return *w1 == *w2; } - void client_startup() { - client_map = g_hash_table_new((GHashFunc)map_hash, - (GEqualFunc)map_key_comp); - client_set_list(); } void client_shutdown() { - g_hash_table_destroy(client_map); } void client_set_list() @@ -117,7 +109,6 @@ void client_manage_all() Window w, *children; XWMHints *wmhints; XWindowAttributes attrib; - Client *active; XQueryTree(ob_display, ob_root, &w, &w, &children, &nchild); @@ -154,19 +145,28 @@ void client_manage_all() stacking list are on the top where you can see them instead of buried at the bottom! */ for (i = startup_stack_size; i > 0; --i) { - Client *c; + ObWindow *obw; w = startup_stack_order[i-1]; - c = g_hash_table_lookup(client_map, &w); - if (c) stacking_lower(CLIENT_AS_WINDOW(c)); + obw = g_hash_table_lookup(window_map, &w); + if (obw) { + g_assert(WINDOW_IS_CLIENT(obw)); + stacking_lower(CLIENT_AS_WINDOW(obw)); + } } g_free(startup_stack_order); startup_stack_order = NULL; startup_stack_size = 0; if (config_focus_new) { - active = g_hash_table_lookup(client_map, &startup_active); - if (!(active && client_focus(active))) + ObWindow *active; + + active = g_hash_table_lookup(window_map, &startup_active); + if (active) { + g_assert(WINDOW_IS_CLIENT(active)); + if (!client_focus(WINDOW_AS_CLIENT(active))) + focus_fallback(Fallback_NoFocus); + } else focus_fallback(Fallback_NoFocus); } } @@ -178,6 +178,7 @@ void client_manage(Window window) XWindowAttributes attrib; XSetWindowAttributes attrib_set; XWMHints *wmhint; + gboolean activate = FALSE; grab_server(TRUE); @@ -202,7 +203,7 @@ void client_manage(Window window) if ((wmhint = XGetWMHints(ob_display, window))) { if ((wmhint->flags & StateHint) && wmhint->initial_state == WithdrawnState) { - slit_add(window, wmhint); + dock_add(window, wmhint); grab_server(FALSE); XFree(wmhint); return; @@ -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); + g_hash_table_insert(window_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,42 +263,45 @@ 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); + g_message("Managed window 0x%lx (%s)", window, self->class); } void client_unmanage_all() @@ -323,7 +315,7 @@ void client_unmanage(Client *self) int j; GSList *it; - g_message("Unmanaging window: %lx", self->window); + g_message("Unmanaging window: %lx (%s)", self->window, self->class); dispatch_client(Event_Client_Destroy, self, 0, 0); g_assert(self != NULL); @@ -338,7 +330,7 @@ void client_unmanage(Client *self) client_list = g_list_remove(client_list, self); stacking_remove(self); - g_hash_table_remove(client_map, &self->window); + g_hash_table_remove(window_map, &self->window); /* update the focus lists */ focus_order_remove(self); @@ -681,9 +673,10 @@ void client_update_transient_for(Client *self) if (XGetTransientForHint(ob_display, self->window, &t)) { self->transient = TRUE; if (t != self->window) { /* cant be transient to itself! */ - c = g_hash_table_lookup(client_map, &t); + c = g_hash_table_lookup(window_map, &t); /* if this happens then we need to check for it*/ g_assert(c != self); + g_assert(!c || WINDOW_IS_CLIENT(c)); if (!c && self->group) { /* not transient to a client, see if it is transient for a @@ -1714,15 +1707,13 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h, event.xconfigure.event = self->window; event.xconfigure.window = self->window; - /* root window coords with border in mind */ - event.xconfigure.x = x - self->border_width + - self->frame->size.left; - event.xconfigure.y = y - self->border_width + - self->frame->size.top; + /* root window real coords */ + event.xconfigure.x = self->frame->area.x + self->frame->size.left; + event.xconfigure.y = self->frame->area.y + self->frame->size.top; - event.xconfigure.width = self->area.width; - event.xconfigure.height = self->area.height; - event.xconfigure.border_width = self->border_width; + event.xconfigure.width = w; + event.xconfigure.height = h; + event.xconfigure.border_width = 0; event.xconfigure.above = self->frame->plate; event.xconfigure.override_redirect = FALSE; XSendEvent(event.xconfigure.display, event.xconfigure.window,