[gtk+/gtk-3-8] Bug 705750 Quartz input method doesn't work correctly for Chinese characters
- From: John Ralls <jralls src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-3-8] Bug 705750 Quartz input method doesn't work correctly for Chinese characters
- Date: Fri, 16 Aug 2013 18:18:56 +0000 (UTC)
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]