]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
some old changes to grav.c test, it wasn't a valid test before.
[chaz/openbox] / openbox / client.c
index fceac8755836690df529d53ea88138816ec84013..4abff4c50984a5296b3ac540ba9e487d558e2304 100644 (file)
@@ -374,7 +374,6 @@ void client_manage(Window window)
              self->window, newx, newy, self->area.width, self->area.height);
     client_apply_startup_state(self, newx, newy);
 
-    keyboard_grab_for_client(self, TRUE);
     mouse_grab_for_client(self, TRUE);
 
     if (activate) {
@@ -385,10 +384,18 @@ void client_manage(Window window)
         ob_debug("Want to focus new window 0x%x with time %u (last time %u)\n",
                  self->window, self->user_time, last_time);
 
-        /* If a nothing at all, or a parent was focused, then focus this
+        /* if it's on another desktop */
+        if (!(self->desktop == screen_desktop || self->desktop == DESKTOP_ALL)
+            && /* the timestamp is from before you changed desktops */
+            self->user_time && screen_desktop_user_time &&
+            !event_time_after(self->user_time, screen_desktop_user_time))
+        {
+            activate = FALSE;
+        }
+        /* If nothing is focused, or a parent was focused, then focus this
            always
         */
-        if (!focus_client || client_search_focus_parent(self) != NULL)
+        else if (!focus_client || client_search_focus_parent(self) != NULL)
             activate = TRUE;
         else
         {
@@ -476,13 +483,9 @@ void client_unmanage(ObClient *self)
     /* flush to send the hide to the server quickly */
     XFlush(ob_display);
 
-    if (focus_client == self) {
-        /* ignore enter events from the unmap so it doesnt mess with the focus
-         */
-        event_ignore_queued_enters();
-    }
+    /* ignore enter events from the unmap so it doesnt mess with the focus */
+    event_ignore_queued_enters();
 
-    keyboard_grab_for_client(self, FALSE);
     mouse_grab_for_client(self, FALSE);
 
     /* remove the window from our save set */
@@ -490,9 +493,24 @@ void client_unmanage(ObClient *self)
 
     /* update the focus lists */
     focus_order_remove(self);
-    /* don't leave an invalid focus_client */
-    if (self == focus_client)
-        focus_client = NULL;
+    if (client_focused(self)) {
+        /* we have to fall back here because we might not get a focus out.
+           1. we need to xselectinput off the window before we unmap it because
+           otherwise we end up getting unmapnotifies we don't want and they
+           can mess up mapping it again quickly
+           2. this means that if we unmanage from a synthetic unmapnotify, we
+              are the ones unmapped it, and causing the focusout. so we won't
+              get the focusout event.
+           3. we can't handle focusin events on the root window because they
+              come from all screens, so the focus change gets lost
+
+           if this ever gets removed in the future MAKE SURE to replace it
+           with:
+           /- don't leave an invalid focus_client -/
+           focus_client = NULL;
+        */
+        focus_fallback(FALSE);
+    }
 
     client_list = g_list_remove(client_list, self);
     stacking_remove(self);
@@ -736,8 +754,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
     Rect *a;
     gint ox = *x, oy = *y;
 
-    frame_client_gravity(self->frame, x, y); /* get where the frame
-                                                would be */
+    /* get where the frame would be */
+    frame_client_gravity(self->frame, x, y, w, h);
 
     /* XXX watch for xinerama dead areas */
     /* This makes sure windows aren't entirely outside of the screen so you
@@ -761,6 +779,15 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
             *y = a->y - self->frame->area.width*9/10;
     }
 
+    /* If rudeness wasn't requested, then figure out of the client is currently
+       entirely on the screen. If it is, then be rude even though it wasn't
+       requested */
+    if (!rude) {
+        a = screen_area_monitor(self->desktop, client_monitor(self));
+        if (RECT_CONTAINS_RECT(*a, self->area))
+            rude = TRUE;
+    }
+
     /* This here doesn't let windows even a pixel outside the screen,
      * when called from client_manage, programs placing themselves are
      * forced completely onscreen, while things like
@@ -786,8 +813,8 @@ gboolean client_find_onscreen(ObClient *self, gint *x, gint *y, gint w, gint h,
         }
     }
 
-    frame_frame_gravity(self->frame, x, y); /* get where the client
-                                               should be */
+    /* get where the client should be */
+    frame_frame_gravity(self->frame, x, y, w, h);
 
     return ox != *x || oy != *y;
 }
@@ -1131,7 +1158,8 @@ void client_update_transient_for(ObClient *self)
             /* remove from old parents */
             for (it = self->group->members; it; it = g_slist_next(it)) {
                 ObClient *c = it->data;
-                if (c != self && !c->transient_for)
+                if (c != self && (!c->transient_for ||
+                                  c->transient_for != OB_TRAN_GROUP))
                     c->transients = g_slist_remove(c->transients, self);
             }
         } else if (self->transient_for != NULL) { /* transient of window */
@@ -1146,7 +1174,8 @@ void client_update_transient_for(ObClient *self)
             /* add to new parents */
             for (it = self->group->members; it; it = g_slist_next(it)) {
                 ObClient *c = it->data;
-                if (c != self && !c->transient_for)
+                if (c != self && (!c->transient_for ||
+                                  c->transient_for != OB_TRAN_GROUP))
                     c->transients = g_slist_append(c->transients, self);
             }
 
@@ -1331,9 +1360,9 @@ void client_update_normal_hints(ObClient *self)
             if (self->frame && self->gravity != oldgravity) {
                 /* move our idea of the client's position based on its new
                    gravity */
-                self->area.x = self->frame->area.x;
-                self->area.y = self->frame->area.y;
-                frame_frame_gravity(self->frame, &self->area.x, &self->area.y);
+                client_convert_gravity(self, oldgravity,
+                                       &self->area.x, &self->area.y,
+                                       self->area.width, self->area.height);
             }
         }
 
