Index: src/display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.142
diff -p -u -r1.142 display.h
--- src/display.h	10 Jan 2006 19:43:21 -0000	1.142
+++ src/display.h	16 Jan 2006 22:45:08 -0000
@@ -372,14 +372,14 @@ struct _MetaDisplay
  * you need then you'll need to swap the order of the arguments and negate
  * the result.
  */
-#define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \
-  ( (( time1 < time2 ) && ( time2 - time1 < ((guint32)-1)/2 )) ||     \
-    (( time1 > time2 ) && ( time1 - time2 > ((guint32)-1)/2 ))        \
+#define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2)      \
+  ( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) ||  \
+    (( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 ))     \
   )
 #define XSERVER_TIME_IS_BEFORE(time1, time2)                          \
-  ( time1 == 0 ||                                                     \
+  ( (time1) == 0 ||                                                   \
     (XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
-     time2 != 0)                                                      \
+     (time2) != 0)                                                    \
   )
 
 gboolean      meta_display_open                (const char  *name);
Index: src/window.c
===================================================================
RCS file: /cvs/gnome/metacity/src/window.c,v
retrieving revision 1.410
diff -p -u -r1.410 window.c
--- src/window.c	13 Jan 2006 19:41:01 -0000	1.410
+++ src/window.c	16 Jan 2006 22:45:08 -0000
@@ -2447,17 +2447,53 @@ unminimize_window_and_all_transient_pare
   meta_window_foreach_ancestor (window, unminimize_func, NULL);
 }
 
+static gboolean
+timestamp_is_reasonable (guint32      timestamp,
+                         guint32     *now,
+                         guint32      reasonable,
+                         MetaDisplay *display)
+{
+  /* FIXME: If Soeren's suggestion in bug 151984 is implemented, we
+   * wouldn't have to ping the server for a timestamp.
+   */
+  *now = meta_display_get_current_time_roundtrip (display);
+
+  if (timestamp == 0)
+    return TRUE;  /* It's a stretch to call this reasonable, but... *shrug* */
+
+  return XSERVER_TIME_IS_BEFORE (*now - reasonable, timestamp) &&
+         XSERVER_TIME_IS_BEFORE (timestamp, *now + 1);
+}
+
+
 static void
 window_activate (MetaWindow     *window,
                  guint32         timestamp,
                  MetaClientType  source_indication)
 {
+  guint32  now;
   gboolean can_ignore_outdated_timestamps;
   meta_topic (META_DEBUG_FOCUS,
               "_NET_ACTIVE_WINDOW message sent for %s at time %lu "
               "by client type %u.\n",
               window->desc, (unsigned long)timestamp, source_indication);
 
+  /* Timestamp considered unreasonable if it's older than an hour */
+  if (!timestamp_is_reasonable (timestamp, &now, 3600000, window->display))
+    {
+      /* Make this window freakin' annoying so that the user notices */
+      meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
+      meta_window_shade (window);
+      meta_window_make_above (window);
+      window->wm_state_demands_attention = TRUE;
+      set_net_wm_state (window);
+
+      meta_warning ("Received totally unreasonable activation time of %lu "
+                    "for %s; now = %lu.  Fix the app that sent this message.\n",
+                    (Time)timestamp, window->desc, (Time)now);
+      return;
+    }      
+
   /* Older EWMH spec didn't specify a timestamp; we decide to honor these only
    * if the app specifies that it is a pager.
    *
@@ -7861,10 +7897,19 @@ void
 meta_window_set_user_time (MetaWindow *window,
                            Time        timestamp)
 {
-  /* FIXME: If Soeren's suggestion in bug 151984 is implemented, it will allow
-   * us to sanity check the timestamp here and ensure it doesn't correspond to
-   * a future time.
-   */
+  /* Timestamp considered unreasonable if it's older than 1 minute */
+  guint32  now;
+  if (!timestamp_is_reasonable (timestamp, &now, 60000, window->display))
+    {
+      /* Make this window freakin' annoying so that the user notices */
+      window->wm_state_demands_attention = TRUE;
+      set_net_wm_state (window);
+
+      meta_warning ("Received totally unreasonable _NET_WM_USER_TIME of %lu "
+                    "for %s; now = %lu.  Fix the app or its toolkit.\n",
+                    timestamp, window->desc, (Time)now);
+      return;
+    }      
 
   /* Only update the time if this timestamp is newer... */
   if (window->net_wm_user_time_set &&
