[gtk/gtk-4-8: 1/2] Use native Windows API for converting keystrokes to characters




commit f2ccb4192e2f8e2d0bb4dd89d616f7dc2b9ad693
Author: Philip Zander <philip zander gmail com>
Date:   Wed Aug 24 13:21:10 2022 +0200

    Use native Windows API for converting keystrokes to characters

 gdk/broadway/gdkeventsource.c         |   3 +-
 gdk/gdkevents.c                       |  40 +++++++++-
 gdk/gdkeventsprivate.h                |  10 ++-
 gdk/macos/gdkmacosdisplay-translate.c |   3 +-
 gdk/macos/gdkmacossurface.c           |   3 +-
 gdk/wayland/gdkdevice-wayland.c       |   3 +-
 gdk/win32/gdkevents-win32.c           | 143 ++++++++++++++--------------------
 gdk/win32/gdksurface-win32.h          |   8 --
 gdk/x11/gdkdevicemanager-xi2.c        |   3 +-
 gtk/gtkimcontext.c                    |   3 +-
 gtk/gtkimcontextime.c                 | 123 ++---------------------------
 gtk/gtkimcontextsimple.c              |   3 +-
 gtk/gtkmain.c                         |   3 +-
 13 files changed, 127 insertions(+), 221 deletions(-)
---
diff --git a/gdk/broadway/gdkeventsource.c b/gdk/broadway/gdkeventsource.c
index 045c8f3040..7aa496d370 100644
--- a/gdk/broadway/gdkeventsource.c
+++ b/gdk/broadway/gdkeventsource.c
@@ -262,7 +262,8 @@ _gdk_broadway_events_got_input (GdkDisplay *display,
                                    message->key.state,
                                    FALSE,
                                    &translated,
-                                   &translated);
+                                   &translated,
+                                   NULL);
 
         node = _gdk_event_queue_append (display, event);
         _gdk_windowing_got_event (display, node, event, message->base.serial);
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index 3e68b26579..890dbf01a1 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -1517,6 +1517,16 @@ gdk_button_event_get_button (GdkEvent *event)
  * An event related to a key-based device.
  */
 
