]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
ok unfocus before removing transient shit, but remove focus related flags so we don...
[chaz/openbox] / openbox / client.c
index 80773f6c45ed8af890dc9b003cee215dccbab291..1e79e58505c1e3f7a9c43d37f35920382ddedd15 100644 (file)
@@ -277,9 +277,7 @@ void client_manage(Window window)
 
     /* focus the new window? */
     if (ob_state() != OB_STATE_STARTING &&
-        (config_focus_new || (self->transient_for &&
-                              self->transient_for != OB_TRAN_GROUP &&
-                              client_focused(self->transient_for))) &&
+        (config_focus_new || client_search_focus_parent(self)) &&
         /* 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 */
@@ -403,6 +401,25 @@ void client_unmanage(ObClient *self)
        influence */
     screen_update_areas();
 
+    for (it = client_destructors; it; it = g_slist_next(it)) {
+        GDestroyNotify func = (GDestroyNotify) it->data;
+        func(self);
+    }
+        
+    if (focus_client == self) {
+        XEvent e;
+
+        /* focus the last focused window on the desktop, and ignore enter
+           events from the unmap so it doesnt mess with the focus */
+        while (XCheckTypedEvent(ob_display, EnterNotify, &e));
+        /* remove these flags so we don't end up getting focused in the
+           fallback! */
+        self->can_focus = FALSE;
+        self->focus_notify = FALSE;
+        self->modal = FALSE;
+        client_unfocus(self);
+    }
+
     /* tell our parent(s) that we're gone */
     if (self->transient_for == OB_TRAN_GROUP) { /* transient of group */
         GSList *it;
@@ -412,8 +429,8 @@ void client_unmanage(ObClient *self)
                 ((ObClient*)it->data)->transients =
                     g_slist_remove(((ObClient*)it->data)->transients, self);
     } else if (self->transient_for) {        /* transient of window */
-       self->transient_for->transients =
-           g_slist_remove(self->transient_for->transients, self);
+        self->transient_for->transients =
+            g_slist_remove(self->transient_for->transients, self);
     }
 
     /* tell our transients that we're gone */
@@ -424,20 +441,6 @@ void client_unmanage(ObClient *self)
         }
     }
 
-    for (it = client_destructors; it; it = g_slist_next(it)) {
-        GDestroyNotify func = (GDestroyNotify) it->data;
-        func(self);
-    }
-        
-    if (focus_client == self) {
-        XEvent e;
-
-        /* focus the last focused window on the desktop, and ignore enter
-           events from the unmap so it doesnt mess with the focus */
-        while (XCheckTypedEvent(ob_display, EnterNotify, &e));
-        client_unfocus(self);
-    }
-
     /* remove from its group */
     if (self->group) {
         group_remove(self->group, self);
@@ -1310,16 +1313,14 @@ void client_update_wmhints(ObClient *self)
         /* the WM_HINTS can contain an icon */
         client_update_icons(self);
 
-       XFree(hints);
+        XFree(hints);
     }
 
     if (ur != self->urgent) {
-       self->urgent = ur;
-       ob_debug("Urgent Hint for 0x%lx: %s\n", self->window,
-                 ur ? "ON" : "OFF");
-       /* fire the urgent callback if we're mapped, otherwise, wait until
-          after we're mapped */
-       if (self->frame)
+        self->urgent = ur;
+        /* fire the urgent callback if we're mapped, otherwise, wait until
+           after we're mapped */
+        if (self->frame)
             client_urgent_notify(self);
     }
 }
