Blame SOURCES/ibus-1897548-emoji-unicode.patch

ef5ff4
From c38e925eba2b1f7af39696e2f64ec1eaea94b00b Mon Sep 17 00:00:00 2001
abd81d
From: Takao Fujiwara <fujiwara@redhat.com>
ef5ff4
Date: Thu, 30 Sep 2021 09:36:12 -0400
abd81d
Subject: [PATCH] Backport IBus Unicode feature
abd81d
abd81d
---
ef5ff4
 configure.ac              | 10 +++++++
ef5ff4
 ui/gtk3/Makefile.am       |  5 +++-
ef5ff4
 ui/gtk3/emojier.vala      | 37 +++++++++++++++--------
ef5ff4
 ui/gtk3/emojierapp.vala   | 63 ++++++++++++++++++++++++++++-----------
abd81d
 ui/gtk3/panelbinding.vala | 13 ++++++--
ef5ff4
 5 files changed, 93 insertions(+), 35 deletions(-)
abd81d
ef5ff4
diff --git a/configure.ac b/configure.ac
ef5ff4
index 46ab7a9..26bb357 100644
ef5ff4
--- a/configure.ac
ef5ff4
+++ b/configure.ac
ef5ff4
@@ -237,12 +237,21 @@ if test x"$enable_gtk3" = x"yes"; then
ef5ff4
     PKG_CHECK_MODULES(GTK3, [
ef5ff4
         gtk+-3.0
ef5ff4
     ])
ef5ff4
+    PKG_CHECK_EXISTS([gdk-wayland-3.0],
ef5ff4
+        [enable_gdk3_wayland=yes],
ef5ff4
+        [enable_gdk3_wayland=no]
ef5ff4
+    )
ef5ff4
 
ef5ff4
     gtk3_binary_version=`$PKG_CONFIG --variable=gtk_binary_version gtk+-3.0`
ef5ff4
     GTK3_IM_MODULEDIR="$libdir"/gtk-3.0/$gtk3_binary_version/immodules
ef5ff4
 else
ef5ff4
     enable_gtk3="no (disabled, use --enable-gtk3 to enable)"
ef5ff4
+    enable_gdk3_wayland=no
ef5ff4
+fi
ef5ff4
+if test x"$enable_gdk3_wayland" != x"yes"; then
ef5ff4
+    enable_gdk3_wayland="no (disabled, need to install gdk-wayland-3.0.pc)"
ef5ff4
 fi
ef5ff4
+AM_CONDITIONAL([ENABLE_GDK3_WAYLAND], [test x"$enable_gdk3_wayland" = x"yes"])
ef5ff4
 
ef5ff4
 if test x"$enable_xim" = x"yes"; then
ef5ff4
     # Check for x11
ef5ff4
@@ -796,6 +805,7 @@ Build options:
ef5ff4
   Build gtk3 immodule           $enable_gtk3
ef5ff4
   Build XIM agent server        $enable_xim
ef5ff4
   Build wayland support         $enable_wayland
ef5ff4
+  Build gdk3 wayland support    $enable_gdk3_wayland
ef5ff4
   Build appindicator support    $enable_appindicator
ef5ff4
   Build appindicator engine icon $enable_appindicator_engine_icon
ef5ff4
   Build python library          $enable_python_library
ef5ff4
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
ef5ff4
index aaba7a4..6ebc96c 100644
ef5ff4
--- a/ui/gtk3/Makefile.am
ef5ff4
+++ b/ui/gtk3/Makefile.am
ef5ff4
@@ -78,7 +78,6 @@ AM_VALAFLAGS = \
ef5ff4
 	--pkg=ibus-1.0 \
ef5ff4
 	--pkg=config \
ef5ff4
 	--pkg=xi \
ef5ff4
-	--pkg=gdk-wayland \
ef5ff4
 	--target-glib="$(VALA_TARGET_GLIB_VERSION)" \
ef5ff4
 	$(NULL)
ef5ff4
 
ef5ff4
@@ -105,6 +104,10 @@ if ENABLE_APPINDICATOR_ENGINE_ICON
ef5ff4
 AM_VALAFLAGS += --define=INDICATOR_ENGINE_ICON
ef5ff4
 endif
ef5ff4
 
ef5ff4
+if ENABLE_GDK3_WAYLAND
ef5ff4
+AM_VALAFLAGS += --pkg=gdk-wayland --define=USE_GDK_WAYLAND
ef5ff4
+endif
ef5ff4
+
ef5ff4
 libexec_PROGRAMS = ibus-ui-gtk3
ef5ff4
 
