diff -urNp gtk+-2.10.6-orig/gtk/gtkentry.c gtk+-2.10.6/gtk/gtkentry.c
--- gtk+-2.10.6-orig/gtk/gtkentry.c	2007-01-05 03:49:52.214264000 +0900
+++ gtk+-2.10.6/gtk/gtkentry.c	2007-01-05 03:50:50.957857000 +0900
@@ -1078,6 +1078,8 @@ gtk_entry_init (GtkEntry *entry)
    * to it; so we create it here and destroy it in finalize().
    */
   entry->im_context = gtk_im_multicontext_new ();
+
+  g_object_set_data(G_OBJECT(entry), "im_context", entry->im_context);
   
   g_signal_connect (entry->im_context, "commit",
 		    G_CALLBACK (gtk_entry_commit_cb), entry);
diff -urNp gtk+-2.10.6-orig/gtk/gtkimcontext.c gtk+-2.10.6/gtk/gtkimcontext.c
--- gtk+-2.10.6-orig/gtk/gtkimcontext.c	2007-01-05 03:49:53.024089000 +0900
+++ gtk+-2.10.6/gtk/gtkimcontext.c	2007-01-05 03:50:50.979266000 +0900
@@ -41,6 +41,8 @@ static void     gtk_im_context_real_get_
 							gchar         **str,
 							PangoAttrList **attrs,
 							gint           *cursor_pos);
