[gtk+/wip/matthiasc/emoji-picker: 754/756] wip: emoji completions
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/emoji-picker: 754/756] wip: emoji completions
- Date: Wed, 18 Oct 2017 16:28:27 +0000 (UTC)
commit 68e648c109935535f269fe92588591561c60ef40
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Aug 15 17:34:44 2017 -0400
wip: emoji completions
gtk/gtkemojicompletion.c | 371 ++++++++++++++++++++
gtk/gtkemojicompletion.h | 41 +++
gtk/gtkemojicompletions.c | 192 ----------
gtk/gtkemojicompletions.h | 43 ---
gtk/gtkentry.c | 124 ++-----
gtk/gtkentryprivate.h | 7 +
gtk/meson.build | 1 +
...tkemojicompletions.ui => gtkemojicompletion.ui} | 2 +-
8 files changed, 455 insertions(+), 326 deletions(-)
---
diff --git a/gtk/gtkemojicompletion.c b/gtk/gtkemojicompletion.c
new file mode 100644
index 0000000..e0036b2
--- /dev/null
+++ b/gtk/gtkemojicompletion.c
@@ -0,0 +1,371 @@
+/* gtkemojicompletion.c: An Emoji picker widget
+ * Copyright 2017, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkemojicompletion.h"
+
+#include "gtkentryprivate.h"
+#include "gtkbox.h"
+#include "gtkcssprovider.h"
+#include "gtklistbox.h"
+#include "gtklabel.h"
+#include "gtkpopover.h"
+#include "gtkintl.h"
+#include "gtkprivate.h"
+
+struct _GtkEmojiCompletion
+{
+ GtkPopover parent_instance;
+
+ GtkEntry *entry;
+ guint length;
+ gulong changed_id;
+
+ GtkWidget *list;
+ GtkWidget *active;
+
+ GVariant *data;
+};
+
+struct _GtkEmojiCompletionClass {
+ GtkPopoverClass parent_class;
+};
+
+static void connect_signals (GtkEmojiCompletion *completion,
+ GtkEntry *entry);
+static void disconnect_signals (GtkEmojiCompletion *completion);
+static int populate_emoji_completion (GtkEmojiCompletion *completion,
+ const char *text);
+
+G_DEFINE_TYPE (GtkEmojiCompletion, gtk_emoji_completion, GTK_TYPE_POPOVER)
+
+static void
+gtk_emoji_completion_finalize (GObject *object)
+{
+ GtkEmojiCompletion *completion = GTK_EMOJI_COMPLETION (object);
+
+ disconnect_signals (completion);
+
+ g_variant_unref (completion->data);
+
+ G_OBJECT_CLASS (gtk_emoji_completion_parent_class)->finalize (object);
+}
+
+static void
+update_completion (GtkEmojiCompletion *completion)
+{
+ const char *text;
+ guint length;
+ guint n_matches;
+
+ n_matches = 0;
+
+ text = gtk_entry_get_text (GTK_ENTRY (completion->entry));
+ length = strlen (text);
+
+ if (length > 0)
+ {
+ gboolean found_candidate = FALSE;
+ const char *p;
+
+ p = text + length;
+ do
+ {
+ p = g_utf8_prev_char (p);
+ if (*p == ':')
+ {
+ if (p == text || !g_unichar_isalnum (g_utf8_get_char (p - 1)))
+ found_candidate = TRUE;
+ break;
+ }
+ }
+ while (g_unichar_isalnum (g_utf8_get_char (p)) || *p == '_');
+
+ if (found_candidate)
+ n_matches = populate_emoji_completion (completion, p);
+ }
+
+ if (n_matches > 0)
+ gtk_popover_popup (GTK_POPOVER (completion));
+ else
+ gtk_popover_popdown (GTK_POPOVER (completion));
+}
+
+static void
+entry_changed (GtkEntry *entry, GtkEmojiCompletion *completion)
+{
+ update_completion (completion);
+}
+
+static void
+emoji_activated (GtkListBox *list,
+ GtkListBoxRow *row,
+ gpointer data)
+{
+ GtkEmojiCompletion *completion = data;
+ const char *emoji;
+ guint length;
+
+ gtk_popover_popdown (GTK_POPOVER (completion));
+
+ emoji = (const char *)g_object_get_data (G_OBJECT (row), "text");
+
+ g_signal_handler_block (completion->entry, completion->changed_id);
+
+ length = g_utf8_strlen (gtk_entry_get_text (completion->entry), -1);
+ gtk_entry_set_positions (completion->entry, length - completion->length, length);
+ gtk_entry_enter_text (completion->entry, emoji);
+
+ g_signal_handler_unblock (completion->entry, completion->changed_id);
+}
+
+static void
+move_active_row (GtkEmojiCompletion *completion,
+ int direction)
+{
+ GtkWidget *child;
+
+ for (child = gtk_widget_get_first_child (completion->list);
+ child != NULL;
+ child = gtk_widget_get_next_sibling (child))
+ {
+ gtk_widget_unset_state_flags (child, GTK_STATE_FLAG_PRELIGHT);
+ }
+
+ if (completion->active != NULL)
+ {
+ if (direction == 1)
+ completion->active = gtk_widget_get_next_sibling (completion->active);
+ else
+ completion->active = gtk_widget_get_prev_sibling (completion->active);
+ }
+
+ if (completion->active == NULL)
+ {
+ if (direction == 1)
+ completion->active = gtk_widget_get_first_child (completion->list);
+ else
+ completion->active = gtk_widget_get_last_child (completion->list);
+ }
+
+ if (completion->active != NULL)
+ gtk_widget_set_state_flags (completion->active, GTK_STATE_FLAG_PRELIGHT, FALSE);
+}
+
+static void
+activate_active_row (GtkEmojiCompletion *completion)
+{
+ if (completion->active != NULL)
+ emoji_activated (GTK_LIST_BOX (completion->list),
+ GTK_LIST_BOX_ROW (completion->active),
+ completion);
+}
+
+static gboolean
+entry_key_press (GtkEntry *entry,
+ GdkEventKey *event,
+ GtkEmojiCompletion *completion)
+{
+ if (!gtk_widget_get_visible (GTK_WIDGET (completion)))
+ return FALSE;
+
+ if (event->keyval == GDK_KEY_Escape)
+ {
+ gtk_popover_popdown (GTK_POPOVER (completion));
+ return TRUE;
+ }
+
+ if (event->keyval == GDK_KEY_Up)
+ {
+ move_active_row (completion, -1);
+ return TRUE;
+ }
+
+ if (event->keyval == GDK_KEY_Down)
+ {
+ move_active_row (completion, 1);
+ return TRUE;
+ }
+
+ if (event->keyval == GDK_KEY_Return ||
+ event->keyval == GDK_KEY_KP_Enter ||
+ event->keyval == GDK_KEY_ISO_Enter)
+ {
+ activate_active_row (completion);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+entry_focus_out (GtkWidget *entry,
+ GdkEventFocus *event,
+ GtkEmojiCompletion *completion)
+{
+ gtk_popover_popdown (GTK_POPOVER (completion));
+ return FALSE;
+}
+
+static void
+connect_signals (GtkEmojiCompletion *completion,
+ GtkEntry *entry)
+{
+ completion->entry = entry;
+
+ completion->changed_id = g_signal_connect (entry, "changed", G_CALLBACK (entry_changed), completion);
+ g_signal_connect (entry, "key-press-event", G_CALLBACK (entry_key_press), completion);
+ g_signal_connect (entry, "focus-out-event", G_CALLBACK (entry_focus_out), completion);
+}
+
+static void
+disconnect_signals (GtkEmojiCompletion *completion)
+{
+ g_signal_handlers_disconnect_by_func (completion->entry, entry_changed, completion);
+ g_signal_handlers_disconnect_by_func (completion->entry, entry_key_press, completion);
+ g_signal_handlers_disconnect_by_func (completion->entry, entry_focus_out, completion);
+
+ completion->entry = NULL;
+}
+
+static void
+add_emoji (GtkWidget *list,
+ GVariant *item)
+{
+ GtkWidget *child;
+ GtkWidget *label;
+ GtkWidget *box;
+ PangoAttrList *attrs;
+ GVariant *codes;
+ char text[64];
+ char *p = text;
+ int i;
+ const char *shortname;
+
+ codes = g_variant_get_child_value (item, 0);
+ for (i = 0; i < g_variant_n_children (codes); i++)
+ {
+ gunichar code;
+
+ g_variant_get_child (codes, i, "u", &code);
+ if (code != 0)
+ p += g_unichar_to_utf8 (code, p);
+ }
+ p[0] = 0;
+
+ label = gtk_label_new (text);
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_X_LARGE));
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
+ pango_attr_list_unref (attrs);
+
+ child = gtk_list_box_row_new ();
+ gtk_widget_set_focus_on_click (child, FALSE);
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_container_add (GTK_CONTAINER (child), box);
+ gtk_box_pack_start (GTK_BOX (box), label);
+
+ g_variant_get_child (item, 2, "&s", &shortname);
+ label = gtk_label_new (shortname);
+ gtk_box_pack_start (GTK_BOX (box), label);
+
+ g_object_set_data_full (G_OBJECT (child), "text", g_strdup (text), g_free);
+ gtk_style_context_add_class (gtk_widget_get_style_context (child), "emoji-completion-row");
+
+ gtk_list_box_insert (GTK_LIST_BOX (list), child, -1);
+}
+
+#define MAX_ROWS 5
+
+static int
+populate_emoji_completion (GtkEmojiCompletion *completion,
+ const char *text)
+{
+ GList *children, *l;
+ gboolean n_matches;
+ GVariantIter iter;
+ GVariant *item;
+
+ completion->length = g_utf8_strlen (text, -1);
+
+ children = gtk_container_get_children (GTK_CONTAINER (completion->list));
+ for (l = children; l; l = l->next)
+ gtk_widget_destroy (GTK_WIDGET (l->data));
+ g_list_free (children);
+
+ completion->active = NULL;
+
+ n_matches = 0;
+ g_variant_iter_init (&iter, completion->data);
+ while ((item = g_variant_iter_next_value (&iter)))
+ {
+ const char *shortname;
+
+ g_variant_get_child (item, 2, "&s", &shortname);
+ if (g_str_has_prefix (shortname, text))
+ {
+ add_emoji (completion->list, item);
+ n_matches++;
+ }
+
+ if (n_matches == MAX_ROWS)
+ break;
+ }
+
+ return n_matches;
+}
+
+static void
+gtk_emoji_completion_init (GtkEmojiCompletion *completion)
+{
+ g_autoptr(GBytes) bytes = NULL;
+
+ gtk_widget_init_template (GTK_WIDGET (completion));
+
+ bytes = g_resources_lookup_data ("/org/gtk/libgtk/emoji/emoji.data", 0, NULL);
+ completion->data = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE ("a(auss)"), bytes, TRUE));
+}
+
+static void
+gtk_emoji_completion_class_init (GtkEmojiCompletionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = gtk_emoji_completion_finalize;
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkemojicompletion.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, GtkEmojiCompletion, list);
+
+ gtk_widget_class_bind_template_callback (widget_class, emoji_activated);
+}
+
+GtkWidget *
+gtk_emoji_completion_new (GtkEntry *entry)
+{
+ GtkEmojiCompletion *completion;
+
+ completion = GTK_EMOJI_COMPLETION (g_object_new (GTK_TYPE_EMOJI_COMPLETION,
+ "relative-to", entry,
+ NULL));
+
+ connect_signals (completion, entry);
+
+ return GTK_WIDGET (completion);
+}
diff --git a/gtk/gtkemojicompletion.h b/gtk/gtkemojicompletion.h
new file mode 100644
index 0000000..ff7cb1f
--- /dev/null
+++ b/gtk/gtkemojicompletion.h
@@ -0,0 +1,41 @@
+/* gtkemojicompletion.h: An Emoji picker widget
+ * Copyright 2017, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkentry.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_EMOJI_COMPLETION (gtk_emoji_completion_get_type ())
+#define GTK_EMOJI_COMPLETION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GTK_TYPE_EMOJI_COMPLETION, GtkEmojiCompletion))
+#define GTK_EMOJI_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GTK_TYPE_EMOJI_COMPLETION, GtkEmojiCompletionClass))
+#define GTK_IS_EMOJI_COMPLETION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GTK_TYPE_EMOJI_COMPLETION))
+#define GTK_IS_EMOJI_COMPLETION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GTK_TYPE_EMOJI_COMPLETION))
+#define GTK_EMOJI_COMPLETION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GTK_TYPE_EMOJI_COMPLETION, GtkEmojiCompletionClass))
+
+typedef struct _GtkEmojiCompletion GtkEmojiCompletion;
+typedef struct _GtkEmojiCompletionClass GtkEmojiCompletionClass;
+
+GType gtk_emoji_completion_get_type (void) G_GNUC_CONST;
+GtkWidget *gtk_emoji_completion_new (GtkEntry *entry);
+
+G_END_DECLS
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index c4884ea..7a46059 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -69,7 +69,7 @@
#include "gtkcssnodeprivate.h"
#include "gtkimageprivate.h"
#include "gtkemojichooser.h"
-#include "gtkemojicompletions.h"
+#include "gtkemojicompletion.h"
#include "a11y/gtkentryaccessible.h"
@@ -243,6 +243,7 @@ struct _GtkEntryPrivate
guint editable : 1;
guint show_emoji_icon : 1;
+ guint enable_emoji_completion : 1;
guint in_drag : 1;
guint overwrite_mode : 1;
guint visible : 1;
@@ -363,6 +364,7 @@ enum {
PROP_POPULATE_ALL,
PROP_TABS,
PROP_SHOW_EMOJI_ICON,
+ PROP_ENABLE_EMOJI_COMPLETION,
PROP_EDITING_CANCELED,
NUM_PROPERTIES = PROP_EDITING_CANCELED
};
@@ -559,11 +561,6 @@ static void gtk_entry_drag_gesture_end (GtkGestureDrag *gesture,
/* Internal routines
*/
-static void gtk_entry_enter_text (GtkEntry *entry,
- const gchar *str);
-static void gtk_entry_set_positions (GtkEntry *entry,
- gint current_pos,
- gint selection_bound);
static void gtk_entry_draw_text (GtkEntry *entry,
GtkSnapshot *snapshot);
static void gtk_entry_draw_cursor (GtkEntry *entry,
@@ -656,7 +653,8 @@ static void buffer_disconnect_signals (GtkEntry *entry);
static GtkEntryBuffer *get_buffer (GtkEntry *entry);
static void set_show_emoji_icon (GtkEntry *entry,
gboolean value);
-static void check_emoji_completion (GtkEntry *entry);
+static void set_enable_emoji_completion (GtkEntry *entry,
+ gboolean value);
static void gtk_entry_measure (GtkWidget *widget,
GtkOrientation orientation,
@@ -1402,6 +1400,13 @@ gtk_entry_class_init (GtkEntryClass *class)
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ entry_props[PROP_ENABLE_EMOJI_COMPLETION] =
+ g_param_spec_boolean ("enable-emoji-completion",
+ P_("Enable Emoji completion"),
+ P_("Whether to suggest Emoji replacements"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, entry_props);
/**
@@ -2161,6 +2166,10 @@ gtk_entry_set_property (GObject *object,
set_show_emoji_icon (entry, g_value_get_boolean (value));
break;
+ case PROP_ENABLE_EMOJI_COMPLETION:
+ set_enable_emoji_completion (entry, g_value_get_boolean (value));
+ break;
+
case PROP_SCROLL_OFFSET:
case PROP_CURSOR_POSITION:
default:
@@ -2393,6 +2402,10 @@ gtk_entry_get_property (GObject *object,
g_value_set_boolean (value, priv->show_emoji_icon);
break;
+ case PROP_ENABLE_EMOJI_COMPLETION:
+ g_value_set_boolean (value, priv->enable_emoji_completion);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -5083,7 +5096,6 @@ gtk_entry_backspace (GtkEntry *entry)
}
gtk_entry_pend_cursor_blink (entry);
- check_emoji_completion (entry);
}
static void
@@ -5333,7 +5345,7 @@ gtk_entry_delete_surrounding_cb (GtkIMContext *slave,
*/
/* Used for im_commit_cb and inserting Unicode chars */
-static void
+void
gtk_entry_enter_text (GtkEntry *entry,
const gchar *str)
{
@@ -5363,13 +5375,12 @@ gtk_entry_enter_text (GtkEntry *entry,
gtk_editable_set_position (editable, tmp_pos);
priv->need_im_reset = old_need_im_reset;
- check_emoji_completion (entry);
}
/* All changes to priv->current_pos and priv->selection_bound
* should go through this function.
*/
-static void
+void
gtk_entry_set_positions (GtkEntry *entry,
gint current_pos,
gint selection_bound)
@@ -9967,88 +9978,21 @@ set_show_emoji_icon (GtkEntry *entry,
}
static void
-dismiss_emoji_completions (GtkEntry *entry)
-{
- GtkWidget *popup;
-
-g_print ("dismiss emoji completions\n");
- popup = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "emoji-completion-popup"));
- if (popup)
- gtk_popover_popdown (GTK_POPOVER (popup));
-}
-
-static void
-emoji_picked (GtkEmojiCompletions *completions,
- const char *emoji_text,
- gpointer data)
-{
- GtkEntry *entry = data;
- const char *text;
- const char *completion_text;
- guint length;
-
- text = gtk_entry_buffer_get_text (get_buffer (entry));
- length = gtk_entry_buffer_get_length (get_buffer (entry));
-
- completion_text = g_object_get_data (entry, "emoji-completion-text");
- gtk_entry_set_positions (entry, length - strlen (completion_text), length);
- gtk_entry_enter_text (entry, emoji_text);
-}
-
-static void
-update_emoji_completions (GtkEntry *entry,
- const char *text)
+set_enable_emoji_completion (GtkEntry *entry,
+ gboolean value)
{
- GtkWidget *popup;
-
-g_print ("update emoji completions\n");
-
- g_object_set_data_full (G_OBJECT (entry), "emoji-completion-text", g_strdup (text), g_free);
-
- popup = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "emoji-completion-popup"));
- if (popup == NULL)
- {
- popup = gtk_emoji_completions_new (entry);
- g_object_set_data_full (G_OBJECT (entry), "emoji-completion-popup", popup,
(GDestroyNotify)gtk_widget_destroy);
- g_signal_connect (popup, "emoji-picked", G_CALLBACK (emoji_picked), entry);
- }
-
- gtk_emoji_completions_show (GTK_EMOJI_COMPLETIONS (popup), text);
-}
-
-static void
-check_emoji_completion (GtkEntry *entry)
-{
- const char *text;
- guint length;
- const char *p;
-
- text = gtk_entry_buffer_get_text (get_buffer (entry));
- length = gtk_entry_buffer_get_length (get_buffer (entry));
+ GtkEntryPrivate *priv = entry->priv;
- if (length > 0)
- {
- gboolean found_candidate = FALSE;
+ if (priv->enable_emoji_completion == value)
+ return;
- p = text + length;
- do
- {
- p = g_utf8_prev_char (p);
- if (*p == ':')
- {
- if (p == text || !g_unichar_isalnum (g_utf8_get_char (p - 1)))
- found_candidate = TRUE;
- break;
- }
- }
- while (g_unichar_isalnum (g_utf8_get_char (p)) || *p == '_');
+ priv->enable_emoji_completion = value;
- if (found_candidate)
- {
- update_emoji_completions (entry, p);
- return;
- }
- }
+ if (priv->enable_emoji_completion)
+ g_object_set_data_full (G_OBJECT (entry), "emoji-completion-popup",
+ gtk_emoji_completion_new (entry), (GDestroyNotify)gtk_widget_destroy);
+ else
+ g_object_set_data (G_OBJECT (entry), "emoji-completion-popup", NULL);
- dismiss_emoji_completions (entry);
+ g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_ENABLE_EMOJI_COMPLETION]);
}
diff --git a/gtk/gtkentryprivate.h b/gtk/gtkentryprivate.h
index 08fab2d..4e96084 100644
--- a/gtk/gtkentryprivate.h
+++ b/gtk/gtkentryprivate.h
@@ -88,6 +88,13 @@ GtkIMContext* _gtk_entry_get_im_context (GtkEntry *entry);
void _gtk_entry_grab_focus (GtkEntry *entry,
gboolean select_all);
+void gtk_entry_enter_text (GtkEntry *entry,
+ const char *text);
+void gtk_entry_set_positions (GtkEntry *entry,
+ int current_pos,
+ int selection_bound);
+
+
G_END_DECLS
#endif /* __GTK_ENTRY_PRIVATE_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index 36a9ceb..2f1ecdf 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -142,6 +142,7 @@ gtk_public_sources = files([
'gtkdrawingarea.c',
'gtkeditable.c',
'gtkemojichooser.c',
+ 'gtkemojicompletion.c',
'gtkentry.c',
'gtkentrybuffer.c',
'gtkentrycompletion.c',
diff --git a/gtk/ui/gtkemojicompletions.ui b/gtk/ui/gtkemojicompletion.ui
similarity index 88%
rename from gtk/ui/gtkemojicompletions.ui
rename to gtk/ui/gtkemojicompletion.ui
index 0af8c47..c6df950 100644
--- a/gtk/ui/gtkemojicompletions.ui
+++ b/gtk/ui/gtkemojicompletion.ui
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk40">
- <template class="GtkEmojiCompletions" parent="GtkPopover">
+ <template class="GtkEmojiCompletion" parent="GtkPopover">
<property name="modal">0</property>
<style>
<class name="emoji-completions"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]