Index: gdk/gdkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.h,v
retrieving revision 1.51
diff -p -u -r1.51 gdkwindow.h
--- gdk/gdkwindow.h	11 Jul 2004 13:26:57 -0000	1.51
+++ gdk/gdkwindow.h	7 Oct 2004 23:27:01 -0000
@@ -517,6 +517,8 @@ void          gdk_window_set_keep_below 
 
 void          gdk_window_register_dnd    (GdkWindow       *window);
 
+void          gdk_window_cancel_activate (GdkWindow       *window);
+
 void gdk_window_begin_resize_drag (GdkWindow     *window,
                                    GdkWindowEdge  edge,
                                    gint           button,
Index: gdk/x11/gdkdisplay-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.c,v
retrieving revision 1.47
diff -p -u -r1.47 gdkdisplay-x11.c
--- gdk/x11/gdkdisplay-x11.c	5 Sep 2004 15:09:55 -0000	1.47
+++ gdk/x11/gdkdisplay-x11.c	7 Oct 2004 23:27:01 -0000
@@ -89,6 +89,7 @@ static const char *const precache_atoms[
   "_NET_WM_WINDOW_TYPE",
   "_NET_WM_WINDOW_TYPE_NORMAL",
   "_NET_WM_USER_TIME",
+  "_NET_WM_TAKE_ACTIVITY",
 };
 
 GType
@@ -253,6 +254,9 @@ gdk_display_open (const gchar *display_n
 
   /* We don't yet know a valid time. */
   display_x11->user_time = 0;
+  
+  /* This ought to be renamed; maybe to something like wm_drag_source? */
+  display_x11->tracking_take_activity = FALSE;
   
 #ifdef HAVE_XKB
   {
Index: gdk/x11/gdkdisplay-x11.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkdisplay-x11.h,v
retrieving revision 1.18
diff -p -u -r1.18 gdkdisplay-x11.h
--- gdk/x11/gdkdisplay-x11.h	11 Jul 2004 13:26:57 -0000	1.18
+++ gdk/x11/gdkdisplay-x11.h	7 Oct 2004 23:27:01 -0000
@@ -143,6 +143,12 @@ struct _GdkDisplayX11
   /* Time of most recent user interaction. */
   gulong user_time;
 
+  /* Information about potential DND operation; _NET_WM_TAKE_ACTIVITY protocol */
+  guint tracking_take_activity : 1;
+  gint  take_activity_x;
+  gint  take_activity_y;
+  Time  take_activity_time;
+
   /* Sets of atoms for DND */
   guint base_dnd_atoms_precached : 1;
   guint xdnd_atoms_precached : 1;
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.141
diff -p -u -r1.141 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	4 Sep 2004 15:07:16 -0000	1.141
+++ gdk/x11/gdkevents-x11.c	7 Oct 2004 23:27:01 -0000
@@ -1126,6 +1126,10 @@ gdk_event_translate (GdkDisplay *display
 	}
 
       set_user_time (window, event);
+
+      display_x11->take_activity_x = xevent->xbutton.x_root;
+      display_x11->take_activity_y = xevent->xbutton.y_root;
+      
       break;
       
     case ButtonRelease:
@@ -1165,6 +1169,36 @@ gdk_event_translate (GdkDisplay *display
 
       set_screen_from_root (display, event, xevent->xbutton.root);
       
+      /* Check if we hade normal (non DND-like) operation for
+       * _NET_WM_TAKE_ACTIVITY; if so, send hint to activate window
+       */
+      if (display_x11->tracking_take_activity)
+        {
+          XEvent xev;
+
+          xev.xclient.type = ClientMessage;
+          xev.xclient.serial = 0;
+          xev.xclient.send_event = True;
+          xev.xclient.window =  GDK_WINDOW_XROOTWIN (window);
+          xev.xclient.message_type = 
+            gdk_x11_get_xatom_by_name_for_display (display,
+                                                   "_NET_WM_TAKE_ACTIVITY");
+          xev.xclient.format = 32;
+          xev.xclient.data.l[0] = 
+            gdk_x11_get_xatom_by_name_for_display (display,
+                                                   "_NET_WM_TAKE_ACTIVITY");
+          xev.xclient.data.l[1] = display_x11->take_activity_time;
+          xev.xclient.data.l[2] = xev.xclient.window;
+          xev.xclient.data.l[3] = 0;
+          xev.xclient.data.l[4] = 0;
+          
+          XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
+                      SubstructureRedirectMask | SubstructureNotifyMask,
+                      &xev);
+
+          display_x11->tracking_take_activity = FALSE;
+        }
+
       break;
       
     case MotionNotify:
@@ -2101,6 +2135,17 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
 			    xevent->xclient.data.l[3]);
 #endif
 	}
+      return GDK_FILTER_REMOVE;
+    }
+  else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_TAKE_ACTIVITY") &&
+	   !_gdk_x11_display_is_root_window (display,
+					     xevent->xclient.window))
+    {
+      GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+      display_x11->tracking_take_activity = TRUE;
+      display_x11->take_activity_time = xevent->xclient.data.l[1];
+
       return GDK_FILTER_REMOVE;
     }
   
