Resolves: #1942970 Clear Emoijer preedit/lookup popup between applications

This commit is contained in:
Takao Fujiwara 2021-10-29 13:34:00 +09:00
parent bcef7391cc
commit 7bcd5b5547
2 changed files with 272 additions and 1 deletions

View File

@ -423,3 +423,271 @@ index 00000000..fa0c9b40
--
2.28.0
From acc5570511698c7b5cc037eb81be2c4be52a824f Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
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 <takao.fujiwara1@gmail.com>
+ * Copyright (c) 2017-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
*
* 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 <alexepico@gmail.com>
- * Copyright (c) 2017-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (c) 2017-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
*
* 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 <shawn.p.huang@gmail.com>
- * Copyright(c) 2018-2020 Takao Fujwiara <takao.fujiwara1@gmail.com>
+ * Copyright(c) 2018-2021 Takao Fujwiara <takao.fujiwara1@gmail.com>
*
* 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

View File

@ -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 <tfujiwar@redhat.com> - 1.5.25-5
- Resolves: #1942970 Clear Emoijer preedit/lookup popup between applications
* Mon Sep 06 2021 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.25-4
- Clear preedit with mouse click and GTK4 applications