]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
don't activate and change desktops if the client's not on the current desktop and...
[chaz/openbox] / openbox / client.c
index 5471bedd21a1e876ede8e6231d17a3606edbac1d..2ca9b5182fdd6fa8a6716f93fcb2425812ab1b60 100644 (file)
@@ -49,7 +49,8 @@
 #include <X11/Xutil.h>
 
 /*! The event mask to grab on client windows */
-#define CLIENT_EVENTMASK (PropertyChangeMask | StructureNotifyMask)
+#define CLIENT_EVENTMASK (PropertyChangeMask | StructureNotifyMask | \
+                          ColormapChangeMask)
 
 #define CLIENT_NOPROPAGATEMASK (ButtonPressMask | ButtonReleaseMask | \
                                 ButtonMotionMask)
@@ -75,6 +76,7 @@ static void client_get_shaped(ObClient *self);
 static void client_get_mwm_hints(ObClient *self);
 static void client_get_gravity(ObClient *self);
 static void client_get_client_machine(ObClient *self);
+static void client_get_colormap(ObClient *self);
 static void client_change_allowed_actions(ObClient *self);
 static void client_change_state(ObClient *self);
 static void client_change_wm_state(ObClient *self);
@@ -318,6 +320,7 @@ void client_manage(Window window)
 
     /* focus the new window? */
     if (ob_state() != OB_STATE_STARTING &&
+        !self->iconic &&
         /* this means focus=true for window is same as config_focus_new=true */
         ((config_focus_new || (settings && settings->focus == 1)) ||
          client_search_focus_parent(self)) &&
@@ -330,37 +333,6 @@ void client_manage(Window window)
          self->type == OB_CLIENT_TYPE_DIALOG))
     {
         activate = TRUE;
-#if 0
-        if (self->desktop != screen_desktop) {
-            /* activate the window */
-            activate = TRUE;
-        } else {
-            gboolean group_foc = FALSE;
-
-            if (self->group) {
-                GSList *it;
-
-                for (it = self->group->members; it; it = g_slist_next(it))
-                {
-                    if (client_focused(it->data))
-                    {
-                        group_foc = TRUE;
-                        break;
-                    }
-                }
-            }
-            if ((group_foc ||
-                 (!self->transient_for && (!self->group ||
-                                           !self->group->members->next))) ||
-                client_search_focus_tree_full(self) ||
-                !focus_client ||
-                !client_normal(focus_client))
-            {
-                /* activate the window */
-                activate = TRUE;
-            }
-        }
-#endif
     }
 
     /* get the current position */
@@ -413,10 +385,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
         {
@@ -433,13 +413,7 @@ void client_manage(Window window)
                 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
-               to queue one for after the focus change takes place */
-            client_raise(self);
-        } else {
+        if (!activate) {
             ob_debug("Focus stealing prevention activated for %s with time %u "
                      "(last time %u)\n",
                      self->title, self->user_time, last_time);
@@ -469,17 +443,8 @@ void client_manage(Window window)
        a window maps since its not based on an action from the user like
        clicking a window to activate it. so keep the new window out of the way
        but do focus it. */
-    if (activate) {
-        /* if using focus_delay, stop the timer now so that focus doesn't
-           go moving on us */
-        event_halt_focus_delay();
-        client_focus(self);
-    }
-
-    /* client_activate does this but we aren't using it so we have to do it
-       here as well */
-    if (screen_showing_desktop)
-        screen_show_desktop(FALSE);
+    if (activate)
+        client_activate(self, FALSE, TRUE);
 
     /* add to client list/map */
     client_list = g_list_append(client_list, self);
@@ -525,7 +490,6 @@ void client_unmanage(ObClient *self)
         event_ignore_queued_enters();
     }
 
-
     keyboard_grab_for_client(self, FALSE);
     mouse_grab_for_client(self, FALSE);
 
@@ -534,6 +498,9 @@ 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;
 
     client_list = g_list_remove(client_list, self);
     stacking_remove(self);
@@ -679,7 +646,7 @@ static ObAppSettings *client_get_settings_state(ObClient *self)
         if (settings->max_vert != -1)
             self->max_vert = !!settings->max_vert;
         if (settings->max_horz != -1)
-            self->max_vert = !!settings->max_horz;
+            self->max_horz = !!settings->max_horz;
 
         if (settings->fullscreen != -1)
             self->fullscreen = !!settings->fullscreen;
@@ -939,7 +906,11 @@ static void client_get_all(ObClient *self)
        (min/max sizes), so we're ready to set up the decorations/functions */
     client_setup_decor_and_functions(self);
   
+#ifdef SYNC
+    client_update_sync_request_counter(self);
+#endif
     client_get_client_machine(self);
+    client_get_colormap(self);
     client_update_title(self);
     client_update_class(self);
     client_update_sm_client_id(self);
@@ -1011,10 +982,6 @@ static void client_get_desktop(ObClient *self)
                 self->desktop = screen_desktop;
         }
     }
-    if (self->desktop != d) {
-        /* set the desktop hint, to make sure that it always exists */
-        PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
-    }
 }
 
 static void client_get_layer(ObClient *self)
