diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index 4e987de..f249ec4 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -423,3 +423,271 @@ index 00000000..fa0c9b40 -- 2.28.0 +From acc5570511698c7b5cc037eb81be2c4be52a824f Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 29 Oct 2021 12:56:49 +0900 +Subject: [PATCH] ui/gtk3: Erase Emojier preedit/lookup popup between + applications + +It would be better to erase Emojier popup window when users change +the input focus between applications. But it hasn't been implemented +because the focus-out/in events also happen when the Emojier popup window +is launching or rebuilding to the category list in GNOME Wayland. +The focus-out/in events do not happen in Xorg desktops with the rebuilding +GUI because GTK popup window causes focus-in/out evnets in Wayland. + +Now I'm convinced with several issues and added a little complicated logic +to erase Emojier popup window with the focus changes between input contexts +to handle focus-in/out events in Wayland. + +BUG=rhbz#1942970 +--- + ui/gtk3/emojier.vala | 69 ++++++++++++++++++++++++++++++++++++--- + ui/gtk3/emojierapp.vala | 12 +++++-- + ui/gtk3/panelbinding.vala | 21 ++++++++++-- + 3 files changed, 94 insertions(+), 8 deletions(-) + +diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala +index 9e6e9263..69fb8abe 100644 +--- a/ui/gtk3/emojier.vala ++++ b/ui/gtk3/emojier.vala +@@ -2,7 +2,7 @@ + * + * ibus - The Input Bus + * +- * Copyright (c) 2017-2019 Takao Fujiwara ++ * Copyright (c) 2017-2021 Takao Fujiwara + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -227,6 +227,8 @@ public class IBusEmojier : Gtk.ApplicationWindow { + BACKWARD, + } + ++ public bool is_wayland { get; set; } ++ + public const uint BUTTON_CLOSE_BUTTON = 1000; + + private const uint EMOJI_GRID_PAGE = 10; +@@ -317,15 +319,18 @@ public class IBusEmojier : Gtk.ApplicationWindow { + private Gdk.Rectangle m_cursor_location; + private bool m_is_up_side_down = false; + private uint m_redraw_window_id; ++ private bool m_rebuilding_gui = false; ++ private uint m_rebuilding_gui_timeout_id; + + public signal void candidate_clicked(uint index, uint button, uint state); + public signal void commit_text(string text); + public signal void cancel(); + +- public IBusEmojier() { ++ public IBusEmojier(bool is_wayland) { + GLib.Object( + type : Gtk.WindowType.POPUP + ); ++ this.is_wayland = is_wayland; + + // GLib.ActionEntry accepts const variables only. + var action = new GLib.SimpleAction.stateful( +@@ -1002,6 +1007,7 @@ public class IBusEmojier : Gtk.ApplicationWindow { + button.button_press_event.connect((w, e) => { + m_category_active_index = -1; + m_show_unicode = false; ++ start_rebuild_gui(false); + hide_candidate_panel(); + show_all(); + return true; +@@ -1458,6 +1464,7 @@ public class IBusEmojier : Gtk.ApplicationWindow { + show_emoji_for_category(m_backward); + show_candidate_panel(); + } else { ++ start_rebuild_gui(false); + hide_candidate_panel(); + show_all(); + } +@@ -1778,6 +1785,34 @@ public class IBusEmojier : Gtk.ApplicationWindow { + } + + ++ private void start_rebuild_gui(bool initial_launching) { ++ if (!this.is_wayland) ++ return; ++ if (!initial_launching && !base.get_visible()) ++ return; ++ if (initial_launching && base.get_visible()) ++ return; ++ if (m_rebuilding_gui_timeout_id != 0) { ++ GLib.Source.remove(m_rebuilding_gui_timeout_id); ++ m_rebuilding_gui_timeout_id = 0; ++ } ++ ++ m_rebuilding_gui = true; ++ m_rebuilding_gui_timeout_id = ++ GLib.Timeout.add_seconds(10, () => { ++ if (!m_rebuilding_gui) { ++ m_rebuilding_gui_timeout_id = 0; ++ return false; ++ } ++ warning("Rebuilding GUI is time out."); ++ m_rebuilding_gui = false; ++ m_rebuilding_gui_timeout_id = 0; ++ return false; ++ }, ++ GLib.Priority.DEFAULT_IDLE); ++ } ++ ++ + public bool has_variants(uint index, + bool need_commit_signal) { + if (index >= m_lookup_table.get_number_of_candidates()) +@@ -1880,12 +1915,17 @@ public class IBusEmojier : Gtk.ApplicationWindow { + m_show_unicode = false; + m_category_active_index = -1; + } ++ start_rebuild_gui(false); + hide_candidate_panel(); + return true; + } else if (m_backward_index >= 0 && m_backward != null) { ++ // Escape on Emoji variants window does not call focus-out events ++ // because hide() is not called here so start_rebuild_gui() ++ // is not called. + show_emoji_for_category(m_backward); + return true; + } else if (m_candidate_panel_is_visible && m_backward != null) { ++ start_rebuild_gui(false); + hide_candidate_panel(); + return true; + } +@@ -2218,7 +2258,7 @@ public class IBusEmojier : Gtk.ApplicationWindow { + + /* Some window managers, e.g. MATE, GNOME, Plasma desktops, + * does not give the keyboard focus when Emojier is lauched +- * twice with Ctrl-Shift-e via XIEvent, if present_with_time() ++ * twice with Ctrl-period via XIEvent, if present_with_time() + * is not applied. + * But XFCE4 desktop does not effect this bug. + * Seems this is caused by the window manager's focus stealing +@@ -2265,8 +2305,10 @@ public class IBusEmojier : Gtk.ApplicationWindow { + #endif + + +- /* override virtual functions */ ++ // override virtual functions + public override void show_all() { ++ // Ctrl-period, space keys causes focus-out/in events in GNOME Wayland. ++ start_rebuild_gui(true); + base.show_all(); + if (m_candidate_panel_mode) + show_candidate_panel(); +@@ -2416,6 +2458,17 @@ public class IBusEmojier : Gtk.ApplicationWindow { + } + + ++ public override bool focus_in_event(Gdk.EventFocus event) { ++ m_rebuilding_gui = false; ++ return base.focus_in_event(event); ++ } ++ ++ ++ public override bool focus_out_event(Gdk.EventFocus event) { ++ return base.focus_out_event(event); ++ } ++ ++ + public bool is_running() { + return m_is_running; + } +@@ -2511,6 +2564,14 @@ public class IBusEmojier : Gtk.ApplicationWindow { + } + + ++ public bool is_rebuilding_gui() { ++ /* The candidate window and preedit text should not be closed ++ * when the GUI is rebuilding. ++ */ ++ return m_rebuilding_gui; ++ } ++ ++ + public static bool has_loaded_emoji_dict() { + if (m_emoji_to_data_dict == null) + return false; +diff --git a/ui/gtk3/emojierapp.vala b/ui/gtk3/emojierapp.vala +index 783c611c..812356f0 100644 +--- a/ui/gtk3/emojierapp.vala ++++ b/ui/gtk3/emojierapp.vala +@@ -3,7 +3,7 @@ + * ibus - The Input Bus + * + * Copyright (c) 2017 Peng Wu +- * Copyright (c) 2017-2019 Takao Fujiwara ++ * Copyright (c) 2017-2021 Takao Fujiwara + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -208,7 +208,15 @@ public class EmojiApplication : Gtk.Application { + IBusEmojier.load_unicode_dict(); + + if (m_emojier == null) { +- m_emojier = new IBusEmojier(); ++ bool is_wayland = false; ++#if USE_GDK_WAYLAND ++ Type instance_type = Gdk.Display.get_default().get_type(); ++ Type wayland_type = typeof(GdkWayland.Display); ++ is_wayland = instance_type.is_a(wayland_type); ++#else ++ warning("Checking Wayland is disabled"); ++#endif ++ m_emojier = new IBusEmojier(is_wayland); + // For title handling in gnome-shell + add_window(m_emojier); + m_emojier.candidate_clicked.connect((i, b, s) => { +diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala +index 861255b1..e63d93f2 100644 +--- a/ui/gtk3/panelbinding.vala ++++ b/ui/gtk3/panelbinding.vala +@@ -3,7 +3,7 @@ + * ibus - The Input Bus + * + * Copyright(c) 2018 Peng Huang +- * Copyright(c) 2018-2020 Takao Fujwiara ++ * Copyright(c) 2018-2021 Takao Fujwiara + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -799,6 +799,23 @@ class PanelBinding : IBus.PanelService { + + public override void focus_out(string input_context_path) { + m_current_context_path = ""; ++ /* Close emoji typing when the focus out happens but it's not a ++ * rebuilding GUI. ++ * Emojier rebuilding GUI happens when Escape key is pressed on ++ * Emojier candidate list and the rebuilding also causes focus-out/in ++ * events in GNOME Wayland but not Xorg desktops. ++ * The rebuilding GUI can be checked with m_emojier.is_rebuilding_gui() ++ * in Wayland. ++ * m_emojier.is_rebuilding_gui() always returns false in Xorg desktops ++ * since focus-out/in events does not happen. ++ */ ++ if (m_emojier != null && !m_emojier.is_rebuilding_gui()) { ++ m_preedit.reset(); ++ m_emojier.set_annotation(""); ++ if (m_wayland_lookup_table_is_visible) ++ hide_wayland_lookup_table(); ++ key_press_escape(); ++ } + } + + +@@ -822,7 +839,7 @@ class PanelBinding : IBus.PanelService { + m_loaded_unicode = true; + } + if (m_emojier == null) { +- m_emojier = new IBusEmojier(); ++ m_emojier = new IBusEmojier(m_is_wayland); + // For title handling in gnome-shell + m_application.add_window(m_emojier); + m_emojier.candidate_clicked.connect((i, b, s) => { +-- +2.28.0 + diff --git a/ibus.spec b/ibus.spec index d11a672..fc208c6 100644 --- a/ibus.spec +++ b/ibus.spec @@ -38,7 +38,7 @@ Name: ibus Version: 1.5.25 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ URL: https://github.com/ibus/%name/wiki @@ -512,6 +512,9 @@ dconf update || : %{_datadir}/installed-tests/ibus %changelog +* Fri Oct 29 2021 Takao Fujiwara - 1.5.25-5 +- Resolves: #1942970 Clear Emoijer preedit/lookup popup between applications + * Mon Sep 06 2021 Takao Fujiwara - 1.5.25-4 - Clear preedit with mouse click and GTK4 applications