Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.6288
diff -p -u -r1.6288 ChangeLog
--- ChangeLog	10 Jan 2005 18:37:08 -0000	1.6288
+++ ChangeLog	11 Jan 2005 17:35:22 -0000
@@ -1,3 +1,17 @@
+2005-01-12  Ivan, Wong Yat Cheung  <email@ivanwong.info>
+
+	* gdk/win32/gdkevents-win32.c (gdk_event_translate): handle
+	WM_DESTROYCLIPBOARD and append a GDK_SELECTION_CLEAR event.
+
+	* gdk/win32/gdkselection-win32.c:
+	(_gdk_selection_set_clear_event_filter_pass): only pass through
+	those selection clear events that we didn't make ourself. 
+	(gdk_selection_send_notify_for_display): remove the artifical
+	GDK_SELECTION_CLEAR event
+
+	* gdk/win32/gdkprivate-win32.h: declare
+	_gdk_selection_set_clear_event_filter_pass()
+
 2005-01-10  Federico Mena Quintero  <federico@ximian.com>
 
 	Fix #162617.
Index: gdk/win32/gdkevents-win32.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/win32/gdkevents-win32.c,v
retrieving revision 1.141
diff -p -u -r1.141 gdkevents-win32.c
--- gdk/win32/gdkevents-win32.c	16 Nov 2004 17:32:15 -0000	1.141
+++ gdk/win32/gdkevents-win32.c	11 Jan 2005 17:35:29 -0000
@@ -3353,6 +3353,19 @@ gdk_event_translate (GdkDisplay *display
       handle_display_change ();
       break;
       
+    case WM_DESTROYCLIPBOARD:
+      if (_gdk_selection_filter_clear_event ())
+	{
+	  event = gdk_event_new (GDK_SELECTION_CLEAR);
+	  event->selection.window = window;
+	  event->selection.selection = GDK_SELECTION_CLIPBOARD;
+	  event->selection.time = _gdk_win32_get_next_tick (msg->time);
+          append_event (display, event);
+	}
+      else
+	return_val = TRUE;
+
+      break;
 
 #ifdef HAVE_WINTAB
       /* Handle WINTAB events here, as we know that gdkinput.c will
Index: gdk/win32/gdkprivate-win32.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/win32/gdkprivate-win32.h,v
retrieving revision 1.64
diff -p -u -r1.64 gdkprivate-win32.h
--- gdk/win32/gdkprivate-win32.h	31 Oct 2004 14:47:15 -0000	1.64
+++ gdk/win32/gdkprivate-win32.h	11 Jan 2005 17:35:29 -0000
@@ -364,6 +364,7 @@ void	_gdk_win32_get_adjusted_client_rect
 					     RECT      *RECT);
 
 void    _gdk_selection_property_delete (GdkWindow *);
+gboolean _gdk_selection_filter_clear_event ();
 
 void    _gdk_dropfiles_store (gchar *data);
 
Index: gdk/win32/gdkselection-win32.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/win32/gdkselection-win32.c,v
retrieving revision 1.37
diff -p -u -r1.37 gdkselection-win32.c
--- gdk/win32/gdkselection-win32.c	7 Jan 2005 14:36:08 -0000	1.37
+++ gdk/win32/gdkselection-win32.c	11 Jan 2005 17:35:30 -0000
@@ -194,6 +194,16 @@ _gdk_dropfiles_store (gchar *data)
     }
 }
 
+static gboolean filter_clear_event = FALSE;
+
+/* only pass through those selection clear events that
+   we didn't make ourself. */
+gboolean
+_gdk_selection_filter_clear_event ()
+{
+  return !filter_clear_event;
+}
+
 gboolean
 gdk_selection_owner_set_for_display (GdkDisplay *display,
                                      GdkWindow  *owner,
@@ -238,11 +248,14 @@ gdk_selection_owner_set_for_display (Gdk
   if (!API_CALL (OpenClipboard, (hwnd)))
     return FALSE;
 
+  filter_clear_event = TRUE;
   if (!API_CALL (EmptyClipboard, ()))
     {
+      filter_clear_event = FALSE;
       API_CALL (CloseClipboard, ());
       return FALSE;
     }
+  filter_clear_event = FALSE;
 #if 0
   /* No delayed rendering */
   if (hwnd != NULL)
@@ -729,32 +742,6 @@ gdk_selection_send_notify_for_display (G
 	     g_free (sel_name),
 	     g_free (tgt_name),
 	     g_free (prop_name)));
-
-  /* Send ourselves a selection clear message so that gtk thinks we
-   * don't have the selection, and will claim it anew when needed, and
-   * we thus get a chance to store data in the Windows clipboard.
-   * Otherwise, if a gtkeditable does a copy to CLIPBOARD several
-   * times only the first one actually gets copied to the Windows
-   * clipboard, as only the first one causes a call to
-   * gdk_property_change().
-   *
-   * Hmm, there is something fishy with this. Cut and paste inside the
-   * same app didn't work, the gtkeditable immediately forgot the
-   * clipboard contents in gtk_editable_selection_clear() as a result
-   * of this message. OTOH, when I changed gdk_selection_owner_get to
-   * return NULL for CLIPBOARD, it works. Sigh.
-   */
-
-  tmp_event.selection.type = GDK_SELECTION_CLEAR;
-  tmp_event.selection.window = gdk_window_lookup (requestor);
-  tmp_event.selection.send_event = FALSE;
-  tmp_event.selection.selection = selection;
-  tmp_event.selection.target = 0;
-  tmp_event.selection.property = 0;
-  tmp_event.selection.requestor = 0;
-  tmp_event.selection.time = time;
-
-  gdk_event_put (&tmp_event);
 }
 
 /* It's hard to say whether implementing this actually is of any use
