diff -Nu gtk+-2.3.2.orig/gtk/gtkentry.c gtk+-2.3.2/gtk/gtkentry.c
--- gtk+-2.3.2.orig/gtk/gtkentry.c	2004-01-23 05:13:40.000000000 +0900
+++ gtk+-2.3.2/gtk/gtkentry.c	2004-01-25 00:38:53.000000000 +0900
@@ -922,12 +922,14 @@
                      GTK_DEST_DEFAULT_HIGHLIGHT,
                      target_table, G_N_ELEMENTS (target_table),
                      GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
-  /* This object is completely private. No external entity can gain a reference
-   * to it; so we create it here and destroy it in finalize().
+  
+  /* Now im_context isn't completely private. But life of im_context is same as
+   * owner widget, 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);
   g_signal_connect (entry->im_context, "preedit_changed",
diff -Nu gtk+-2.3.2.orig/gtk/gtkimcontext.c gtk+-2.3.2/gtk/gtkimcontext.c
--- gtk+-2.3.2.orig/gtk/gtkimcontext.c	2004-01-23 05:13:42.000000000 +0900
+++ gtk+-2.3.2/gtk/gtkimcontext.c	2004-01-25 00:29:28.000000000 +0900
@@ -38,19 +38,21 @@
 static void gtk_im_context_class_init (GtkIMContextClass *class);
 static void gtk_im_context_init (GtkIMContext *im_context);
 
-static void     gtk_im_context_real_get_preedit_string (GtkIMContext   *context,
-							gchar         **str,
-							PangoAttrList **attrs,
-							gint           *cursor_pos);
-static gboolean gtk_im_context_real_filter_keypress    (GtkIMContext   *context,
-							GdkEventKey    *event);
-static gboolean gtk_im_context_real_get_surrounding    (GtkIMContext   *context,
-							gchar         **text,
-							gint           *cursor_index);
-static void     gtk_im_context_real_set_surrounding    (GtkIMContext   *context,
-							const char     *text,
-							gint            len,
-							gint            cursor_index);
+static void     gtk_im_context_real_get_preedit_string  (GtkIMContext   *context,
+							 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,
+							 gchar         **text,
+							 gint           *cursor_index);
+static void     gtk_im_context_real_set_surrounding     (GtkIMContext   *context,
+						 	 const char     *text,
+							 gint            len,
+							 gint            cursor_index);
 
 GType
 gtk_im_context_get_type (void)
@@ -84,7 +86,8 @@
 static void
 gtk_im_context_class_init (GtkIMContextClass *klass)
 {
-  klass->get_preedit_string = gtk_im_context_real_get_preedit_string;
+  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;
@@ -166,6 +169,13 @@
 }
 
 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)
 {
@@ -292,6 +302,34 @@
 }
 
 /**
+ * gtk_im_context_filter_pre_keypress:
+ * @context: a #GtkIMContext
+ * @event: the key event
+ * 
+ * Allow an input method to internally handle a key press event.
+ * If this function returns %TRUE, then no further processing
+ * should be done for this keystroke.
+ * 
+ * This function is called in gtk_propagate_event, so widget must
+ * not call this function.
+ *
+ * Return value: %TRUE if the input method handled the keystroke.
+ *
+ **/
+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
  * @event: the key event
diff -Nu gtk+-2.3.2.orig/gtk/gtkimcontext.h gtk+-2.3.2/gtk/gtkimcontext.h
--- gtk+-2.3.2.orig/gtk/gtkimcontext.h	2002-10-11 07:18:36.000000000 +0900
+++ gtk+-2.3.2/gtk/gtkimcontext.h	2004-01-25 00:30:52.000000000 +0900
@@ -85,9 +85,9 @@
   gboolean (*get_surrounding)     (GtkIMContext   *context,
 				   gchar         **text,
 				   gint           *cursor_index);
-
+  gboolean (*filter_pre_keypress) (GtkIMContext   *context,
+			           GdkEventKey    *event);
   /* Padding for future expansion */
-  void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
   void (*_gtk_reserved4) (void);
@@ -103,6 +103,8 @@
 					     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 -Nu gtk+-2.3.2.orig/gtk/gtkimmulticontext.c gtk+-2.3.2/gtk/gtkimmulticontext.c
--- gtk+-2.3.2.orig/gtk/gtkimmulticontext.c	2003-09-21 08:52:16.000000000 +0900
+++ gtk+-2.3.2/gtk/gtkimmulticontext.c	2004-01-24 22:44:15.000000000 +0900
@@ -53,6 +53,8 @@
 							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);
@@ -127,6 +129,7 @@
 
   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;
@@ -304,6 +307,18 @@
     }
 }
 
+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 -Nu gtk+-2.3.2.orig/gtk/gtkmain.c gtk+-2.3.2/gtk/gtkmain.c
--- gtk+-2.3.2.orig/gtk/gtkmain.c	2004-01-23 05:13:44.000000000 +0900
+++ gtk+-2.3.2/gtk/gtkmain.c	2004-01-25 01:40:53.000000000 +0900
@@ -63,6 +63,7 @@
 #include "gtkwindow.h"
 #include "gtkprivate.h"
 #include "gtkdebug.h"
+#include "gtkimcontext.h"
 
 /* Private type definitions
  */
@@ -2278,6 +2279,8 @@
 		     GdkEvent  *event)
 {
   gint handled_event;
+  GtkIMContext *im_context;
+  GtkWidget *focus;
   
   g_return_if_fail (GTK_IS_WIDGET (widget));
   g_return_if_fail (event != NULL);
@@ -2297,12 +2300,24 @@
       GtkWidget *window;
 
       window = gtk_widget_get_toplevel (widget);
+      
       if (window && GTK_IS_WINDOW (window))
 	{
+	  focus = GTK_WINDOW(window)->focus_widget;
+	  
+	  if(focus)
+	    {
+	      /* Using g_object_get_data is not good. If we can break ABI, we should
+		 add im_context for member of GtkWidget and stop using g_object_get_data. */
+	      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 -Nu gtk+-2.3.2.orig/gtk/gtktextview.c gtk+-2.3.2/gtk/gtktextview.c
--- gtk+-2.3.2.orig/gtk/gtktextview.c	2004-01-23 05:13:50.000000000 +0900
+++ gtk+-2.3.2/gtk/gtktextview.c	2004-01-24 14:54:55.000000000 +0900
@@ -1047,6 +1047,7 @@
    * 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);
