Index: src/window.c
===================================================================
RCS file: /cvs/gnome/metacity/src/window.c,v
retrieving revision 1.404
diff -p -u -r1.404 window.c
--- src/window.c	2 Jan 2006 18:48:30 -0000	1.404
+++ src/window.c	6 Jan 2006 23:44:32 -0000
@@ -2313,19 +2313,21 @@ unminimize_window_and_all_transient_pare
   meta_window_foreach_ancestor (window, unminimize_func, NULL);
 }
 
-void
-meta_window_activate (MetaWindow *window,
-                      guint32     timestamp)
+static void
+window_activate (MetaWindow     *window,
+                 guint32         timestamp,
+                 MetaClientType  source_indication)
 {
   meta_topic (META_DEBUG_FOCUS,
-              "_NET_ACTIVE_WINDOW message sent for %s at time %lu.\n",
-              window->desc, (unsigned long)timestamp);
+              "_NET_ACTIVE_WINDOW message sent for %s at time %lu "
+              "by client type %u.\n",
+              window->desc, (unsigned long)timestamp, source_indication);
 
-  /* Older EWMH spec didn't specify a timestamp, so it can be 0 and we
-   * have to treat that as a new request.
+  /* Older EWMH spec didn't specify a timestamp; we decide to honor these only
+   * if the app specifies that it is a pager.
    */
   if (XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time) &&
-      timestamp != 0)
+      (timestamp != 0 || source_indication != META_CLIENT_TYPE_PAGER))
     {
       meta_topic (META_DEBUG_FOCUS,
                   "last_user_time (%lu) is more recent; ignoring "
@@ -2335,9 +2337,13 @@ meta_window_activate (MetaWindow *window
       set_net_wm_state (window);
       return;
     }
-  
-  if (timestamp == 0)
+
+  /* For those stupid pagers, get a valid timestamp and show a warning */  
+  if (timestamp == 0) {
+    meta_warning ("meta_window_activate called by a pager with a 0 timestamp; "
+                  "the pager needs to be fixed.\n");
     timestamp = meta_display_get_current_time_roundtrip (window->display);
+  }
 
   meta_window_set_user_time (window, timestamp);
 
@@ -2362,6 +2368,21 @@ meta_window_activate (MetaWindow *window
   meta_window_focus (window, timestamp);
 }
 
+/* This function exists since most of the functionality in window_activate
+ * is useful for Metacity, but Metacity shouldn't need to specify a client
+ * type for itself.  ;-)
+ */
+void
+meta_window_activate (MetaWindow     *window,
+                      guint32         timestamp)
+{
+  /* We're not really a pager, but the behavior we want is the same as if
+   * we were such.  If we change the pager behavior later, we could revisit
+   * this and just add extra flags to window_activate.
+   */
+  window_activate (window, timestamp, META_CLIENT_TYPE_PAGER);
+}
+
 /* Manually fix all the weirdness explained in the big comment at the
  * beginning of meta_window_move_resize_internal() giving positions
  * expected by meta_window_constrain (i.e. positions & sizes of the
@@ -4507,25 +4528,23 @@ meta_window_client_message (MetaWindow *
   else if (event->xclient.message_type ==
            display->atom_net_active_window)
     {
+      MetaClientType source_indication;
+      guint32        timestamp;
+
       meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n",
                     window->desc);
 
-      if (event->xclient.data.l[0] != 0)
-        {
-          /* Client supports newer _NET_ACTIVE_WINDOW with a
-           * convenient timestamp
-           */
-          meta_window_activate (window,
-                                event->xclient.data.l[1]);
-          
-        }
-      else
-        {
-          /* Client using older EWMH _NET_ACTIVE_WINDOW without a
-           * timestamp
-           */
-          meta_window_activate (window, meta_display_get_current_time (window->display));
-        }
+      source_indication = event->xclient.data.l[0];
+      timestamp = event->xclient.data.l[1];
+
+      if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED)
+        source_indication = META_CLIENT_TYPE_UNKNOWN;
+
+      if (timestamp == 0)
+        /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */
+        timestamp = meta_display_get_current_time (window->display);
+
+      window_activate (window, timestamp, source_indication);
       return TRUE;
     }
   
Index: src/window.h
===================================================================
RCS file: /cvs/gnome/metacity/src/window.h,v
retrieving revision 1.119
diff -p -u -r1.119 window.h
--- src/window.h	19 Nov 2005 14:58:50 -0000	1.119
+++ src/window.h	6 Jan 2006 23:44:32 -0000
@@ -58,6 +58,13 @@ typedef enum
   META_MAXIMIZE_VERTICAL   = 1 << 1
 } MetaMaximizeFlags;
 
+typedef enum {
+  META_CLIENT_TYPE_UNKNOWN = 0,
+  META_CLIENT_TYPE_APPLICATION = 1,
+  META_CLIENT_TYPE_PAGER = 2,
+  META_CLIENT_TYPE_MAX_RECOGNIZED = 2
+} MetaClientType;
+
 struct _MetaStruts
 {
   /* struts */
@@ -386,8 +393,8 @@ void        meta_window_change_workspace
 void        meta_window_stick              (MetaWindow  *window);
 void        meta_window_unstick            (MetaWindow  *window);
 
-void        meta_window_activate           (MetaWindow  *window,
-                                            guint32      current_time);
+void        meta_window_activate           (MetaWindow     *window,
+                                            guint32         current_time);
 void        meta_window_make_fullscreen    (MetaWindow  *window);
 void        meta_window_unmake_fullscreen  (MetaWindow  *window);
 
