]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
Resizing removes maximization now, so don't only snap "grow to edge" to screen edges.
[chaz/openbox] / openbox / client.c
index bdfe9391f3518a4f977a82210309cc1be0e2ba0e..6a169336cae0452b97e2cd556ffec4667190da57 100644 (file)
@@ -110,6 +110,7 @@ static void client_ping_event(ObClient *self, gboolean dead);
 static void client_prompt_kill(ObClient *self);
 static gboolean client_can_steal_focus(ObClient *self,
                                        gboolean allow_other_desktop,
+                                       gboolean request_from_user,
                                        Time steal_time, Time launch_time);
 
 void client_startup(gboolean reconfig)
@@ -302,8 +303,10 @@ void client_manage(Window window, ObPrompt *prompt)
     ob_debug("Going to try activate new window? %s",
              try_activate ? "yes" : "no");
     if (try_activate)
-        do_activate = client_can_steal_focus(self, settings->focus,
-                                             event_time(), launch_time);
+        do_activate = client_can_steal_focus(
+            self, settings->focus == 1,
+            (!!launch_time || settings->focus == 1),
+            event_time(), launch_time);
     else
         do_activate = FALSE;
 
@@ -694,6 +697,7 @@ void client_fake_unmanage(ObClient *self)
 
 static gboolean client_can_steal_focus(ObClient *self,
                                        gboolean allow_other_desktop,
+                                       gboolean request_from_user,
                                        Time steal_time,
                                        Time launch_time)
 {
@@ -708,18 +712,75 @@ static gboolean client_can_steal_focus(ObClient *self,
 
     /* This is focus stealing prevention */
     ob_debug("Want to focus window 0x%x at time %u "
-             "launched at %u (last user interaction time %u)",
+             "launched at %u (last user interaction time %u) "
+             "request from %s, allow other desktop: %s",
              self->window, steal_time, launch_time,
-             event_last_user_time);
+             event_last_user_time,
+             (request_from_user ? "user" : "other"),
+             (allow_other_desktop ? "yes" : "no"));
 
-    /* if it's on another desktop... */
+    /*
+      if no launch time is provided for an application, make one up.
+
+      if the window is related to other existing windows
+        and one of those windows was the last used
+          then we will give it a launch time equal to the last user time,
+          which will end up giving the window focus probably.
+        else
+          the window is related to other windows, but you are not working in
+          them?
+          seems suspicious, so we will give it a launch time of
+          NOW - STEAL_INTERVAL,
+          so it will be given focus only if we didn't use something else
+          during the steal interval.
+      else
+        the window is all on its own, so we can't judge it.  give it a launch
+        time equal to the last user time, so it will probably take focus.
+
+      this way running things from a terminal will give them focus, but popups
+      without a launch time shouldn't steal focus so easily.
+    */
+
+    if (!launch_time) {
+        if (client_has_relative(self)) {
+            if (event_last_user_time && client_search_focus_group_full(self)) {
+                /* our relative is focused */
+                launch_time = event_last_user_time;
+                ob_debug("Unknown launch time, using %u - window in active "
+                         "group", launch_time);
+            }
+            else if (!request_from_user) {
+                /* has relatives which are not being used. suspicious */
+                launch_time = event_time() - OB_EVENT_USER_TIME_DELAY;
+                ob_debug("Unknown launch time, using %u - window in inactive "
+                         "group", launch_time);
+            }
+            else {
+                /* has relatives which are not being used, but the user seems
+                   to want to go there! */
+            launch_time = event_last_user_time;
+            ob_debug("Unknown launch time, using %u - user request",
+                     launch_time);
+            }
+        }
+        else {
+            /* the window is on its own, probably the user knows it is going
+               to appear */
+            launch_time = event_last_user_time;
+            ob_debug("Unknown launch time, using %u - independent window",
+                     launch_time);
+        }
+    }
+
+    /* if it's on another desktop
+       then if allow_other_desktop is true, we don't want to let it steal
+       focus, unless it was launched after we changed desktops and the request
+       came from the user
+     */
     if (!(self->desktop == screen_desktop ||
           self->desktop == DESKTOP_ALL) &&
-        /* and (we dont know when it launched, and we don't want to allow
-           focus stealing from other desktops */
-        ((!launch_time && !allow_other_desktop) ||
-         /* or the timestamp is from before you changed desktops) */
-         (screen_desktop_user_time &&
+        (!allow_other_desktop ||
+         (request_from_user && screen_desktop_user_time &&
           !event_time_after(launch_time, screen_desktop_user_time))))
     {
         steal = FALSE;
@@ -731,9 +792,9 @@ static gboolean client_can_steal_focus(ObClient *self,
            steal focus */
         if (!relative_focused &&
             event_last_user_time &&
-            (!launch_time ||
-             (event_time_after(event_last_user_time, launch_time) &&
-              event_last_user_time != launch_time)) &&
+            /* last user time must be strictly > launch_time to block focus */
+            (event_time_after(event_last_user_time, launch_time) &&
+             event_last_user_time != launch_time) &&
             event_time_after(event_last_user_time,
                              steal_time - OB_EVENT_USER_TIME_DELAY))
         {
@@ -741,23 +802,6 @@ static gboolean client_can_steal_focus(ObClient *self,
             ob_debug("Not focusing the window because the user is "
                      "working in another window that is not its relative");
         }
-        /* If the new window is a transient (and its relatives aren't
-           focused) */
-        else if (client_has_parent(self) && !relative_focused) {
-            steal = FALSE;
-            ob_debug("Not focusing the window because it is a "
-                     "transient, and its relatives aren't focused");
-        }
-        /* Don't steal focus from globally active clients.
-           I stole this idea from KWin. It seems nice.
-        */
-        else if (!(focus_client->can_focus ||
-                   focus_client->focus_notify))
-        {
-            steal = FALSE;
-            ob_debug("Not focusing the window because a globally "
-                     "active client has focus");
-        }
         /* Don't move focus if it's not going to go to this window
            anyway */
         else if (client_focus_target(self) != self) {
@@ -765,15 +809,34 @@ static gboolean client_can_steal_focus(ObClient *self,
             ob_debug("Not focusing the window because another window "
                      "would get the focus anyway");
         }
-        /* Don't move focus if the window is not visible on the current
-           desktop and none of its relatives are focused */
-        else if (!(self->desktop == screen_desktop ||
-                   self->desktop == DESKTOP_ALL) &&
-                 !relative_focused)
-        {
-            steal = FALSE;
-            ob_debug("Not focusing the window because it is on "
-                     "another desktop and no relatives are focused ");
+        /* For requests that don't come from the user */
+        else if (!request_from_user) {
+            /* If the new window is a transient (and its relatives aren't
+               focused) */
+            if (client_has_parent(self) && !relative_focused) {
+                steal = FALSE;
+                ob_debug("Not focusing the window because it is a "
+                         "transient, and its relatives aren't focused");
+            }
+            /* Don't steal focus from globally active clients.
+               I stole this idea from KWin. It seems nice.
+            */
+            else if (!(focus_client->can_focus || focus_client->focus_notify))
+            {
+                steal = FALSE;
+                ob_debug("Not focusing the window because a globally "
+                         "active client has focus");
+            }
+            /* Don't move focus if the window is not visible on the current
+               desktop and none of its relatives are focused */
+            else if (!allow_other_desktop &&
+                     !screen_compare_desktops(self->desktop, screen_desktop) &&
+                     !relative_focused)
+            {
+                steal = FALSE;
+                ob_debug("Not focusing the window because it is on "
+                         "another desktop and no relatives are focused ");
+            }
         }
     }
 
@@ -781,6 +844,10 @@ static gboolean client_can_steal_focus(ObClient *self,
         ob_debug("Focus stealing prevention activated for %s at "
                  "time %u (last user interaction time %u)",
                  self->title, steal_time, event_last_user_time);
+    else
+        ob_debug("Allowing focus stealing for %s at time %u (last user "
+                 "interaction time %u)",
+                 self->title, steal_time, event_last_user_time);
     return steal;
 }
 
@@ -2437,6 +2504,11 @@ gboolean client_has_parent(ObClient *self)
     return self->parents != NULL;
 }
 
+gboolean client_has_children(ObClient *self)
+{
+    return self->transients != NULL;
+}
+
 gboolean client_is_oldfullscreen(const ObClient *self,
                                  const Rect *area)
 {
@@ -2802,6 +2874,13 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
        the updated frame dimensions. */
     frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
 
+    /* cap any X windows at the size of an unsigned short */
+    *w = MIN(*w,
+             G_MAXUSHORT - self->frame->size.left - self->frame->size.right);
+    *h = MIN(*h,
+             G_MAXUSHORT - self->frame->size.top - self->frame->size.bottom);
+
+
     /* gets the frame's position */
     frame_client_gravity(self->frame, x, y);
 
@@ -3910,13 +3989,10 @@ void client_activate(ObClient *self, gboolean desktop,
                      gboolean here, gboolean raise,
                      gboolean unshade, gboolean user)
 {
-    if ((user && (desktop ||
-                  self->desktop == DESKTOP_ALL ||
-                  self->desktop == screen_desktop)) ||
-        client_can_steal_focus(self, desktop, event_time(), CurrentTime))
-    {
+    self = client_focus_target(self);
+
+    if (client_can_steal_focus(self, desktop, user, event_time(), CurrentTime))
         client_present(self, here, raise, unshade);
-    }
     else
         client_hilite(self, TRUE);
 }
@@ -4249,32 +4325,26 @@ void client_find_edge_directional(ObClient *self, ObDirection dir,
     }
 
     /* search for edges of clients */
-    if (((dir == OB_DIRECTION_NORTH || dir == OB_DIRECTION_SOUTH) &&
-         !self->max_vert) ||
-        ((dir == OB_DIRECTION_EAST || dir == OB_DIRECTION_WEST) &&
-         !self->max_horz))
-    {
-        for (it = client_list; it; it = g_list_next(it)) {
-            ObClient *cur = it->data;
+    for (it = client_list; it; it = g_list_next(it)) {
+        ObClient *cur = it->data;
 
-            /* skip windows to not bump into */
-            if (cur == self)
-                continue;
-            if (cur->iconic)
-                continue;
-            if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL &&
-                cur->desktop != screen_desktop)
-                continue;
+        /* skip windows to not bump into */
+        if (cur == self)
+            continue;
+        if (cur->iconic)
+            continue;
+        if (self->desktop != cur->desktop && cur->desktop != DESKTOP_ALL &&
+            cur->desktop != screen_desktop)
+            continue;
 
-            ob_debug("trying window %s", cur->title);
+        ob_debug("trying window %s", cur->title);
 
-            detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start,
-                        my_edge_size, dest, near_edge);
-        }
-        dock_get_area(&dock_area);
-        detect_edge(dock_area, dir, my_head, my_size, my_edge_start,
+        detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start,
                     my_edge_size, dest, near_edge);
     }
+    dock_get_area(&dock_area);
+    detect_edge(dock_area, dir, my_head, my_size, my_edge_start,
+                my_edge_size, dest, near_edge);
 
     g_slice_free(Rect, a);
 }
@@ -4461,6 +4531,13 @@ gboolean client_has_group_siblings(ObClient *self)
     return self->group && self->group->members->next;
 }
 
+gboolean client_has_relative(ObClient *self)
+{
+    return client_has_parent(self) ||
+        client_has_group_siblings(self) ||
+        client_has_children(self);
+}
+
 /*! Returns TRUE if the client is running on the same machine as Openbox */
 gboolean client_on_localhost(ObClient *self)
 {
This page took 0.035273 seconds and 4 git commands to generate.