summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfujiwarat <takao.fujiwara1@gmail.com>2021-10-29 12:56:49 +0900
committerfujiwarat <takao.fujiwara1@gmail.com>2021-10-29 12:56:49 +0900
commitacc5570511698c7b5cc037eb81be2c4be52a824f (patch)
treee67083ebef87750359427844fe8a5f8a5c5e7ef9
parent51e3295659dd9178b98fb266da5abcb750805be8 (diff)
downloadibus-acc5570511698c7b5cc037eb81be2c4be52a824f.tar.gz
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
-rw-r--r--ui/gtk3/emojier.vala69
-rw-r--r--ui/gtk3/emojierapp.vala12
-rw-r--r--ui/gtk3/panelbinding.vala21
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) => {