ef5ff4
 ibus_ui_gtk3_SOURCES = \
abd81d
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
abd81d
index 3eac2f2..9e6e926 100644
abd81d
--- a/ui/gtk3/emojier.vala
abd81d
+++ b/ui/gtk3/emojier.vala
abd81d
@@ -2,7 +2,7 @@
abd81d
  *
abd81d
  * ibus - The Input Bus
abd81d
  *
abd81d
- * Copyright (c) 2017-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
abd81d
+ * Copyright (c) 2017-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
abd81d
  *
abd81d
  * This library is free software; you can redistribute it and/or
abd81d
  * modify it under the terms of the GNU Lesser General Public
abd81d
@@ -320,6 +320,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
 
abd81d
     public signal void candidate_clicked(uint index, uint button, uint state);
abd81d
     public signal void commit_text(string text);
abd81d
+    public signal void cancel();
abd81d
 
abd81d
     public IBusEmojier() {
abd81d
         GLib.Object(
abd81d
@@ -864,7 +865,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
         row.get_allocation(out alloc);
abd81d
         var adjustment = m_scrolled_window.get_vadjustment();
abd81d
         adjustment.clamp_page(alloc.y, alloc.y + alloc.height);
abd81d
-        return_val_if_fail(m_category_active_index >= 0, false);
abd81d
+        return_if_fail(m_category_active_index >= 0);
abd81d
         m_lookup_table.set_cursor_pos((uint)m_category_active_index);
abd81d
     }
abd81d
 
abd81d
@@ -936,8 +937,13 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
             update_unicode_blocks();
abd81d
             return;
abd81d
         } else {
abd81d
-            unowned GLib.SList<unowned string> emojis =
abd81d
-                    m_category_to_emojis_dict.lookup(category);
abd81d
+            // Use copy_deep() since vala 0.43.4 does not allow to assign
abd81d
+            // a weak pointer to the full one in SList:
abd81d
+            // emojier.vala:885.48-886.62: error: Assignment: Cannot convert
abd81d
+            // from `GLib.SList<string>' to `GLib.SList<weak string>?'
abd81d
+            GLib.SList<string> emojis =
abd81d
+                    m_category_to_emojis_dict.lookup(category).copy_deep(
abd81d
+                            GLib.strdup);
abd81d
             m_lookup_table.clear();
abd81d
             m_candidate_panel_mode = true;
abd81d
             foreach (unowned string emoji in emojis) {
abd81d
@@ -1601,8 +1607,8 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
             m_vbox.add(widget);
abd81d
             widget.show_all();
abd81d
         }
abd81d
-        unowned GLib.SList<unowned string>? annotations =
abd81d
-                data.get_annotations();
abd81d
+        GLib.SList<string> annotations =
abd81d
+                data.get_annotations().copy_deep(GLib.strdup);
abd81d
         var buff = new GLib.StringBuilder();
abd81d
         int i = 0;
abd81d
         foreach (unowned string annotation in annotations) {
abd81d
@@ -1784,8 +1790,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
             show_emoji_variants(emojis);
abd81d
             return true;
abd81d
         }
abd81d
-        if (m_input_context_path != "")
abd81d
-            m_result = text;
abd81d
+        m_result = text;
abd81d
         if (need_commit_signal)
abd81d
             commit_text(text);
abd81d
         return false;
abd81d
@@ -1892,6 +1897,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
             // PageUp/PageDown.
abd81d
             remove_all_children();
abd81d
         }
abd81d
+        cancel();
abd81d
         return false;
abd81d
     }
abd81d
 
abd81d
@@ -2055,17 +2061,20 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
                     ) as IBus.EmojiData;
abd81d
                 m_emoji_to_data_dict.insert(favorite, new_data);
abd81d
             } else {
abd81d
-                unowned GLib.SList<string> annotations = data.get_annotations();
abd81d
+                GLib.SList<string> annotations =
abd81d
+                        data.get_annotations().copy_deep(GLib.strdup);
abd81d
                 if (annotations.find_custom(annotation, GLib.strcmp) == null) {
abd81d
                     annotations.append(annotation);
abd81d
-                    data.set_annotations(annotations.copy());
abd81d
+                    data.set_annotations(annotations.copy_deep(GLib.strdup));
abd81d
                 }
abd81d
             }
abd81d
             unowned GLib.SList<string> emojis =
abd81d
                     m_annotation_to_emojis_dict.lookup(annotation);
