Index: gtk/gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.168
diff -u -p -u -r1.168 gtkmenu.c
--- gtk/gtkmenu.c	15 Mar 2004 02:03:52 -0000	1.168
+++ gtk/gtkmenu.c	26 Apr 2004 21:45:34 -0000
@@ -74,6 +74,9 @@ struct _GtkMenuAttachData
 
 struct _GtkMenuPrivate 
 {
+  gboolean seen_motion;
+  gboolean seen_enter;
+    
   gboolean have_position;
   gint x;
   gint y;
@@ -1231,6 +1234,7 @@ gtk_menu_popup (GtkMenu		    *menu,
   GtkWidget *parent;
   GdkEvent *current_event;
   GtkMenuShell *menu_shell;
+  GtkMenuPrivate *priv = gtk_menu_get_private (menu);
 
   g_return_if_fail (GTK_IS_MENU (menu));
   
@@ -1238,6 +1242,9 @@ gtk_menu_popup (GtkMenu		    *menu,
   menu_shell = GTK_MENU_SHELL (menu);
   
   menu_shell->parent_menu_shell = parent_menu_shell;
+
+  priv->seen_motion = FALSE;
+  priv->seen_enter = FALSE;
   
   /* Find the last viewable ancestor, and make an X grab on it
    */
@@ -2668,7 +2675,20 @@ gtk_menu_motion_notify  (GtkWidget	   *w
   gboolean need_enter;
 
   if (GTK_IS_MENU (widget))
-    gtk_menu_handle_scrolling (GTK_MENU (widget), TRUE);
+    {
+      GtkMenuPrivate *priv = gtk_menu_get_private (GTK_MENU (widget));
+      
+      gtk_menu_handle_scrolling (GTK_MENU (widget), TRUE);
+      priv->seen_motion = TRUE;
+      if (priv->seen_enter)
+	{
+	  /* After having seen both a motion event and an enter event,
+	   * button releases should be interpreted to mean "activate"
+	   */
+	  
+	  GTK_MENU_SHELL (widget)->activate_time = 0;
+	}
+    }
 
   /* We received the event for one of two reasons:
    *
@@ -2899,9 +2919,19 @@ gtk_menu_enter_notify (GtkWidget        
   if (widget && GTK_IS_MENU (widget))
     {
       GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
+      GtkMenuPrivate *priv = gtk_menu_get_private (GTK_MENU (widget));
 
       if (!menu_shell->ignore_enter)
 	gtk_menu_handle_scrolling (GTK_MENU (widget), TRUE);
+
+      priv->seen_enter = TRUE;
+      if (priv->seen_motion)
+	{
+	  /* After having seen both a motion event and an enter event,
+	   * button releases should be interpreted to mean "activate"
+	   */
+	  menu_shell->activate_time = 0;
+	}
     }
   
   /* If this is a faked enter (see gtk_menu_motion_notify), 'widget'
Index: gtk/gtkmenushell.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenushell.c,v
retrieving revision 1.78
diff -u -p -u -r1.78 gtkmenushell.c
--- gtk/gtkmenushell.c	15 Mar 2004 02:03:55 -0000	1.78
+++ gtk/gtkmenushell.c	26 Apr 2004 21:45:38 -0000
@@ -454,9 +454,10 @@ gtk_menu_shell_button_press (GtkWidget  
 	      (menu_item != menu_shell->active_menu_item))
 	    {
 	      if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
-		g_object_set_data (G_OBJECT (menu_shell),
-				   "gtk-menushell-just-activated",
-				   GUINT_TO_POINTER (1));
+		{
+		  menu_shell->activate_time = event->time;
+		}
+      
 	      gtk_menu_shell_select_item (menu_shell, menu_item);
 	    }
 	}
@@ -488,8 +489,6 @@ gtk_menu_shell_button_release (GtkWidget
   menu_shell = GTK_MENU_SHELL (widget);
   if (menu_shell->active)
     {
-      gboolean deactivate_immediately = FALSE;
-
       if (menu_shell->button && (event->button != menu_shell->button))
 	{
 	  menu_shell->button = 0;
@@ -502,23 +501,8 @@ gtk_menu_shell_button_release (GtkWidget
 
       deactivate = TRUE;
 
-      if (menu_item
-	  && GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
-	{
-	  if (g_object_get_data (G_OBJECT (menu_shell), "gtk-menushell-just-activated"))
-	    g_object_set_data (G_OBJECT (menu_shell), "gtk-menushell-just-activated", NULL);
-	  else
-	    deactivate_immediately = TRUE;
-	}
-
       if ((event->time - menu_shell->activate_time) > MENU_SHELL_TIMEOUT)
 	{
-	  if (deactivate_immediately)
-	    {
-	      gtk_menu_shell_deactivate (menu_shell);
-	      return TRUE;
-	    }
-	    
 	  if (menu_item && (menu_shell->active_menu_item == menu_item) &&
 	      _gtk_menu_item_is_selectable (menu_item))
 	    {
@@ -528,8 +512,12 @@ gtk_menu_shell_button_release (GtkWidget
 		  return TRUE;
 		}
 	    }
-	  else if (menu_item && !_gtk_menu_item_is_selectable (menu_item))
-	    deactivate = FALSE;
+	  else if (menu_item &&
+		   !_gtk_menu_item_is_selectable (menu_item) &&
+		   GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
+	    {
+	      deactivate = FALSE;
+	    }
 	  else if (menu_shell->parent_menu_shell)
 	    {
 	      menu_shell->active = TRUE;
@@ -539,8 +527,11 @@ gtk_menu_shell_button_release (GtkWidget
 
 	  /* If we ended up on an item with a submenu, leave the menu up.
 	   */
-	  if (menu_item && (menu_shell->active_menu_item == menu_item))
-	    deactivate = FALSE;
+	  if (menu_item && (menu_shell->active_menu_item == menu_item) &&
+	      GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)
+	    {
+	      deactivate = FALSE;
+	    }
 	}
       else /* a very fast press-release */
 	{
@@ -745,6 +736,7 @@ gtk_real_menu_shell_deactivate (GtkMenuS
     {
       menu_shell->button = 0;
       menu_shell->active = FALSE;
+      menu_shell->activate_time = 0;
 
       if (menu_shell->active_menu_item)
 	{
