Index: src/core.c
===================================================================
RCS file: /cvs/gnome/metacity/src/core.c,v
retrieving revision 1.40
diff -p -u -r1.40 core.c
--- src/core.c	16 Sep 2004 00:06:38 -0000	1.40
+++ src/core.c	3 Oct 2004 18:03:19 -0000
@@ -237,7 +237,8 @@ meta_core_user_raise (Display *xdisplay,
 
 void
 meta_core_user_lower_and_unfocus (Display *xdisplay,
-                                  Window   frame_xwindow)
+                                  Window   frame_xwindow,
+                                  Time     timestamp)
 {
   MetaDisplay *display;
   MetaWindow *window;
@@ -277,7 +278,9 @@ meta_core_user_lower_and_unfocus (Displa
 
       /* focus on the (new) topmost window */
       if (window->has_focus)
-        meta_workspace_focus_default_window (window->screen->active_workspace, window);
+        meta_workspace_focus_default_window (window->screen->active_workspace,
+                                             window,
+                                             timestamp);
     }
 }
 
Index: src/core.h
===================================================================
RCS file: /cvs/gnome/metacity/src/core.h,v
retrieving revision 1.25
diff -p -u -r1.25 core.h
--- src/core.h	16 Sep 2004 00:06:38 -0000	1.25
+++ src/core.h	3 Oct 2004 18:03:19 -0000
@@ -61,7 +61,8 @@ void meta_core_user_resize  (Display *xd
 void meta_core_user_raise   (Display *xdisplay,
                              Window   frame_xwindow);
 void meta_core_user_lower_and_unfocus (Display *xdisplay,
-                                       Window   frame_xwindow);
+                                       Window   frame_xwindow,
+                                       Time     timestamp);
 
 void meta_core_user_focus   (Display *xdisplay,
                              Window   frame_xwindow,
Index: src/display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.229
diff -p -u -r1.229 display.c
--- src/display.c	22 Sep 2004 18:57:36 -0000	1.229
+++ src/display.c	3 Oct 2004 18:03:20 -0000
@@ -1099,6 +1099,35 @@ meta_display_get_current_time (MetaDispl
   return display->current_time;
 }
 
+/* Get a timestamp, even if it means a roundtrip */
+guint32
+meta_display_get_current_time_roundtrip (MetaDisplay *display)
+{
+  guint32 timestamp;
+  
+  timestamp = meta_display_get_current_time (display);
+  if (timestamp == CurrentTime)
+    {
+      XEvent property_event;
+
+      /* Using the property XA_PRIMARY because it's safe; nothing
+       * would use it as a property. The type doesn't matter.
+       */
+      XChangeProperty (display->xdisplay,
+                       display->leader_window,
+                       XA_PRIMARY, XA_STRING, 8,
+                       PropModeAppend, NULL, 0);
+      XWindowEvent (display->xdisplay,
+                    display->leader_window,
+                    PropertyChangeMask,
+                    &property_event);
+
+      timestamp = property_event.xproperty.time;
+    }
+
+  return timestamp;
+}
+
 static void
 add_ignored_serial (MetaDisplay  *display,
                     unsigned long serial)
@@ -2100,7 +2129,7 @@ event_callback (XEvent   *event,
                                                         space);
 
                   if (workspace)
-                    meta_workspace_activate (workspace);
+                    meta_workspace_activate (workspace, meta_display_get_current_time_roundtrip (display));
                   else
                     meta_verbose ("Don't know about workspace %d\n", space);
                 }