@@ -1289,18 +1256,37 @@ void client_update_protocols(ObClient *self)
 
     if (PROP_GETA32(self->window, wm_protocols, atom, &proto, &num_return)) {
         for (i = 0; i < num_return; ++i) {
-            if (proto[i] == prop_atoms.wm_delete_window) {
+            if (proto[i] == prop_atoms.wm_delete_window)
                 /* this means we can request the window to close */
                 self->delete_window = TRUE;
-            else if (proto[i] == prop_atoms.wm_take_focus)
+            else if (proto[i] == prop_atoms.wm_take_focus)
                 /* if this protocol is requested, then the window will be
                    notified whenever we want it to receive focus */
                 self->focus_notify = TRUE;
+#ifdef SYNC
+            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 */
+                self->sync_request = TRUE;
+#endif
         }
         g_free(proto);
     }
 }
 
+#ifdef SYNC
+void client_update_sync_request_counter(ObClient *self)
+{
+    guint32 i;
+
+    if (PROP_GET32(self->window, net_wm_sync_request_counter, cardinal, &i)) {
+        self->sync_counter = i;
+    } else
+        self->sync_counter = None;
+}
+#endif
+
 static void client_get_gravity(ObClient *self)
 {
     XWindowAttributes wattrib;
@@ -1311,6 +1297,19 @@ static void client_get_gravity(ObClient *self)
     self->gravity = wattrib.win_gravity;
 }
 
+void client_get_colormap(ObClient *self)
+{
+    XWindowAttributes wa;
+
+    if (XGetWindowAttributes(ob_display, self->window, &wa))
+        client_update_colormap(self, wa.colormap);
+}
+
+void client_update_colormap(ObClient *self, Colormap colormap)
+{
+    self->colormap = colormap;
+}
+
 void client_update_normal_hints(ObClient *self)
 {
     XSizeHints size;
@@ -1851,7 +1850,26 @@ void client_update_icons(ObClient *self)
         }
     }
 
-    if (self->frame)
+    /* set the default icon onto the window
+       in theory, this could be a race, but if a window doesn't set an icon
+       or removes it entirely, it's not very likely it is going to set one
+       right away afterwards */
+    if (self->nicons == 0) {
+        RrPixel32 *icon = ob_rr_theme->def_win_icon;
+        gulong *data;
+
+        data = g_new(guint32, 48*48+2);
+        data[0] = data[1] =  48;
+        for (i = 0; i < 48*48; ++i)
+            data[i+2] = (((icon[i] >> RrDefaultAlphaOffset) & 0xff) << 24) +
+                (((icon[i] >> RrDefaultRedOffset) & 0xff) << 16) +
+                (((icon[i] >> RrDefaultGreenOffset) & 0xff) << 8) +
+                (((icon[i] >> RrDefaultBlueOffset) & 0xff) << 0);
+        PROP_SETA32(self->window, net_wm_icon, cardinal, data, 48*48+2);
+        g_free(data);
+    } else if (self->frame)
+        /* don't draw the icon empty if we're just setting one now anyways,
+           we'll get the property change any second */
         frame_adjust_icon(self->frame);
 }
 
@@ -2133,6 +2151,9 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y)
     self->area.x = x;
     self->area.y = y;
 
+    /* set the desktop hint, to make sure that it always exists */
+    PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
+
     /* these are in a carefully crafted order.. */
 
     if (self->iconic) {
@@ -2399,8 +2420,10 @@ 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)
@@ -2446,8 +2469,10 @@ 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)))
+    if (send_resize_client && (!user || (w <= oldw || h <= oldh))) {
+        frame_adjust_client_area(self->frame);
         XResizeWindow(ob_display, self->window, w, h);
+    }
 
     XFlush(ob_display);
 }
@@ -3078,16 +3103,21 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
        to activate it or not (a parent or group member is currently
        active)?
     */
-    ob_debug("Want to activate window 0x%x with time %u (last time %u), "
-             "source=%s\n",
-             self->window, event_curtime, last_time,
-             (user ? "user" : "application"));
+    ob_debug_type(OB_DEBUG_FOCUS,
+                  "Want to activate window 0x%x with time %u (last time %u), "
+                  "source=%s\n",
+                  self->window, event_curtime, last_time,
+                  (user ? "user" : "application"));
 
     if (!user && event_curtime && last_time &&
         !event_time_after(event_curtime, last_time))
     {
         client_hilite(self, TRUE);
     } else {
+        /* if using focus_delay, stop the timer now so that focus doesn't
+           go moving on us */
+        event_halt_focus_delay();
+
         if (client_normal(self) && screen_showing_desktop)
             screen_show_desktop(FALSE);
         if (self->iconic)
@@ -3107,11 +3137,11 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
 
         client_focus(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. */
+        /* we do this as 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);
     }
 }
@@ -3226,7 +3256,8 @@ guint client_monitor(ObClient *self)
 
 ObClient *client_search_top_parent(ObClient *self)
 {
-    while (self->transient_for && self->transient_for != OB_TRAN_GROUP)
+    while (self->transient_for && self->transient_for != OB_TRAN_GROUP &&
+           client_normal(self))
         self = self->transient_for;
     return self;
 }
This page took 0.032123 seconds and 4 git commands to generate.