Index: gdk/x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.223
diff -p -u -r1.223 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c	5 Oct 2004 05:40:42 -0000	1.223
+++ gdk/x11/gdkwindow-x11.c	7 Oct 2004 23:27:01 -0000
@@ -474,12 +474,13 @@ static void
 set_wm_protocols (GdkWindow *window)
 {
   GdkDisplay *display = gdk_drawable_get_display (window);
-  Atom protocols[4];
+  Atom protocols[5];
   int n = 0;
   
   protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
   protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
   protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
+  protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_TAKE_ACTIVITY");
 
 #ifdef HAVE_XSYNC
   if (GDK_DISPLAY_X11 (display)->use_sync)
@@ -3736,6 +3737,42 @@ gdk_x11_window_set_user_time (GdkWindow 
     display_x11->user_time = timestamp_long;
 
   toplevel->user_time = timestamp_long;
+}
+
+/**
+ * gdk_window_cancel_activate:
+ * @window: A toplevel #GdkWindow
+ *
+ * The application can use this call to hint that a click should
+ * not result in the client becoming activated (i.e. raised and
+ * focused).  This will typically be the case for highlighting
+ * text in order to paste, drag and drop operations, moving
+ * scrollbars, etc.
+ *
+ * On X, it is the responsibility of the window manager to handle
+ * this, and it is accomplished through the _NET_WM_TAKE_ACTIVITY
+ * protocol.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_cancel_activate (GdkWindow *window)
+{
+  GdkDisplay *display;
+  GdkDisplayX11 *display_x11;
+  GdkToplevelX11 *toplevel;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  display = gdk_drawable_get_display (window);
+  display_x11 = GDK_DISPLAY_X11 (display);
+  toplevel = _gdk_x11_window_get_toplevel (window);
+
+  display_x11->tracking_take_activity = FALSE;
 }
 
 /**
Index: gtk/gtkdnd.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkdnd.c,v
retrieving revision 1.117
diff -p -u -r1.117 gtkdnd.c
--- gtk/gtkdnd.c	9 Aug 2004 16:59:51 -0000	1.117
+++ gtk/gtkdnd.c	7 Oct 2004 23:27:01 -0000
@@ -1873,6 +1873,8 @@ gtk_drag_begin_internal (GtkWidget      
   GtkWidget *ipc_widget;
   GdkCursor *cursor;
  
+  gdk_window_cancel_activate (widget->window);
+
   ipc_widget = gtk_drag_get_ipc_widget (gtk_widget_get_screen (widget));
   
   gtk_drag_get_event_actions (event, button, actions,
Index: gtk/gtkentry.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
retrieving revision 1.264
diff -p -u -r1.264 gtkentry.c
--- gtk/gtkentry.c	18 Sep 2004 10:17:23 -0000	1.264
+++ gtk/gtkentry.c	7 Oct 2004 23:27:01 -0000
@@ -1668,6 +1668,8 @@ gtk_entry_motion_notify (GtkWidget      
   if (event->window != entry->text_area || entry->button != 1)
     return FALSE;
 
+  gdk_window_cancel_activate (widget->window);
+      
   if (entry->select_lines)
     return TRUE;
 
Index: gtk/gtkrange.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkrange.c,v
retrieving revision 1.102
diff -p -u -r1.102 gtkrange.c
--- gtk/gtkrange.c	6 Oct 2004 05:11:36 -0000	1.102
+++ gtk/gtkrange.c	7 Oct 2004 23:27:01 -0000
@@ -1486,7 +1486,10 @@ gtk_range_motion_notify (GtkWidget      
     gtk_widget_queue_draw (widget);
 
   if (range->layout->grab_location == MOUSE_SLIDER)
-    update_slider_position (range, x, y);
+    {
+      gdk_window_cancel_activate (GTK_WIDGET (range)->window);
+      update_slider_position (range, x, y);
+    }
 
   /* We handled the event if the mouse was in the range_rect */
   return range->layout->mouse_location != MOUSE_OUTSIDE;
Index: gtk/gtktextview.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktextview.c,v
retrieving revision 1.260
diff -p -u -r1.260 gtktextview.c
--- gtk/gtktextview.c	30 Aug 2004 13:16:39 -0000	1.260
+++ gtk/gtktextview.c	7 Oct 2004 23:27:02 -0000
@@ -5533,6 +5533,8 @@ selection_motion_event_handler (GtkTextV
 {
   SelectionGranularity granularity = GPOINTER_TO_INT (data);
 
+  gdk_window_cancel_activate (GTK_WIDGET (text_view)->window);
+
   if (granularity == SELECT_CHARACTERS) 
     {
       move_mark_to_pointer_and_scroll (text_view, "insert");
