public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ibus] autotool: Fix time lag of CandidatePanel in X11
@ 2026-05-31 2:08 Takao Fujiwara
0 siblings, 0 replies; only message in thread
From: Takao Fujiwara @ 2026-05-31 2:08 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/ibus
Branch : autotool
Commit : b17b2c5349ed16e3b5b7fc67ad7ec3b137102f32
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date : 2025-03-14T21:47:28+09:00
Stats : +419/-1 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/ibus/c/b17b2c5349ed16e3b5b7fc67ad7ec3b137102f32?branch=autotool
Log:
Fix time lag of CandidatePanel in X11
Fix infinite Return key in xterm with Wayalnd input-method protocol V2
---
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
index 310739c..eada3fc 100644
--- a/ibus-HEAD.patch
+++ b/ibus-HEAD.patch
@@ -127,3 +127,416 @@ index 20f89cef..fa15d2e7 100644
--
2.47.0
+From 5797150892317a30e37756ee62ae4fd644700dfc Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Fri, 14 Mar 2025 21:00:38 +0900
+Subject: [PATCH] ui/gtk3: Fix time lag of CandidatePanel in X11
+
+The timed `set_lookup_table()` is a workaround with the Wayland
+input-method protocol under the construction to stop the many D-Bus
+methods but it should not affect Xorg UI at least.
+
+Now `m_is_wayland flag` is inherited to the CandidatePanel and Switcher
+and add `m_first_set_lookup_table` flag newly to enhance the lag
+with the Wayland input-method protocol.
+
+Also fix compile warnings with `valac` in `xkblayout.vala`.
+
+Fixes: https://github.com/ibus/ibus/commit/d5e6e71
+BUG=https://github.com/ibus/ibus/issues/2740
+---
+ ui/gtk3/candidatepanel.vala | 63 ++++++++++++++++++++++++++++++++-----
+ ui/gtk3/panel.vala | 5 +--
+ ui/gtk3/switcher.vala | 25 ++++++++-------
+ ui/gtk3/xkblayout.vala | 34 ++++++++++----------
+ 4 files changed, 90 insertions(+), 37 deletions(-)
+
+diff --git a/ui/gtk3/candidatepanel.vala b/ui/gtk3/candidatepanel.vala
+index f2447703..5ba8cf36 100644
+--- a/ui/gtk3/candidatepanel.vala
++++ b/ui/gtk3/candidatepanel.vala
+@@ -36,9 +36,10 @@ public class CandidatePanel : Gtk.Box{
+
+ private Pango.Attribute m_language_attribute;
+ private uint m_update_id;
++ private bool m_is_wayland;
++ private bool m_no_wayland_panel;
+
+ #if USE_GDK_WAYLAND
+- private bool m_no_wayland_panel;
+ private bool m_hide_after_show;
+ private uint m_prev_page_size;
+ private uint m_prev_ncandidates;
+@@ -48,6 +49,7 @@ public class CandidatePanel : Gtk.Box{
+ private uint m_set_preedit_text_id;
+ private uint m_set_auxiliary_text_id;
+ private uint m_set_lookup_table_id;
++ private bool m_first_set_lookup_table;
+ #endif
+
+ public signal void cursor_up();
+@@ -64,7 +66,8 @@ public class CandidatePanel : Gtk.Box{
+ public signal void realize_surface(void *surface);
+ #endif
+
+- public CandidatePanel(bool no_wayland_panel) {
++ public CandidatePanel(bool is_wayland,
++ bool no_wayland_panel) {
+ // Call base class constructor
+ GLib.Object(
+ name : "IBusCandidate",
+@@ -72,9 +75,8 @@ public class CandidatePanel : Gtk.Box{
+ visible: true
+ );
+
+-#if USE_GDK_WAYLAND
++ m_is_wayland = is_wayland;
+ m_no_wayland_panel = no_wayland_panel;
+-#endif
+ m_toplevel = new Gtk.Window(Gtk.WindowType.POPUP);
+ m_toplevel.add_events(Gdk.EventMask.BUTTON_PRESS_MASK);
+ m_toplevel.button_press_event.connect((w, e) => {
+@@ -87,7 +89,7 @@ public class CandidatePanel : Gtk.Box{
+ adjust_window_position(w);
+ });
+ #if USE_GDK_WAYLAND
+- if (!BindingCommon.default_is_xdisplay()) {
++ if (m_is_wayland) {
+ m_toplevel.realize.connect((w) => {
+ realize_window(true);
+ });
+@@ -201,6 +203,10 @@ public class CandidatePanel : Gtk.Box{
+ }
+
+ public void set_preedit_text(IBus.Text? text, uint cursor) {
++ if (!m_is_wayland) {
++ set_preedit_text_real(text, cursor);
++ return;
++ }
+ #if USE_GDK_WAYLAND
+ if (m_set_preedit_text_id > 0)
+ GLib.Source.remove(m_set_preedit_text_id);
+@@ -238,6 +244,10 @@ public class CandidatePanel : Gtk.Box{
+ }
+
+ public void set_auxiliary_text(IBus.Text? text) {
++ if (!m_is_wayland) {
++ set_auxiliary_text_real(text);
++ return;
++ }
+ #if USE_GDK_WAYLAND
+ if (m_set_auxiliary_text_id > 0)
+ GLib.Source.remove(m_set_auxiliary_text_id);
+@@ -269,6 +279,10 @@ public class CandidatePanel : Gtk.Box{
+ }
+
+ public void set_lookup_table(IBus.LookupTable? table) {
++ if (!m_is_wayland) {
++ set_lookup_table_real(table);
++ return;
++ }
+ #if USE_GDK_WAYLAND
+ if (m_set_lookup_table_id > 0) {
+ if (table == null ||
+@@ -282,14 +296,25 @@ public class CandidatePanel : Gtk.Box{
+ }
+ }
+ if (table != null) {
++ if (m_prev_ncandidates == 0)
++ m_first_set_lookup_table = true;
+ m_prev_page_size = table.get_page_size();
+ m_prev_ncandidates = table.get_number_of_candidates();
+ m_prev_cursor = table.get_cursor_pos();
+ m_prev_cursor_in_page = table.get_cursor_in_page();
+ m_prev_show_cursor = table.is_cursor_visible();
++ } else {
++ m_prev_page_size = m_prev_ncandidates = m_prev_cursor =
++ m_prev_cursor_in_page = 0;
++ m_prev_show_cursor = false;
+ }
+ // FIXME: Too many PreeditText D-Bus signal happens in Wayland.
+ m_set_lookup_table_id = Timeout.add(100,
++ // FIXME: If m_set_lookup_table_id
++ // == 0, delete the queued timed
++ // callbacks to avoid the last
++ // reverse cursor move after the
++ // key release.
+ () => {
+ m_set_lookup_table_id = 0;
+ set_lookup_table_real(table);
+@@ -353,9 +378,33 @@ public class CandidatePanel : Gtk.Box{
+ }
+
+ private void update() {
++ if (!m_is_wayland) {
++ update_real();
++ return;
++ }
++#if USE_GDK_WAYLAND
++ // Show the first lookup table immediately with the Wayland
++ // input-method protocol because keeping pressing the space key
++ // causes many update() and the timed update_real() is not called
++ // until the space key is released.
++ if (m_first_set_lookup_table) {
++ m_first_set_lookup_table = false;
++ if (m_update_id > 0) {
++ GLib.Source.remove(m_update_id);
++ m_update_id = 0;
++ }
++ update_real();
++ return;
++ }
++#endif
+ if (m_update_id > 0)
+ GLib.Source.remove(m_update_id);
+- // set_lookup_table() and set_preedit_text() happens sequentially.
++ // - set_lookup_table() and set_preedit_text() happens sequentially.
++ // - Hide CandidatePanel after a candidate is committed with Emojier
++ // and xterm without the Wayland panel in the Wayland input-method V2.
++ // - Don't show the hidden lookup table unexpectedly again after
++ // a candidate is committed with the Wayland applications in the
++ // Wayland input-method V2.
+ m_update_id = Timeout.add(100,
+ () => {
+ m_update_id = 0;
+@@ -436,7 +485,7 @@ public class CandidatePanel : Gtk.Box{
+
+ public new void hide() {
+ #if USE_GDK_WAYLAND
+- if (!BindingCommon.default_is_xdisplay())
++ if (m_is_wayland)
+ realize_surface(null);
+ #endif
+ m_toplevel.hide();
+diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
+index 186b3ac9..e42a166e 100644
+--- a/ui/gtk3/panel.vala
++++ b/ui/gtk3/panel.vala
+@@ -173,7 +173,8 @@ class Panel : IBus.PanelService {
+ }
+
+ private CandidatePanel candidate_panel_new(bool no_wayland_panel) {
+- CandidatePanel candidate_panel = new CandidatePanel(no_wayland_panel);
++ CandidatePanel candidate_panel = new CandidatePanel(m_is_wayland,
++ no_wayland_panel);
+ candidate_panel.page_up.connect((w) => this.page_up());
+ candidate_panel.page_down.connect((w) => this.page_down());
+ candidate_panel.cursor_up.connect((w) => this.cursor_up());
+@@ -190,7 +191,7 @@ class Panel : IBus.PanelService {
+ }
+
+ private Switcher switcher_new(bool no_wayland_panel) {
+- Switcher switcher = new Switcher(no_wayland_panel);
++ Switcher switcher = new Switcher(m_is_wayland, no_wayland_panel);
+ #if USE_GDK_WAYLAND
+ switcher.realize_surface.connect(
+ (w, s) => this.realize_surface(s));
+diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
+index 13eeb481..99a2fa0b 100644
+--- a/ui/gtk3/switcher.vala
++++ b/ui/gtk3/switcher.vala
+@@ -96,6 +96,7 @@ class Switcher : Gtk.Window {
+ private double m_mouse_init_x;
+ private double m_mouse_init_y;
+ private bool m_mouse_moved;
++ private bool m_is_wayland;
+ private bool m_no_wayland_panel;
+ private GLib.HashTable<string, string> m_xkb_languages =
+ new GLib.HashTable<string, string>(GLib.str_hash,
+@@ -106,16 +107,19 @@ class Switcher : Gtk.Window {
+ public signal void realize_surface(void *surface);
+ #endif
+
+- public Switcher(bool no_wayland_panel) {
++ public Switcher(bool is_wayland,
++ bool no_wayland_panel) {
+ GLib.Object(
+ type : Gtk.WindowType.POPUP,
+- events : Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK,
++ events : Gdk.EventMask.KEY_PRESS_MASK |
++ Gdk.EventMask.KEY_RELEASE_MASK,
+ window_position : Gtk.WindowPosition.CENTER,
+ accept_focus : true,
+ decorated : false,
+ modal : true,
+ focus_visible : true
+ );
++ m_is_wayland = is_wayland;
+ m_no_wayland_panel = no_wayland_panel;
+ Gtk.Box vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+ add(vbox);
+@@ -139,7 +143,7 @@ class Switcher : Gtk.Window {
+ vbox.pack_end(m_label, false, false, 0);
+
+ #if USE_GDK_WAYLAND
+- if (!BindingCommon.default_is_xdisplay()) {
++ if (m_is_wayland) {
+ this.realize.connect((w) => {
+ realize_window(true);
+ });
+@@ -381,12 +385,8 @@ class Switcher : Gtk.Window {
+ return false;
+ }
+ m_mouse_moved = true;
+-#if USE_GDK_WAYLAND
+- if (BindingCommon.default_is_xdisplay())
++ if (!m_is_wayland)
+ button.grab_focus();
+-#else
+- button.grab_focus();
+-#endif
+ m_selected_engine = index;
+ return false;
+ });
+@@ -571,7 +571,7 @@ class Switcher : Gtk.Window {
+ // if e.type == Gdk.EventType.KEY_RELEASE, m_loop is already null.
+ // m_loop is always null in Wayland but this signal is not emitted
+ // when the Wayland panel protocol is enabled.
+- if (m_loop == null && !m_no_wayland_panel)
++ if (m_loop == null && !m_is_wayland)
+ return Gdk.EVENT_PROPAGATE;
+
+ if (m_popup_delay_time > 0) {
+@@ -582,9 +582,9 @@ class Switcher : Gtk.Window {
+ }
+
+ m_result = (int)m_selected_engine;
+- if (!m_no_wayland_panel) {
++ if (!m_is_wayland) {
+ m_loop.quit();
+- } else {
++ } else if (m_no_wayland_panel) {
+ // Switcher without the Wayland panel protocol can return
+ // the m_result_engine immediately in Wayland without waiting
+ // for the focus-in event due to a virtual input context in
+@@ -592,6 +592,9 @@ class Switcher : Gtk.Window {
+ GLib.assert(m_result < m_engines.length);
+ m_result_engine = m_engines[m_result];
+ hide();
++ } else {
++ // Switcher should not get focus with the Wayland panel protocol.
++ GLib.assert_not_reached();
+ }
+ return Gdk.EVENT_STOP;
+ }
+diff --git a/ui/gtk3/xkblayout.vala b/ui/gtk3/xkblayout.vala
+index 874920ee..598431c3 100644
+--- a/ui/gtk3/xkblayout.vala
++++ b/ui/gtk3/xkblayout.vala
+@@ -48,6 +48,11 @@ class XKBLayout
+ public void get_layout(out string layout,
+ out string variant,
+ out string option) {
++ layout = "";
++ variant = "";
++ var o = Environment.get_variable("XKB_DEFAULT_OPTIONS");
++ option = o != null ? o : "";
++
+ search_get_layout_program();
+ if (m_get_layout_args[0] == null) {
+ warning("Not found localectl or setxkbmap command in PATH");
+@@ -60,11 +65,6 @@ class XKBLayout
+ string standard_error = null;
+ int exit_status = 0;
+
+- layout = "";
+- variant = "";
+- var o = Environment.get_variable("XKB_DEFAULT_OPTIONS");
+- option = o != null ? o : "";
+-
+ try {
+ GLib.Process.spawn_sync(null,
+ exec_command,
+@@ -84,14 +84,14 @@ class XKBLayout
+
+ if (exec_command[0] == "localectl") {
+ parse_localectl_status_str(standard_output,
+- out layout,
+- out variant,
+- out option);
++ ref layout,
++ ref variant,
++ ref option);
+ } else if (exec_command[0] == XKB_COMMAND) {
+ parse_xkbmap_query_str(standard_output,
+- out layout,
+- out variant,
+- out option);
++ ref layout,
++ ref variant,
++ ref option);
+ }
+ }
+
+@@ -113,9 +113,9 @@ class XKBLayout
+
+
+ private void parse_localectl_status_str(string standard_output,
+- out string layout,
+- out string variant,
+- out string option) {
++ ref string layout,
++ ref string variant,
++ ref string option) {
+ foreach (string line in standard_output.split("\n")) {
+ const string[] elements = { "X11 Layout:", "X11 Variant:" };
+ foreach (unowned string element in elements) {
+@@ -136,9 +136,9 @@ class XKBLayout
+
+
+ private void parse_xkbmap_query_str(string standard_output,
+- out string layout,
+- out string variant,
+- out string option) {
++ ref string layout,
++ ref string variant,
++ ref string option) {
+ foreach (string line in standard_output.split("\n")) {
+ const string[] elements = { "layout:", "variant:", "options:" };
+ foreach (unowned string element in elements) {
+--
+2.47.0
+
+From 1d56d77b19daf5c8d6f3ee87a0712ae5904293f4 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1@gmail.com>
+Date: Fri, 14 Mar 2025 21:00:52 +0900
+Subject: [PATCH] client/wayland: Fix infinite Return key in xterm
+
+Currently the repeating key feature of IBus is disabled when the focus
+is changed but the feature of the Wayland compositor still happens in
+the Sway desktop session when invoke xterm by manual in foot.
+I think Sway should stop the repeating key feature when the focus is
+changed from the Wayland application to the non-Wayland application.
+
+I add a workaround to call `zwp_virtual_keyboard_v1_key()` with
+the `WL_KEYBOARD_KEY_STATE_RELEASED` flag to stop the feature of
+the Sway compositor after the IBus repeating key timeout.
+---
+ client/wayland/ibuswaylandim.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
+index ba392c6b..356cec31 100644
+--- a/client/wayland/ibuswaylandim.c
++++ b/client/wayland/ibuswaylandim.c
+@@ -1332,6 +1332,17 @@ _process_key_event_repeat_delay_cb (gpointer user_data)
+ /* The key release event was sent to non-Wayland apps likes xterm. */
+ if (!priv->ibuscontext) {
+ event->count_cb_id = 0;
++ /* Stop the infinite Return keys in non-Wayland apps likes xterm in
++ * the Sway desktop session.
++ * But priv->context in NULL in the Wayland input-method V1 here.
++ */
++ if (priv->version != INPUT_METHOD_V1) {
++ ibus_wayland_im_key(event->wlim,
++ event->serial,
++ event->time + priv->repeat_delay,
++ event->key,
++ WL_KEYBOARD_KEY_STATE_RELEASED);
++ }
+ return G_SOURCE_REMOVE;
+ }
+ /* The focus is changed. */
+--
+2.47.0
+
diff --git a/ibus.spec b/ibus.spec
index 5caa42d..b1ba38d 100644
--- a/ibus.spec
+++ b/ibus.spec
@@ -63,7 +63,7 @@
Name: ibus
Version: 1.5.32~rc1
# https://github.com/fedora-infra/rpmautospec/issues/101
-Release: 3%{?dist}
+Release: 4%{?dist}
Summary: Intelligent Input Bus for Linux OS
License: LGPL-2.1-or-later
URL: https://github.com/ibus/%name/wiki
@@ -386,6 +386,7 @@ fi
--enable-introspection \
--enable-install-tests \
%{nil}
+make -C ui/gtk3 maintainer-clean-generic
%make_build
@@ -638,6 +639,10 @@ dconf update || :
%{_datadir}/installed-tests/ibus
%changelog
+* Fri Mar 14 2025 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.32~rc1-4
+- Fix time lag of CandidatePanel in X11
+- Fix infinite Return key in xterm with Wayalnd input-method protocol V2
+
* Sun Mar 09 2025 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.32~rc1-3
- Send RequireSurroundingText method with engine active-surrounding-text property
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-05-31 2:08 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-31 2:08 [rpms/ibus] autotool: Fix time lag of CandidatePanel in X11 Takao Fujiwara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox