[gtk/gtk-3-24: 1/2] macOS: Fix bug that entry cannot press and hold a key to input accented character.
- From: John Ralls <jralls src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 1/2] macOS: Fix bug that entry cannot press and hold a key to input accented character.
- Date: Sun, 17 Feb 2019 21:24:59 +0000 (UTC)
commit cfad43b80d15328f2e82ccc677ce634bd32a5560
Author: Suyuan Chang <suyuan chang gmail com>
Date: Thu Jan 24 23:10:34 2019 -0800
macOS: Fix bug that entry cannot press and hold a key to input accented character.
There're two issues in GdkQuartzView's NSTextInputClient implementation
causes this bug.
1. The -(NSRange)selectedRange should not return [NSNotFound, 0] if
there's no selection. The accented character window will not show
if returned NSRange's location is NSNotFound. Instead of that, the
NSRange's location should be the caret position in the text input
buffer.
2. The accented character window will invoke
-(void)insertText:replacementRange: with non-empty replacement
range, to replace non-accented character with accented character
after user select it from accented character window. This case is
not implemented in original code. Here I use another gobject data
to pass the information to input module and convert it into
'delete-surrounding' event.
Besides these, there's another bug cause gtk_im_context_filter_keypress()
return wrong value while user press and hold a key. When user press
and hold a key, the accented character window will consume the
repeating key down event. Is this case, gtk_im_context_filter_keypress()
should return TRUE, indicate the key press is filtered by input
method module. But it will return FALSE because
gtk_im_context_filter_keypress() assume that every key press event
will generate some text from input method module.
Fixes #1618
gdk/quartz/GdkQuartzView.c | 24 ++++++++++++++++++++++--
gdk/quartz/GdkQuartzView.h | 1 +
modules/input/imquartz.c | 15 +++++++++++++++
3 files changed, 38 insertions(+), 2 deletions(-)
---
diff --git a/gdk/quartz/GdkQuartzView.c b/gdk/quartz/GdkQuartzView.c
index 684832f7a7..8d8502701d 100644
--- a/gdk/quartz/GdkQuartzView.c
+++ b/gdk/quartz/GdkQuartzView.c
@@ -31,7 +31,7 @@
if ((self = [super initWithFrame: frameRect]))
{
markedRange = NSMakeRange (NSNotFound, 0);
- selectedRange = NSMakeRange (NSNotFound, 0);
+ selectedRange = NSMakeRange (0, 0);
}
return self;
@@ -57,6 +57,16 @@
-(void) keyDown: (NSEvent *) theEvent
{
+ /* NOTE: When user press Cmd+A, interpretKeyEvents: will call noop:
+ method. When user press and hold A to show the accented char window,
+ it consumed repeating key down events for key 'A' do NOT call
+ any other method. We use this behavior to determine if this key
+ down event is filtered by interpretKeyEvents.
+ */
+
+ g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY,
+ GUINT_TO_POINTER (GIC_FILTER_FILTERED));
+
GDK_NOTE (EVENTS, g_message ("keyDown"));
[self interpretKeyEvents: [NSArray arrayWithObject: theEvent]];
}
@@ -124,7 +134,8 @@
-(void)unmarkText
{
GDK_NOTE (EVENTS, g_message ("unmarkText"));
- markedRange = selectedRange = NSMakeRange (NSNotFound, 0);
+ selectedRange = NSMakeRange (0, 0);
+ markedRange = NSMakeRange (NSNotFound, 0);
g_object_set_data_full (G_OBJECT (gdk_window), TIC_MARKED_TEXT, NULL, g_free);
}
@@ -209,8 +220,15 @@
else
{
str = [string UTF8String];
+ selectedRange = NSMakeRange ([string length], 0);
}
+ if (replacementRange.length > 0)
+ {
+ g_object_set_data (G_OBJECT (gdk_window), TIC_INSERT_TEXT_REPLACE_LEN,
+ GINT_TO_POINTER (replacementRange.length));
+ }
+
g_object_set_data_full (G_OBJECT (gdk_window), TIC_INSERT_TEXT, g_strdup (str), g_free);
GDK_NOTE (EVENTS, g_message ("insertText: set %s (%p, nsview %p): %s",
TIC_INSERT_TEXT, gdk_window, self,
@@ -537,6 +555,8 @@
-(void)noop: (id)sender
{
GDK_NOTE (EVENTS, g_message ("noop"));
+ g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY,
+ GUINT_TO_POINTER (GIC_FILTER_PASSTHRU));
}
/* --------------------------------------------------------------- */
diff --git a/gdk/quartz/GdkQuartzView.h b/gdk/quartz/GdkQuartzView.h
index 732c677ee5..da06a8bdce 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_INSERT_TEXT_REPLACE_LEN "tic-insert-text-replace-len"
#define TIC_IN_KEY_DOWN "tic-in-key-down"
/* GtkIMContext */
diff --git a/modules/input/imquartz.c b/modules/input/imquartz.c
index b7428fcf92..17758493c3 100644
--- a/modules/input/imquartz.c
+++ b/modules/input/imquartz.c
@@ -129,8 +129,11 @@ output_result (GtkIMContext *context,
{
GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
gboolean retval = FALSE;
+ int fixed_str_replace_len;
gchar *fixed_str, *marked_str;
+ fixed_str_replace_len = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (win),
+ TIC_INSERT_TEXT_REPLACE_LEN));
fixed_str = g_strdup (g_object_get_data (G_OBJECT (win), TIC_INSERT_TEXT));
marked_str = g_strdup (g_object_get_data (G_OBJECT (win), TIC_MARKED_TEXT));
if (fixed_str)
@@ -139,6 +142,13 @@ output_result (GtkIMContext *context,
g_free (qc->preedit_str);
qc->preedit_str = NULL;
g_object_set_data (G_OBJECT (win), TIC_INSERT_TEXT, NULL);
+ if (fixed_str_replace_len)
+ {
+ gboolean retval;
+ g_object_set_data (G_OBJECT (win), TIC_INSERT_TEXT_REPLACE_LEN, 0);
+ g_signal_emit_by_name (context, "delete-surrounding",
+ -fixed_str_replace_len, fixed_str_replace_len, &retval);
+ }
g_signal_emit_by_name (context, "commit", fixed_str);
g_signal_emit_by_name (context, "preedit_changed");
@@ -168,6 +178,11 @@ output_result (GtkIMContext *context,
}
if (!fixed_str && !marked_str)
{
+ unsigned int filtered =
+ GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (win),
+ GIC_FILTER_KEY));
+ if (filtered)
+ retval = TRUE;
if (qc->preedit_str && strlen (qc->preedit_str) > 0)
retval = TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]