[gtk/im-context-key-forward] Add gtk_im_context_filter_key



commit 506d73cf327d9b34a137b3c6dd537f794e36877f
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu May 28 16:10:54 2020 -0400

    Add gtk_im_context_filter_key
    
    An event-less variant of the filtering api.

 docs/reference/gtk/gtk4-sections.txt |  1 +
 gtk/gtkimcontext.c                   | 96 ++++++++++++++++++++++++++++++++++++
 gtk/gtkimcontext.h                   | 13 ++++-
 3 files changed, 109 insertions(+), 1 deletion(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 40c6947d45..085b77d7ca 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -1486,6 +1486,7 @@ GtkIMContext
 GtkIMContextClass
 gtk_im_context_get_preedit_string
 gtk_im_context_filter_keypress
+gtk_im_context_filter_key
 gtk_im_context_focus_in
 gtk_im_context_focus_out
 gtk_im_context_reset
diff --git a/gtk/gtkimcontext.c b/gtk/gtkimcontext.c
index 986608e718..dc31fd3c2c 100644
--- a/gtk/gtkimcontext.c
+++ b/gtk/gtkimcontext.c
@@ -522,6 +522,102 @@ gtk_im_context_filter_keypress (GtkIMContext *context,
   return klass->filter_keypress (context, key);
 }
 
+/**
+ * gtk_im_context_filter_key:
+ * @context: a #GtkIMContext
+ * @press: whether to forward a key press or release event
+ * @surface: the surface the event is for
+ * @device: the device that the event is for
+ * @time: the timestamp for the event
+ * @keycode: the keycode for the event
+ * @state: modifier state for the event
+ * @group: the active keyboard group for the event
+ *
+ * Allow an input method to forward key press and release events
+ * to another input method, without necessarily having a GdkEvent
+ * available.
+ *
+ * Returns: %TRUE if the input method handled the key event.
+ */
+gboolean
+gtk_im_context_filter_key (GtkIMContext    *context,
+                           gboolean         press,
+                           GdkSurface      *surface,
+                           GdkDevice       *device,
+                           guint32          time,
+                           guint            keycode,
+                           GdkModifierType  state,
+                           int              group)
+{
+  GdkDevice *source_device;
+  GdkTranslatedKey translated, no_lock;
+  GdkEvent *key;
+  gboolean ret;
+  guint keyval;
+  int layout;
+  int level;
+  GdkModifierType consumed;
+
+  g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
+
+  if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER)
+    {
+      source_device = NULL;
+    }
+  else
+    {
+      source_device = device;
+      device = gdk_device_get_associated_device (source_device);
+    }
+
+  if (!gdk_display_translate_key (gdk_surface_get_display (surface),
+                                  keycode,
+                                  state,
+                                  group,
+                                  &keyval,
+                                  &layout,
+                                  &level,
+                                  &consumed))
+    return FALSE;
+
+  translated.keyval = keyval;
+  translated.layout = layout;
+  translated.level = level;
+  translated.consumed = consumed;
+
+  if (!gdk_display_translate_key (gdk_surface_get_display (surface),
+                                  keycode,
+                                  state & ~GDK_LOCK_MASK,
+                                  group,
+                                  &keyval,
+                                  &layout,
+                                  &level,
+                                  &consumed))
+    return FALSE;
+
+  no_lock.keyval = keyval;
+  no_lock.layout = layout;
+  no_lock.level = level;
+  no_lock.consumed = consumed;
+
+  key = gdk_key_event_new (press ? GDK_KEY_PRESS : GDK_KEY_RELEASE,
+                           surface,
+                           device,
+                           source_device,
+                           time,
+                           keycode,
+                           state,
+                           FALSE, /* FIXME */
+                           &translated,
+                           &no_lock);
+
+  ret = GTK_IM_CONTEXT_GET_CLASS (context)->filter_keypress (context, key);
+
+  gdk_event_unref (key);
+
+  return ret;
+}
+
 /**
  * gtk_im_context_focus_in:
  * @context: a #GtkIMContext
diff --git a/gtk/gtkimcontext.h b/gtk/gtkimcontext.h
index 33b41d5895..fee5cf2046 100644
--- a/gtk/gtkimcontext.h
+++ b/gtk/gtkimcontext.h
@@ -106,7 +106,18 @@ void     gtk_im_context_get_preedit_string  (GtkIMContext       *context,
                                             gint               *cursor_pos);
 GDK_AVAILABLE_IN_ALL
 gboolean gtk_im_context_filter_keypress     (GtkIMContext       *context,
-                                            GdkEvent           *event);
+                                             GdkEvent           *event);
+
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_im_context_filter_key          (GtkIMContext       *context,
+                                             gboolean            press,
+                                             GdkSurface         *surface,
+                                             GdkDevice          *device,
+                                             guint32             time,
+                                             guint               keycode,
+                                             GdkModifierType     state,
+                                             int                 group);
+
 GDK_AVAILABLE_IN_ALL
 void     gtk_im_context_focus_in            (GtkIMContext       *context);
 GDK_AVAILABLE_IN_ALL


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