[gtk+/gtk-3-8] Bug 705750 Quartz input method doesn't work correctly for Chinese characters



commit f2e7bce43ab1614a5d19b792c0a956af43f57701
Author: Ek Kato <ek kato gmail com>
Date:   Fri Aug 16 09:54:34 2013 -0700

    Bug 705750 Quartz input method doesn't work correctly for Chinese characters
    
    Modified from original for Gtk3.
    
    (cherry picked from commit bc35d5d166bcc4ec8ac074b792cc88f4f98c282e)

 gdk/quartz/GdkQuartzView.c     |   35 ++++++++++++--
 gdk/quartz/GdkQuartzView.h     |    1 +
 gdk/quartz/gdkevents-quartz.c  |   18 +++++++
 gdk/quartz/gdkprivate-quartz.h |    1 +
 modules/input/imquartz.c       |  103 +++++++++++++++++++++++++--------------
 5 files changed, 117 insertions(+), 41 deletions(-)
---
diff --git a/gdk/quartz/GdkQuartzView.c b/gdk/quartz/GdkQuartzView.c
index 1d125d3..a2ed1f5 100644
--- a/gdk/quartz/GdkQuartzView.c
+++ b/gdk/quartz/GdkQuartzView.c
@@ -167,6 +167,13 @@
   GDK_NOTE (EVENTS, g_print ("setMarkedText: set %s (%p, nsview %p): %s\n",
                             TIC_MARKED_TEXT, gdk_window, self,
                             str ? str : "(empty)"));
+
+  /* handle text input changes by mouse events */
+  if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (gdk_window),
+                                            TIC_IN_KEY_DOWN)))
+    {
+      _gdk_quartz_synthesize_null_key_event(gdk_window);
+    }
 }
 
 -(void)doCommandBySelector: (SEL)aSelector
@@ -180,19 +187,32 @@
 {
   GDK_NOTE (EVENTS, g_print ("insertText\n"));
   const char *str;
+  NSString *string;
   gchar *prev_str;
 
   if ([self hasMarkedText])
     [self unmarkText];
 
   if ([aString isKindOfClass: [NSAttributedString class]])
-    {
-      str = [[aString string] UTF8String];
-    }
+      string = [aString string];
   else
+      string = aString;
+
+  NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet];
+  NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet];
+  if ([string rangeOfCharacterFromSet:ctrlChars].length &&
+      [string rangeOfCharacterFromSet:wsnlChars].length == 0)
     {
-      str = [aString UTF8String];
+      /* discard invalid text input with Chinese input methods */
+      str = "";
+      [self unmarkText];
+      NSInputManager *currentInputManager = [NSInputManager currentInputManager];
+      [currentInputManager markedTextAbandoned:self];
     }
+  else
+   {
+      str = [string UTF8String];
+   }
 
   prev_str = g_object_get_data (G_OBJECT (gdk_window), TIC_INSERT_TEXT);
   if (prev_str)
@@ -204,6 +224,13 @@
 
   g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY,
                     GUINT_TO_POINTER (GIC_FILTER_FILTERED));
+
+  /* handle text input changes by mouse events */
+  if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (gdk_window),
+                                            TIC_IN_KEY_DOWN)))
+    {
+      _gdk_quartz_synthesize_null_key_event(gdk_window);
+    }
 }
 
 -(void)deleteBackward: (id)sender
diff --git a/gdk/quartz/GdkQuartzView.h b/gdk/quartz/GdkQuartzView.h
index 83455c3..732c677 100644
--- a/gdk/quartz/GdkQuartzView.h
+++ b/gdk/quartz/GdkQuartzView.h
@@ -24,6 +24,7 @@
 #define TIC_SELECTED_POS  "tic-selected-pos"
 #define TIC_SELECTED_LEN  "tic-selected-len"
 #define TIC_INSERT_TEXT "tic-insert-text"
+#define TIC_IN_KEY_DOWN "tic-in-key-down"
 
 /* GtkIMContext */
 #define GIC_CURSOR_RECT  "gic-cursor-rect"
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
index bfd0430..90bcdb9 100644
--- a/gdk/quartz/gdkevents-quartz.c
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -1156,6 +1156,24 @@ synthesize_crossing_event (GdkWindow *window,
   return FALSE;
 }
 