abd81d
             if (emojis.find_custom(favorite, GLib.strcmp) == null) {
abd81d
                 emojis.append(favorite);
abd81d
-                m_annotation_to_emojis_dict.replace(annotation, emojis.copy());
abd81d
+                m_annotation_to_emojis_dict.replace(
abd81d
+                        annotation,
abd81d
+                        emojis.copy_deep(GLib.strdup));
abd81d
             }
abd81d
         }
abd81d
     }
abd81d
@@ -2117,7 +2126,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
     public string get_current_candidate() {
abd81d
         // If category_list mode, do not show the category name on preedit.
abd81d
         // If candidate_panel mode, the first space key does not show the
abd81d
-        // lookup table but the first candidate is avaiable on preedit.
abd81d
+        // lookup table but the first candidate is available on preedit.
abd81d
         if (!m_candidate_panel_mode)
abd81d
             return "";
abd81d
         uint cursor = m_lookup_table.get_cursor_pos();
abd81d
@@ -2139,11 +2148,13 @@ public class IBusEmojier : Gtk.ApplicationWindow {
abd81d
                         ncandidates));
abd81d
         int char_count = text.text.char_count();
abd81d
         int start_index = -1;
abd81d
+        unowned string title = text.text;
abd81d
         for (int i = 0; i < char_count; i++) {
abd81d
-            if (text.text.utf8_offset(i).has_prefix(language)) {
abd81d
+            if (title.has_prefix(language)) {
abd81d
                 start_index = i;
abd81d
                 break;
abd81d
             }
abd81d
+            title = title.next_char();
abd81d
         }
abd81d
         if (start_index >= 0) {
abd81d
             var attr = new IBus.Attribute(
abd81d
diff --git a/ui/gtk3/emojierapp.vala b/ui/gtk3/emojierapp.vala
ef5ff4
index fab99d9..7bc7b42 100644
abd81d
--- a/ui/gtk3/emojierapp.vala
abd81d
+++ b/ui/gtk3/emojierapp.vala
abd81d
@@ -3,6 +3,7 @@
abd81d
  * ibus - The Input Bus
abd81d
  *
abd81d
  * Copyright (c) 2017 Peng Wu <alexepico@gmail.com>
abd81d
+ * Copyright (c) 2017-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
abd81d
  *
abd81d
  * This library is free software; you can redistribute it and/or
abd81d
  * modify it under the terms of the GNU Lesser General Public
abd81d
@@ -40,6 +41,33 @@ public class EmojiApplication : Gtk.Application {
abd81d
     }
abd81d
 
abd81d
 
abd81d
+    private void save_selected_string(string? selected_string,
abd81d
+                                      bool    cancelled) {
abd81d
+        if (cancelled) {
abd81d
+            m_command_line.print("%s\n", _("Canceled to choose an emoji."));
abd81d
+            return;
abd81d
+        }
abd81d
+        GLib.return_if_fail(selected_string != null);
abd81d
+        Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
abd81d
+        clipboard.set_text(selected_string, -1);
abd81d
+        clipboard.store();
abd81d
+
abd81d
+        var emojier_favorites = m_settings_emoji.get_strv("favorites");
abd81d
+        bool has_favorite = false;
abd81d
+        foreach (unowned string favorite in emojier_favorites) {
abd81d
+            if (favorite == selected_string) {
abd81d
+                has_favorite = true;
abd81d
+                break;
abd81d
+            }
abd81d
+        }
abd81d
+        if (!has_favorite) {
abd81d
+            emojier_favorites += selected_string;
abd81d
+            m_settings_emoji.set_strv("favorites", emojier_favorites);
abd81d
+        }
abd81d
+        m_command_line.print("%s\n", _("Copied an emoji to your clipboard."));
abd81d
+    }
abd81d
+
abd81d
+
abd81d
     private void show_dialog(ApplicationCommandLine command_line) {
abd81d
         m_command_line = command_line;
abd81d
         m_emojier.reset();
abd81d
@@ -55,7 +83,7 @@ public class EmojiApplication : Gtk.Application {
abd81d
             return;
abd81d
         if (button == IBusEmojier.BUTTON_CLOSE_BUTTON) {
abd81d
             m_emojier.hide();
abd81d
-            m_command_line.print("%s\n", _("Canceled to choose an emoji."));
abd81d
+            save_selected_string(null, true);
abd81d
             m_command_line = null;
abd81d
             return;
abd81d
         }
abd81d
@@ -74,23 +102,7 @@ public class EmojiApplication : Gtk.Application {
abd81d
         }
abd81d
         string emoji = m_emojier.get_current_candidate();
abd81d
         m_emojier.hide();
abd81d
-        Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
abd81d
-        clipboard.set_text(emoji, -1);
abd81d
-        clipboard.store();
abd81d
-
abd81d
-        var emojier_favorites = m_settings_emoji.get_strv("favorites");
abd81d
-        bool has_favorite = false;
abd81d
-        foreach (unowned string favorite in emojier_favorites) {
abd81d
-            if (favorite == emoji) {
abd81d
-                has_favorite = true;
abd81d
-                break;
abd81d
-            }
abd81d
-        }
abd81d
-        if (!has_favorite) {
abd81d
-            emojier_favorites += emoji;
abd81d
-            m_settings_emoji.set_strv("favorites", emojier_favorites);
abd81d
-        }
abd81d
-        m_command_line.print("%s\n", _("Copied an emoji to your clipboard."));
abd81d
+        save_selected_string(emoji, false);
abd81d
         m_command_line = null;
abd81d
     }
abd81d
 
abd81d
@@ -202,6 +214,21 @@ public class EmojiApplication : Gtk.Application {
abd81d
             m_emojier.candidate_clicked.connect((i, b, s) => {
abd81d
                 candidate_clicked_lookup_table(i, b, s);
abd81d
             });
abd81d
+            m_emojier.cancel.connect(() => {
abd81d
+                if (m_command_line == null)
abd81d
+                    return;
abd81d
+                m_emojier.hide();
abd81d
+                save_selected_string(null, true);
abd81d
+                m_command_line = null;
abd81d
+            });
abd81d
+            m_emojier.commit_text.connect(() => {
abd81d
+                if (m_command_line == null)
abd81d
+                    return;
abd81d
+                m_emojier.hide();
abd81d
+                string selected_string = m_emojier.get_selected_string();
abd81d
+                save_selected_string(selected_string, false);
abd81d
+                m_command_line = null;
abd81d
+            });
abd81d
         }
abd81d
 
abd81d
         activate_dialog(command_line);
abd81d
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
abd81d
index cfedb2d..861255b 100644
abd81d
--- a/ui/gtk3/panelbinding.vala
abd81d
+++ b/ui/gtk3/panelbinding.vala
abd81d
@@ -3,7 +3,7 @@
abd81d
  * ibus - The Input Bus
abd81d
  *
abd81d
  * Copyright(c) 2018 Peng Huang <shawn.p.huang@gmail.com>
abd81d
- * Copyright(c) 2018 Takao Fujwiara <takao.fujiwara1@gmail.com>
abd81d
+ * Copyright(c) 2018-2020 Takao Fujwiara <takao.fujiwara1@gmail.com>
abd81d
  *
abd81d
  * This library is free software; you can redistribute it and/or
abd81d
  * modify it under the terms of the GNU Lesser General Public
abd81d
@@ -190,7 +190,7 @@ class Preedit : Gtk.Window {
abd81d
 
abd81d
     public IBus.Text get_commit_text() {
abd81d
         string extension_text = m_extension_preedit_emoji.get_text();
abd81d
-        if (extension_text.length == 0)
abd81d
+        if (extension_text.length == 0 && m_prefix != "u")
abd81d
             extension_text = m_extension_preedit_text.get_text();
abd81d
         return new IBus.Text.from_string(extension_text);
abd81d
     }
abd81d
@@ -237,9 +237,14 @@ class PanelBinding : IBus.PanelService {
abd81d
         GLib.Object(connection : bus.get_connection(),
abd81d
                     object_path : IBus.PATH_PANEL_EXTENSION_EMOJI);
abd81d
 
abd81d
+#if USE_GDK_WAYLAND
abd81d
         Type instance_type = Gdk.Display.get_default().get_type();
abd81d
         Type wayland_type = typeof(GdkWayland.Display);
abd81d
         m_is_wayland = instance_type.is_a(wayland_type);
abd81d
+#else
abd81d
+        m_is_wayland = false;
abd81d
+        warning("Checking Wayland is disabled");
abd81d
+#endif
abd81d
 
abd81d
         m_bus = bus;
abd81d
         m_application = application;
abd81d
@@ -551,8 +556,10 @@ class PanelBinding : IBus.PanelService {
abd81d
 
abd81d
     private bool key_press_keyval(uint keyval) {
abd81d
         unichar ch = IBus.keyval_to_unicode(keyval);
abd81d
+        if (m_extension_name == "unicode" && !ch.isxdigit())
abd81d
+            return false;
abd81d
         if (ch.iscntrl())
abd81d
-                return false;
abd81d
+            return false;
abd81d
         string str = ch.to_string();
abd81d
         m_preedit.append_text(str);
abd81d
         string annotation = m_preedit.get_text();
abd81d
-- 
ef5ff4
2.27.0
abd81d