Index: gtk+/modules/input/gtkimcontextxim.c
===================================================================
RCS file: /cvs/gnome/gtk+/modules/input/gtkimcontextxim.c,v
retrieving revision 1.33
diff -u -p -r1.33 gtkimcontextxim.c
--- gtk+/modules/input/gtkimcontextxim.c	29 Jan 2003 22:45:51 -0000	1.33
+++ gtk+/modules/input/gtkimcontextxim.c	11 Mar 2003 23:21:49 -0000
@@ -416,11 +416,20 @@ gtk_im_context_xim_init (GtkIMContextXIM
   im_context_xim->status_visible = FALSE;
 }
 
+static guint snooper_id = 0;
+static GtkIMContextXIM *snooped_context_xim = NULL;
+
 static void
 gtk_im_context_xim_finalize (GObject *obj)
 {
   GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (obj);
 
+  if (snooper_id != 0 && context_xim == snooped_context_xim)
+    {
+      gtk_key_snooper_remove (snooper_id);
+      snooper_id = 0;
+      snooped_context_xim = NULL;
+    }
   set_ic_client_window (context_xim, NULL, FALSE);
 
   g_free (context_xim->locale);
@@ -550,9 +559,6 @@ gtk_im_context_xim_filter_keypress (GtkI
   xevent.keycode = event->hardware_keycode;
   xevent.same_screen = True;
   
-  if (XFilterEvent ((XEvent *)&xevent, GDK_DRAWABLE_XID (context_xim->client_window)))
-    return TRUE;
-  
  again:
   if (ic)
     num_bytes = XmbLookupString (ic, &xevent, buffer, buffer_size, &keysym, &status);
@@ -603,6 +609,39 @@ gtk_im_context_xim_filter_keypress (GtkI
   return result;
 }
 
+static gboolean
+gtk_im_context_xim_key_snooper (GtkWidget *grab_widget,
+				GdkEventKey *event,
+				gpointer func_data)
+{
+  GtkIMContext *context = (GtkIMContext*)func_data;
+  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
+  GdkWindow *root_window = gdk_screen_get_root_window (gdk_drawable_get_screen (event->window));
+
+  XKeyPressedEvent xevent;
+
+  if (event->type == GDK_KEY_RELEASE && !context_xim->filter_key_release)
+    return FALSE;
+
+  xevent.type = (event->type == GDK_KEY_PRESS) ? KeyPress : KeyRelease;
+  xevent.serial = 0;		/* hope it doesn't matter */
+  xevent.send_event = event->send_event;
+  xevent.display = GDK_DRAWABLE_XDISPLAY (event->window);
+  xevent.window = GDK_DRAWABLE_XID (event->window);
+  xevent.root = GDK_DRAWABLE_XID (root_window);
+  xevent.subwindow = xevent.window;
+  xevent.time = event->time;
+  xevent.x = xevent.x_root = 0;
+  xevent.y = xevent.y_root = 0;
+  xevent.state = event->state;
+  xevent.keycode = event->hardware_keycode;
+  xevent.same_screen = True;
+  
+  if (XFilterEvent ((XEvent *)&xevent, GDK_DRAWABLE_XID (context_xim->client_window)))
+    return TRUE;
+  return FALSE;
+}
+
 static void
 gtk_im_context_xim_focus_in (GtkIMContext *context)
 {
@@ -612,6 +651,15 @@ gtk_im_context_xim_focus_in (GtkIMContex
   if (!ic)
     return;
 
+  if (snooper_id != 0 && context_xim == snooped_context_xim)
+    {
+      gtk_key_snooper_remove (snooper_id);
+      snooper_id = 0;
+      snooped_context_xim = NULL;
+    }
+  snooper_id = gtk_key_snooper_install (gtk_im_context_xim_key_snooper,
+					context);
+  snooped_context_xim = context_xim;
   XSetICFocus (ic);
 
   status_window_show (context_xim);
@@ -627,6 +675,12 @@ gtk_im_context_xim_focus_out (GtkIMConte
 
   if (!ic)
     return;
+
+  if (snooper_id != 0)
+    {
+      gtk_key_snooper_remove (snooper_id);
+      snooper_id = 0;
+    }
 
   XUnsetICFocus (ic);
 
