summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-03-04 22:48:25 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-03-04 22:48:25 +0000
commitc303ec15534cd349a33a620f56bdfa51cf2ae9ef (patch)
tree764bd6f2b8b4065728ac50191a0e536038a77f07
parent053d7cfe9ff20f54387022f562529983c2871705 (diff)
parentd28df0b87e1422a0491970c1b0f9c9bcc5e7689c (diff)
downloadgtk+-c303ec15534cd349a33a620f56bdfa51cf2ae9ef.tar.gz
Merge branch 'preedit-selection-fix' into 'master'
Preedit selection fix Closes #1123 See merge request GNOME/gtk!3255
-rw-r--r--docs/reference/gtk/gtk4-sections.txt2
-rw-r--r--gtk/gtkimcontext.c172
-rw-r--r--gtk/gtkimcontext.h40
-rw-r--r--gtk/gtkimcontextwayland.c14
-rw-r--r--gtk/gtkimmulticontext.c48
-rw-r--r--gtk/gtktext.c22
-rw-r--r--gtk/gtktextview.c62
7 files changed, 283 insertions, 77 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 302d1ad0be..7f20d98ae2 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -1812,6 +1812,8 @@ gtk_im_context_set_cursor_location
gtk_im_context_set_use_preedit
gtk_im_context_set_surrounding
gtk_im_context_get_surrounding
+gtk_im_context_set_surrounding_with_selection
+gtk_im_context_get_surrounding_with_selection
gtk_im_context_delete_surrounding
<SUBSECTION Standard>
GTK_IM_CONTEXT
diff --git a/gtk/gtkimcontext.c b/gtk/gtkimcontext.c
index 3080699379..13a8c3bb31 100644
--- a/gtk/gtkimcontext.c
+++ b/gtk/gtkimcontext.c
@@ -128,13 +128,18 @@ static void gtk_im_context_real_get_preedit_string (GtkIMContext *context,
int *cursor_pos);
static gboolean gtk_im_context_real_filter_keypress (GtkIMContext *context,
GdkEvent *event);
-static gboolean gtk_im_context_real_get_surrounding (GtkIMContext *context,
- char **text,
- int *cursor_index);
-static void gtk_im_context_real_set_surrounding (GtkIMContext *context,
- const char *text,
- int len,
- int cursor_index);
+
+static gboolean gtk_im_context_real_get_surrounding_with_selection
+ (GtkIMContext *context,
+ char **text,
+ int *cursor_index,
+ int *selection_bound);
+static void gtk_im_context_real_set_surrounding_with_selection
+ (GtkIMContext *context,
+ const char *text,
+ int len,
+ int cursor_index,
+ int selection_bound);
static void gtk_im_context_get_property (GObject *obj,
guint property_id,
@@ -204,6 +209,18 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkIMContext, gtk_im_context, G_TYPE_OBJECT
* behavior. The base implementation emits
* #GtkIMContext::retrieve-surrounding and records the context received
* by the subsequent invocation of @get_surrounding.
+ * @set_surrounding_with_selection: Called via gtk_im_context_set_surrounding_with_selection()
+ * in response to signal #GtkIMContext::retrieve-surrounding to update the input
+ * method’s idea of the context around the cursor. It is not necessary to
+ * override this method even with input methods which implement
+ * context-dependent behavior. The base implementation is sufficient for
+ * gtk_im_context_get_surrounding() to work.
+ * @get_surrounding_with_selection: Called via gtk_im_context_get_surrounding_with_selection()
+ * to update the context around the cursor location. It is not necessary to override
+ * this method even with input methods which implement context-dependent
+ * behavior. The base implementation emits
+ * #GtkIMContext::retrieve-surrounding and records the context received
+ * by the subsequent invocation of @get_surrounding.
*/
static void
gtk_im_context_class_init (GtkIMContextClass *klass)
@@ -215,8 +232,8 @@ gtk_im_context_class_init (GtkIMContextClass *klass)
klass->get_preedit_string = gtk_im_context_real_get_preedit_string;
klass->filter_keypress = gtk_im_context_real_filter_keypress;
- klass->get_surrounding = gtk_im_context_real_get_surrounding;
- klass->set_surrounding = gtk_im_context_real_set_surrounding;
+ klass->get_surrounding_with_selection = gtk_im_context_real_get_surrounding_with_selection;
+ klass->set_surrounding_with_selection = gtk_im_context_real_set_surrounding_with_selection;
/**
* GtkIMContext::preedit-start:
@@ -381,13 +398,15 @@ typedef struct
{
char *text;
int cursor_index;
+ int selection_bound;
} SurroundingInfo;
static void
-gtk_im_context_real_set_surrounding (GtkIMContext *context,
- const char *text,
- int len,
- int cursor_index)
+gtk_im_context_real_set_surrounding_with_selection (GtkIMContext *context,
+ const char *text,
+ int len,
+ int cursor_index,
+ int selection_bound)
{
SurroundingInfo *info = g_object_get_data (G_OBJECT (context),
"gtk-im-surrounding-info");
@@ -397,13 +416,15 @@ gtk_im_context_real_set_surrounding (GtkIMContext *context,
g_free (info->text);
info->text = g_strndup (text, len);
info->cursor_index = cursor_index;
+ info->selection_bound = selection_bound;
}
}
static gboolean
-gtk_im_context_real_get_surrounding (GtkIMContext *context,
- char **text,
- int *cursor_index)
+gtk_im_context_real_get_surrounding_with_selection (GtkIMContext *context,
+ char **text,
+ int *cursor_index,
+ int *selection_bound)
{
gboolean result;
gboolean info_is_local = FALSE;
@@ -426,11 +447,13 @@ gtk_im_context_real_get_surrounding (GtkIMContext *context,
{
*text = g_strdup (info->text ? info->text : "");
*cursor_index = info->cursor_index;
+ *selection_bound = info->selection_bound;
}
else
{
*text = NULL;
*cursor_index = 0;
+ *selection_bound = 0;
}
if (info_is_local)
@@ -722,20 +745,47 @@ gtk_im_context_set_use_preedit (GtkIMContext *context,
* @text.
* @len: the length of @text, or -1 if @text is nul-terminated
* @cursor_index: the byte index of the insertion cursor within @text.
- *
+ *
* Sets surrounding context around the insertion point and preedit
* string. This function is expected to be called in response to the
* GtkIMContext::retrieve_surrounding signal, and will likely have no
* effect if called at other times.
- **/
+ *
+ * Deprecated: 4.2: Use gtk_im_context_set_surrounding_with_selection() instead
+ */
void
gtk_im_context_set_surrounding (GtkIMContext *context,
- const char *text,
- int len,
- int cursor_index)
+ const char *text,
+ int len,
+ int cursor_index)
+{
+ gtk_im_context_set_surrounding_with_selection (context, text, len, cursor_index, cursor_index);
+}
+
+/**
+ * gtk_im_context_set_surrounding_with_selection:
+ * @context: a #GtkIMContext
+ * @text: text surrounding the insertion point, as UTF-8.
+ * the preedit string should not be included within
+ * @text.
+ * @len: the length of @text, or -1 if @text is nul-terminated
+ * @cursor_index: the byte index of the insertion cursor within @text.
+ * @anchor_index: the byte index of the selection bound within @text
+ *
+ * Sets surrounding context around the insertion point and preedit
+ * string. This function is expected to be called in response to the
+ * GtkIMContext::retrieve_surrounding signal, and will likely have no
+ * effect if called at other times.
+ */
+void
+gtk_im_context_set_surrounding_with_selection (GtkIMContext *context,
+ const char *text,
+ int len,
+ int cursor_index,
+ int anchor_index)
{
GtkIMContextClass *klass;
-
+
g_return_if_fail (GTK_IS_IM_CONTEXT (context));
g_return_if_fail (text != NULL || len == 0);
@@ -747,7 +797,9 @@ gtk_im_context_set_surrounding (GtkIMContext *context,
g_return_if_fail (cursor_index >= 0 && cursor_index <= len);
klass = GTK_IM_CONTEXT_GET_CLASS (context);
- if (klass->set_surrounding)
+ if (klass->set_surrounding_with_selection)
+ klass->set_surrounding_with_selection (context, text, len, cursor_index, anchor_index);
+ else if (klass->set_surrounding)
klass->set_surrounding (context, text, len, cursor_index);
}
@@ -760,7 +812,7 @@ gtk_im_context_set_surrounding (GtkIMContext *context,
* stored in this location with g_free().
* @cursor_index: (out): location to store byte index of the insertion
* cursor within @text.
- *
+ *
* Retrieves context around the insertion point. Input methods
* typically want context in order to constrain input text based on
* existing text; this is important for languages such as Thai where
@@ -776,24 +828,78 @@ gtk_im_context_set_surrounding (GtkIMContext *context,
*
* Returns: %TRUE if surrounding text was provided; in this case
* you must free the result stored in *text.
- **/
+ *
+ * Deprecated: 4.2: Use gtk_im_context_get_surrounding_with_selection() instead.
+ */
+gboolean
+gtk_im_context_get_surrounding (GtkIMContext *context,
+ char **text,
+ int *cursor_index)
+{
+ return gtk_im_context_get_surrounding_with_selection (context,
+ text,
+ cursor_index,
+ NULL);
+}
+
+/**
+ * gtk_im_context_get_surrounding:
+ * @context: a #GtkIMContext
+ * @text: (out) (transfer full): location to store a UTF-8 encoded
+ * string of text holding context around the insertion point.
+ * If the function returns %TRUE, then you must free the result
+ * stored in this location with g_free().
+ * @cursor_index: (out): location to store byte index of the insertion
+ * cursor within @text.
+ * @anchor_index: (out): location to store byte index of the selection
+ * bound within @text
+ *
+ * Retrieves context around the insertion point. Input methods
+ * typically want context in order to constrain input text based on
+ * existing text; this is important for languages such as Thai where
+ * only some sequences of characters are allowed.
+ *
+ * This function is implemented by emitting the
+ * GtkIMContext::retrieve_surrounding signal on the input method; in
+ * response to this signal, a widget should provide as much context as
+ * is available, up to an entire paragraph, by calling
+ * gtk_im_context_set_surrounding(). Note that there is no obligation
+ * for a widget to respond to the ::retrieve_surrounding signal, so input
+ * methods must be prepared to function without context.
+ *
+ * Returns: %TRUE if surrounding text was provided; in this case
+ * you must free the result stored in *text.
+ */
gboolean
-gtk_im_context_get_surrounding (GtkIMContext *context,
- char **text,
- int *cursor_index)
+gtk_im_context_get_surrounding_with_selection (GtkIMContext *context,
+ char **text,
+ int *cursor_index,
+ int *anchor_index)
{
GtkIMContextClass *klass;
char *local_text = NULL;
int local_index;
gboolean result = FALSE;
-
+
g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
klass = GTK_IM_CONTEXT_GET_CLASS (context);
- if (klass->get_surrounding)
- result = klass->get_surrounding (context,
- text ? text : &local_text,
- cursor_index ? cursor_index : &local_index);
+ if (klass->get_surrounding_with_selection)
+ result = klass->get_surrounding_with_selection
+ (context,
+ text ? text : &local_text,
+ cursor_index ? cursor_index : &local_index,
+ anchor_index ? anchor_index : &local_index);
+ else if (klass->get_surrounding)
+ {
+ result = klass->get_surrounding (context,
+ text ? text : &local_text,
+ &local_index);
+ if (cursor_index)
+ *cursor_index = local_index;
+ if (anchor_index)
+ *anchor_index = local_index;
+ }
if (result)
g_free (local_text);
diff --git a/gtk/gtkimcontext.h b/gtk/gtkimcontext.h
index 17419eb180..c9558f2ba3 100644
--- a/gtk/gtkimcontext.h
+++ b/gtk/gtkimcontext.h
@@ -83,6 +83,18 @@ struct _GtkIMContextClass
gboolean (*get_surrounding) (GtkIMContext *context,
char **text,
int *cursor_index);
+ void (*set_surrounding_with_selection)
+ (GtkIMContext *context,
+ const char *text,
+ int len,
+ int cursor_index,
+ int anchor_index);
+ gboolean (*get_surrounding_with_selection)
+ (GtkIMContext *context,
+ char **text,
+ int *cursor_index,
+ int *anchor_index);
+
/*< private >*/
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
@@ -90,7 +102,6 @@ struct _GtkIMContextClass
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
- void (*_gtk_reserved6) (void);
};
GDK_AVAILABLE_IN_ALL
@@ -130,15 +141,28 @@ void gtk_im_context_set_cursor_location (GtkIMContext *context,
GDK_AVAILABLE_IN_ALL
void gtk_im_context_set_use_preedit (GtkIMContext *context,
gboolean use_preedit);
-GDK_AVAILABLE_IN_ALL
+GDK_DEPRECATED_IN_4_2_FOR(gtk_im_context_set_surrounding_with_selection)
void gtk_im_context_set_surrounding (GtkIMContext *context,
- const char *text,
- int len,
- int cursor_index);
-GDK_AVAILABLE_IN_ALL
+ const char *text,
+ int len,
+ int cursor_index);
+GDK_DEPRECATED_IN_4_2_FOR(gtk_im_context_get_surrounding_with_selection)
gboolean gtk_im_context_get_surrounding (GtkIMContext *context,
- char **text,
- int *cursor_index);
+ char **text,
+ int *cursor_index);
+GDK_AVAILABLE_IN_ALL
+void gtk_im_context_set_surrounding_with_selection
+ (GtkIMContext *context,
+ const char *text,
+ int len,
+ int cursor_index,
+ int anchor_index);
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_im_context_get_surrounding_with_selection
+ (GtkIMContext *context,
+ char **text,
+ int *cursor_index,
+ int *anchor_index);
GDK_AVAILABLE_IN_ALL
gboolean gtk_im_context_delete_surrounding (GtkIMContext *context,
int offset,
diff --git a/gtk/gtkimcontextwayland.c b/gtk/gtkimcontextwayland.c
index 0bee5162d9..b380a8a150 100644
--- a/gtk/gtkimcontextwayland.c
+++ b/gtk/gtkimcontextwayland.c
@@ -909,7 +909,8 @@ static void
gtk_im_context_wayland_set_surrounding (GtkIMContext *context,
const char *text,
int len,
- int cursor_index)
+ int cursor_index,
+ int selection_bound)
{
GtkIMContextWayland *context_wayland;
@@ -918,8 +919,7 @@ gtk_im_context_wayland_set_surrounding (GtkIMContext *context,
g_free (context_wayland->surrounding.text);
context_wayland->surrounding.text = g_strndup (text, len);
context_wayland->surrounding.cursor_idx = cursor_index;
- /* Anchor is not exposed via the set_surrounding interface, emulating. */
- context_wayland->surrounding.anchor_idx = cursor_index;
+ context_wayland->surrounding.anchor_idx = selection_bound;
notify_surrounding_text (context_wayland);
/* State changes coming from reset don't have any other opportunity to get
@@ -932,7 +932,8 @@ gtk_im_context_wayland_set_surrounding (GtkIMContext *context,
static gboolean
gtk_im_context_wayland_get_surrounding (GtkIMContext *context,
char **text,
- int *cursor_index)
+ int *cursor_index,
+ int *selection_bound)
{
GtkIMContextWayland *context_wayland;
@@ -943,6 +944,7 @@ gtk_im_context_wayland_get_surrounding (GtkIMContext *context,
*text = context_wayland->surrounding.text;
*cursor_index = context_wayland->surrounding.cursor_idx;
+ *selection_bound = context_wayland->surrounding.anchor_idx;
return TRUE;
}
@@ -962,8 +964,8 @@ gtk_im_context_wayland_class_init (GtkIMContextWaylandClass *klass)
im_context_class->reset = gtk_im_context_wayland_reset;
im_context_class->set_cursor_location = gtk_im_context_wayland_set_cursor_location;
im_context_class->set_use_preedit = gtk_im_context_wayland_set_use_preedit;
- im_context_class->set_surrounding = gtk_im_context_wayland_set_surrounding;
- im_context_class->get_surrounding = gtk_im_context_wayland_get_surrounding;
+ im_context_class->set_surrounding_with_selection = gtk_im_context_wayland_set_surrounding;
+ im_context_class->get_surrounding_with_selection = gtk_im_context_wayland_get_surrounding;
}
static void
diff --git a/gtk/gtkimmulticontext.c b/gtk/gtkimmulticontext.c
index 75a70c3f0d..5775a42880 100644
--- a/gtk/gtkimmulticontext.c
+++ b/gtk/gtkimmulticontext.c
@@ -74,13 +74,17 @@ static void gtk_im_multicontext_set_cursor_location (GtkIMContext
GdkRectangle *area);
static void gtk_im_multicontext_set_use_preedit (GtkIMContext *context,
gboolean use_preedit);
-static gboolean gtk_im_multicontext_get_surrounding (GtkIMContext *context,
- char **text,
- int *cursor_index);
-static void gtk_im_multicontext_set_surrounding (GtkIMContext *context,
- const char *text,
- int len,
- int cursor_index);
+static gboolean gtk_im_multicontext_get_surrounding_with_selection
+ (GtkIMContext *context,
+ char **text,
+ int *cursor_index,
+ int *anchor_index);
+static void gtk_im_multicontext_set_surrounding_with_selection
+ (GtkIMContext *context,
+ const char *text,
+ int len,
+ int cursor_index,
+ int anchor_index);
static void gtk_im_multicontext_preedit_start_cb (GtkIMContext *delegate,
GtkIMMulticontext *multicontext);
@@ -118,8 +122,8 @@ gtk_im_multicontext_class_init (GtkIMMulticontextClass *class)
im_context_class->reset = gtk_im_multicontext_reset;
im_context_class->set_cursor_location = gtk_im_multicontext_set_cursor_location;
im_context_class->set_use_preedit = gtk_im_multicontext_set_use_preedit;
- im_context_class->set_surrounding = gtk_im_multicontext_set_surrounding;
- im_context_class->get_surrounding = gtk_im_multicontext_get_surrounding;
+ im_context_class->set_surrounding_with_selection = gtk_im_multicontext_set_surrounding_with_selection;
+ im_context_class->get_surrounding_with_selection = gtk_im_multicontext_get_surrounding_with_selection;
gobject_class->finalize = gtk_im_multicontext_finalize;
}
@@ -460,37 +464,41 @@ gtk_im_multicontext_set_use_preedit (GtkIMContext *context,
}
static gboolean
-gtk_im_multicontext_get_surrounding (GtkIMContext *context,
- char **text,
- int *cursor_index)
+gtk_im_multicontext_get_surrounding_with_selection (GtkIMContext *context,
+ char **text,
+ int *cursor_index,
+ int *anchor_index)
{
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
GtkIMContext *delegate = gtk_im_multicontext_get_delegate (multicontext);
if (delegate)
- return gtk_im_context_get_surrounding (delegate, text, cursor_index);
+ return gtk_im_context_get_surrounding_with_selection (delegate, text, cursor_index, anchor_index);
else
{
if (text)
- *text = NULL;
+ *text = NULL;
if (cursor_index)
- *cursor_index = 0;
+ *cursor_index = 0;
+ if (anchor_index)
+ *anchor_index = 0;
return FALSE;
}
}
static void
-gtk_im_multicontext_set_surrounding (GtkIMContext *context,
- const char *text,
- int len,
- int cursor_index)
+gtk_im_multicontext_set_surrounding_with_selection (GtkIMContext *context,
+ const char *text,
+ int len,
+ int cursor_index,
+ int anchor_index)
{
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
GtkIMContext *delegate = gtk_im_multicontext_get_delegate (multicontext);
if (delegate)
- gtk_im_context_set_surrounding (delegate, text, len, cursor_index);
+ gtk_im_context_set_surrounding_with_selection (delegate, text, len, cursor_index, anchor_index);
}
static void
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index 3984750034..20c7fee841 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -418,6 +418,8 @@ static void direction_changed (GdkDevice *keyboard,
static void gtk_text_commit_cb (GtkIMContext *context,
const char *str,
GtkText *self);
+static void gtk_text_preedit_start_cb (GtkIMContext *context,
+ GtkText *self);
static void gtk_text_preedit_changed_cb (GtkIMContext *context,
GtkText *self);
static gboolean gtk_text_retrieve_surrounding_cb (GtkIMContext *context,
@@ -1843,6 +1845,8 @@ gtk_text_init (GtkText *self)
*/
priv->im_context = gtk_im_multicontext_new ();
+ g_signal_connect (priv->im_context, "preedit-start",
+ G_CALLBACK (gtk_text_preedit_start_cb), self);
g_signal_connect (priv->im_context, "commit",
G_CALLBACK (gtk_text_commit_cb), self);
g_signal_connect (priv->im_context, "preedit-changed",
@@ -3305,6 +3309,9 @@ gtk_text_insert_text (GtkText *self,
int n_inserted;
int n_chars;
+ if (length == 0)
+ return;
+
n_chars = g_utf8_strlen (text, length);
/*
@@ -3334,6 +3341,9 @@ gtk_text_delete_text (GtkText *self,
{
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
+ if (start_pos == end_pos)
+ return;
+
begin_change (self);
gtk_entry_buffer_delete_text (get_buffer (self), start_pos, end_pos - start_pos);
@@ -4151,6 +4161,13 @@ direction_changed (GdkDevice *device,
*/
static void
+gtk_text_preedit_start_cb (GtkIMContext *context,
+ GtkText *self)
+{
+ gtk_text_delete_selection (self);
+}
+
+static void
gtk_text_commit_cb (GtkIMContext *context,
const char *str,
GtkText *self)
@@ -4200,8 +4217,9 @@ gtk_text_retrieve_surrounding_cb (GtkIMContext *context,
/* XXXX ??? does this even make sense when text is not visible? Should we return FALSE? */
text = gtk_text_get_display_text (self, 0, -1);
- gtk_im_context_set_surrounding (context, text, strlen (text), /* Length in bytes */
- g_utf8_offset_to_pointer (text, priv->current_pos) - text);
+ gtk_im_context_set_surrounding_with_selection (context, text, strlen (text), /* Length in bytes */
+ g_utf8_offset_to_pointer (text, priv->current_pos) - text,
+ g_utf8_offset_to_pointer (text, priv->selection_bound) - text);
g_free (text);
return TRUE;
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index bece4d5839..5b8bca680a 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -504,8 +504,10 @@ static void gtk_text_view_commit_handler (GtkIMContext *conte
GtkTextView *text_view);
static void gtk_text_view_commit_text (GtkTextView *text_view,
const char *text);
+static void gtk_text_view_preedit_start_handler (GtkIMContext *context,
+ GtkTextView *text_view);
static void gtk_text_view_preedit_changed_handler (GtkIMContext *context,
- GtkTextView *text_view);
+ GtkTextView *text_view);
static gboolean gtk_text_view_retrieve_surrounding_handler (GtkIMContext *context,
GtkTextView *text_view);
static gboolean gtk_text_view_delete_surrounding_handler (GtkIMContext *context,
@@ -1883,6 +1885,8 @@ gtk_text_view_init (GtkTextView *text_view)
g_signal_connect (priv->im_context, "commit",
G_CALLBACK (gtk_text_view_commit_handler), text_view);
+ g_signal_connect (priv->im_context, "preedit-start",
+ G_CALLBACK (gtk_text_view_preedit_start_handler), text_view);
g_signal_connect (priv->im_context, "preedit-changed",
G_CALLBACK (gtk_text_view_preedit_changed_handler), text_view);
g_signal_connect (priv->im_context, "retrieve-surrounding",
@@ -8213,6 +8217,13 @@ gtk_text_view_commit_text (GtkTextView *text_view,
}
static void
+gtk_text_view_preedit_start_handler (GtkIMContext *context,
+ GtkTextView *self)
+{
+ gtk_text_buffer_delete_selection (self->priv->buffer, TRUE, self->priv->editable);
+}
+
+static void
gtk_text_view_preedit_changed_handler (GtkIMContext *context,
GtkTextView *text_view)
{
@@ -8259,19 +8270,54 @@ gtk_text_view_retrieve_surrounding_handler (GtkIMContext *context,
{
GtkTextIter start;
GtkTextIter end;
- int pos;
+ GtkTextIter start1;
+ GtkTextIter end1;
+ int cursor_pos;
+ int anchor_pos;
char *text;
+ char *pre;
+ char *sel;
+ char *post;
+ gboolean flip;
gtk_text_buffer_get_iter_at_mark (text_view->priv->buffer, &start,
- gtk_text_buffer_get_insert (text_view->priv->buffer));
- end = start;
+ gtk_text_buffer_get_insert (text_view->priv->buffer));
+ gtk_text_buffer_get_iter_at_mark (text_view->priv->buffer, &end,
+ gtk_text_buffer_get_selection_bound (text_view->priv->buffer));
+
+ flip = gtk_text_iter_compare (&start, &end) < 0;
+
+ gtk_text_iter_order (&start, &end);
+
+ start1 = start;
+ end1 = end;
- pos = gtk_text_iter_get_line_index (&start);
gtk_text_iter_set_line_offset (&start, 0);
- gtk_text_iter_forward_to_line_end (&end);
+ gtk_text_iter_forward_to_line_end (&end1);
+
+ pre = gtk_text_iter_get_slice (&start1, &start);
+ sel = gtk_text_iter_get_slice (&start, &end);
+ post = gtk_text_iter_get_slice (&end, &end1);
+
+ if (flip)
+ {
+ anchor_pos = strlen (pre);
+ cursor_pos = anchor_pos + strlen (sel);
+ }
+ else
+ {
+ cursor_pos = strlen (pre);
+ anchor_pos = cursor_pos + strlen (sel);
+ }
+
+ text = g_strconcat (pre, sel, post, NULL);
+
+ g_free (pre);
+ g_free (sel);
+ g_free (post);
+
+ gtk_im_context_set_surrounding_with_selection (context, text, -1, cursor_pos, anchor_pos);
- text = gtk_text_iter_get_slice (&start, &end);
- gtk_im_context_set_surrounding (context, text, -1, pos);
g_free (text);
return TRUE;