X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fclient.c;h=b561f4e2a801b2b54e61b8cbb99255270dcec8b6;hb=b2e08c0ad50a7422bcdd287b60c98868b61514ed;hp=dfc44a9b6418edb0d7622f9d502119e3546499c9;hpb=6714a0e2caa97517c16441721969cbc48b7d7637;p=chaz%2Fopenbox diff --git a/openbox/client.c b/openbox/client.c index dfc44a9b..b561f4e2 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -2,7 +2,7 @@ client.c for the Openbox window manager Copyright (c) 2006 Mikael Magnusson - Copyright (c) 2003 Ben Jansens + Copyright (c) 2003-2007 Dana Jansens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,8 +45,7 @@ #include /*! The event mask to grab on client windows */ -#define CLIENT_EVENTMASK (PropertyChangeMask | FocusChangeMask | \ - StructureNotifyMask) +#define CLIENT_EVENTMASK (PropertyChangeMask | StructureNotifyMask) #define CLIENT_NOPROPAGATEMASK (ButtonPressMask | ButtonReleaseMask | \ ButtonMotionMask) @@ -461,11 +460,28 @@ void client_manage(Window window) mouse_grab_for_client(self, TRUE); if (activate) { - /* This is focus stealing prevention, if a user_time has been set */ + /* This is focus stealing prevention */ ob_debug("Want to focus new window 0x%x with time %u (last time %u)\n", self->window, self->user_time, client_last_user_time); - if (!self->user_time || self->user_time >= client_last_user_time || - client_search_focus_parent(self) != NULL) + + /* If a nothing at all, or a parent was focused, then focus this + always + */ + if (!focus_client || client_search_focus_parent(self) != NULL) + activate = TRUE; + else + { + /* If time stamp is old, don't steal focus */ + if (self->user_time && self->user_time < client_last_user_time) + activate = FALSE; + /* Don't steal focus from globally active clients. + I stole this idea from KWin. It seems nice. + */ + if (!focus_client->can_focus && focus_client->focus_notify) + activate = FALSE; + } + + if (activate) { /* since focus can change the stacking orders, if we focus the window then the standard raise it gets is not enough, we need @@ -478,9 +494,6 @@ void client_manage(Window window) /* if the client isn't focused, then hilite it so the user knows it is there */ client_hilite(self, TRUE); - - /* don't focus it ! (focus stealing prevention) */ - activate = FALSE; } } else { @@ -541,7 +554,8 @@ void client_unmanage(ObClient *self) guint j; GSList *it; - ob_debug("Unmanaging window: %lx (%s)\n", self->window, self->class); + ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window, self->class, + self->title ? self->title : ""); g_assert(self != NULL); @@ -1103,9 +1117,15 @@ void client_update_transient_for(ObClient *self) } } } - } else if (self->type == OB_CLIENT_TYPE_DIALOG && self->group) { - self->transient = TRUE; - target = OB_TRAN_GROUP; + } else if (self->group) { + if (self->type == OB_CLIENT_TYPE_DIALOG || + self->type == OB_CLIENT_TYPE_TOOLBAR || + self->type == OB_CLIENT_TYPE_MENU || + self->type == OB_CLIENT_TYPE_UTILITY) + { + self->transient = TRUE; + target = OB_TRAN_GROUP; + } } else self->transient = FALSE; @@ -1990,8 +2010,6 @@ static void client_calc_layer_recursive(ObClient *self, ObClient *orig, own = calc_layer(self); self->layer = MAX(own, min); - ob_debug("layer for %s: %d\n", self->title, self->layer); - for (it = self->transients; it; it = g_slist_next(it)) client_calc_layer_recursive(it->data, orig, self->layer, @@ -2012,7 +2030,7 @@ void client_calc_layer(ObClient *self) orig = self; /* transients take on the layer of their parents */ - it = client_search_top_transients(self); + it = client_search_all_top_parents(self); for (; it; it = g_slist_next(it)) client_calc_layer_recursive(it->data, orig, 0, FALSE); @@ -2408,6 +2426,10 @@ static void client_iconify_recursive(ObClient *self, bottom'. */ focus_order_to_top(self); + /* Fall back focus since we're disappearing */ + if (focus_client == self) + client_unfocus(self); + changed = TRUE; } } else { @@ -2437,21 +2459,18 @@ static void client_iconify_recursive(ObClient *self, screen_update_areas(); } - /* iconify all transients */ + /* iconify all direct transients */ for (it = self->transients; it; it = g_slist_next(it)) - if (it->data != self) client_iconify_recursive(it->data, - iconic, curdesk); + if (it->data != self) + if (client_is_direct_child(self, it->data)) + client_iconify_recursive(it->data, iconic, curdesk); } void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk) { - GSList *it; - /* move up the transient chain as far as possible first */ - it = client_search_top_transients(self); - - for (; it; it = g_slist_next(it)) - client_iconify_recursive(it->data, iconic, curdesk); + self = client_search_top_parent(self); + client_iconify_recursive(self, iconic, curdesk); } void client_maximize(ObClient *self, gboolean max, gint dir, gboolean savearea) @@ -2598,6 +2617,9 @@ void client_kill(ObClient *self) void client_hilite(ObClient *self, gboolean hilite) { + if (self->demands_attention == hilite) + return; /* no change */ + /* don't allow focused windows to hilite */ self->demands_attention = hilite && !client_focused(self); if (self->demands_attention) @@ -2645,18 +2667,23 @@ void client_set_desktop_recursive(ObClient *self, /* move all transients */ for (it = self->transients; it; it = g_slist_next(it)) - if (it->data != self) client_set_desktop_recursive(it->data, - target, donthide); + if (it->data != self) + if (client_is_direct_child(self, it->data)) + client_set_desktop_recursive(it->data, target, donthide); } void client_set_desktop(ObClient *self, guint target, gboolean donthide) { - GSList *it; - - it = client_search_top_transients(self); + self = client_search_top_parent(self); + client_set_desktop_recursive(self, target, donthide); +} - for(; it; it = g_slist_next(it)) - client_set_desktop_recursive(it->data, 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; + return child == parent; } ObClient *client_search_modal_child(ObClient *self) @@ -2914,6 +2941,11 @@ gboolean client_focus(ObClient *self) /* choose the correct target */ self = client_focus_target(self); +#if 0 + if (!client_validate(self)) + return FALSE; +#endif + if (!client_can_focus(self)) { if (!self->frame->visible) { /* update the focus lists */ @@ -2922,6 +2954,8 @@ gboolean client_focus(ObClient *self) return FALSE; } + ob_debug("Focusing client \"%s\" at time %u\n", self->title, event_curtime); + if (self->can_focus) { /* RevertToPointerRoot causes much more headache than RevertToNone, so I choose to use it always, hopefully to find errors quicker, if any @@ -2962,8 +2996,9 @@ gboolean client_focus(ObClient *self) return TRUE; } -/* Used when the current client is closed, focus_last will then prevent - * focus from going to the mouse pointer */ +/* Used when the current client is closed or otherwise hidden, focus_last will + then prevent focus from going to the mouse pointer +*/ void client_unfocus(ObClient *self) { if (focus_client == self) { @@ -3224,7 +3259,14 @@ guint client_monitor(ObClient *self) return screen_find_monitor(&self->frame->area); } -GSList *client_search_top_transients(ObClient *self) +ObClient *client_search_top_parent(ObClient *self) +{ + while (self->transient_for && self->transient_for != OB_TRAN_GROUP) + self = self->transient_for; + return self; +} + +GSList *client_search_all_top_parents(ObClient *self) { GSList *ret = NULL;