]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
new least-intrusive focus stealing prevention
[chaz/openbox] / openbox / client.c
index b8a2ea2454e7d3a384b434d061189b158d36f31c..cc721830153a715e44da59d22564ee791505f117 100644 (file)
@@ -1,5 +1,5 @@
 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-   
+
    client.c for the Openbox window manager
    Copyright (c) 2006        Mikael Magnusson
    Copyright (c) 2003-2007   Dana Jansens
    client.c for the Openbox window manager
    Copyright (c) 2006        Mikael Magnusson
    Copyright (c) 2003-2007   Dana Jansens
@@ -32,7 +32,6 @@
 #include "event.h"
 #include "grab.h"
 #include "focus.h"
 #include "event.h"
 #include "grab.h"
 #include "focus.h"
-#include "propwin.h"
 #include "stacking.h"
 #include "openbox.h"
 #include "group.h"
 #include "stacking.h"
 #include "openbox.h"
 #include "group.h"
@@ -213,8 +212,9 @@ void client_manage(Window window)
     XWMHints *wmhint;
     gboolean activate = FALSE;
     ObAppSettings *settings;
     XWMHints *wmhint;
     gboolean activate = FALSE;
     ObAppSettings *settings;
-    gint placex, placey, placew, placeh;
     gboolean transient = FALSE;
     gboolean transient = FALSE;
+    Rect place, *monitor;
+    Time launch_time, map_time;
 
     grab_server(TRUE);
 
 
     grab_server(TRUE);
 
@@ -237,7 +237,7 @@ void client_manage(Window window)
         grab_server(FALSE);
         return; /* don't manage it */
     }
         grab_server(FALSE);
         return; /* don't manage it */
     }
-  
+
     /* is the window a docking app */
     if ((wmhint = XGetWMHints(ob_display, window))) {
         if ((wmhint->flags & StateHint) &&
     /* is the window a docking app */
     if ((wmhint = XGetWMHints(ob_display, window))) {
         if ((wmhint->flags & StateHint) &&
@@ -253,6 +253,8 @@ void client_manage(Window window)
 
     ob_debug("Managing window: 0x%lx\n", window);
 
 
     ob_debug("Managing window: 0x%lx\n", window);
 
+    map_time = event_get_server_time();
+
     /* choose the events we want to receive on the CLIENT window */
     attrib_set.event_mask = CLIENT_EVENTMASK;
     attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
     /* choose the events we want to receive on the CLIENT window */
     attrib_set.event_mask = CLIENT_EVENTMASK;
     attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
@@ -269,7 +271,6 @@ void client_manage(Window window)
     self->wmstate = WithdrawnState; /* make sure it gets updated first time */
     self->gravity = NorthWestGravity;
     self->desktop = screen_num_desktops; /* always an invalid value */
     self->wmstate = WithdrawnState; /* make sure it gets updated first time */
     self->gravity = NorthWestGravity;
     self->desktop = screen_num_desktops; /* always an invalid value */
-    self->user_time = focus_client ? focus_client->user_time : CurrentTime;
 
     /* get all the stuff off the window */
     client_get_all(self, TRUE);
 
     /* get all the stuff off the window */
     client_get_all(self, TRUE);
@@ -300,10 +301,8 @@ void client_manage(Window window)
     /* now we have all of the window's information so we can set this up */
     client_setup_decor_and_functions(self, FALSE);
 
     /* now we have all of the window's information so we can set this up */
     client_setup_decor_and_functions(self, FALSE);
 
-    {
-        Time t = sn_app_started(self->startup_id, self->class);
-        if (t) self->user_time = t;
-    }
+    /* tell startup notification that this app started */
+    launch_time = sn_app_started(self->startup_id, self->class);
 
     /* do this after we have a frame.. it uses the frame to help determine the
        WM_STATE to apply. */
 
     /* do this after we have a frame.. it uses the frame to help determine the
        WM_STATE to apply. */
@@ -337,10 +336,8 @@ void client_manage(Window window)
     frame_adjust_client_area(self->frame);
 
     /* where the frame was placed is where the window was originally */
     frame_adjust_client_area(self->frame);
 
     /* where the frame was placed is where the window was originally */
-    placex = self->area.x;
-    placey = self->area.y;
-    placew = self->area.width;
-    placeh = self->area.height;
+    place = self->area;
+    monitor = screen_physical_area_monitor(screen_find_monitor(&place));
 
     /* figure out placement for the window if the window is new */
     if (ob_state() == OB_STATE_RUNNING) {
 
     /* figure out placement for the window if the window is new */
     if (ob_state() == OB_STATE_RUNNING) {
@@ -350,7 +347,7 @@ void client_manage(Window window)
                    (self->positioned == USPosition ? "user specified" :
                     (self->positioned == (PPosition | USPosition) ?
                      "program + user specified" :
                    (self->positioned == USPosition ? "user specified" :
                     (self->positioned == (PPosition | USPosition) ?
                      "program + user specified" :
-                     "BADNESS !?")))), placex, placey);
+                     "BADNESS !?")))), place.x, place.y);
 
         ob_debug("Sized: %s @ %d %d\n",
                  (!self->sized ? "no" :
 
         ob_debug("Sized: %s @ %d %d\n",
                  (!self->sized ? "no" :
@@ -358,14 +355,15 @@ void client_manage(Window window)
                    (self->sized == USSize ? "user specified" :
                     (self->sized == (PSize | USSize) ?
                      "program + user specified" :
                    (self->sized == USSize ? "user specified" :
                     (self->sized == (PSize | USSize) ?
                      "program + user specified" :
-                     "BADNESS !?")))), placew, placeh);
+                     "BADNESS !?")))), place.width, place.height);
 
         /* splash screens are also returned as TRUE for transient,
            and so will be forced on screen below */
 
         /* splash screens are also returned as TRUE for transient,
            and so will be forced on screen below */