+static void
+gdk_key_event_finalize (GdkEvent *event)
+{
+  GdkKeyEvent *self = (GdkKeyEvent *) event;
+
+  g_free (self->compose_sequence);
+
+  GDK_EVENT_SUPER (event)->finalize (event);
+}
+
 static GdkModifierType
 gdk_key_event_get_state (GdkEvent *event)
 {
@@ -1528,7 +1538,7 @@ gdk_key_event_get_state (GdkEvent *event)
 static const GdkEventTypeInfo gdk_key_event_info = {
   sizeof (GdkKeyEvent),
   NULL,
-  NULL,
+  gdk_key_event_finalize,
   gdk_key_event_get_state,
   NULL,
   NULL,
@@ -1552,6 +1562,10 @@ GDK_DEFINE_EVENT_TYPE (GdkKeyEvent, gdk_key_event,
  * @is_modifier: whether the event is a modifiers only event
  * @translated: the translated key data for the given @state
  * @no_lock: the translated key data without the given @state
+ * @compose_sequence: (transfer none) (nullable):
+ *   The compose sequence string, either partial or only the
+ *   final composed string, if that can be determined at event
+ *   creation time. Used by selected IM modules.
  *
  * Creates a new `GdkKeyEvent`.
  *
@@ -1566,7 +1580,8 @@ gdk_key_event_new (GdkEventType      type,
                    GdkModifierType   state,
                    gboolean          is_modifier,
                    GdkTranslatedKey *translated,
-                   GdkTranslatedKey *no_lock)
+                   GdkTranslatedKey *no_lock,
+                   char             *compose_sequence)
 {
   g_return_val_if_fail (type == GDK_KEY_PRESS ||
                         type == GDK_KEY_RELEASE, NULL);
@@ -1579,6 +1594,7 @@ gdk_key_event_new (GdkEventType      type,
   self->key_is_modifier = is_modifier;
   self->translated[0] = *translated;
   self->translated[1] = *no_lock;
+  self->compose_sequence = g_strdup (compose_sequence);
 
   return event;
 }
@@ -1609,6 +1625,26 @@ gdk_key_event_get_translated_key (GdkEvent *event,
   return &(self->translated[0]);
 }
 
+/*< private >
+ * gdk_key_event_get_compose_sequence:
+ * @event: (type GdkKeyEvent): a key event
+ *
+ * Extracts the compose sequence string from a key event.
+ *
+ * Returns: (transfer none): the compose sequence string
+ */
+char *
+gdk_key_event_get_compose_sequence (GdkEvent *event)
+{
+  GdkKeyEvent *self = (GdkKeyEvent *) event;
+
+  g_return_val_if_fail (GDK_IS_EVENT (event), 0);
+  g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
+                        GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), FALSE);
+
+  return self->compose_sequence;
+}
+
 /**
  * gdk_key_event_get_keyval:
  * @event: (type GdkKeyEvent): a key event
diff --git a/gdk/gdkeventsprivate.h b/gdk/gdkeventsprivate.h
index a36c5d100b..aad8218b37 100644
--- a/gdk/gdkeventsprivate.h
+++ b/gdk/gdkeventsprivate.h
@@ -259,6 +259,9 @@ typedef struct {
  * @keycode: the raw code of the key that was pressed or released.
  * @translated: the result of translating @keycode. First with the full
  *   @state, then while ignoring Caps Lock.
+ * @compose_sequence: optional string for use by selected IM modules.
+ *   Contains either partial compose sequences or the final composed
+ *   string of the keystroke sequence.
  *
  * Describes a key press or key release event.
  */
@@ -270,6 +273,7 @@ struct _GdkKeyEvent
   guint32 keycode;
   gboolean key_is_modifier;
   GdkTranslatedKey translated[2];
+  char *compose_sequence;
 };
 
 /*
@@ -470,7 +474,8 @@ GdkEvent * gdk_key_event_new            (GdkEventType      type,
                                          GdkModifierType   modifiers,
                                          gboolean          is_modifier,
                                          GdkTranslatedKey *translated,
-                                         GdkTranslatedKey *no_lock);
+                                         GdkTranslatedKey *no_lock,
+                                         char             *compose_sequence);
 
 GdkEvent * gdk_focus_event_new          (GdkSurface      *surface,
                                          GdkDevice       *device,
@@ -597,6 +602,8 @@ GdkEvent * gdk_grab_broken_event_new    (GdkSurface      *surface,
 GdkTranslatedKey *      gdk_key_event_get_translated_key        (GdkEvent *event,
                                                                  gboolean  no_lock);
 
+char *                  gdk_key_event_get_compose_sequence      (GdkEvent *event);
+
 typedef enum
 {
   /* Following flag is set for events on the event queue during
@@ -626,7 +633,6 @@ void    _gdk_event_queue_flush                     (GdkDisplay       *display);
 
 double * gdk_event_dup_axes (GdkEvent *event);
 
-
 G_END_DECLS
 
 #endif /* __GDK_EVENTS_PRIVATE_H__ */
diff --git a/gdk/macos/gdkmacosdisplay-translate.c b/gdk/macos/gdkmacosdisplay-translate.c
index 7eaa6dca03..502a9a8cac 100644
--- a/gdk/macos/gdkmacosdisplay-translate.c
+++ b/gdk/macos/gdkmacosdisplay-translate.c
@@ -431,7 +431,8 @@ fill_key_event (GdkMacosDisplay *display,
                             state,
                             is_modifier,
                             &translated,
-                            &no_lock);
+                            &no_lock,
+                            NULL);
 }
 
 static GdkEvent *
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 46074a5d9d..b847ea0ff4 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -944,7 +944,8 @@ _gdk_macos_surface_synthesize_null_key (GdkMacosSurface *self)
                              0,
                              FALSE,
                              &translated,
-                             &no_lock);
+                             &no_lock,
+                             NULL);
   _gdk_event_queue_append (display, event);
 }
 
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index cd314b6d67..98e08ecb5f 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -2205,7 +2205,8 @@ deliver_key_event (GdkWaylandSeat *seat,
                              device_get_modifiers (seat->logical_pointer),
                              _gdk_wayland_keymap_key_is_modifier (keymap, key),
                              &translated,
-                             &no_lock);
+                             &no_lock,
+                             NULL);
 
   _gdk_wayland_display_deliver_event (seat->display, event);
 
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index f85aca6506..9857095519 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1857,7 +1857,8 @@ gdk_event_translate (MSG *msg,
                                    0,
                                    FALSE,
                                    &translated,
-                                   &translated);
+                                   &translated,
+                                   NULL);
         _gdk_win32_append_event (event);
       }
       break;