@@ -1552,7 +1581,7 @@ void client_reconfigure(ObClient *self)
     /* by making this pass FALSE for user, we avoid the emacs event storm where
        every configurenotify causes an update in its normal hints, i think this
        is generally what we want anyways... */
-    client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y,
+    client_configure(self, self->area.x, self->area.y,
                      self->area.width, self->area.height, FALSE, TRUE);
 }
 
@@ -1850,7 +1879,7 @@ void client_update_icons(ObClient *self)
         RrPixel32 *icon = ob_rr_theme->def_win_icon;
         gulong *data;
 
-        data = g_new(guint32, 48*48+2);
+        data = g_new(gulong, 48*48+2);
         data[0] = data[1] =  48;
         for (i = 0; i < 48*48; ++i)
             data[i+2] = (((icon[i] >> RrDefaultAlphaOffset) & 0xff) << 24) +
@@ -2205,8 +2234,21 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y)
     */
 }
 
-void client_try_configure(ObClient *self, ObCorner anchor,
-                          gint *x, gint *y, gint *w, gint *h,
+void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y,
+                            gint w, gint h)
+{
+    gint oldg = self->gravity;
+
+    /* get the frame's position from the requested stuff */
+    self->gravity = gravity;
+    frame_client_gravity(self->frame, x, y, w, h);
+    self->gravity = oldg;
+
+    /* get the client's position in its true gravity from that */
+    frame_frame_gravity(self->frame, x, y, w, h);
+}
+
+void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
                           gint *logicalw, gint *logicalh,
                           gboolean user)
 {
@@ -2301,7 +2343,7 @@ void client_try_configure(ObClient *self, ObCorner anchor,
     }
 
     /* gets the frame's position */
-    frame_client_gravity(self->frame, x, y);
+    frame_client_gravity(self->frame, x, y, *w, *h);
 
     /* these positions are frame positions, not client positions */
 
@@ -2342,7 +2384,7 @@ void client_try_configure(ObClient *self, ObCorner anchor,
     }
 
     /* gets the client's position */
-    frame_frame_gravity(self->frame, x, y);
+    frame_frame_gravity(self->frame, x, y, *w, *h);
 
     /* these override the above states! if you cant move you can't move! */
     if (user) {
@@ -2358,26 +2400,10 @@ void client_try_configure(ObClient *self, ObCorner anchor,
 
     g_assert(*w > 0);
     g_assert(*h > 0);
-
-    switch (anchor) {
-    case OB_CORNER_TOPLEFT:
-        break;
-    case OB_CORNER_TOPRIGHT:
-        *x -= *w - self->area.width;
-        break;
-    case OB_CORNER_BOTTOMLEFT:
-        *y -= *h - self->area.height;
-        break;
-    case OB_CORNER_BOTTOMRIGHT:
-        *x -= *w - self->area.width;
-        *y -= *h - self->area.height;
-        break;
-    }
 }
 
 
-void client_configure_full(ObClient *self, ObCorner anchor,
-                           gint x, gint y, gint w, gint h,
+void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h,
                            gboolean user, gboolean final,
                            gboolean force_reply)
 {
@@ -2389,8 +2415,7 @@ void client_configure_full(ObClient *self, ObCorner anchor,
     gint logicalw, logicalh;
 
     /* find the new x, y, width, and height (and logical size) */
-    client_try_configure(self, anchor, &x, &y, &w, &h,
-                         &logicalw, &logicalh, user);
+    client_try_configure(self, &x, &y, &w, &h, &logicalw, &logicalh, user);
 
     /* set the logical size if things changed */
     if (!(w == self->area.width && h == self->area.height))
@@ -2412,10 +2437,8 @@ void client_configure_full(ObClient *self, ObCorner anchor,
                                     (resized && config_resize_redraw))));
 
     /* if the client is enlarging, then resize the client before the frame */
-    if (send_resize_client && user && (w > oldw || h > oldh)) {
+    if (send_resize_client && user && (w > oldw || h > oldh))
         XResizeWindow(ob_display, self->window, MAX(w, oldw), MAX(h, oldh));
-        frame_adjust_client_area(self->frame);
-    }
 
     /* find the frame's dimensions and move/resize it */
     if (self->decorations != fdecor || self->max_horz != fhorz)
@@ -2461,10 +2484,8 @@ void client_configure_full(ObClient *self, ObCorner anchor,
     }
 
     /* if the client is shrinking, then resize the frame before the client */
-    if (send_resize_client && (!user || (w <= oldw || h <= oldh))) {
-        frame_adjust_client_area(self->frame);
+    if (send_resize_client && (!user || (w <= oldw || h <= oldh)))
         XResizeWindow(ob_display, self->window, w, h);
-    }
 
     XFlush(ob_display);
 }
@@ -3106,6 +3127,9 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
     {
         client_hilite(self, TRUE);
     } else {
+        if (event_curtime != CurrentTime)
+            self->user_time = event_curtime;
+
         /* if using focus_delay, stop the timer now so that focus doesn't
            go moving on us */
         event_halt_focus_delay();
@@ -3235,7 +3259,7 @@ void client_set_undecorated(ObClient *self, gboolean undecorated)
          * since 125 of these are sent per second when moving the window (with
          * user = FALSE) i doubt it matters much.
          */
-        client_configure(self, OB_CORNER_TOPLEFT, self->area.x, self->area.y,
+        client_configure(self, self->area.x, self->area.y,
                          self->area.width, self->area.height, TRUE, TRUE);
         client_change_state(self); /* reflect this in the state hints */
     }
This page took 0.031026 seconds and 4 git commands to generate.