@@ -1668,7 +1669,9 @@ static ObStackingLayer calc_layer(ObClient *self)
 {
     ObStackingLayer l;
 
-    if (self->fullscreen) l = OB_STACKING_LAYER_FULLSCREEN;
+    if (self->fullscreen &&
+        (client_focused(self) || client_search_focus_tree(self)))
+        l = OB_STACKING_LAYER_FULLSCREEN;
     else if (self->type == OB_CLIENT_TYPE_DESKTOP)
         l = OB_STACKING_LAYER_DESKTOP;
     else if (self->type == OB_CLIENT_TYPE_DOCK) {
@@ -2185,7 +2188,7 @@ void client_maximize(ObClient *self, gboolean max, int dir, gboolean savearea)
             }
         }
         if ((dir == 0 || dir == 2) && self->max_vert) { /* vert */
-            if (self->pre_max_area.width > 0) {
+            if (self->pre_max_area.height > 0) {
                 y = self->pre_max_area.y;
                 h = self->pre_max_area.height;
 
@@ -2291,7 +2294,7 @@ void client_set_desktop_recursive(ObClient *self,
             client_showhide(self);
         /* raise if it was not already on the desktop */
         if (old != DESKTOP_ALL)
-            stacking_raise(CLIENT_AS_WINDOW(self));
+            client_raise(self);
         screen_update_areas();
 
         /* add to the new desktop(s) */
@@ -2494,7 +2497,7 @@ ObClient *client_focus_target(ObClient *self)
     ObClient *child;
      
     /* if we have a modal child, then focus it, not us */
-    child = client_search_modal_child(self);
+    child = client_search_modal_child(client_search_top_transient(self));
     if (child) return child;
     return self;
 }
@@ -2604,7 +2607,7 @@ void client_activate(ObClient *self, gboolean here)
     if (client_normal(self) && screen_showing_desktop)
         screen_show_desktop(FALSE);
     if (self->iconic)
-        client_iconify(self, FALSE, FALSE);
+        client_iconify(self, FALSE, here);
     if (self->desktop != DESKTOP_ALL &&
         self->desktop != screen_desktop) {
         if (here)
@@ -2617,8 +2620,25 @@ void client_activate(ObClient *self, gboolean here)
         return;
     if (self->shaded)
         client_shade(self, FALSE);
+
     client_focus(self);
-    stacking_raise(CLIENT_AS_WINDOW(self));
+
+    /* we do this an action here. this is rather important. this is because
+       we want the results from the focus change to take place BEFORE we go
+       about raising the window. when a fullscreen window loses focus, we need
+       this or else the raise wont be able to raise above the to-lose-focus
+       fullscreen window. */
+    client_raise(self);
+}
+
+void client_raise(ObClient *self)
+{
+    action_run_string("Raise", self);
+}
+
+void client_lower(ObClient *self)
+{
+    action_run_string("Raise", self);
 }
 
 gboolean client_focused(ObClient *self)
@@ -2809,6 +2829,52 @@ ObClient *client_search_top_transient(ObClient *self)
     return self;
 }
 
+ObClient *client_search_focus_parent(ObClient *self)
+{
+    if (self->transient_for) {
+        if (self->transient_for != OB_TRAN_GROUP) {
+            if (client_focused(self->transient_for))
+                return self->transient_for;
+        } else {
+            GSList *it;
+
+            for (it = self->group->members; it; it = it->next) {
+                ObClient *c = it->data;
+
+                /* checking transient_for prevents infinate loops! */
+                if (c != self && !c->transient_for)
+                    if (client_focused(c))
+                        return c;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+ObClient *client_search_parent(ObClient *self, ObClient *search)
+{
+    if (self->transient_for) {
+        if (self->transient_for != OB_TRAN_GROUP) {
+            if (self->transient_for == search)
+                return search;
+        } else {
+            GSList *it;
+
+            for (it = self->group->members; it; it = it->next) {
+                ObClient *c = it->data;
+
+                /* checking transient_for prevents infinate loops! */
+                if (c != self && !c->transient_for)
+                    if (c == search)
+                        return search;
+            }
+        }
+    }
+
+    return NULL;
+}
+
 ObClient *client_search_transient(ObClient *self, ObClient *search)
 {
     GSList *sit;
This page took 0.03306 seconds and 4 git commands to generate.