@@ -1906,8 +1907,12 @@ gdk_event_translate (MSG *msg,
         GdkTranslatedKey translated;
         GdkTranslatedKey no_lock;
         BYTE key_state[256];
-        wchar_t wbuf[100];
-        int ccount = 0;
+        GArray *translation;
+        MSG msg2;
+        int level = 0;
+        int effective_group = 0;
+        GdkModifierType consumed = 0;
+        char *composed = NULL;
 
         /* Ignore key messages intended for the IME */
         if (msg->wParam == VK_PROCESSKEY || in_ime_composition)
@@ -1929,33 +1934,40 @@ gdk_event_translate (MSG *msg,
 
         API_CALL (GetKeyboardState, (key_state));
 
-        ccount = 0;
+        keyval = GDK_KEY_VoidSymbol;
+        keycode = msg->wParam;
 
-        if (msg->wParam == VK_PACKET)
+        /* Get the WinAPI translation of the WM_KEY messages to characters.
+
+           The WM_CHAR messages are generated by a previous call to TranslateMessage() and always
+           follow directly after the corresponding WM_KEY* messages.
+           There could be 0 or more WM_CHAR messages following (for example dead keys don't generate
+           WM_CHAR messages - they generate WM_DEAD_CHAR instead, but we are not interested in those
+           messages). */
+
+        translation = g_array_sized_new (FALSE, FALSE, sizeof (gunichar2), 2);
+        while (PeekMessageW (&msg2, msg->hwnd, 0, 0, 0) && (msg2.message == WM_CHAR || msg2.message == 
WM_SYSCHAR))
           {
-            ccount = ToUnicode (VK_PACKET, HIWORD (msg->lParam), key_state, wbuf, 1, 0);
-            if (ccount == 1)
-              {
-                if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
-                  {
-                    if (msg->message == WM_KEYDOWN)
-                      impl->leading_surrogate_keydown = wbuf[0];
-                    else
-                      impl->leading_surrogate_keyup = wbuf[0];
-
-                    /* don't emit an event */
-                    return_val = TRUE;
-                    break;
-                  }
-                else
-                  {
-                    /* wait until an event is created */;
-                  }
-              }
+            /* The character is encoded in WPARAM as UTF-16. */
+            gunichar2 c = msg2.wParam;
+
+            /* Append character to translation string. */
+            g_array_append_val (translation, c);
+
+            /* Remove message from queue */
+            GetMessageW (&msg2, msg->hwnd, 0, 0);
           }
 
-        keyval = GDK_KEY_VoidSymbol;
-        keycode = msg->wParam;
+        if (translation->len > 0)
+          composed = g_utf16_to_utf8 ((gunichar2*)translation->data,
+                                      translation->len, NULL, NULL, NULL);
+
+        g_array_unref (translation);
+        translation = NULL;
+
+        /* Ignore control sequences like Backspace */
+        if (composed && g_unichar_iscntrl (g_utf8_get_char (composed)))
+          g_clear_pointer (&composed, g_free);
 
         if (HIWORD (msg->lParam) & KF_EXTENDED)
           {
@@ -1985,61 +1997,20 @@ gdk_event_translate (MSG *msg,
         state = build_key_event_state (key_state);
         group = get_active_group ();
 
-        if (msg->wParam == VK_PACKET && ccount == 1)
-          {
-            if (wbuf[0] >= 0xD800 && wbuf[0] < 0xDC00)
-              {
-                g_assert_not_reached ();
-              }
-            else if (wbuf[0] >= 0xDC00 && wbuf[0] < 0xE000)
-              {
-                wchar_t leading;
-
-                if (msg->message == WM_KEYDOWN)
-                  leading = impl->leading_surrogate_keydown;
-                else
-                  leading = impl->leading_surrogate_keyup;
-
-                keyval = gdk_unicode_to_keyval ((leading - 0xD800) * 0x400 + wbuf[0] - 0xDC00 + 0x10000);
-              }
-            else
-              {
-                keyval = gdk_unicode_to_keyval (wbuf[0]);
-              }
-
-            translated.keyval = keyval;
-            translated.consumed = 0;
-            translated.layout = 0;
-            translated.level = 0;
-
-            no_lock = translated;
-          }
-        else
-          {
-            int level = 0;
-            int effective_group = 0;
-            GdkModifierType consumed = 0;
-
-            gdk_keymap_translate_keyboard_state ((GdkKeymap*) win32_keymap, keycode, state, group,
-                                                 &keyval, &effective_group, &level, &consumed);
-            translated.keyval = keyval;
-            translated.consumed = consumed;
-            translated.layout = effective_group;
-            translated.level = level;
-
-            gdk_keymap_translate_keyboard_state ((GdkKeymap*) win32_keymap, keycode,
-                                                 state & ~GDK_LOCK_MASK, group, &keyval,
-                                                 &effective_group, &level, &consumed);
-            no_lock.keyval = keyval;
-            no_lock.consumed = consumed;
-            no_lock.layout = effective_group;
-            no_lock.level = level;
-          }
-
-        if (msg->message == WM_KEYDOWN)
-          impl->leading_surrogate_keydown = 0;
-        else
-          impl->leading_surrogate_keyup = 0;
+        gdk_keymap_translate_keyboard_state ((GdkKeymap*) win32_keymap, keycode, state, group,
+                                             &keyval, &effective_group, &level, &consumed);
+        translated.keyval = keyval;
+        translated.consumed = consumed;
+        translated.layout = effective_group;
+        translated.level = level;
+
+        gdk_keymap_translate_keyboard_state ((GdkKeymap*) win32_keymap, keycode,
+                                             state & ~GDK_LOCK_MASK, group, &keyval,
+                                             &effective_group, &level, &consumed);
+        no_lock.keyval = keyval;
+        no_lock.consumed = consumed;
+        no_lock.layout = effective_group;
+        no_lock.level = level;
 
         /* Only one release key event is fired when both shift keys are pressed together
            and then released. In order to send the missing event, press events for shift
@@ -2087,10 +2058,12 @@ gdk_event_translate (MSG *msg,
                                    state,
                                    is_modifier,
                                    &translated,
-                                   &no_lock);
+                                   &no_lock,
+                                   composed);
 
         _gdk_win32_append_event (event);
 
+        g_free (composed);
         return_val = TRUE;
       }
       break;
@@ -2169,7 +2142,8 @@ gdk_event_translate (MSG *msg,
                                        build_key_event_state (key_state),
                                        FALSE,
                                        &translated,
-                                       &translated);
+                                       &translated,
+                                       NULL);
 
             _gdk_win32_append_event (event);
 
@@ -2182,7 +2156,8 @@ gdk_event_translate (MSG *msg,
                                        build_key_event_state (key_state),
                                        FALSE,
                                        &translated,
-                                       &translated);
+                                       &translated,
+                                       NULL);
 
             _gdk_win32_append_event (event);
           }
diff --git a/gdk/win32/gdksurface-win32.h b/gdk/win32/gdksurface-win32.h
index cff41117ef..22daa8faa7 100644
--- a/gdk/win32/gdksurface-win32.h
+++ b/gdk/win32/gdksurface-win32.h
@@ -235,14 +235,6 @@ struct _GdkWin32Surface
   /* The cursor that GDK set for this window via GdkDevice */
   GdkWin32HCursor *cursor;
 
-  /* When VK_PACKET sends us a leading surrogate, it's stashed here.
-   * Later, when another VK_PACKET sends a tailing surrogate, we make up
-   * a full unicode character from them, or discard the leading surrogate,
-   * if the next key is not a tailing surrogate.
-   */
-  wchar_t leading_surrogate_keydown;
-  wchar_t leading_surrogate_keyup;
-
   /* Window size hints */
   int hint_flags;
   GdkGeometry hints;
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 566d519809..02ceb2f110 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1595,7 +1595,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
                                    state,
                                    gdk_x11_keymap_key_is_modifier (keymap, xev->detail),
                                    &translated,
-                                   &no_lock);
+                                   &no_lock,
+                                   NULL);
 
         if (ev->evtype == XI_KeyPress)
           set_user_time (event);
diff --git a/gtk/gtkimcontext.c b/gtk/gtkimcontext.c
index 3772d58db4..26f33b2cbe 100644
--- a/gtk/gtkimcontext.c
+++ b/gtk/gtkimcontext.c
@@ -607,7 +607,8 @@ gtk_im_context_filter_key (GtkIMContext    *context,
                            state,
                            FALSE, /* FIXME */
                            &translated,
-                           &no_lock);
+                           &no_lock,
+                           NULL);
 
   ret = GTK_IM_CONTEXT_GET_CLASS (context)->filter_keypress (context, key);
 
diff --git a/gtk/gtkimcontextime.c b/gtk/gtkimcontextime.c
index e341925733..1fba0af36f 100644
--- a/gtk/gtkimcontextime.c
+++ b/gtk/gtkimcontextime.c
@@ -34,6 +34,7 @@
 #include "imm-extra.h"
 
 #include "gdk/gdkkeysyms.h"
+#include "gdk/gdkeventsprivate.h"
 #include "gdk/win32/gdkwin32.h"
 #include "gtk/gtkimmodule.h"
 #include "gtk/gtkstylecontextprivate.h"
@@ -61,9 +62,6 @@ typedef enum {
   GTK_WIN32_IME_FOCUS_BEHAVIOR_FOLLOW,
 } GtkWin32IMEFocusBehavior;
 
-#define IS_DEAD_KEY(k) \
-    ((k) >= GDK_KEY_dead_grave && (k) <= (GDK_KEY_dead_dasia+1))
-
 struct _GtkIMContextIMEPrivate
 {
   /* When pretend_empty_preedit is set to TRUE,
@@ -81,7 +79,6 @@ struct _GtkIMContextIMEPrivate
    *   https://gitlab.gnome.org/GNOME/gtk/commit/c255ba68fc2c918dd84da48a472e7973d3c00b03
    */
   gboolean pretend_empty_preedit;
-  guint32 dead_key_keyval;
   GtkWin32IMEFocusBehavior focus_behavior;
 };
 
@@ -277,134 +274,26 @@ gtk_im_context_ime_set_client_widget (GtkIMContext *context,
   context_ime->client_surface = surface;
 }
 
-static gunichar
-_gtk_im_context_ime_dead_key_unichar (guint    keyval,
-                                      gboolean spacing)
-{
-  switch (keyval)
-    {
-#define CASE(keysym, unicode, spacing_unicode) \
-      case GDK_KEY_dead_##keysym: return (spacing) ? spacing_unicode : unicode;
-
-      CASE (grave, 0x0300, 0x0060);
-      CASE (acute, 0x0301, 0x00b4);
-      CASE (circumflex, 0x0302, 0x005e);
-      CASE (tilde, 0x0303, 0x007e);    /* Also used with perispomeni, 0x342. */
-      CASE (macron, 0x0304, 0x00af);
-      CASE (breve, 0x0306, 0x02d8);
-      CASE (abovedot, 0x0307, 0x02d9);
-      CASE (diaeresis, 0x0308, 0x00a8);
-      CASE (hook, 0x0309, 0);
-      CASE (abovering, 0x030A, 0x02da);
-      CASE (doubleacute, 0x030B, 0x2dd);
-      CASE (caron, 0x030C, 0x02c7);
-      CASE (abovecomma, 0x0313, 0);         /* Equivalent to psili */
-      CASE (abovereversedcomma, 0x0314, 0); /* Equivalent to dasia */
-      CASE (horn, 0x031B, 0);  /* Legacy use for psili, 0x313 (or 0x343). */
-      CASE (belowdot, 0x0323, 0);
-      CASE (cedilla, 0x0327, 0x00b8);
-      CASE (ogonek, 0x0328, 0);        /* Legacy use for dasia, 0x314.*/
-      CASE (iota, 0x0345, 0);
-
-#undef CASE
-    default:
-      return 0;
-    }
-}
-
-static void
-_gtk_im_context_ime_commit_unichar (GtkIMContextIME *context_ime,
-                                    gunichar         c)
-{
-  char utf8[10];
-  int len;
-
-  if (context_ime->priv->dead_key_keyval != 0)
-    {
-      gunichar combining;
-
-      combining =
-        _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval,
-                                              FALSE);
-      g_unichar_compose (c, combining, &c);
-    }
-
-  len = g_unichar_to_utf8 (c, utf8);
-  utf8[len] = 0;
-
-  g_signal_emit_by_name (context_ime, "commit", utf8);
-  context_ime->priv->dead_key_keyval = 0;
-}
-
 static gboolean
 gtk_im_context_ime_filter_keypress (GtkIMContext *context,
                                     GdkEvent     *event)
 {
   GtkIMContextIME *context_ime;
-  gboolean retval = FALSE;
-  guint32 c;
-  GdkModifierType state, consumed_modifiers, no_text_input_mask;
-  guint keyval;
+  char *compose_sequence = NULL;
 
   g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context), FALSE);
   g_return_val_if_fail (event, FALSE);
 