-        transient = place_client(self, &placex, &placey, settings);
+        transient = place_client(self, &place.x, &place.y, settings);
 
         /* make sure the window is visible. */
 
         /* make sure the window is visible. */
-        client_find_onscreen(self, &placex, &placey, placew, placeh,
+        client_find_onscreen(self, &place.x, &place.y,
+                             place.width, place.height,
                              /* non-normal clients has less rules, and
                                 windows that are being restored from a
                                 session do also. we can assume you want
                              /* non-normal clients has less rules, and
                                 windows that are being restored from a
                                 session do also. we can assume you want
@@ -385,7 +383,13 @@ void client_manage(Window window)
                               (!((self->positioned & USPosition) ||
                                  (settings && settings->pos_given)) &&
                                client_normal(self) &&
                               (!((self->positioned & USPosition) ||
                                  (settings && settings->pos_given)) &&
                                client_normal(self) &&
-                               !self->session)));
+                               !self->session &&
+                               /* don't move oldschool fullscreen windows to
+                                  fit inside the struts (fixes Acroread, which
+                                  makes its fullscreen window fit the screen
+                                  but it is not USSize'd or USPosition'd) */
+                               !(self->decorations == 0 &&
+                                 RECT_EQUAL(place, *monitor)))));
     }
 
     /* if the window isn't user-sized, then make it fit inside
     }
 
     /* if the window isn't user-sized, then make it fit inside
@@ -401,34 +405,34 @@ void client_manage(Window window)
         (transient ||
          (!(self->sized & USSize || self->positioned & USPosition) &&
           client_normal(self) &&
         (transient ||
          (!(self->sized & USSize || self->positioned & USPosition) &&
           client_normal(self) &&
-          !self->session)))
+          !self->session &&
+          /* don't shrink oldschool fullscreen windows to fit inside the
+             struts (fixes Acroread, which makes its fullscreen window
+             fit the screen but it is not USSize'd or USPosition'd) */
+          !(self->decorations == 0 && RECT_EQUAL(place, *monitor)))))
     {
     {
-        Rect placer;
+        Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &place);
 
 
-        RECT_SET(placer, placex, placey, placew, placeh);
-        frame_rect_to_frame(self->frame, &placer);
+        /* get the size of the frame */
+        place.width += self->frame->size.left + self->frame->size.right;
+        place.height += self->frame->size.top + self->frame->size.bottom;
 
 
-        Rect *a = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, &placer);
+        /* fit the window inside the area */
+        place.width = MIN(place.width, a->width);
+        place.height = MIN(place.height, a->height);
 
 
-        /* shrink by the frame's area */
-        a->width -= self->frame->size.left + self->frame->size.right;
-        a->height -= self->frame->size.top + self->frame->size.bottom;
+        ob_debug("setting window size to %dx%d\n", place.width, place.height);
 
 
-        /* fit the window inside the area */
-        if (placew > a->width || self->area.height > a->height) {
-            placew = MIN(self->area.width, a->width);
-            placeh = MIN(self->area.height, a->height);
+        /* get the size of the client back */
+        place.width -= self->frame->size.left + self->frame->size.right;
+        place.height -= self->frame->size.top + self->frame->size.bottom;
 
 
-            ob_debug("setting window size to %dx%d\n",
-                     self->area.width, self->area.height);
-        }
         g_free(a);
     }
 
         g_free(a);
     }
 