@@ -2129,7 +2158,7 @@ event_callback (XEvent   *event,
 		  else
 		    {
 		      meta_screen_unshow_desktop (screen);
-		      meta_workspace_focus_default_window (screen->active_workspace, NULL);
+		      meta_workspace_focus_default_window (screen->active_workspace, NULL, meta_display_get_current_time_roundtrip (display));
 		    }
 		}
               else if (event->xclient.message_type ==
Index: src/display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.123
diff -p -u -r1.123 display.h
--- src/display.h	15 Sep 2004 15:38:09 -0000	1.123
+++ src/display.h	3 Oct 2004 18:03:20 -0000
@@ -422,7 +422,8 @@ void     meta_display_increment_event_se
 
 void     meta_display_update_active_window_hint (MetaDisplay *display);
 
-guint32  meta_display_get_current_time (MetaDisplay *display);
+guint32  meta_display_get_current_time           (MetaDisplay *display);
+guint32  meta_display_get_current_time_roundtrip (MetaDisplay *display);
 
 /* utility goo */
 const char* meta_event_mode_to_string   (int m);
Index: src/frames.c
===================================================================
RCS file: /cvs/gnome/metacity/src/frames.c,v
retrieving revision 1.79
diff -p -u -r1.79 frames.c
--- src/frames.c	16 Sep 2004 23:18:22 -0000	1.79
+++ src/frames.c	3 Oct 2004 18:03:21 -0000
@@ -1372,7 +1372,9 @@ meta_frames_button_press_event (GtkWidge
     }
   else if (event->button == 2)
     {
-      meta_core_user_lower_and_unfocus (gdk_display, frame->xwindow);
+      meta_core_user_lower_and_unfocus (gdk_display,
+                                        frame->xwindow,
+                                        event->time);
     }
   else if (event->button == 3)
     {
Index: src/keybindings.c
===================================================================
RCS file: /cvs/gnome/metacity/src/keybindings.c,v
retrieving revision 1.102
diff -p -u -r1.102 keybindings.c
--- src/keybindings.c	22 Sep 2004 19:15:26 -0000	1.102
+++ src/keybindings.c	3 Oct 2004 18:03:21 -0000
@@ -2474,7 +2474,7 @@ handle_activate_workspace (MetaDisplay  
   
   if (workspace)
     {
-      meta_workspace_activate (workspace);
+      meta_workspace_activate (workspace, event->xkey.time);
     }
   else
     {
@@ -2680,7 +2680,9 @@ process_workspace_switch_grab (MetaDispl
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Focusing default window on target workspace\n");
 
-          meta_workspace_focus_default_window (target_workspace, NULL);
+          meta_workspace_focus_default_window (target_workspace, 
+                                               NULL,
+                                               event->xkey.time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2749,7 +2751,7 @@ process_workspace_switch_grab (MetaDispl
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Activating target workspace\n");
 
-          meta_workspace_activate (target_workspace);
+          meta_workspace_activate (target_workspace, event->xkey.time);
 
           return TRUE; /* we already ended the grab */
         }
@@ -2760,7 +2762,7 @@ process_workspace_switch_grab (MetaDispl
               "Ending workspace tabbing & focusing default window; uninteresting key pressed\n");
   workspace =
     (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->tab_popup);
-  meta_workspace_focus_default_window (workspace, NULL);
+  meta_workspace_focus_default_window (workspace, NULL, event->xkey.time);
   return FALSE;
 }
 
@@ -2774,7 +2776,9 @@ handle_toggle_desktop (MetaDisplay    *d
   if (screen->showing_desktop)
     {
       meta_screen_unshow_desktop (screen);
-      meta_workspace_focus_default_window (screen->active_workspace, NULL);
+      meta_workspace_focus_default_window (screen->active_workspace, 
+                                           NULL,
+                                           event->xkey.time);
     }
   else
     meta_screen_show_desktop (screen);
@@ -3210,7 +3214,7 @@ do_handle_move_to_workspace  (MetaDispla
       /* Activate second, so the window is never unmapped */
       meta_window_change_workspace (window, workspace);
       if (flip)
-        meta_workspace_activate_with_focus (workspace, window);
+        meta_workspace_activate_with_focus (workspace, window, event->xkey.time);
     }
   else
     {
@@ -3374,7 +3378,7 @@ handle_workspace_switch  (MetaDisplay   
           meta_display_end_grab_op (display, event->xkey.time);
         }
       
-      meta_workspace_activate (next);
+      meta_workspace_activate (next, event->xkey.time);
 
       if (grabbed_before_release)
         {
Index: src/screen.c
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.c,v
retrieving revision 1.129
diff -p -u -r1.129 screen.c
--- src/screen.c	16 Sep 2004 23:18:22 -0000	1.129
+++ src/screen.c	3 Oct 2004 18:03:23 -0000
@@ -604,7 +604,7 @@ meta_screen_new (MetaDisplay *display,
   /* Screens must have at least one workspace at all times,
    * so create that required workspace.
    */
-  meta_workspace_activate (meta_workspace_new (screen));
+  meta_workspace_activate (meta_workspace_new (screen), timestamp);
   update_num_workspaces (screen);
   
   set_workspace_names (screen);
@@ -641,7 +641,7 @@ meta_screen_new (MetaDisplay *display,
                                                 current_workspace);
     
     if (space != NULL)
-      meta_workspace_activate (space);
+      meta_workspace_activate (space, timestamp);
   }
 
   meta_compositor_manage_screen (screen->display->compositor,
@@ -1077,7 +1077,7 @@ update_num_workspaces (MetaScreen *scree
     }
 
   if (need_change_space)
-    meta_workspace_activate (last_remaining);
+    meta_workspace_activate (last_remaining, meta_display_get_current_time_roundtrip (screen->display));
 
   /* Should now be safe to free the workspaces */
   tmp = extras;
Index: src/window.c
===================================================================
RCS file: /cvs/gnome/metacity/src/window.c,v
retrieving revision 1.345
diff -p -u -r1.345 window.c
--- src/window.c	15 Sep 2004 15:54:51 -0000	1.345
+++ src/window.c	3 Oct 2004 18:03:24 -0000
@@ -931,7 +931,7 @@ meta_window_free (MetaWindow  *window)
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing default window since we're unmanaging %s\n",
                   window->desc);
-      meta_workspace_focus_default_window (window->screen->active_workspace, window);
+      meta_workspace_focus_default_window (window->screen->active_workspace, window, meta_display_get_current_time_roundtrip (window->display));
     }
   else if (window->display->expected_focus_window == window)
     {
@@ -939,7 +939,7 @@ meta_window_free (MetaWindow  *window)
                   "Focusing default window since expected focus window freed %s\n",
                   window->desc);
       window->display->expected_focus_window = NULL;
-      meta_workspace_focus_default_window (window->screen->active_workspace, window);
+      meta_workspace_focus_default_window (window->screen->active_workspace, window, meta_display_get_current_time_roundtrip (window->display));
     }
   else
     {
@@ -1487,25 +1487,6 @@ idle_calc_showing (gpointer data)
       tmp = tmp->next;
     }
 
-  /* for all displays used in the queue, set a sentinel property on
-   * the root window so that we can ignore EnterNotify events that
-   * occur before the window maps occur.  This avoids a race
-   * condition.
-   */
-  tmp = should_show;
-  while (tmp != NULL)
-    {
-      MetaWindow *window = tmp->data;
-      
-      if (g_slist_find (displays, window->display) == NULL)
-        {
-          displays = g_slist_prepend (displays, window->display);
-          meta_display_increment_focus_sentinel (window->display);
-        }
-
-      tmp = tmp->next;
-    }
-
   g_slist_free (copy);
 
   g_slist_free (unplaced);
@@ -1898,7 +1879,7 @@ meta_window_minimize (MetaWindow  *windo
           meta_topic (META_DEBUG_FOCUS,
                       "Focusing default window due to minimization of focus window %s\n",
                       window->desc);
-          meta_workspace_focus_default_window (window->screen->active_workspace, window);
+          meta_workspace_focus_default_window (window->screen->active_workspace, window, meta_display_get_current_time_roundtrip (window->display));
         }
       else
         {
@@ -4021,7 +4002,7 @@ meta_window_client_message (MetaWindow *
               meta_topic (META_DEBUG_FOCUS,
                           "Focusing default window because of minimization of former focus window %s, which was due to a wm_change_state client message\n",
                       window->desc);
-              meta_workspace_focus_default_window (window->screen->active_workspace, window);
+              meta_workspace_focus_default_window (window->screen->active_workspace, window, meta_display_get_current_time_roundtrip (window->display));
             }
         }
 
Index: src/workspace.c
===================================================================
RCS file: /cvs/gnome/metacity/src/workspace.c,v
retrieving revision 1.63
diff -p -u -r1.63 workspace.c
--- src/workspace.c	17 Sep 2004 19:49:32 -0000	1.63
+++ src/workspace.c	3 Oct 2004 18:03:24 -0000
@@ -30,7 +30,8 @@
 void meta_workspace_queue_calc_showing      (MetaWorkspace *workspace);
 static void set_active_space_hint           (MetaScreen *screen);
 static void meta_workspace_focus_mru_window (MetaWorkspace *workspace,
-                                             MetaWindow    *not_this_one);
+                                             MetaWindow    *not_this_one,
+                                             Time           timestamp);
 
 static void
 maybe_add_to_list (MetaScreen *screen, MetaWindow *window, gpointer data)
@@ -270,7 +271,8 @@ meta_workspace_queue_calc_showing  (Meta
 
 void
 meta_workspace_activate_with_focus (MetaWorkspace *workspace,
-                                    MetaWindow    *focus_this)
+                                    MetaWindow    *focus_this,
+                                    Time           timestamp)
 {
   MetaWorkspace *old;
   MetaWindow *move_window;
@@ -322,8 +324,7 @@ meta_workspace_activate_with_focus (Meta
 
   if (focus_this)
     {
-      meta_window_focus (focus_this,
-                         meta_display_get_current_time (focus_this->display));
+      meta_window_focus (focus_this, timestamp);
       meta_window_raise (focus_this);
     }
   else if (move_window)
@@ -333,15 +334,15 @@ meta_workspace_activate_with_focus (Meta
   else
     {
       meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
-      meta_workspace_focus_default_window (workspace, NULL);
+      meta_workspace_focus_default_window (workspace, NULL, timestamp);
     }
 }
 
 void
-meta_workspace_activate (MetaWorkspace *workspace)
+meta_workspace_activate (MetaWorkspace *workspace,
+                         Time           timestamp)
 {
-  meta_workspace_activate_with_focus (workspace,
-                                      NULL);
+  meta_workspace_activate_with_focus (workspace, NULL, timestamp);
 }
 
 int
@@ -790,10 +791,18 @@ meta_workspace_get_name (MetaWorkspace *
 
 void
 meta_workspace_focus_default_window (MetaWorkspace *workspace,
-                                     MetaWindow *not_this_one)
+                                     MetaWindow    *not_this_one,
+                                     Time           timestamp)
 {
+  if (timestamp == CurrentTime)
+    {
+      meta_warning ("CurrentTime used to choose focus window; "
+                    "focus window may not be correct.\n");
+    }
+
+
   if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
-    meta_workspace_focus_mru_window (workspace, not_this_one);
+    meta_workspace_focus_mru_window (workspace, not_this_one, timestamp);
   else
     {
       MetaWindow * window;
@@ -802,13 +811,28 @@ meta_workspace_focus_default_window (Met
           window->type != META_WINDOW_DOCK &&
           window->type != META_WINDOW_DESKTOP)
         {
-          meta_topic (META_DEBUG_FOCUS,
-                      "Focusing mouse window %s\n", window->desc);
+          if (timestamp == CurrentTime)
+            {
+
+              /* We would like for this to never happen.  However, if
+               * it does happen then we kludge since using CurrentTime
+               * can mean ugly race conditions--and we can avoid these
+               * by allowing EnterNotify events (which come with
+               * timestamps) to handle focus.
+               */
 
-          meta_window_focus (window, meta_display_get_current_time (workspace->screen->display));
+              meta_topic (META_DEBUG_FOCUS,
+                          "Not focusing mouse window %s because EnterNotify events should handle that\n", window->desc);
+            }
+          else
+            {
+              meta_topic (META_DEBUG_FOCUS,
+                          "Focusing mouse window %s\n", window->desc);
+              meta_window_focus (window, timestamp);
+            }
         }
       else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_SLOPPY)
-        meta_workspace_focus_mru_window (workspace, not_this_one);
+        meta_workspace_focus_mru_window (workspace, not_this_one, timestamp);
       else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_MOUSE)
         {
           meta_topic (META_DEBUG_FOCUS,
@@ -817,7 +841,7 @@ meta_workspace_focus_default_window (Met
           XSetInputFocus (workspace->screen->display->xdisplay,
                           workspace->screen->display->no_focus_window,
                           RevertToPointerRoot,
-                          meta_display_get_current_time (workspace->screen->display));
+                          timestamp);
         }
     }
 }
@@ -825,7 +849,8 @@ meta_workspace_focus_default_window (Met
 /* Focus MRU window (or top window if failed) on active workspace */
 void
 meta_workspace_focus_mru_window (MetaWorkspace *workspace,
-                                 MetaWindow *not_this_one)
+                                 MetaWindow    *not_this_one,
+                                 Time           timestamp)
 {
   MetaWindow *window = NULL;
   GList *tmp;
@@ -857,8 +882,7 @@ meta_workspace_focus_mru_window (MetaWor
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing workspace MRU window %s\n", window->desc);
       
-      meta_window_focus (window,
-                         meta_display_get_current_time (workspace->screen->display));
+      meta_window_focus (window, timestamp);
 
       /* Also raise the window if in click-to-focus */
       if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
@@ -870,6 +894,6 @@ meta_workspace_focus_mru_window (MetaWor
       XSetInputFocus (workspace->screen->display->xdisplay,
                       workspace->screen->display->no_focus_window,
                       RevertToPointerRoot,
-                      meta_display_get_current_time (workspace->screen->display));
+                      timestamp);
     }
 }
Index: src/workspace.h
===================================================================
RCS file: /cvs/gnome/metacity/src/workspace.h,v
retrieving revision 1.18
diff -p -u -r1.18 workspace.h
--- src/workspace.h	15 Sep 2004 16:42:52 -0000	1.18
+++ src/workspace.h	3 Oct 2004 18:03:24 -0000
@@ -63,8 +63,10 @@ void           meta_workspace_relocate_w
 gboolean       meta_workspace_contains_window (MetaWorkspace *workspace,
                                                MetaWindow  *window);
 void           meta_workspace_activate_with_focus (MetaWorkspace *workspace,
-                                                   MetaWindow    *focus_this);
-void           meta_workspace_activate            (MetaWorkspace *workspace);
+                                                   MetaWindow    *focus_this,
+                                                   Time           timestamp);
+void           meta_workspace_activate            (MetaWorkspace *workspace,
+                                                   Time           timestamp);
 int            meta_workspace_index         (MetaWorkspace *workspace);
 GList*         meta_workspace_list_windows  (MetaWorkspace *workspace);
 
@@ -78,7 +80,8 @@ void meta_workspace_get_work_area_all_xi
                                                  MetaRectangle *area);
 
 void meta_workspace_focus_default_window (MetaWorkspace *workspace,
-                                          MetaWindow    *not_this_one);
+                                          MetaWindow    *not_this_one,
+                                          Time           timestamp);
 
 MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace      *workspace,
                                             MetaMotionDirection direction);
