Index: gtkimcontextxim.c
===================================================================
RCS file: /cvs/gnome/gtk+/modules/input/gtkimcontextxim.c,v
retrieving revision 1.32.2.5
diff -u -p -r1.32.2.5 gtkimcontextxim.c
--- gtkimcontextxim.c	10 Jun 2003 18:25:25 -0000	1.32.2.5
+++ gtkimcontextxim.c	23 Jun 2003 22:06:02 -0000
@@ -419,17 +419,18 @@ get_im (GdkWindow *client_window,
 	const char *locale)
 {
   GSList *tmp_list;
-  GtkXIMInfo *info;
+  GtkXIMInfo *tmp_info, *info;
   GdkScreen *screen = gdk_drawable_get_screen (client_window);
 
   info = NULL;
   tmp_list = open_ims;
   while (tmp_list)
     {
-      info = tmp_list->data;
-      if (info->screen == screen &&
-	  strcmp (info->locale, locale) == 0)
+      tmp_info = tmp_list->data;
+      if (tmp_info->screen == screen &&
+	  strcmp (tmp_info->locale, locale) == 0)
 	{
+	  info = tmp_info;
 	  if (info->im)
 	    return info;
 	  else
@@ -680,6 +681,41 @@ gtk_im_context_xim_filter_keypress (GtkI
   return result;
 }
 
+/* global variables : just for quick testing */
+static GtkWidget *cur_toplevel = NULL;
+gulong cur_handler_id;
+
+static gboolean
+gtk_im_key_press_on_toplevel (GtkWidget *widget, 
+			      GdkEventKey *event,
+			      GtkIMContextXIM *context_xim)
+{
+  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)
 {
@@ -693,6 +729,31 @@ gtk_im_context_xim_focus_in (GtkIMContex
 
   status_window_show (context_xim);
 
+  /* connect key-press on the toplevel */
+  {
+    GdkWindow *toplevel_gdk;
+    GtkWidget *window;
+    GdkScreen *screen;
+    GdkWindow *root_window;
+
+    toplevel_gdk = context_xim->client_window;
+    screen = gdk_drawable_get_screen (toplevel_gdk);
+    root_window = gdk_screen_get_root_window (screen);
+  
+    while (toplevel_gdk)
+      {
+	GdkWindow *parent = gdk_window_get_parent (toplevel_gdk);
+	if (parent == root_window)
+	  break;
+	else
+	  toplevel_gdk = parent;
+      }
+
+    gdk_window_get_user_data (toplevel_gdk, (gpointer *)&cur_toplevel);
+    if (cur_toplevel)
+      cur_handler_id = g_signal_connect (cur_toplevel, "key_press_event",
+					 G_CALLBACK (gtk_im_key_press_on_toplevel), context_xim);
+  }
   return;
 }
 
@@ -709,6 +770,12 @@ gtk_im_context_xim_focus_out (GtkIMConte
 
   status_window_hide (context_xim);
 
+  if (cur_toplevel)
+    {
+      g_signal_handler_disconnect (cur_toplevel, cur_handler_id);
+      cur_toplevel = 0;
+    }
+
   return;
 }
 
@@ -1320,7 +1387,7 @@ status_window_get (GtkIMContextXIM *cont
   screen = gdk_drawable_get_screen (toplevel_gdk);
   root_window = gdk_screen_get_root_window (screen);
   
-  while (TRUE)
+  while (toplevel_gdk)
     {
       GdkWindow *parent = gdk_window_get_parent (toplevel_gdk);
       if (parent == root_window)