-  if (gdk_event_get_event_type ((GdkEvent *) event) == GDK_KEY_RELEASE)
-    return FALSE;
-
-  no_text_input_mask = GDK_ALT_MASK|GDK_CONTROL_MASK;
-
-  state = gdk_event_get_modifier_state ((GdkEvent *) event);
-  consumed_modifiers = gdk_key_event_get_consumed_modifiers (event);
-
-  if (state & no_text_input_mask & ~consumed_modifiers)
-    return FALSE;
-
   context_ime = GTK_IM_CONTEXT_IME (context);
 
-  if (!context_ime->focus)
-    return FALSE;
-
-  if (!GDK_IS_SURFACE (context_ime->client_surface))
-    return FALSE;
-
-  keyval = gdk_key_event_get_keyval ((GdkEvent *) event);
-
-  if (keyval == GDK_KEY_space &&
-      context_ime->priv->dead_key_keyval != 0)
+  compose_sequence = gdk_key_event_get_compose_sequence (event);
+  if (compose_sequence)
     {
-      c = _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval, TRUE);
-      context_ime->priv->dead_key_keyval = 0;
-      _gtk_im_context_ime_commit_unichar (context_ime, c);
+      g_signal_emit_by_name (context_ime, "commit", compose_sequence);
       return TRUE;
     }
 