-
     ob_debug("placing window 0x%x at %d, %d with size %d x %d. "
              "some restrictions may apply\n",
     ob_debug("placing window 0x%x at %d, %d with size %d x %d. "
              "some restrictions may apply\n",
-             self->window, placex, placey, placew, placeh);
+             self->window, place.x, place.y, place.width, place.height);
     if (self->session)
         ob_debug("  but session requested %d, %d  %d x %d instead, "
                  "overriding\n",
     if (self->session)
         ob_debug("  but session requested %d, %d  %d x %d instead, "
                  "overriding\n",
@@ -440,25 +444,40 @@ void client_manage(Window window)
 
        this also places the window
     */
 
        this also places the window
     */
-    client_apply_startup_state(self, placex, placey, placew, placeh);
+    client_apply_startup_state(self, place.x, place.y,
+                               place.width, place.height);
+
+    g_free(monitor);
+    monitor = NULL;
 
     if (activate) {
 
     if (activate) {
-        guint32 last_time = focus_client ?
-            focus_client->user_time : CurrentTime;
+        gboolean raise = FALSE;
 
         /* This is focus stealing prevention */
         ob_debug_type(OB_DEBUG_FOCUS,
 
         /* This is focus stealing prevention */
         ob_debug_type(OB_DEBUG_FOCUS,
-                      "Want to focus new window 0x%x with time %u "
-                      "(last time %u)\n",
-                      self->window, self->user_time, last_time);
+                      "Want to focus new window 0x%x at time %u "
+                      "launched at %u (last user interaction time %u)\n",
+                      self->window, map_time, launch_time,
+                      event_last_user_time);
+
+        if (menu_frame_visible || moveresize_in_progress) {
+            activate = FALSE;
+            raise = TRUE;
+            ob_debug_type(OB_DEBUG_FOCUS,
+                          "Not focusing the window because the user is inside "
+                          "an Openbox menu or is move/resizing a window and "
+                          "we don't want to interrupt them\n");
+        }
 
         /* if it's on another desktop */
 
         /* 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))
+        else if (!(self->desktop == screen_desktop ||
+              self->desktop == DESKTOP_ALL) &&
+            /* the timestamp is from before you changed desktops */
+            launch_time && screen_desktop_user_time &&
+            !event_time_after(launch_time, screen_desktop_user_time))
         {
             activate = FALSE;
         {
             activate = FALSE;
+            raise = TRUE;
             ob_debug_type(OB_DEBUG_FOCUS,
                           "Not focusing the window because its on another "
                           "desktop\n");
             ob_debug_type(OB_DEBUG_FOCUS,
                           "Not focusing the window because its on another "
                           "desktop\n");
@@ -467,26 +486,25 @@ void client_manage(Window window)
         else if (focus_client && client_search_focus_tree_full(self) == NULL &&
                  client_search_focus_group_full(self) == NULL)
         {
         else if (focus_client && client_search_focus_tree_full(self) == NULL &&
                  client_search_focus_group_full(self) == NULL)
         {
-            /* If time stamp is old, don't steal focus */
-            if (self->user_time && last_time &&
-                !event_time_after(self->user_time, last_time))
+            /* If the user is working in another window right now, then don't
+               steal focus */
+            if (event_last_user_time && launch_time &&
+                event_time_after(event_last_user_time, launch_time) &&
+                event_last_user_time != launch_time &&
+                event_time_after(event_last_user_time,
+                                 map_time - OB_EVENT_USER_TIME_DELAY))
             {
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
             {
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
-                              "Not focusing the window because the time is "
-                              "too old\n");
+                              "Not focusing the window because the user is "
+                              "working in another window\n");
             }
             }
-            /* If its a transient (and parents aren't focused) and the time
-               is ambiguous (either the current focus target doesn't have
-               a timestamp, or they are the same (we probably inherited it
-               from them) */
-            else if (client_has_parent(self) &&
-                     (!last_time || self->user_time == last_time))
-            {
+            /* If its a transient (and its parents aren't focused) */
+            else if (client_has_parent(self)) {
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Not focusing the window because it is a "
                 activate = FALSE;
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Not focusing the window because it is a "
-                              "transient, and the time is very ambiguous\n");
+                              "transient, and its relatives aren't focused\n");
             }
             /* Don't steal focus from globally active clients.
                I stole this idea from KWin. It seems nice.
             }
             /* Don't steal focus from globally active clients.
                I stole this idea from KWin. It seems nice.
@@ -503,6 +521,7 @@ void client_manage(Window window)
                anyway */
             else if (client_focus_target(self) != self) {
                 activate = FALSE;
                anyway */
             else if (client_focus_target(self) != self) {
                 activate = FALSE;
+                raise = TRUE;
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Not focusing the window because another window "
                               "would get the focus anyway\n");
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Not focusing the window because another window "
                               "would get the focus anyway\n");
@@ -511,12 +530,15 @@ void client_manage(Window window)
 
         if (!activate) {
             ob_debug_type(OB_DEBUG_FOCUS,
 
         if (!activate) {
             ob_debug_type(OB_DEBUG_FOCUS,
-                          "Focus stealing prevention activated for %s with "
-                          "time %u (last time %u)\n",
-                          self->title, self->user_time, last_time);
+                          "Focus stealing prevention activated for %s at "
+                          "time %u (last user interactioon time %u)\n",
+                          self->title, map_time, event_last_user_time);
             /* if the client isn't focused, then hilite it so the user
                knows it is there */
             client_hilite(self, TRUE);
             /* if the client isn't focused, then hilite it so the user
                knows it is there */
             client_hilite(self, TRUE);
+            /* we may want to raise it even tho we're not activating it */
+            if (raise && !client_restore_session_stacking(self))
+                stacking_raise(CLIENT_AS_WINDOW(self));
         }
     }
     else {
         }
     }
     else {
@@ -597,7 +619,7 @@ ObClient *client_fake_manage(Window window)
     frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
 
     ob_debug("gave extents left %d right %d top %d bottom %d\n",
     frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
 
     ob_debug("gave extents left %d right %d top %d bottom %d\n",
-             self->frame->size.left, self->frame->size.right, 
+             self->frame->size.left, self->frame->size.right,
              self->frame->size.top, self->frame->size.bottom);
 
     /* free the ObAppSettings shallow copy */
              self->frame->size.top, self->frame->size.bottom);
 
     /* free the ObAppSettings shallow copy */
@@ -644,9 +666,6 @@ void client_unmanage(ObClient *self)
     /* remove the window from our save set */
     XChangeSaveSet(ob_display, self->window, SetModeDelete);
 
     /* remove the window from our save set */
     XChangeSaveSet(ob_display, self->window, SetModeDelete);
 
-    /* kill the property windows */
-    propwin_remove(self->user_time_window, OB_PROPWIN_USER_TIME, self);
-
     /* update the focus lists */
     focus_order_remove(self);
     if (client_focused(self)) {
     /* update the focus lists */
     focus_order_remove(self);
     if (client_focused(self)) {
@@ -1078,7 +1097,7 @@ static void client_get_all(ObClient *self, gboolean real)
         if (self->type == OB_CLIENT_TYPE_DESKTOP)
             self->desktop = DESKTOP_ALL;
     }
         if (self->type == OB_CLIENT_TYPE_DESKTOP)
             self->desktop = DESKTOP_ALL;
     }
-  
+
 #ifdef SYNC
     client_update_sync_request_counter(self);
 #endif
 #ifdef SYNC
     client_update_sync_request_counter(self);
 #endif
@@ -1086,9 +1105,6 @@ static void client_get_all(ObClient *self, gboolean real)
     client_get_colormap(self);
     client_update_strut(self);
     client_update_icons(self);
     client_get_colormap(self);
     client_update_strut(self);
     client_update_icons(self);
-    client_update_user_time_window(self);
-    if (!self->user_time_window) /* check if this would have been called */
-        client_update_user_time(self);
     client_update_icon_geometry(self);
 }
 
     client_update_icon_geometry(self);
 }
 
@@ -1104,7 +1120,7 @@ static void client_get_area(ObClient *self)
 {
     XWindowAttributes wattrib;
     Status ret;
 {
     XWindowAttributes wattrib;
     Status ret;
-  
+
     ret = XGetWindowAttributes(ob_display, self->window, &wattrib);
     g_assert(ret != BadWindow);
 
     ret = XGetWindowAttributes(ob_display, self->window, &wattrib);
     g_assert(ret != BadWindow);
 
@@ -1125,7 +1141,7 @@ static void client_get_desktop(ObClient *self)
             self->desktop = screen_num_desktops - 1;
         else
             self->desktop = d;
             self->desktop = screen_num_desktops - 1;
         else
             self->desktop = d;
-        ob_debug("client requested desktop 0x%x\n", self->desktop); 
+        ob_debug("client requested desktop 0x%x\n", self->desktop);
     } else {
         GSList *it;
         gboolean first = TRUE;
     } else {
         GSList *it;
         gboolean first = TRUE;
@@ -1172,7 +1188,7 @@ static void client_get_state(ObClient *self)
 {
     guint32 *state;
     guint num;
 {
     guint32 *state;
     guint num;
-  
+
     if (PROP_GETA32(self->window, net_wm_state, atom, &state, &num)) {
         gulong i;
         for (i = 0; i < num; ++i) {
     if (PROP_GETA32(self->window, net_wm_state, atom, &state, &num)) {
         gulong i;
         for (i = 0; i < num; ++i) {
@@ -1255,7 +1271,7 @@ void client_update_transient_for(ObClient *self)
                                  self->transient_for_group, trangroup,
                                  client_direct_parent(self), target);
     self->transient_for_group = trangroup;
                                  self->transient_for_group, trangroup,
                                  client_direct_parent(self), target);
     self->transient_for_group = trangroup;
-                          
+
 }
 
 static void client_update_transient_tree(ObClient *self,
 }
 
 static void client_update_transient_tree(ObClient *self,
@@ -1401,7 +1417,7 @@ void client_get_type_and_transientness(ObClient *self)
 
     self->type = -1;
     self->transient = FALSE;
 
     self->type = -1;
     self->transient = FALSE;
-  
+
     if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) {
         /* use the first value that we know about in the array */
         for (i = 0; i < num; ++i) {
     if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) {
         /* use the first value that we know about in the array */
         for (i = 0; i < num; ++i) {
@@ -1437,7 +1453,7 @@ void client_get_type_and_transientness(ObClient *self)
 
     if (XGetTransientForHint(ob_display, self->window, &t))
         self->transient = TRUE;
 
     if (XGetTransientForHint(ob_display, self->window, &t))
         self->transient = TRUE;
-            
+
     if (self->type == (ObClientType) -1) {
         /*the window type hint was not set, which means we either classify
           ourself as a normal window or a dialog, depending on if we are a
     if (self->type == (ObClientType) -1) {
         /*the window type hint was not set, which means we either classify
           ourself as a normal window or a dialog, depending on if we are a
@@ -1476,7 +1492,7 @@ void client_update_protocols(ObClient *self)
                    notified whenever we want it to receive focus */
                 self->focus_notify = TRUE;
 #ifdef SYNC
                    notified whenever we want it to receive focus */
                 self->focus_notify = TRUE;
 #ifdef SYNC
-            else if (proto[i] == prop_atoms.net_wm_sync_request) 
+            else if (proto[i] == prop_atoms.net_wm_sync_request)
                 /* if this protocol is requested, then resizing the
                    window will be synchronized between the frame and the
                    client */
                 /* if this protocol is requested, then resizing the
                    window will be synchronized between the frame and the
                    client */
@@ -1556,13 +1572,13 @@ void client_update_normal_hints(ObClient *self)
 
         if (size.flags & PMinSize)
             SIZE_SET(self->min_size, size.min_width, size.min_height);
 
         if (size.flags & PMinSize)
             SIZE_SET(self->min_size, size.min_width, size.min_height);
-    
+
         if (size.flags & PMaxSize)
             SIZE_SET(self->max_size, size.max_width, size.max_height);
         if (size.flags & PMaxSize)
             SIZE_SET(self->max_size, size.max_width, size.max_height);
-    
+
         if (size.flags & PBaseSize)
             SIZE_SET(self->base_size, size.base_width, size.base_height);
         if (size.flags & PBaseSize)
             SIZE_SET(self->base_size, size.base_width, size.base_height);
-    
+
         if (size.flags & PResizeInc && size.width_inc && size.height_inc)
             SIZE_SET(self->size_inc, size.width_inc, size.height_inc);
 
         if (size.flags & PResizeInc && size.width_inc && size.height_inc)
             SIZE_SET(self->size_inc, size.width_inc, size.height_inc);
 
@@ -1796,7 +1812,7 @@ void client_update_wmhints(ObClient *self)
 
     /* assume a window takes input if it doesnt specify */
     self->can_focus = TRUE;
 
     /* assume a window takes input if it doesnt specify */
     self->can_focus = TRUE;
-  
+
     if ((hints = XGetWMHints(ob_display, self->window)) != NULL) {
         gboolean ur;
 
     if ((hints = XGetWMHints(ob_display, self->window)) != NULL) {
         gboolean ur;
 
@@ -1883,7 +1899,7 @@ void client_update_title(ObClient *self)
     gchar *visible = NULL;
 
     g_free(self->title);
     gchar *visible = NULL;
 
     g_free(self->title);
-     
+
     /* try netwm */
     if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) {
         /* try old x stuff */
     /* try netwm */
     if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) {
         /* try old x stuff */
@@ -2011,7 +2027,7 @@ void client_update_icons(ObClient *self)
         }
 
         self->icons = g_new(ObClientIcon, self->nicons);
         }
 
         self->icons = g_new(ObClientIcon, self->nicons);
-    
+
         /* store the icons */
         i = 0;
         for (j = 0; j < self->nicons; ++j) {
         /* store the icons */
         i = 0;
         for (j = 0; j < self->nicons; ++j) {
@@ -2068,7 +2084,7 @@ void client_update_icons(ObClient *self)
        or removes it entirely, it's not very likely it is going to set one
        right away afterwards
 
        or removes it entirely, it's not very likely it is going to set one
        right away afterwards
 
-       if it has parents, then one of them will have an icon already 
+       if it has parents, then one of them will have an icon already
     */
     if (self->nicons == 0 && !self->parents) {
         RrPixel32 *icon = ob_rr_theme->def_win_icon;
     */
     if (self->nicons == 0 && !self->parents) {
         RrPixel32 *icon = ob_rr_theme->def_win_icon;
@@ -2089,62 +2105,6 @@ void client_update_icons(ObClient *self)
         frame_adjust_icon(self->frame);
 }
 
         frame_adjust_icon(self->frame);
 }
 
-void client_update_user_time(ObClient *self)
-{
-    guint32 time;
-    gboolean got = FALSE;
-
-    if (self->user_time_window)
-        got = PROP_GET32(self->user_time_window,
-                         net_wm_user_time, cardinal, &time);
-    if (!got)
-        got = PROP_GET32(self->window, net_wm_user_time, cardinal, &time);
-
-    if (got) {
-        /* we set this every time, not just when it grows, because in practice
-           sometimes time goes backwards! (ntpdate.. yay....) so.. if it goes
-           backward we don't want all windows to stop focusing. we'll just
-           assume noone is setting times older than the last one, cuz that
-           would be pretty stupid anyways
-        */
-        self->user_time = time;
-
-        /*ob_debug("window %s user time %u\n", self->title, time);*/
-    }
-}
-
-void client_update_user_time_window(ObClient *self)
-{
-    guint32 w;
-
-    if (!PROP_GET32(self->window, net_wm_user_time_window, window, &w))
-        w = None;
-
-    if (w != self->user_time_window) {
-        /* remove the old window */
-        propwin_remove(self->user_time_window, OB_PROPWIN_USER_TIME, self);
-        self->user_time_window = None;
-
-        if (self->group && self->group->leader == w) {
-            ob_debug_type(OB_DEBUG_APP_BUGS, "Window is setting its "
-                          "_NET_WM_USER_TYPE_WINDOW to its group leader\n");
-            /* do it anyways..? */
-        }
-        else if (w == self->window) {
-            ob_debug_type(OB_DEBUG_APP_BUGS, "Window is setting its "
-                          "_NET_WM_USER_TIME_WINDOW to itself\n");
-            w = None; /* don't do it */
-        }
-
-        /* add the new window */
-        propwin_add(w, OB_PROPWIN_USER_TIME, self);
-        self->user_time_window = w;
-
-        /* and update from it */
-        client_update_user_time(self);
-    }
-}
-
 void client_update_icon_geometry(ObClient *self)
 {
     guint num;
 void client_update_icon_geometry(ObClient *self)
 {
     guint num;
@@ -2442,7 +2402,7 @@ gboolean client_should_show(ObClient *self)
         return FALSE;
     if (self->desktop == screen_desktop || self->desktop == DESKTOP_ALL)
         return TRUE;
         return FALSE;
     if (self->desktop == screen_desktop || self->desktop == DESKTOP_ALL)
         return TRUE;
-    
+
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -2586,7 +2546,7 @@ static void client_apply_startup_state(ObClient *self,
         client_shade(self, TRUE);
     if (demands_attention)
         client_hilite(self, TRUE);
         client_shade(self, TRUE);
     if (demands_attention)
         client_hilite(self, TRUE);
-  
+
     if (max_vert && max_horz)
         client_maximize(self, TRUE, 0);
     else if (max_vert)
     if (max_vert && max_horz)
         client_maximize(self, TRUE, 0);
     else if (max_vert)
@@ -2788,7 +2748,7 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
         /* you cannot resize to nothing */
         if (basew + *w < 1) *w = 1 - basew;
         if (baseh + *h < 1) *h = 1 - baseh;
         /* you cannot resize to nothing */
         if (basew + *w < 1) *w = 1 - basew;
         if (baseh + *h < 1) *h = 1 - baseh;
-  
+
         /* save the logical size */
         *logicalw = incw > 1 ? *w : *w + basew;
         *logicalh = inch > 1 ? *h : *h + baseh;
         /* save the logical size */
         *logicalw = incw > 1 ? *w : *w + basew;
         *logicalh = inch > 1 ? *h : *h + baseh;
@@ -3103,7 +3063,7 @@ void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk,
 void client_maximize(ObClient *self, gboolean max, gint dir)
 {
     gint x, y, w, h;
 void client_maximize(ObClient *self, gboolean max, gint dir)
 {
     gint x, y, w, h;
-     
+
     g_assert(dir == 0 || dir == 1 || dir == 2);
     if (!(self->functions & OB_CLIENT_FUNC_MAXIMIZE)) return; /* can't */
 
     g_assert(dir == 0 || dir == 1 || dir == 2);
     if (!(self->functions & OB_CLIENT_FUNC_MAXIMIZE)) return; /* can't */
 
@@ -3191,7 +3151,7 @@ void client_close(ObClient *self)
        close, we just kill it */
     if (!self->delete_window)
         client_kill(self);
        close, we just kill it */
     if (!self->delete_window)
         client_kill(self);
-    
+
     /*
       XXX: itd be cool to do timeouts and shit here for killing the client's
       process off
     /*
       XXX: itd be cool to do timeouts and shit here for killing the client's
       process off
@@ -3293,7 +3253,7 @@ ObClient *client_search_modal_child(ObClient *self)
 {
     GSList *it;
     ObClient *ret;
 {
     GSList *it;
     ObClient *ret;
-  
+
     for (it = self->transients; it; it = g_slist_next(it)) {
         ObClient *c = it->data;
         if ((ret = client_search_modal_child(c))) return ret;
     for (it = self->transients; it; it = g_slist_next(it)) {
         ObClient *c = it->data;
         if ((ret = client_search_modal_child(c))) return ret;
@@ -3304,7 +3264,7 @@ ObClient *client_search_modal_child(ObClient *self)
 
 gboolean client_validate(ObClient *self)
 {
 
 gboolean client_validate(ObClient *self)
 {
-    XEvent e; 
+    XEvent e;
 
     XSync(ob_display, FALSE); /* get all events on the server */
 
 
     XSync(ob_display, FALSE); /* get all events on the server */
 
@@ -3320,7 +3280,7 @@ gboolean client_validate(ObClient *self)
 void client_set_wm_state(ObClient *self, glong state)
 {
     if (state == self->wmstate) return; /* no change */
 void client_set_wm_state(ObClient *self, glong state)
 {
     if (state == self->wmstate) return; /* no change */
-  
+
     switch (state) {
     case IconicState:
         client_iconify(self, TRUE, TRUE, FALSE);
     switch (state) {
     case IconicState:
         client_iconify(self, TRUE, TRUE, FALSE);
@@ -3349,11 +3309,11 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
           action == prop_atoms.net_wm_state_remove ||
           action == prop_atoms.net_wm_state_toggle))
         /* an invalid action was passed to the client message, ignore it */
           action == prop_atoms.net_wm_state_remove ||
           action == prop_atoms.net_wm_state_toggle))
         /* an invalid action was passed to the client message, ignore it */
-        return; 
+        return;
 
     for (i = 0; i < 2; ++i) {
         Atom state = i == 0 ? data1 : data2;
 
     for (i = 0; i < 2; ++i) {
         Atom state = i == 0 ? data1 : data2;
-    
+
         if (!state) continue;
 
         /* if toggling, then pick whether we're adding or removing */
         if (!state) continue;
 
         /* if toggling, then pick whether we're adding or removing */
@@ -3400,7 +3360,7 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2)
                 action = undecorated ? prop_atoms.net_wm_state_remove :
                     prop_atoms.net_wm_state_add;
         }
                 action = undecorated ? prop_atoms.net_wm_state_remove :
                     prop_atoms.net_wm_state_add;
         }
-    
+
         if (action == prop_atoms.net_wm_state_add) {
             if (state == prop_atoms.net_wm_state_modal) {
                 modal = TRUE;
         if (action == prop_atoms.net_wm_state_add) {
             if (state == prop_atoms.net_wm_state_modal) {
                 modal = TRUE;
@@ -3626,34 +3586,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise,
 void client_activate(ObClient *self, gboolean here, gboolean raise,
                      gboolean unshade, gboolean user)
 {
 void client_activate(ObClient *self, gboolean here, gboolean raise,
                      gboolean unshade, gboolean user)
 {
-    guint32 last_time = focus_client ? focus_client->user_time : CurrentTime;
-    gboolean allow = FALSE;
-
-    /* if the currently focused app doesn't set a user_time, then it can't
-       benefit from any focus stealing prevention.
-
-       if the timestamp is missing in the request then let it go through
-       even if it is source=app, because EVERY APPLICATION DOES THIS because
-       GTK IS VERY BUGGY AND HARDCODES source=application... WHY!?
-    */
-    if (!last_time || !event_curtime)
-        allow = TRUE;
-    /* otherwise, if they didn't give a time stamp or if it is too old, they
-       don't get focus */
-    else
-        allow = event_time_after(event_curtime, last_time);
-
-    ob_debug_type(OB_DEBUG_FOCUS,
-                  "Want to activate window 0x%x with time %u (last time %u), "
-                  "source=%s allowing? %d\n",
-                  self->window, event_curtime, last_time,
-                  (user ? "user" : "application"), allow);
-
-    if (allow)
-        client_present(self, here, raise, unshade);
-    else
-        /* don't focus it but tell the user it wants attention */
-        client_hilite(self, TRUE);
+    client_present(self, here, raise, unshade);
 }
 
 static void client_bring_windows_recursive(ObClient *self,
 }
 
 static void client_bring_windows_recursive(ObClient *self,
@@ -3709,7 +3642,7 @@ static ObClientIcon* client_icon_recursive(ObClient *self, gint w, gint h)
             if ((parent = client_icon_recursive(c, w, h)))
                 break;
         }
             if ((parent = client_icon_recursive(c, w, h)))
                 break;
         }
-        
+
         return parent;
     }
 
         return parent;
     }
 
@@ -3763,7 +3696,7 @@ void client_set_layer(ObClient *self, gint layer)
 void client_set_undecorated(ObClient *self, gboolean undecorated)
 {
     if (self->undecorated != undecorated &&
 void client_set_undecorated(ObClient *self, gboolean undecorated)
 {
     if (self->undecorated != undecorated &&
-        /* don't let it undecorate if the function is missing, but let 
+        /* don't let it undecorate if the function is missing, but let
            it redecorate */
         (self->functions & OB_CLIENT_FUNC_UNDECORATE || !undecorated))
     {
            it redecorate */
         (self->functions & OB_CLIENT_FUNC_UNDECORATE || !undecorated))
     {
@@ -3783,7 +3716,7 @@ ObClient *client_direct_parent(ObClient *self)
     if (!self->parents) return NULL;
     if (self->transient_for_group) return NULL;
     return self->parents->data;
     if (!self->parents) return NULL;
     if (self->transient_for_group) return NULL;
     return self->parents->data;
-}                        
+}
 
 ObClient *client_search_top_direct_parent(ObClient *self)
 {
 
 ObClient *client_search_top_direct_parent(ObClient *self)
 {
@@ -3798,7 +3731,7 @@ static GSList *client_search_all_top_parents_internal(ObClient *self,
 {
     GSList *ret;
     ObClient *p;
 {
     GSList *ret;
     ObClient *p;
-    
+
     /* move up the direct transient chain as far as possible */
     while ((p = client_direct_parent(self)) &&
            (!bylayer || p->layer == layer))
     /* move up the direct transient chain as far as possible */
     while ((p = client_direct_parent(self)) &&
            (!bylayer || p->layer == layer))
@@ -3962,25 +3895,25 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
 
     switch(dir) {
     case OB_DIRECTION_NORTH:
 
     switch(dir) {
     case OB_DIRECTION_NORTH:
-        if (my_head >= RECT_TOP(*mon))
+        if (my_head >= RECT_TOP(*mon) + 1)
             edge = RECT_TOP(*mon) - 1;
         else
             edge = RECT_TOP(*a) - 1;
         break;
     case OB_DIRECTION_SOUTH:
             edge = RECT_TOP(*mon) - 1;
         else
             edge = RECT_TOP(*a) - 1;
         break;
     case OB_DIRECTION_SOUTH:
-        if (my_head <= RECT_BOTTOM(*mon))
+        if (my_head <= RECT_BOTTOM(*mon) - 1)
             edge = RECT_BOTTOM(*mon) + 1;
         else
             edge = RECT_BOTTOM(*a) + 1;
         break;
     case OB_DIRECTION_EAST:
             edge = RECT_BOTTOM(*mon) + 1;
         else
             edge = RECT_BOTTOM(*a) + 1;
         break;
     case OB_DIRECTION_EAST:
-        if (my_head <= RECT_RIGHT(*mon))
+        if (my_head <= RECT_RIGHT(*mon) - 1)
             edge = RECT_RIGHT(*mon) + 1;
         else
             edge = RECT_RIGHT(*a) + 1;
         break;
     case OB_DIRECTION_WEST:
             edge = RECT_RIGHT(*mon) + 1;
         else
             edge = RECT_RIGHT(*a) + 1;
         break;
     case OB_DIRECTION_WEST:
-        if (my_head >= RECT_LEFT(*mon))
+        if (my_head >= RECT_LEFT(*mon) + 1)
             edge = RECT_LEFT(*mon) - 1;
         else
             edge = RECT_LEFT(*a) - 1;
             edge = RECT_LEFT(*mon) - 1;
         else
             edge = RECT_LEFT(*a) - 1;
This page took 0.039752 seconds and 4 git commands to generate.