[gtk: 1/2] IMContextSimple/IMContextIME: Fix AltGr not working on Win32




commit b9bc7d9166e6551b2b9ddf4e4b3bbbe2636fadba
Author: Philip Zander <philip zander gmail com>
Date:   Thu Jan 13 13:43:23 2022 +0100

    IMContextSimple/IMContextIME: Fix AltGr not working on Win32
    
    The old code assumed that any key press containing Ctrl or Alt cannot be
    regular text input. This is not correct on Win32 as AltGr = Ctrl + Alt.

 gdk/win32/gdkevents-win32.c | 15 ++++++++++-----
 gtk/gtkimcontextime.c       |  7 +++++--
 gtk/gtkimcontextsimple.c    | 17 ++++++++++++++++-
 3 files changed, 31 insertions(+), 8 deletions(-)
---
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 9e752d12f5..66c11d194c 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1772,10 +1772,11 @@ gdk_event_translate (MSG *msg,
 
   int i;
 
-  GdkModifierType state;
+  GdkModifierType state, consumed_modifiers;
   guint keyval;
   guint16 keycode;
   guint8 group;
+  int level;
   gboolean is_modifier;
 
   double delta_x, delta_y;
@@ -2003,6 +2004,10 @@ gdk_event_translate (MSG *msg,
            {
              keyval = gdk_unicode_to_keyval (wbuf[0]);
            }
+
+          /* TODO: What values to use for level and consumed_modifiers? */
+          level = 0;
+          consumed_modifiers = 0;
        }
       else
        {
@@ -2011,7 +2016,7 @@ gdk_event_translate (MSG *msg,
                                               state,
                                               group,
                                               &keyval,
-                                              NULL, NULL, NULL);
+                                              NULL, &level, &consumed_modifiers);
        }
 
       if (msg->message == WM_KEYDOWN)
@@ -2055,11 +2060,11 @@ gdk_event_translate (MSG *msg,
       if (msg->wParam == VK_MENU)
        state &= ~GDK_ALT_MASK;
 
-      /* FIXME do proper translation */
       translated.keyval = keyval;
-      translated.consumed = 0;
+      translated.consumed = consumed_modifiers;
       translated.layout = group;
-      translated.level = 0;
+      translated.level = level;
+
       event = gdk_key_event_new ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
                                    ? GDK_KEY_PRESS
                                    : GDK_KEY_RELEASE,
diff --git a/gtk/gtkimcontextime.c b/gtk/gtkimcontextime.c
index c5ca85997c..6025239543 100644
--- a/gtk/gtkimcontextime.c
+++ b/gtk/gtkimcontextime.c
@@ -344,7 +344,7 @@ gtk_im_context_ime_filter_keypress (GtkIMContext *context,
   GtkIMContextIME *context_ime;
   gboolean retval = FALSE;
   guint32 c;
-  GdkModifierType state;
+  GdkModifierType state, consumed_modifiers, no_text_input_mask;
   guint keyval;
 
   g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context), FALSE);
@@ -353,9 +353,12 @@ gtk_im_context_ime_filter_keypress (GtkIMContext *context,
   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 & GDK_CONTROL_MASK)
+  if (state & no_text_input_mask & ~consumed_modifiers)
     return FALSE;
 
   context_ime = GTK_IM_CONTEXT_IME (context);
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index 515219b493..a0e278c257 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -901,9 +901,24 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
        !is_hex_start && !is_hex_end && !is_escape && !is_backspace))
     {
       GdkModifierType no_text_input_mask;
+      GdkModifierType consumed_modifiers = 0;
 
       no_text_input_mask = GDK_ALT_MASK|GDK_CONTROL_MASK;
 
+#ifdef G_OS_WIN32
+     /* On Win32, even Ctrl + Alt could be text input because AltGr = Ctrl
+      * + Alt. For example, Ctrl + Alt + e = € on a German keyboard. The
+      * GdkEvent's state, however, reports *all* modifiers that were
+      * active at the time the key was pressed, including the ones that
+      * were consumed to generate the keyval. So we cannot just assume
+      * that any key event containing Ctrl or Alt is a keybinding. We have
+      * to first check if those modifiers were actually used to generate
+      * the keyval. If so, then the keypress is regular input and we
+      * should not exit here.
+      */
+      consumed_modifiers = gdk_key_event_get_consumed_modifiers (event);
+#endif
+
       if (priv->in_hex_sequence && priv->modifiers_dropped &&
          (keyval == GDK_KEY_Return ||
           keyval == GDK_KEY_ISO_Enter ||
@@ -912,7 +927,7 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
          return FALSE;
        }
 
-      if (state & no_text_input_mask)
+      if (state & no_text_input_mask & ~consumed_modifiers)
         {
           if (priv->in_hex_sequence || priv->in_compose_sequence)
             return TRUE; /* Don't leak random key events during preedit */


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