Blame ui/gtk3/panelbinding.vala

Packit Service 1d8f1c
/* vim:set et sts=4 sw=4:
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * ibus - The Input Bus
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * Copyright(c) 2018 Peng Huang <shawn.p.huang@gmail.com>
Packit Service 1d8f1c
 * Copyright(c) 2018 Takao Fujwiara <takao.fujiwara1@gmail.com>
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is free software; you can redistribute it and/or
Packit Service 1d8f1c
 * modify it under the terms of the GNU Lesser General Public
Packit Service 1d8f1c
 * License as published by the Free Software Foundation; either
Packit Service 1d8f1c
 * version 2.1 of the License, or (at your option) any later version.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * This library is distributed in the hope that it will be useful,
Packit Service 1d8f1c
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 1d8f1c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 1d8f1c
 * Lesser General Public License for more details.
Packit Service 1d8f1c
 *
Packit Service 1d8f1c
 * You should have received a copy of the GNU Lesser General Public
Packit Service 1d8f1c
 * License along with this library; if not, write to the Free Software
Packit Service 1d8f1c
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
Packit Service 1d8f1c
 * USA
Packit Service 1d8f1c
 */
Packit Service 1d8f1c
Packit Service 1d8f1c
class Preedit : Gtk.Window {
Packit Service 1d8f1c
    private Gtk.Label m_extension_preedit_text;
Packit Service 1d8f1c
    private Gtk.Label m_extension_preedit_emoji;
Packit Service 1d8f1c
    private IBus.Text? m_engine_preedit_text;
Packit Service 1d8f1c
    private bool m_engine_preedit_text_show;
Packit Service 1d8f1c
    private uint m_engine_preedit_cursor_pos;
Packit Service 1d8f1c
    private string m_prefix = "@";
Packit Service 1d8f1c
    private bool m_is_shown = true;
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public Preedit() {
Packit Service 1d8f1c
        GLib.Object(
Packit Service 1d8f1c
            name : "IBusPreedit",
Packit Service 1d8f1c
            type: Gtk.WindowType.POPUP
Packit Service 1d8f1c
        );
Packit Service 1d8f1c
        m_extension_preedit_text  = new Gtk.Label("");
Packit Service 1d8f1c
        m_extension_preedit_emoji  = new Gtk.Label("");
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public new void hide() {
Packit Service 1d8f1c
        reset();
Packit Service 1d8f1c
        base.hide();
Packit Service 1d8f1c
        m_is_shown = false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public bool is_shown() {
Packit Service 1d8f1c
        return m_is_shown;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void reset() {
Packit Service 1d8f1c
        set_emoji("");
Packit Service 1d8f1c
        set_text("");
Packit Service 1d8f1c
        resize(1, 1);
Packit Service 1d8f1c
        m_is_shown = true;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void append_text(string text) {
Packit Service 1d8f1c
        if (text.length == 0)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        string total = m_extension_preedit_text.get_text();
Packit Service 1d8f1c
        total += text;
Packit Service 1d8f1c
        m_extension_preedit_text.set_text(total);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public string get_text() {
Packit Service 1d8f1c
        return m_extension_preedit_text.get_text();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void set_text(string text) {
Packit Service 1d8f1c
        m_extension_preedit_text.set_text(text);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public string get_emoji() {
Packit Service 1d8f1c
        return m_extension_preedit_emoji.get_text();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void set_emoji(string text) {
Packit Service 1d8f1c
        m_extension_preedit_emoji.set_text(text);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public bool backspace() {
Packit Service 1d8f1c
        string total = m_extension_preedit_emoji.get_text();
Packit Service 1d8f1c
        if (total.length > 0) {
Packit Service 1d8f1c
            m_extension_preedit_emoji.set_text("");
Packit Service 1d8f1c
            resize(1, 1);
Packit Service 1d8f1c
            return false;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        total = m_extension_preedit_text.get_text();
Packit Service 1d8f1c
        int char_count = total.char_count();
Packit Service 1d8f1c
        if (char_count == 0)
Packit Service 1d8f1c
            return true;
Packit Service 1d8f1c
        total = total[0:total.index_of_nth_char(char_count - 1)];
Packit Service 1d8f1c
        resize(1, 1);
Packit Service 1d8f1c
        m_extension_preedit_text.set_text(total);
Packit Service 1d8f1c
        if (total.length == 0)
Packit Service 1d8f1c
            resize(1, 1);
Packit Service 1d8f1c
        return true;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private string get_extension_text () {
Packit Service 1d8f1c
        string extension_text = m_extension_preedit_emoji.get_text();
Packit Service 1d8f1c
        if (extension_text.length == 0)
Packit Service 1d8f1c
            extension_text = m_extension_preedit_text.get_text();
Packit Service 1d8f1c
        return m_prefix + extension_text;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void set_preedit_color(IBus.Text text,
Packit Service 1d8f1c
                                   uint start_index,
Packit Service 1d8f1c
                                   uint end_index) {
Packit Service 1d8f1c
        text.append_attribute(IBus.AttrType.UNDERLINE,
Packit Service 1d8f1c
                              IBus.AttrUnderline.SINGLE,
Packit Service 1d8f1c
                              start_index, (int)end_index);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public IBus.Text get_engine_preedit_text() {
Packit Service 1d8f1c
        string extension_text = get_extension_text();
Packit Service 1d8f1c
        uint char_count = extension_text.char_count();
Packit Service 1d8f1c
        IBus.Text retval;
Packit Service 1d8f1c
        if (m_engine_preedit_text == null || !m_engine_preedit_text_show) {
Packit Service 1d8f1c
            retval = new IBus.Text.from_string(extension_text);
Packit Service 1d8f1c
            set_preedit_color(retval, 0, char_count);
Packit Service 1d8f1c
            return retval;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        retval = new IBus.Text.from_string(
Packit Service 1d8f1c
                extension_text + m_engine_preedit_text.get_text());
Packit Service 1d8f1c
        set_preedit_color(retval, 0, char_count);
Packit Service 1d8f1c
Packit Service 1d8f1c
        unowned IBus.AttrList attrs = m_engine_preedit_text.get_attributes();
Packit Service 1d8f1c
Packit Service 1d8f1c
        if (attrs == null)
Packit Service 1d8f1c
            return retval;
Packit Service 1d8f1c
Packit Service 1d8f1c
        int i = 0;
Packit Service 1d8f1c
        while (true) {
Packit Service 1d8f1c
            IBus.Attribute attr = attrs.get(i++);
Packit Service 1d8f1c
            if (attr == null)
Packit Service 1d8f1c
                break;
Packit Service 1d8f1c
            long start_index = attr.start_index;
Packit Service 1d8f1c
            long end_index = attr.end_index;
Packit Service 1d8f1c
            if (start_index < 0)
Packit Service 1d8f1c
                start_index = 0;
Packit Service 1d8f1c
            if (end_index < 0)
Packit Service 1d8f1c
                end_index = m_engine_preedit_text.get_length();
Packit Service 1d8f1c
            retval.append_attribute(attr.type, attr.value,
Packit Service 1d8f1c
                                    char_count + (uint)start_index,
Packit Service 1d8f1c
                                    (int)char_count + (int)end_index);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        return retval;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void set_engine_preedit_text(IBus.Text? text) {
Packit Service 1d8f1c
        m_engine_preedit_text = text;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void show_engine_preedit_text() {
Packit Service 1d8f1c
        m_engine_preedit_text_show = true;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void hide_engine_preedit_text() {
Packit Service 1d8f1c
        m_engine_preedit_text_show = false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public uint get_engine_preedit_cursor_pos() {
Packit Service 1d8f1c
        return get_extension_text().char_count() + m_engine_preedit_cursor_pos;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void set_engine_preedit_cursor_pos(uint cursor_pos) {
Packit Service 1d8f1c
        m_engine_preedit_cursor_pos = cursor_pos;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public IBus.Text get_commit_text() {
Packit Service 1d8f1c
        string extension_text = m_extension_preedit_emoji.get_text();
Packit Service 1d8f1c
        if (extension_text.length == 0)
Packit Service 1d8f1c
            extension_text = m_extension_preedit_text.get_text();
Packit Service 1d8f1c
        return new IBus.Text.from_string(extension_text);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void set_extension_name(string extension_name) {
Packit Service 1d8f1c
        if (extension_name.length == 0)
Packit Service 1d8f1c
            m_prefix = "@";
Packit Service 1d8f1c
        else
Packit Service 1d8f1c
            m_prefix = extension_name[0:1];
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
}
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
class PanelBinding : IBus.PanelService {
Packit Service 1d8f1c
    private bool m_is_wayland;
Packit Service 1d8f1c
    private bool m_wayland_lookup_table_is_visible;
Packit Service 1d8f1c
    private IBus.Bus m_bus;
Packit Service 1d8f1c
    private Gtk.Application m_application;
Packit Service 1d8f1c
    private GLib.Settings m_settings_panel = null;
Packit Service 1d8f1c
    private GLib.Settings m_settings_emoji = null;
Packit Service 1d8f1c
    private string m_current_context_path = "";
Packit Service 1d8f1c
    private string m_real_current_context_path = "";
Packit Service 1d8f1c
    private IBusEmojier? m_emojier;
Packit Service 1d8f1c
    private uint m_emojier_set_emoji_lang_id;
Packit Service 1d8f1c
    private uint m_emojier_focus_commit_text_id;
Packit Service 1d8f1c
    private string[] m_emojier_favorites = {};
Packit Service 1d8f1c
    private Gtk.CssProvider m_css_provider;
Packit Service 1d8f1c
    private const uint PRELOAD_ENGINES_DELAY_TIME = 30000;
Packit Service 1d8f1c
    private bool m_load_emoji_at_startup;
Packit Service 1d8f1c
    private bool m_loaded_emoji = false;
Packit Service 1d8f1c
    private bool m_load_unicode_at_startup;
Packit Service 1d8f1c
    private bool m_loaded_unicode = false;
Packit Service 1d8f1c
    private bool m_enable_extension;
Packit Service 1d8f1c
    private string m_extension_name = "";
Packit Service 1d8f1c
    private Preedit m_preedit;
Packit Service 1d8f1c
    private IBus.ProcessKeyEventData m_key_event_data =
Packit Service 1d8f1c
            IBus.ProcessKeyEventData();
Packit Service 1d8f1c
Packit Service 1d8f1c
    public PanelBinding(IBus.Bus bus,
Packit Service 1d8f1c
                        Gtk.Application application) {
Packit Service 1d8f1c
        GLib.assert(bus.is_connected());
Packit Service 1d8f1c
        // Chain up base class constructor
Packit Service 1d8f1c
        GLib.Object(connection : bus.get_connection(),
Packit Service 1d8f1c
                    object_path : IBus.PATH_PANEL_EXTENSION_EMOJI);
Packit Service 1d8f1c
Packit Service 1d8f1c
        Type instance_type = Gdk.Display.get_default().get_type();
Packit Service 1d8f1c
        Type wayland_type = typeof(GdkWayland.Display);
Packit Service 1d8f1c
        m_is_wayland = instance_type.is_a(wayland_type);
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_bus = bus;
Packit Service 1d8f1c
        m_application = application;
Packit Service 1d8f1c
Packit Service 1d8f1c
        init_settings();
Packit Service 1d8f1c
        m_preedit = new Preedit();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void init_settings() {
Packit Service 1d8f1c
        m_settings_panel = new GLib.Settings("org.freedesktop.ibus.panel");
Packit Service 1d8f1c
        m_settings_emoji = new GLib.Settings("org.freedesktop.ibus.panel.emoji");
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_panel.changed["custom-font"].connect((key) => {
Packit Service 1d8f1c
                BindingCommon.set_custom_font(m_settings_panel,
Packit Service 1d8f1c
                                              m_settings_emoji,
Packit Service 1d8f1c
                                              ref m_css_provider);
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_panel.changed["use-custom-font"].connect((key) => {
Packit Service 1d8f1c
                BindingCommon.set_custom_font(m_settings_panel,
Packit Service 1d8f1c
                                              m_settings_emoji,
Packit Service 1d8f1c
                                              ref m_css_provider);
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["unicode-hotkey"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_hotkey();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["font"].connect((key) => {
Packit Service 1d8f1c
                BindingCommon.set_custom_font(m_settings_panel,
Packit Service 1d8f1c
                                              m_settings_emoji,
Packit Service 1d8f1c
                                              ref m_css_provider);
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["hotkey"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_hotkey();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["favorites"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_favorites();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["favorite-annotations"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_favorites();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["lang"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_lang();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["has-partial-match"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_partial_match();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["partial-match-length"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_partial_match();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["partial-match-condition"].connect((key) => {
Packit Service 1d8f1c
                set_emoji_partial_match();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["load-emoji-at-startup"].connect((key) => {
Packit Service 1d8f1c
                set_load_emoji_at_startup();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
Packit Service 1d8f1c
        m_settings_emoji.changed["load-unicode-at-startup"].connect((key) => {
Packit Service 1d8f1c
                set_load_unicode_at_startup();
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    // Returning unowned IBus.KeyEventData causes NULL with gcc optimization
Packit Service 1d8f1c
    // and use m_key_event_data.
Packit Service 1d8f1c
    private void parse_accelerator(string accelerator) {
Packit Service 1d8f1c
        m_key_event_data = {};
Packit Service 1d8f1c
        uint keysym = 0;
Packit Service 1d8f1c
        IBus.ModifierType modifiers = 0;
Packit Service 1d8f1c
        IBus.accelerator_parse(accelerator,
Packit Service 1d8f1c
                out keysym, out modifiers);
Packit Service 1d8f1c
        if (keysym == 0U && modifiers == 0) {
Packit Service 1d8f1c
            warning("Failed to parse shortcut key '%s'".printf(accelerator));
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if ((modifiers & IBus.ModifierType.SUPER_MASK) != 0) {
Packit Service 1d8f1c
            modifiers ^= IBus.ModifierType.SUPER_MASK;
Packit Service 1d8f1c
            modifiers |= IBus.ModifierType.MOD4_MASK;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        m_key_event_data.keyval = keysym;
Packit Service 1d8f1c
        m_key_event_data.state = modifiers;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void set_emoji_hotkey() {
Packit Service 1d8f1c
        IBus.ProcessKeyEventData[] emoji_keys = {};
Packit Service 1d8f1c
        IBus.ProcessKeyEventData key;
Packit Service 1d8f1c
        string[] accelerators = m_settings_emoji.get_strv("hotkey");
Packit Service 1d8f1c
        foreach (var accelerator in accelerators) {
Packit Service 1d8f1c
            parse_accelerator(accelerator);
Packit Service 1d8f1c
            emoji_keys += m_key_event_data;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
Packit Service 1d8f1c
        /* Since {} is not allocated, parse_accelerator() should be unowned. */
Packit Service 1d8f1c
        key = {};
Packit Service 1d8f1c
        emoji_keys += key;
Packit Service 1d8f1c
Packit Service 1d8f1c
        IBus.ProcessKeyEventData[] unicode_keys = {};
Packit Service 1d8f1c
        accelerators = m_settings_emoji.get_strv("unicode-hotkey");
Packit Service 1d8f1c
        foreach (var accelerator in accelerators) {
Packit Service 1d8f1c
            parse_accelerator(accelerator);
Packit Service 1d8f1c
            unicode_keys += m_key_event_data;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        key = {};
Packit Service 1d8f1c
        unicode_keys += key;
Packit Service 1d8f1c
Packit Service 1d8f1c
        panel_extension_register_keys("emoji", emoji_keys,
Packit Service 1d8f1c
                                      "unicode", unicode_keys);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void set_emoji_favorites() {
Packit Service 1d8f1c
        m_emojier_favorites = m_settings_emoji.get_strv("favorites");
Packit Service 1d8f1c
        IBusEmojier.set_favorites(
Packit Service 1d8f1c
                m_emojier_favorites,
Packit Service 1d8f1c
                m_settings_emoji.get_strv("favorite-annotations"));
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void set_emoji_lang() {
Packit Service 1d8f1c
        if (m_emojier_set_emoji_lang_id > 0) {
Packit Service 1d8f1c
            GLib.Source.remove(m_emojier_set_emoji_lang_id);
Packit Service 1d8f1c
            m_emojier_set_emoji_lang_id = 0;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        m_emojier_set_emoji_lang_id = GLib.Idle.add(() => {
Packit Service 1d8f1c
            IBusEmojier.set_annotation_lang(
Packit Service 1d8f1c
                    m_settings_emoji.get_string("lang"));
Packit Service 1d8f1c
            m_emojier_set_emoji_lang_id = 0;
Packit Service 1d8f1c
            m_loaded_emoji = true;
Packit Service 1d8f1c
            if (m_load_unicode_at_startup && !m_loaded_unicode) {
Packit Service 1d8f1c
                IBusEmojier.load_unicode_dict();
Packit Service 1d8f1c
                m_loaded_unicode = true;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            return false;
Packit Service 1d8f1c
        });
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void set_emoji_partial_match() {
Packit Service 1d8f1c
        IBusEmojier.set_partial_match(
Packit Service 1d8f1c
                m_settings_emoji.get_boolean("has-partial-match"));
Packit Service 1d8f1c
        IBusEmojier.set_partial_match_length(
Packit Service 1d8f1c
                m_settings_emoji.get_int("partial-match-length"));
Packit Service 1d8f1c
        IBusEmojier.set_partial_match_condition(
Packit Service 1d8f1c
                m_settings_emoji.get_int("partial-match-condition"));
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void set_load_emoji_at_startup() {
Packit Service 1d8f1c
        m_load_emoji_at_startup =
Packit Service 1d8f1c
            m_settings_emoji.get_boolean("load-emoji-at-startup");
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void set_load_unicode_at_startup() {
Packit Service 1d8f1c
        m_load_unicode_at_startup =
Packit Service 1d8f1c
            m_settings_emoji.get_boolean("load-unicode-at-startup");
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public void load_settings() {
Packit Service 1d8f1c
Packit Service 1d8f1c
        set_emoji_hotkey();
Packit Service 1d8f1c
        set_load_emoji_at_startup();
Packit Service 1d8f1c
        set_load_unicode_at_startup();
Packit Service 1d8f1c
        BindingCommon.set_custom_font(m_settings_panel,
Packit Service 1d8f1c
                                      m_settings_emoji,
Packit Service 1d8f1c
                                      ref m_css_provider);
Packit Service 1d8f1c
        set_emoji_favorites();
Packit Service 1d8f1c
        if (m_load_emoji_at_startup && !m_loaded_emoji)
Packit Service 1d8f1c
            set_emoji_lang();
Packit Service 1d8f1c
        set_emoji_partial_match();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    /**
Packit Service 1d8f1c
     * disconnect_signals:
Packit Service 1d8f1c
     *
Packit Service 1d8f1c
     * Call this API before m_panel = null so that the ref_count becomes 0
Packit Service 1d8f1c
     */
Packit Service 1d8f1c
    public void disconnect_signals() {
Packit Service 1d8f1c
        if (m_emojier_set_emoji_lang_id > 0) {
Packit Service 1d8f1c
            GLib.Source.remove(m_emojier_set_emoji_lang_id);
Packit Service 1d8f1c
            m_emojier_set_emoji_lang_id = 0;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (m_emojier != null) {
Packit Service 1d8f1c
            m_application.remove_window(m_emojier);
Packit Service 1d8f1c
            m_emojier = null;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        m_application = null;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
rpm-build 0a7332
    private void commit_text_update_favorites(IBus.Text text,
rpm-build 0a7332
                                              bool      disable_extension) {
Packit Service 1d8f1c
        commit_text(text);
rpm-build 0a7332
rpm-build 0a7332
        // If disable_extension is false, the extension event is already
rpm-build 0a7332
        // sent before the focus-in is received.
rpm-build 0a7332
        if (disable_extension) {
rpm-build 0a7332
            IBus.ExtensionEvent event = new IBus.ExtensionEvent(
Packit Service 1d8f1c
                    "name", m_extension_name,
Packit Service 1d8f1c
                    "is-enabled", false,
Packit Service 1d8f1c
                    "is-extension", true);
rpm-build 0a7332
            panel_extension(event);
rpm-build 0a7332
        }
Packit Service 1d8f1c
        string committed_string = text.text;
Packit Service 1d8f1c
        string preedit_string = m_preedit.get_text();
Packit Service 1d8f1c
        m_preedit.hide();
Packit Service 1d8f1c
        if (preedit_string == committed_string)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        bool has_favorite = false;
Packit Service 1d8f1c
        foreach (unowned string favorite in m_emojier_favorites) {
Packit Service 1d8f1c
            if (favorite == committed_string) {
Packit Service 1d8f1c
                has_favorite = true;
Packit Service 1d8f1c
                break;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (!has_favorite) {
Packit Service 1d8f1c
            m_emojier_favorites += committed_string;
Packit Service 1d8f1c
            m_settings_emoji.set_strv("favorites", m_emojier_favorites);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool emojier_focus_commit_real() {
Packit Service 1d8f1c
        if (m_emojier == null)
Packit Service 1d8f1c
            return true;
Packit Service 1d8f1c
        string selected_string = m_emojier.get_selected_string();
Packit Service 1d8f1c
        string prev_context_path = m_emojier.get_input_context_path();
Packit Service 1d8f1c
        if (selected_string != null &&
Packit Service 1d8f1c
            prev_context_path != "" &&
Packit Service 1d8f1c
            prev_context_path == m_current_context_path) {
Packit Service 1d8f1c
            IBus.Text text = new IBus.Text.from_string(selected_string);
rpm-build 0a7332
            commit_text_update_favorites(text, false);
Packit Service 1d8f1c
            m_emojier.reset();
Packit Service 1d8f1c
            return true;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
Packit Service 1d8f1c
        return false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void emojier_focus_commit() {
Packit Service 1d8f1c
        if (m_emojier == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        string selected_string = m_emojier.get_selected_string();
Packit Service 1d8f1c
        string prev_context_path = m_emojier.get_input_context_path();
Packit Service 1d8f1c
        if (selected_string == null &&
Packit Service 1d8f1c
            prev_context_path != "") {
Packit Service 1d8f1c
            var context = GLib.MainContext.default();
Packit Service 1d8f1c
            if (m_emojier_focus_commit_text_id > 0 &&
Packit Service 1d8f1c
                context.find_source_by_id(m_emojier_focus_commit_text_id)
Packit Service 1d8f1c
                        != null) {
Packit Service 1d8f1c
                GLib.Source.remove(m_emojier_focus_commit_text_id);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            m_emojier_focus_commit_text_id = GLib.Timeout.add(100, () => {
Packit Service 1d8f1c
                // focus_in is comming before switcher returns
Packit Service 1d8f1c
                emojier_focus_commit_real();
Packit Service 1d8f1c
                m_emojier_focus_commit_text_id = -1;
Packit Service 1d8f1c
                return false;
Packit Service 1d8f1c
            });
Packit Service 1d8f1c
        } else {
Packit Service 1d8f1c
            if (emojier_focus_commit_real()) {
Packit Service 1d8f1c
                var context = GLib.MainContext.default();
Packit Service 1d8f1c
                if (m_emojier_focus_commit_text_id > 0 &&
Packit Service 1d8f1c
                    context.find_source_by_id(m_emojier_focus_commit_text_id)
Packit Service 1d8f1c
                            != null) {
Packit Service 1d8f1c
                    GLib.Source.remove(m_emojier_focus_commit_text_id);
Packit Service 1d8f1c
                }
Packit Service 1d8f1c
                m_emojier_focus_commit_text_id = -1;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool key_press_escape() {
Packit Service 1d8f1c
        if (is_emoji_lookup_table()) {
Packit Service 1d8f1c
            bool show_candidate = m_emojier.key_press_escape();
Packit Service 1d8f1c
            convert_preedit_text();
Packit Service 1d8f1c
            return show_candidate;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (m_preedit.get_emoji() != "") {
Packit Service 1d8f1c
            m_preedit.set_emoji("");
Packit Service 1d8f1c
            string annotation = m_preedit.get_text();
Packit Service 1d8f1c
            m_emojier.set_annotation(annotation);
Packit Service 1d8f1c
            return false;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        m_enable_extension = false;
Packit Service 1d8f1c
        hide_emoji_lookup_table();
Packit Service 1d8f1c
        m_preedit.hide();
Packit Service 1d8f1c
        IBus.ExtensionEvent event = new IBus.ExtensionEvent(
Packit Service 1d8f1c
                "name", m_extension_name,
Packit Service 1d8f1c
                "is-enabled", false,
Packit Service 1d8f1c
                "is-extension", true);
Packit Service 1d8f1c
        panel_extension(event);
Packit Service 1d8f1c
        return false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
rpm-build 0a7332
    private bool key_press_keyval(uint keyval) {
rpm-build 0a7332
        unichar ch = IBus.keyval_to_unicode(keyval);
rpm-build 0a7332
        if (ch.iscntrl())
rpm-build 0a7332
                return false;
rpm-build 0a7332
        string str = ch.to_string();
rpm-build 0a7332
        m_preedit.append_text(str);
rpm-build 0a7332
        string annotation = m_preedit.get_text();
rpm-build 0a7332
        m_emojier.set_annotation(annotation);
rpm-build 0a7332
        m_preedit.set_emoji("");
rpm-build 0a7332
        return true;
rpm-build 0a7332
    }
rpm-build 0a7332
rpm-build 0a7332
Packit Service 1d8f1c
    private bool key_press_enter() {
Packit Service 1d8f1c
        if (m_extension_name != "unicode" && is_emoji_lookup_table()) {
Packit Service 1d8f1c
            // Check if variats exist
rpm-build 0a7332
            if (m_emojier.key_press_enter(false)) {
Packit Service 1d8f1c
                convert_preedit_text();
Packit Service 1d8f1c
                return true;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        IBus.Text text = m_preedit.get_commit_text();
rpm-build 0a7332
        commit_text_update_favorites(text, true);
Packit Service 1d8f1c
        return false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void convert_preedit_text() {
Packit Service 1d8f1c
        if (m_emojier.get_number_of_candidates() > 0)
Packit Service 1d8f1c
            m_preedit.set_emoji(m_emojier.get_current_candidate());
Packit Service 1d8f1c
        else
Packit Service 1d8f1c
            m_preedit.set_emoji("");
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool key_press_space() {
Packit Service 1d8f1c
        bool show_candidate = false;
Packit Service 1d8f1c
        if (m_preedit.get_emoji() != "") {
Packit Service 1d8f1c
            m_emojier.key_press_cursor_horizontal(Gdk.Key.Right, 0);
Packit Service 1d8f1c
            show_candidate = true;
Packit Service 1d8f1c
        } else {
Packit Service 1d8f1c
            string annotation = m_preedit.get_text();
Packit Service 1d8f1c
            if (annotation.length == 0) {
Packit Service 1d8f1c
                show_candidate = true;
Packit Service 1d8f1c
                if (is_emoji_lookup_table())
Packit Service 1d8f1c
                    m_emojier.key_press_cursor_horizontal(Gdk.Key.Right, 0);
Packit Service 1d8f1c
            } else {
Packit Service 1d8f1c
                m_emojier.set_annotation(annotation);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        convert_preedit_text();
Packit Service 1d8f1c
        return show_candidate;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool key_press_cursor_horizontal(uint keyval,
Packit Service 1d8f1c
                                             uint modifiers) {
Packit Service 1d8f1c
        if (is_emoji_lookup_table()) {
Packit Service 1d8f1c
            m_emojier.key_press_cursor_horizontal(keyval, modifiers);
Packit Service 1d8f1c
            convert_preedit_text();
Packit Service 1d8f1c
            return true;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        return false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool key_press_cursor_vertical(uint keyval,
Packit Service 1d8f1c
                                           uint modifiers) {
Packit Service 1d8f1c
        if (is_emoji_lookup_table()) {
Packit Service 1d8f1c
            m_emojier.key_press_cursor_vertical(keyval, modifiers);
Packit Service 1d8f1c
            convert_preedit_text();
Packit Service 1d8f1c
            return true;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        return false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool key_press_cursor_home_end(uint keyval,
Packit Service 1d8f1c
                                           uint modifiers) {
Packit Service 1d8f1c
        if (is_emoji_lookup_table()) {
Packit Service 1d8f1c
            m_emojier.key_press_cursor_home_end(keyval, modifiers);
Packit Service 1d8f1c
            convert_preedit_text();
Packit Service 1d8f1c
            return true;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        return false;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool key_press_control_keyval(uint keyval,
Packit Service 1d8f1c
                                          uint modifiers) {
Packit Service 1d8f1c
        bool show_candidate = false;
Packit Service 1d8f1c
        switch(keyval) {
Packit Service 1d8f1c
        case Gdk.Key.f:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_horizontal(Gdk.Key.Right,
Packit Service 1d8f1c
                                                         modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.b:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_horizontal(Gdk.Key.Left,
Packit Service 1d8f1c
                                                         modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.n:
Packit Service 1d8f1c
        case Gdk.Key.N:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_vertical(Gdk.Key.Down, modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.p:
Packit Service 1d8f1c
        case Gdk.Key.P:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_vertical(Gdk.Key.Up, modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.h:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_home_end(Gdk.Key.Home, modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.e:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_home_end(Gdk.Key.End, modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.u:
Packit Service 1d8f1c
            m_preedit.reset();
Packit Service 1d8f1c
            m_emojier.set_annotation("");
Packit Service 1d8f1c
            hide_emoji_lookup_table();
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.C:
Packit Service 1d8f1c
        case Gdk.Key.c:
Packit Service 1d8f1c
            if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
Packit Service 1d8f1c
                if (!m_is_wayland && m_emojier != null &&
Packit Service 1d8f1c
                    m_emojier.get_number_of_candidates() > 0) {
Packit Service 1d8f1c
                    var text = m_emojier.get_current_candidate();
Packit Service 1d8f1c
                    Gtk.Clipboard clipboard =
Packit Service 1d8f1c
                            Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
Packit Service 1d8f1c
                    clipboard.set_text(text, -1);
Packit Service 1d8f1c
                    clipboard.store();
Packit Service 1d8f1c
                }
Packit Service 1d8f1c
                show_candidate = is_emoji_lookup_table();
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        default:
Packit Service 1d8f1c
            show_candidate = is_emoji_lookup_table();
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        return show_candidate;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void hide_wayland_lookup_table() {
Packit Service 1d8f1c
        m_wayland_lookup_table_is_visible = false;
Packit Service 1d8f1c
        var text = new IBus.Text.from_string("");
Packit Service 1d8f1c
        update_auxiliary_text_received(text, false);
Packit Service 1d8f1c
        update_lookup_table_received(
Packit Service 1d8f1c
                new IBus.LookupTable(1, 0, false, true),
Packit Service 1d8f1c
                false);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void show_wayland_lookup_table(IBus.Text text) {
Packit Service 1d8f1c
        m_wayland_lookup_table_is_visible = true;
Packit Service 1d8f1c
        var table = m_emojier.get_one_dimension_lookup_table();
Packit Service 1d8f1c
        uint ncandidates = table.get_number_of_candidates();
Packit Service 1d8f1c
        update_auxiliary_text_received(
Packit Service 1d8f1c
                text,
Packit Service 1d8f1c
                ncandidates > 0 ? true : false);
Packit Service 1d8f1c
        update_lookup_table_received(
Packit Service 1d8f1c
                table,
Packit Service 1d8f1c
                ncandidates > 0 ? true : false);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void hide_emoji_lookup_table() {
Packit Service 1d8f1c
        if (m_emojier == null)
Packit Service 1d8f1c
            return;
rpm-build 0a7332
        if (m_wayland_lookup_table_is_visible)
Packit Service 1d8f1c
            hide_wayland_lookup_table();
Packit Service 1d8f1c
        else
Packit Service 1d8f1c
            m_emojier.hide();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void show_emoji_lookup_table() {
Packit Service 1d8f1c
        /* Emojier category_list is shown in both Xorg and Wayland
Packit Service 1d8f1c
         * because the annotation information is useful but the Wayland lookup
Packit Service 1d8f1c
         * window is alway one dimension. So the category_list is shown
Packit Service 1d8f1c
         * when the user annotation is null.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        if (m_is_wayland && m_preedit.get_text() != "") {
Packit Service 1d8f1c
            var text = m_emojier.get_title_text();
Packit Service 1d8f1c
            show_wayland_lookup_table(text);
Packit Service 1d8f1c
        } else {
Packit Service 1d8f1c
            // POPUP window takes the focus in Wayland.
Packit Service 1d8f1c
            if (m_is_wayland)
Packit Service 1d8f1c
                m_emojier.set_input_context_path(m_real_current_context_path);
Packit Service 1d8f1c
            m_emojier.show_all();
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private bool is_emoji_lookup_table() {
Packit Service 1d8f1c
        if (m_is_wayland)
rpm-build 0a7332
            return m_wayland_lookup_table_is_visible;
Packit Service 1d8f1c
        else
Packit Service 1d8f1c
            return m_emojier.get_visible();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    private void show_preedit_and_candidate(bool show_candidate) {
Packit Service 1d8f1c
        uint cursor_pos = 0;
Packit Service 1d8f1c
        if (!show_candidate)
Packit Service 1d8f1c
            cursor_pos = m_preedit.get_engine_preedit_cursor_pos();
Packit Service 1d8f1c
        update_preedit_text_received(
Packit Service 1d8f1c
                m_preedit.get_engine_preedit_text(),
Packit Service 1d8f1c
                cursor_pos,
Packit Service 1d8f1c
                true);
Packit Service 1d8f1c
        if (!show_candidate) {
Packit Service 1d8f1c
            hide_emoji_lookup_table();
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (m_emojier == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        /* Wayland gives the focus on Emojir which is a GTK popup window
Packit Service 1d8f1c
         * and move the focus fom the current input context to Emojier.
Packit Service 1d8f1c
         * This forwards the lookup table to gnome-shell's lookup table
Packit Service 1d8f1c
         * but it enables one dimension lookup table only.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        show_emoji_lookup_table();
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void focus_in(string input_context_path) {
Packit Service 1d8f1c
        m_current_context_path = input_context_path;
Packit Service 1d8f1c
Packit Service 1d8f1c
        /* 'fake' input context is named as 
Packit Service 1d8f1c
         * '/org/freedesktop/IBus/InputContext_1' and always send in
Packit Service 1d8f1c
         * focus-out events by ibus-daemon for the global engine mode.
Packit Service 1d8f1c
         * Now ibus-daemon assumes to always use the global engine.
Packit Service 1d8f1c
         * But this event should not be used for modal dialogs
Packit Service 1d8f1c
         * such as Switcher.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        if (!input_context_path.has_suffix("InputContext_1")) {
Packit Service 1d8f1c
            m_real_current_context_path = m_current_context_path;
rpm-build 0a7332
            if (m_is_wayland)
rpm-build 0a7332
                this.emojier_focus_commit();
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void focus_out(string input_context_path) {
Packit Service 1d8f1c
        m_current_context_path = "";
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void panel_extension_received(IBus.ExtensionEvent event) {
Packit Service 1d8f1c
        m_extension_name = event.get_name();
Packit Service 1d8f1c
        if (m_extension_name != "emoji" && m_extension_name != "unicode") {
Packit Service 1d8f1c
            string format = "The name %s is not implemented in PanelExtension";
Packit Service 1d8f1c
            warning (format.printf(m_extension_name));
Packit Service 1d8f1c
            m_extension_name = "";
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        m_enable_extension = event.is_enabled;
Packit Service 1d8f1c
        if (!m_enable_extension) {
Packit Service 1d8f1c
            hide_emoji_lookup_table();
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (!m_loaded_emoji)
Packit Service 1d8f1c
            set_emoji_lang();
Packit Service 1d8f1c
        if (!m_loaded_unicode && m_loaded_emoji) {
Packit Service 1d8f1c
            IBusEmojier.load_unicode_dict();
Packit Service 1d8f1c
            m_loaded_unicode = true;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (m_emojier == null) {
Packit Service 1d8f1c
            m_emojier = new IBusEmojier();
Packit Service 1d8f1c
            // For title handling in gnome-shell
Packit Service 1d8f1c
            m_application.add_window(m_emojier);
Packit Service 1d8f1c
            m_emojier.candidate_clicked.connect((i, b, s) => {
rpm-build 0a7332
                candidate_clicked_lookup_table_real(i, b, s, true);
rpm-build 0a7332
            });
rpm-build 0a7332
            m_emojier.commit_text.connect((s) => {
Packit Service 1d8f1c
                if (!m_is_wayland)
rpm-build 0a7332
                    return;
rpm-build 0a7332
                // Currently emojier has a focus but the text input focus
rpm-build 0a7332
                // does not and commit the text later.
rpm-build 0a7332
                IBus.ExtensionEvent close_event = new IBus.ExtensionEvent(
rpm-build 0a7332
                        "name", m_extension_name,
rpm-build 0a7332
                        "is-enabled", false,
rpm-build 0a7332
                        "is-extension", true);
rpm-build 0a7332
                panel_extension(close_event);
Packit Service 1d8f1c
            });
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        m_emojier.reset();
Packit Service 1d8f1c
        m_emojier.set_annotation("");
Packit Service 1d8f1c
        m_preedit.set_extension_name(m_extension_name);
Packit Service 1d8f1c
        m_preedit.reset();
Packit Service 1d8f1c
        update_preedit_text_received(
Packit Service 1d8f1c
                m_preedit.get_engine_preedit_text(),
Packit Service 1d8f1c
                m_preedit.get_engine_preedit_cursor_pos(),
Packit Service 1d8f1c
                true);
Packit Service 1d8f1c
        string params = event.get_params();
Packit Service 1d8f1c
        if (params == "category-list") {
Packit Service 1d8f1c
            key_press_space();
Packit Service 1d8f1c
            show_preedit_and_candidate(true);
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void set_cursor_location(int x,
Packit Service 1d8f1c
                                             int y,
Packit Service 1d8f1c
                                             int width,
Packit Service 1d8f1c
                                             int height) {
Packit Service 1d8f1c
        if (m_emojier != null)
Packit Service 1d8f1c
            m_emojier.set_cursor_location(x, y, width, height);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void update_preedit_text(IBus.Text text,
Packit Service 1d8f1c
                                             uint      cursor_pos,
Packit Service 1d8f1c
                                             bool      visible) {
Packit Service 1d8f1c
        m_preedit.set_engine_preedit_text(text);
Packit Service 1d8f1c
        if (visible)
Packit Service 1d8f1c
            m_preedit.show_engine_preedit_text();
Packit Service 1d8f1c
        else
Packit Service 1d8f1c
            m_preedit.hide_engine_preedit_text();
Packit Service 1d8f1c
        m_preedit.set_engine_preedit_cursor_pos(cursor_pos);
Packit Service 1d8f1c
        update_preedit_text_received(m_preedit.get_engine_preedit_text(),
Packit Service 1d8f1c
                                     m_preedit.get_engine_preedit_cursor_pos(),
Packit Service 1d8f1c
                                     visible);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void show_preedit_text() {
Packit Service 1d8f1c
        m_preedit.show_engine_preedit_text();
Packit Service 1d8f1c
        show_preedit_and_candidate(false);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void hide_preedit_text() {
Packit Service 1d8f1c
        m_preedit.hide_engine_preedit_text();
Packit Service 1d8f1c
        show_preedit_and_candidate(false);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override bool process_key_event(uint keyval,
Packit Service 1d8f1c
                                           uint keycode,
Packit Service 1d8f1c
                                           uint state) {
Packit Service 1d8f1c
        if ((state & IBus.ModifierType.RELEASE_MASK) != 0)
Packit Service 1d8f1c
            return false;
Packit Service 1d8f1c
        uint modifiers = state;
Packit Service 1d8f1c
        bool show_candidate = false;
Packit Service 1d8f1c
        switch(keyval) {
Packit Service 1d8f1c
        case Gdk.Key.Escape:
Packit Service 1d8f1c
            show_candidate = key_press_escape();
Packit Service 1d8f1c
            if (!m_preedit.is_shown())
Packit Service 1d8f1c
                return true;
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Return:
Packit Service 1d8f1c
        case Gdk.Key.KP_Enter:
Packit Service 1d8f1c
            if (m_extension_name == "unicode")
Packit Service 1d8f1c
                key_press_space();
Packit Service 1d8f1c
            show_candidate = key_press_enter();
Packit Service 1d8f1c
            if (!m_preedit.is_shown()) {
Packit Service 1d8f1c
                hide_emoji_lookup_table();
Packit Service 1d8f1c
                return true;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.BackSpace:
Packit Service 1d8f1c
            m_preedit.backspace();
Packit Service 1d8f1c
            string annotation = m_preedit.get_text();
Packit Service 1d8f1c
            if (annotation == "" && m_extension_name == "unicode") {
Packit Service 1d8f1c
                key_press_escape();
Packit Service 1d8f1c
                return true;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            m_emojier.set_annotation(annotation);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.space:
Packit Service 1d8f1c
        case Gdk.Key.KP_Space:
rpm-build 0a7332
            if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
rpm-build 0a7332
                if (!key_press_keyval(keyval))
rpm-build 0a7332
                    return true;
rpm-build 0a7332
                show_candidate = is_emoji_lookup_table();
rpm-build 0a7332
                break;
rpm-build 0a7332
            }
Packit Service 1d8f1c
            show_candidate = key_press_space();
Packit Service 1d8f1c
            if (m_extension_name == "unicode") {
Packit Service 1d8f1c
                key_press_enter();
Packit Service 1d8f1c
                return true;
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Right:
Packit Service 1d8f1c
        case Gdk.Key.KP_Right:
Packit Service 1d8f1c
            /* one dimension in Wayland, two dimensions in X11 */
Packit Service 1d8f1c
            if (m_is_wayland) {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Down,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            } else {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_horizontal(Gdk.Key.Right,
Packit Service 1d8f1c
                                                             modifiers);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Left:
Packit Service 1d8f1c
        case Gdk.Key.KP_Left:
Packit Service 1d8f1c
            if (m_is_wayland) {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Up,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            } else {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_horizontal(Gdk.Key.Left,
Packit Service 1d8f1c
                                                             modifiers);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Down:
Packit Service 1d8f1c
        case Gdk.Key.KP_Down:
Packit Service 1d8f1c
            if (m_is_wayland) {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_horizontal(Gdk.Key.Right,
Packit Service 1d8f1c
                                                             modifiers);
Packit Service 1d8f1c
            } else {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Down,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Up:
Packit Service 1d8f1c
        case Gdk.Key.KP_Up:
Packit Service 1d8f1c
            if (m_is_wayland) {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_horizontal(Gdk.Key.Left,
Packit Service 1d8f1c
                                                             modifiers);
Packit Service 1d8f1c
            } else {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Up,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Page_Down:
Packit Service 1d8f1c
        case Gdk.Key.KP_Page_Down:
Packit Service 1d8f1c
            if (m_is_wayland) {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Down,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            } else {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Page_Down,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Page_Up:
Packit Service 1d8f1c
        case Gdk.Key.KP_Page_Up:
Packit Service 1d8f1c
            if (m_is_wayland) {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Up,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            } else {
Packit Service 1d8f1c
                show_candidate = key_press_cursor_vertical(Gdk.Key.Page_Up,
Packit Service 1d8f1c
                                                           modifiers);
Packit Service 1d8f1c
            }
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.Home:
Packit Service 1d8f1c
        case Gdk.Key.KP_Home:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_home_end(Gdk.Key.Home, modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        case Gdk.Key.End:
Packit Service 1d8f1c
        case Gdk.Key.KP_End:
Packit Service 1d8f1c
            show_candidate = key_press_cursor_home_end(Gdk.Key.End, modifiers);
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        default:
Packit Service 1d8f1c
            if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
Packit Service 1d8f1c
                show_candidate = key_press_control_keyval(keyval, modifiers);
Packit Service 1d8f1c
                break;
Packit Service 1d8f1c
            }
rpm-build 0a7332
            if (!key_press_keyval(keyval))
Packit Service 1d8f1c
                return true;
Packit Service 1d8f1c
            show_candidate = is_emoji_lookup_table();
Packit Service 1d8f1c
            break;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        show_preedit_and_candidate(show_candidate);
Packit Service 1d8f1c
        return true;
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void commit_text_received(IBus.Text text) {
Packit Service 1d8f1c
        unowned string? str = text.text;
Packit Service 1d8f1c
        if (str == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        /* Do not call convert_preedit_text() because it depends on
Packit Service 1d8f1c
         * each IME whether process_key_event() receives Shift-space or not.
Packit Service 1d8f1c
         */
Packit Service 1d8f1c
        m_preedit.append_text(str);
Packit Service 1d8f1c
        m_preedit.set_emoji("");
Packit Service 1d8f1c
        string annotation = m_preedit.get_text();
Packit Service 1d8f1c
        m_emojier.set_annotation(annotation);
Packit Service 1d8f1c
        show_preedit_and_candidate(false);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void page_up_lookup_table() {
Packit Service 1d8f1c
        bool show_candidate = key_press_cursor_vertical(Gdk.Key.Up, 0);
Packit Service 1d8f1c
        show_preedit_and_candidate(show_candidate);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void page_down_lookup_table() {
Packit Service 1d8f1c
        bool show_candidate = key_press_cursor_vertical(Gdk.Key.Down, 0);
Packit Service 1d8f1c
        show_preedit_and_candidate(show_candidate);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void cursor_up_lookup_table() {
Packit Service 1d8f1c
        bool show_candidate = key_press_cursor_horizontal(Gdk.Key.Left, 0);
Packit Service 1d8f1c
        show_preedit_and_candidate(show_candidate);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
Packit Service 1d8f1c
    public override void cursor_down_lookup_table() {
Packit Service 1d8f1c
        bool show_candidate = key_press_cursor_horizontal(Gdk.Key.Right, 0);
Packit Service 1d8f1c
        show_preedit_and_candidate(show_candidate);
Packit Service 1d8f1c
    }
Packit Service 1d8f1c
rpm-build 0a7332
    private void candidate_clicked_lookup_table_real(uint index,
rpm-build 0a7332
                                                     uint button,
rpm-build 0a7332
                                                     uint state,
rpm-build 0a7332
                                                     bool is_emojier) {
Packit Service 1d8f1c
        if (button == IBusEmojier.BUTTON_CLOSE_BUTTON) {
Packit Service 1d8f1c
            m_enable_extension = false;
Packit Service 1d8f1c
            hide_emoji_lookup_table();
Packit Service 1d8f1c
            m_preedit.hide();
Packit Service 1d8f1c
            IBus.ExtensionEvent event = new IBus.ExtensionEvent(
Packit Service 1d8f1c
                    "name", m_extension_name,
Packit Service 1d8f1c
                    "is-enabled", false,
Packit Service 1d8f1c
                    "is-extension", true);
Packit Service 1d8f1c
            panel_extension(event);
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (m_emojier == null)
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        bool show_candidate = false;
Packit Service 1d8f1c
        uint ncandidates = m_emojier.get_number_of_candidates();
Packit Service 1d8f1c
        if (ncandidates > 0 && ncandidates >= index) {
Packit Service 1d8f1c
            m_emojier.set_cursor_pos(index);
rpm-build 0a7332
            bool need_commit_signal = m_is_wayland && is_emojier;
rpm-build 0a7332
            show_candidate = m_emojier.has_variants(index, need_commit_signal);
rpm-build 0a7332
            if (!m_is_wayland)
rpm-build 0a7332
                m_preedit.set_emoji(m_emojier.get_current_candidate());
Packit Service 1d8f1c
        } else {
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        if (!show_candidate) {
Packit Service 1d8f1c
            IBus.Text text = m_preedit.get_commit_text();
Packit Service 1d8f1c
            hide_emoji_lookup_table();
rpm-build 0a7332
            if (!is_emojier || !m_is_wayland)
rpm-build 0a7332
                commit_text_update_favorites(text, true);
Packit Service 1d8f1c
            return;
Packit Service 1d8f1c
        }
Packit Service 1d8f1c
        show_preedit_and_candidate(show_candidate);
Packit Service 1d8f1c
    }
rpm-build 0a7332
rpm-build 0a7332
    public override void candidate_clicked_lookup_table(uint index,
rpm-build 0a7332
                                                        uint button,
rpm-build 0a7332
                                                        uint state) {
rpm-build 0a7332
        candidate_clicked_lookup_table_real(index, button, state, false);
rpm-build 0a7332
    }
Packit Service 1d8f1c
}