-  c = gdk_keyval_to_unicode (keyval);
-
-  if (c && !g_unichar_iscntrl(c))
-    {
-      _gtk_im_context_ime_commit_unichar (context_ime, c);
-      retval = TRUE;
-    }
-  else if (IS_DEAD_KEY (keyval))
-    {
-      gunichar dead_key;
-
-      dead_key = _gtk_im_context_ime_dead_key_unichar (keyval, FALSE);
-
-      /* Emulate double input of dead keys */
-      if (dead_key && keyval == context_ime->priv->dead_key_keyval)
-        {
-          c = _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval, TRUE);
-          context_ime->priv->dead_key_keyval = 0;
-          _gtk_im_context_ime_commit_unichar (context_ime, c);
-          _gtk_im_context_ime_commit_unichar (context_ime, c);
-        }
-      else
-        context_ime->priv->dead_key_keyval = keyval;
-    }
-
-  return retval;
+  return FALSE;
 }
 
 
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index a0682bd617..8eede2b243 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -663,7 +663,8 @@ no_sequence_matches (GtkIMContextSimple *context_simple,
                                                    gdk_event_get_modifier_state (event),
                                                    FALSE,
                                                    &translated,
-                                                   &translated);
+                                                   &translated,
+                                                   NULL);
 
          gtk_im_context_filter_keypress (context, tmp_event);
          gdk_event_unref (tmp_event);
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 7ea84d4878..65a6c10e6e 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1084,7 +1084,8 @@ rewrite_event_for_toplevel (GdkEvent *event)
                             gdk_key_event_get_keycode (event),
                             gdk_event_get_modifier_state (event),
                             gdk_key_event_is_modifier (event),
-                            key, key_no_lock);
+                            key, key_no_lock,
+                            gdk_key_event_get_compose_sequence (event));
 }
 
 static gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]