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	1 Oct 2004 17:20:22 -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;
+
+  /* We record take_activity info upon ButtonPress and use upon ButtonRelease */
+  display_x11->tracking_take_activity_info = 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	1 Oct 2004 17:20:22 -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 */
+  gboolean tracking_take_activity_info;
+  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	1 Oct 2004 17:20:22 -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 DND stuff for _NET_WM_TAKE_ACTIVITY; FIXME: use drag_threshold */
+
+      if (display_x11->tracking_take_activity_info &&
+          (ABS (display_x11->take_activity_x - xevent->xbutton.x_root) <= 8 &&
+           ABS (display_x11->take_activity_y - xevent->xbutton.y_root) <= 8))
+        {
+          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_info = FALSE;
+
       break;
       
     case MotionNotify:
@@ -1195,6 +1229,14 @@ gdk_event_translate (GdkDisplay *display
       event->motion.device = display->core_pointer;
       
       set_screen_from_root (display, event, xevent->xmotion.root);
+
+      /* FIXME: don't hardcode the dnd threshold here; get it from elsewhere */
+      if (display_x11->tracking_take_activity_info &&
+          (ABS (display_x11->take_activity_x - xevent->xbutton.x_root > 8) ||
+           ABS (display_x11->take_activity_y - xevent->xbutton.y_root > 8)))
+        {
+          display_x11->tracking_take_activity_info = FALSE;
+        }
       
       break;
       
@@ -2101,6 +2143,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_info = 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.222
diff -p -u -r1.222 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c	23 Aug 2004 19:05:04 -0000	1.222
+++ gdk/x11/gdkwindow-x11.c	1 Oct 2004 17:20:22 -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)