+void
+_gdk_quartz_synthesize_null_key_event (GdkWindow *window)
+{
+  GdkEvent *event;
+  GdkQuartzDeviceManagerCore *device_manager;
+
+  event = gdk_event_new (GDK_KEY_PRESS);
+  event->any.type = GDK_KEY_PRESS;
+  event->key.window = window;
+  event->key.state = 0;
+  event->key.hardware_keycode = 0;
+  event->key.group = 0;
+  event->key.keyval = GDK_KEY_VoidSymbol;
+  device_manager = GDK_QUARTZ_DEVICE_MANAGER_CORE (_gdk_display->device_manager);
+  gdk_event_set_device (event, device_manager->core_keyboard);
+  append_event(event, FALSE);
+}
+
 GdkModifierType
 _gdk_quartz_events_get_current_keyboard_modifiers (void)
 {
diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h
index dcac502..e403209 100644
--- a/gdk/quartz/gdkprivate-quartz.h
+++ b/gdk/quartz/gdkprivate-quartz.h
@@ -74,6 +74,7 @@ void       _gdk_quartz_event_loop_release_event (NSEvent *event);
 /* Keys */
 GdkEventType _gdk_quartz_keys_event_type  (NSEvent   *event);
 gboolean     _gdk_quartz_keys_is_modifier (guint      keycode);
+void         _gdk_quartz_synthesize_null_key_event (GdkWindow *window);
 
 /* Drag and Drop */
 void        _gdk_quartz_window_register_dnd      (GdkWindow   *window);
diff --git a/modules/input/imquartz.c b/modules/input/imquartz.c
index 06ebc68..febf41b 100644
--- a/modules/input/imquartz.c
+++ b/modules/input/imquartz.c
@@ -126,48 +126,13 @@ quartz_get_preedit_string (GtkIMContext *context,
 }
 
 static gboolean
-quartz_filter_keypress (GtkIMContext *context,
-                        GdkEventKey *event)
+output_result (GtkIMContext *context,
+               GdkWindow *win)
 {
   GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
   gboolean retval = FALSE;
-  NSView *nsview;
-  GdkWindow *win;
   gchar *fixed_str, *marked_str;
 
-  GTK_NOTE (MISC, g_print ("quartz_filter_keypress\n"));
-
-  if (!qc->client_window)
-    return FALSE;
-
-  nsview = gdk_quartz_window_get_nsview (qc->client_window);
-  if (GDK_IS_WINDOW (nsview))
-       /* it gets GDK_WINDOW in some cases */
-    return gtk_im_context_filter_keypress (qc->slave, event);
-  else
-    win = (GdkWindow *)[ (GdkQuartzView *)nsview gdkWindow];
-  GTK_NOTE (MISC, g_print ("client_window: %p, win: %p, nsview: %p\n",
-                          qc->client_window, win, nsview));
-
-  NSEvent *nsevent = gdk_quartz_event_get_nsevent ((GdkEvent *)event);
-  if (!nsevent)
-    return gtk_im_context_filter_keypress (qc->slave, event);
-
-  if (event->type == GDK_KEY_RELEASE)
-    return FALSE;
-
-  if (event->hardware_keycode == 55)   /* Command */
-    return FALSE;
-
-  NSEventType etype = [nsevent type];
-  if (etype == NSKeyDown)
-       [nsview keyDown: nsevent];
-  /* JIS_Eisu || JIS_Kana */
-  if (event->hardware_keycode == 102 || event->hardware_keycode == 104)
-    return FALSE;
-
-  GTK_NOTE (MISC,
-           g_print ("quartz_filter_keypress: getting tic-insert-text\n"));
   fixed_str = g_object_get_data (G_OBJECT (win), TIC_INSERT_TEXT);
   marked_str = g_object_get_data (G_OBJECT (win), TIC_MARKED_TEXT);
   if (fixed_str)
@@ -203,10 +168,74 @@ quartz_filter_keypress (GtkIMContext *context,
       g_signal_emit_by_name (context, "preedit_changed");
       retval = TRUE;
     }
+  if (!fixed_str && !marked_str) 
+    {
+      if (qc->preedit_str && strlen (qc->preedit_str) > 0)
+        retval = TRUE;
+    }
+
   g_free (fixed_str);
   g_free (marked_str);
 
+  return retval;
+}
+
+static gboolean
+quartz_filter_keypress (GtkIMContext *context,
+                        GdkEventKey *event)
+{
+  GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
+  gboolean retval;
+  NSView *nsview;
+  GdkWindow *win;
+
+  GTK_NOTE (MISC, g_print ("quartz_filter_keypress\n"));
+
+  if (!qc->client_window)
+    return FALSE;
+
+  nsview = gdk_quartz_window_get_nsview (qc->client_window);
+  if (GDK_IS_WINDOW (nsview))
+       /* it gets GDK_WINDOW in some cases */
+    return gtk_im_context_filter_keypress (qc->slave, event);
+  else
+    win = (GdkWindow *)[ (GdkQuartzView *)nsview gdkWindow];
+  GTK_NOTE (MISC, g_print ("client_window: %p, win: %p, nsview: %p\n",
+                          qc->client_window, win, nsview));
+
+  NSEvent *nsevent = gdk_quartz_event_get_nsevent ((GdkEvent *)event);
+
+  if (!nsevent)
+    {
+      if (event->hardware_keycode == 0 && event->keyval == 0xffffff)
+        /* update text input changes by mouse events */
+        output_result(context, win);
+      else
+        return gtk_im_context_filter_keypress (qc->slave, event);
+    }
+
+  if (event->type == GDK_KEY_RELEASE)
+    return FALSE;
+
+  if (event->hardware_keycode == 55)   /* Command */
+    return FALSE;
+
+  NSEventType etype = [nsevent type];
+  if (etype == NSKeyDown)
+    {
+       g_object_set_data (G_OBJECT (win), TIC_IN_KEY_DOWN,
+                                          GUINT_TO_POINTER (TRUE));
+       [nsview keyDown: nsevent];
+    }
+  /* JIS_Eisu || JIS_Kana */
+  if (event->hardware_keycode == 102 || event->hardware_keycode == 104)
+    return FALSE;
+
+  retval = output_result(context, win);
+  g_object_set_data (G_OBJECT (win), TIC_IN_KEY_DOWN,
+                                     GUINT_TO_POINTER (FALSE));
   GTK_NOTE (MISC, g_print ("quartz_filter_keypress done\n"));
+
   return retval;
 }
 


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