+static gboolean gtk_im_context_real_filter_pre_keypress    (GtkIMContext   *context,
+							GdkEventKey    *event);
 static gboolean gtk_im_context_real_filter_keypress    (GtkIMContext   *context,
 							GdkEventKey    *event);
 static gboolean gtk_im_context_real_get_surrounding    (GtkIMContext   *context,
@@ -57,6 +59,7 @@ static void
 gtk_im_context_class_init (GtkIMContextClass *klass)
 {
   klass->get_preedit_string = gtk_im_context_real_get_preedit_string;
+  klass->filter_pre_keypress = gtk_im_context_real_filter_pre_keypress;
   klass->filter_keypress = gtk_im_context_real_filter_keypress;
   klass->get_surrounding = gtk_im_context_real_get_surrounding;
   klass->set_surrounding = gtk_im_context_real_set_surrounding;
@@ -138,6 +141,13 @@ gtk_im_context_real_get_preedit_string (
 }
 
 static gboolean
+gtk_im_context_real_filter_pre_keypress (GtkIMContext       *context,
+                                         GdkEventKey        *event)
+{
+  return FALSE;
+}
+
+static gboolean
 gtk_im_context_real_filter_keypress (GtkIMContext       *context,
 				     GdkEventKey        *event)
 {
@@ -263,6 +273,19 @@ gtk_im_context_get_preedit_string (GtkIM
   g_return_if_fail (str == NULL || g_utf8_validate (*str, -1, NULL));
 }
 
+gboolean
+gtk_im_context_filter_pre_keypress (GtkIMContext *context,
+				    GdkEventKey  *key)
+{
+  GtkIMContextClass *klass;
+  
+  g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  klass = GTK_IM_CONTEXT_GET_CLASS (context);
+  return klass->filter_pre_keypress (context, key);
+}
+
 /**
  * gtk_im_context_filter_keypress:
  * @context: a #GtkIMContext
diff -urNp gtk+-2.10.6-orig/gtk/gtkimcontext.h gtk+-2.10.6/gtk/gtkimcontext.h
--- gtk+-2.10.6-orig/gtk/gtkimcontext.h	2007-01-05 03:49:57.156457000 +0900
+++ gtk+-2.10.6/gtk/gtkimcontext.h	2007-01-05 03:50:50.989096000 +0900
@@ -66,6 +66,8 @@ struct _GtkIMContextClass
 				   gchar         **str,
 				   PangoAttrList **attrs,
 				   gint           *cursor_pos);
+  gboolean (*filter_pre_keypress)     (GtkIMContext   *context,
+			               GdkEventKey    *event);
   gboolean (*filter_keypress)     (GtkIMContext   *context,
 			           GdkEventKey    *event);
   void     (*focus_in)            (GtkIMContext   *context);
@@ -100,6 +102,8 @@ void     gtk_im_context_get_preedit_stri
 					     gchar         **str,
 					     PangoAttrList **attrs,
 					     gint           *cursor_pos);
+gboolean gtk_im_context_filter_pre_keypress (GtkIMContext   *context,
+				 	     GdkEventKey    *event);
 gboolean gtk_im_context_filter_keypress     (GtkIMContext   *context,
 					     GdkEventKey    *event);
 void     gtk_im_context_focus_in            (GtkIMContext   *context);
diff -urNp gtk+-2.10.6-orig/gtk/gtkimmulticontext.c gtk+-2.10.6/gtk/gtkimmulticontext.c
--- gtk+-2.10.6-orig/gtk/gtkimmulticontext.c	2007-01-05 03:49:59.300536000 +0900
+++ gtk+-2.10.6/gtk/gtkimmulticontext.c	2007-01-05 03:50:51.013052000 +0900
@@ -52,6 +52,8 @@ static void     gtk_im_multicontext_get_
 							gchar                  **str,
 							PangoAttrList          **attrs,
 							gint                   *cursor_pos);
+static gboolean gtk_im_multicontext_filter_pre_keypress (GtkIMContext            *context,
+							GdkEventKey             *event);
 static gboolean gtk_im_multicontext_filter_keypress    (GtkIMContext            *context,
 							GdkEventKey             *event);
 static void     gtk_im_multicontext_focus_in           (GtkIMContext            *context);
@@ -97,6 +99,7 @@ gtk_im_multicontext_class_init (GtkIMMul
   
   im_context_class->set_client_window = gtk_im_multicontext_set_client_window;
   im_context_class->get_preedit_string = gtk_im_multicontext_get_preedit_string;
+  im_context_class->filter_pre_keypress = gtk_im_multicontext_filter_pre_keypress;
   im_context_class->filter_keypress = gtk_im_multicontext_filter_keypress;
   im_context_class->focus_in = gtk_im_multicontext_focus_in;
   im_context_class->focus_out = gtk_im_multicontext_focus_out;
@@ -276,6 +279,19 @@ gtk_im_multicontext_get_preedit_string (
 }
 
 static gboolean
+gtk_im_multicontext_filter_pre_keypress (GtkIMContext *context,
+				     GdkEventKey  *event)
+{
+  GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
+  GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+  
+  if (slave)
+    return gtk_im_context_filter_pre_keypress (slave, event);
+  else
+    return FALSE;
+}
+
+static gboolean
 gtk_im_multicontext_filter_keypress (GtkIMContext *context,
 				     GdkEventKey  *event)
 {
diff -urNp gtk+-2.10.6-orig/gtk/gtkmain.c gtk+-2.10.6/gtk/gtkmain.c
--- gtk+-2.10.6-orig/gtk/gtkmain.c	2007-01-05 03:49:51.445990000 +0900
+++ gtk+-2.10.6/gtk/gtkmain.c	2007-01-05 03:50:51.300791000 +0900
@@ -68,6 +68,7 @@
 #include "gtkprivate.h"
 #include "gtkdebug.h"
 #include "gtkalias.h"
+#include "gtkimcontext.h"
 
 #include "gdk/gdkprivate.h" /* for GDK_WINDOW_DESTROYED */
 
@@ -2126,6 +2127,8 @@ gtk_propagate_event (GtkWidget *widget,
 		     GdkEvent  *event)
 {
   gint handled_event;
+  GtkIMContext *im_context;
+  GtkWidget *focus;
   
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (event != NULL);
@@ -2147,10 +2150,18 @@ gtk_propagate_event (GtkWidget *widget,
       window = gtk_widget_get_toplevel (widget);
       if (window && GTK_IS_WINDOW (window))
 	{
+	  focus = GTK_WINDOW(window)->focus_widget;
+
+	  if (focus)
+	    {
+	      im_context = g_object_get_data(focus, "im_context");
+	      if(im_context && gtk_im_context_filter_pre_keypress (im_context, event))
+		handled_event = TRUE;
+	    }
 	  /* If there is a grab within the window, give the grab widget
 	   * a first crack at the key event
 	   */
-	  if (widget != window && GTK_WIDGET_HAS_GRAB (widget))
+	  if (!handled_event && widget != window && GTK_WIDGET_HAS_GRAB (widget))
 	    handled_event = gtk_widget_event (widget, event);
 	  
 	  if (!handled_event)
diff -urNp gtk+-2.10.6-orig/gtk/gtktextview.c gtk+-2.10.6/gtk/gtktextview.c
--- gtk+-2.10.6-orig/gtk/gtktextview.c	2007-01-05 03:49:53.244360000 +0900
+++ gtk+-2.10.6/gtk/gtktextview.c	2007-01-05 03:50:51.358132000 +0900
@@ -1045,6 +1045,7 @@ gtk_text_view_init (GtkTextView *text_vi
    * to it; so we create it here and destroy it in finalize ().
    */
   text_view->im_context = gtk_im_multicontext_new ();
+  g_object_set_data(G_OBJECT(text_view), "im_context", text_view->im_context);
 
   g_signal_connect (text_view->im_context, "commit",
                     G_CALLBACK (gtk_text_view_commit_handler), text_view);
diff -urNp gtk+-2.10.6-orig/modules/input/gtkimcontextxim.c gtk+-2.10.6/modules/input/gtkimcontextxim.c
--- gtk+-2.10.6-orig/modules/input/gtkimcontextxim.c	2007-01-05 03:49:35.391151000 +0900
+++ gtk+-2.10.6/modules/input/gtkimcontextxim.c	2007-01-05 03:50:51.591058000 +0900
@@ -68,6 +68,7 @@ struct _GtkIMContextXIM
 
   XIC ic;
 
+  guint filter_pre_key_press;
   guint filter_key_release : 1;
   guint use_preedit : 1;
   guint finalizing : 1;
@@ -110,6 +111,8 @@ static void     gtk_im_context_xim_init 
 static void     gtk_im_context_xim_finalize           (GObject               *obj);
 static void     gtk_im_context_xim_set_client_window  (GtkIMContext          *context,
 						       GdkWindow             *client_window);
+static gboolean gtk_im_context_xim_filter_pre_keypress(GtkIMContext          *context,
+						       GdkEventKey           *key);
 static gboolean gtk_im_context_xim_filter_keypress    (GtkIMContext          *context,
 						       GdkEventKey           *key);
 static void     gtk_im_context_xim_reset              (GtkIMContext          *context);
@@ -538,6 +541,7 @@ gtk_im_context_xim_class_init (GtkIMCont
   parent_class = g_type_class_peek_parent (class);
 
   im_context_class->set_client_window = gtk_im_context_xim_set_client_window;
+  im_context_class->filter_pre_keypress = gtk_im_context_xim_filter_pre_keypress;
   im_context_class->filter_keypress = gtk_im_context_xim_filter_keypress;
   im_context_class->reset = gtk_im_context_xim_reset;
   im_context_class->get_preedit_string = gtk_im_context_xim_get_preedit_string;
@@ -692,6 +696,40 @@ mb_to_utf8 (GtkIMContextXIM *context_xim
 }
 
 static gboolean
+gtk_im_context_xim_filter_pre_keypress (GtkIMContext *context,
+                                        GdkEventKey  *event)
+{
+  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))) {
+    context_xim->filter_pre_key_press = event->hardware_keycode;
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+static gboolean
 gtk_im_context_xim_filter_keypress (GtkIMContext *context,
 				    GdkEventKey  *event)
 {
@@ -711,6 +749,11 @@ gtk_im_context_xim_filter_keypress (GtkI
   if (event->type == GDK_KEY_RELEASE && !context_xim->filter_key_release)
     return FALSE;
 
+  if (context_xim->filter_pre_key_press == event->hardware_keycode) {
+    context_xim->filter_pre_key_press = 0;
+    return TRUE;
+  }
+
   xevent.type = (event->type == GDK_KEY_PRESS) ? KeyPress : KeyRelease;
   xevent.serial = 0;		/* hope it doesn't matter */
   xevent.send_event = event->send_event;
