public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ibus] rawhide: Bump to 1.5.35-alpha2
@ 2026-06-19 12:15 Takao Fujiwara
0 siblings, 0 replies; only message in thread
From: Takao Fujiwara @ 2026-06-19 12:15 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/ibus
Branch : rawhide
Commit : de0ac625d7f44faa1e9349db6449a36081f2dbf2
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date : 2026-06-19T21:14:30+09:00
Stats : +276/-1494 in 6 file(s)
URL : https://src.fedoraproject.org/rpms/ibus/c/de0ac625d7f44faa1e9349db6449a36081f2dbf2?branch=rawhide
Log:
Bump to 1.5.35-alpha2
---
diff --git a/.gitignore b/.gitignore
index 03a3114..8dc27ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,3 +91,4 @@ ibus-1.3.6.tar.gz
/ibus-1.5.34-rc2.tar.gz
/ibus-1.5.34.tar.gz
/ibus-1.5.35-alpha1.tar.xz
+/ibus-1.5.35-alpha2.tar.xz
diff --git a/ibus-2444009-wayland-xkb-lv-tilde.patch b/ibus-2444009-wayland-xkb-lv-tilde.patch
index 04e942c..4071cac 100644
--- a/ibus-2444009-wayland-xkb-lv-tilde.patch
+++ b/ibus-2444009-wayland-xkb-lv-tilde.patch
@@ -1,7 +1,7 @@
-From 569a9090defbab0600042c795c138bd8fe2370cd Mon Sep 17 00:00:00 2001
+From 1686cb59c17744b07d8afefed0bda97d6c4930b8 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Mon, 18 May 2026 17:05:11 +0900
-Subject: [PATCH 1/9] client/wayland: Fix latch key in Latvian(tilde) keymap
+Date: Wed, 17 Jun 2026 19:49:31 +0900
+Subject: [PATCH 1/4] client/wayland: Fix latch key in Latvian(tilde) keymap
"lv(tilde)" keymap has `ISO_Level3_Latch` and there are several issues.
1. KDE Wayland does not handle `ISO_Level3_Latch` keysym but outputs the
@@ -24,17 +24,17 @@ Subject: [PATCH 1/9] client/wayland: Fix latch key in Latvian(tilde) keymap
6. Fix to clear modifiers with the key release of Shift + Latch key.
7. Save CapsLock state
-Fixes: https://github.com/ibus/ibus/commit/0104486
+Fixes: 0104486
Closes: rhbz#2444009
---
- client/wayland/ibuswaylandim.c | 279 ++++++++++++++++++++++++++++-----
- 1 file changed, 243 insertions(+), 36 deletions(-)
+ client/wayland/ibuswaylandim.c | 304 +++++++++++++++++++++++++++------
+ 1 file changed, 248 insertions(+), 56 deletions(-)
diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
-index 367b07c5..fa72ce4e 100644
+index d7d12d05..237f50ef 100644
--- a/client/wayland/ibuswaylandim.c
+++ b/client/wayland/ibuswaylandim.c
-@@ -39,6 +39,9 @@
+@@ -40,6 +40,9 @@
#include "virtual-keyboard-unstable-v1-client-protocol.h"
#include "ibuswaylandim.h"
@@ -44,7 +44,7 @@ index 367b07c5..fa72ce4e 100644
enum {
PROP_0 = 0,
PROP_BUS,
-@@ -125,6 +128,7 @@ struct _IBusWaylandIMPrivate
+@@ -146,6 +149,7 @@ struct _IBusWaylandIMPrivate
guint preedit_cursor_pos;
guint preedit_mode;
IBusModifierType modifiers;
@@ -52,7 +52,7 @@ index 367b07c5..fa72ce4e 100644
gboolean hiding_preedit_text;
IBusInputHints ibus_hints;
IBusInputPurpose ibus_purpose;
-@@ -195,10 +199,6 @@ static char _use_sync_mode = 1;
+@@ -203,10 +207,6 @@ static char _use_sync_mode = 1;
static guint wayland_im_signals[LAST_SIGNAL] = { 0 };
@@ -63,7 +63,7 @@ index 367b07c5..fa72ce4e 100644
static GObject *ibus_wayland_im_constructor (GType type,
guint n_params,
GObjectConstructParam
-@@ -220,6 +220,19 @@ static gboolean ibus_wayland_im_post_key (IBusWaylandIM *wlim,
+@@ -228,6 +228,19 @@ static gboolean ibus_wayland_im_post_key (IBusWaylandIM *wlim,
xkb_keysym_t sym,
gboolean
filtered);
@@ -83,79 +83,23 @@ index 367b07c5..fa72ce4e 100644
static char
-@@ -1098,6 +1111,7 @@ ibus_wayland_im_update_xkb_state (IBusWaylandIM *wlim,
- xkb_keymap_unref (priv->keymap);
- priv->keymap = keymap;
- priv->state = state;
-+
- return TRUE;
- }
-
-@@ -1119,7 +1133,14 @@ _bus_global_engine_changed_cb (IBusBus *bus,
- g_assert (!g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name));
+@@ -1129,7 +1142,14 @@ _bus_global_engine_changed_cb (IBusBus *bus,
keymap = create_user_xkb_keymap (priv->xkb_context, desc);
- if (keymap && !ibus_wayland_im_update_xkb_state (wlim, keymap))
+ if (keymap && !ibus_xkb_keymap_update_with_keymap (&priv->key_user,
+ keymap)) {
- xkb_keymap_unref (keymap);
+ g_clear_pointer (&keymap, xkb_keymap_unref);
++ }
+ if (priv->verbose) {
+ fprintf (priv->log, "New engine:%s keymap:%s state:%s\n",
+ ibus_engine_desc_get_name (desc),
+ keymap ? "TRUE" : "FALSE",
-+ priv->state ? "TRUE" : "FALSE");
++ priv->key_user.state ? "TRUE" : "FALSE");
+ fflush (priv->log);
-+ }
- g_object_unref (desc);
- }
-
-@@ -1134,6 +1155,8 @@ input_method_keyboard_keymap (void *data,
- IBusWaylandIM *wlim = data;
- IBusWaylandIMPrivate *priv;
- struct xkb_keymap *keymap;
-+ struct xkb_state *prev_state = NULL;
-+ gboolean has_new_state = FALSE;
-
- if (!IBUS_IS_WAYLAND_IM (wlim)) {
- close (fd);
-@@ -1158,10 +1181,35 @@ input_method_keyboard_keymap (void *data,
- return;
}
- keymap = create_system_xkb_keymap (priv->xkb_context, format, fd, size);
-- if (keymap && !ibus_wayland_im_update_xkb_state (wlim, keymap))
-- xkb_keymap_unref (keymap);
- if (priv->state)
-- priv->state_system = xkb_state_ref (priv->state);
-+ prev_state = xkb_state_ref (priv->state);
-+ if (keymap)
-+ has_new_state = ibus_wayland_im_update_xkb_state (wlim, keymap);
-+ if (priv->state) {
-+ if (has_new_state) {
-+ priv->state_system = xkb_state_ref (priv->state);
-+ /* prev->state is user prev->state_system is system */
-+ if (prev_state) {
-+ xkb_state_unref (priv->state);
-+ priv->state = prev_state;
-+ }
-+ } else {
-+ if (prev_state)
-+ xkb_state_unref (prev_state);
-+ if (keymap)
-+ g_clear_pointer (&keymap, xkb_keymap_unref);
-+ }
-+ } else if (keymap) {
-+ g_clear_pointer (&keymap, xkb_keymap_unref);
-+ }
-+ if (priv->verbose) {
-+ fprintf (priv->log, "System keymap format:%u fd:%d size:%u "
-+ "keymap:%s state:%s\n",
-+ format, fd, size,
-+ keymap ? "TRUE" : "FALSE",
-+ priv->state ? "TRUE" : "FALSE");
-+ fflush (priv->log);
-+ }
+ g_object_unref (desc);
}
-
-
-@@ -1199,6 +1247,7 @@ _get_seat_with_name (GPtrArray *seats,
+@@ -1253,6 +1273,7 @@ _get_seat_with_name (GPtrArray *seats,
return NULL;
}
@@ -163,10 +107,10 @@ index 367b07c5..fa72ce4e 100644
static gboolean
ibus_wayland_im_post_key (IBusWaylandIM *wlim,
uint32_t key,
-@@ -1208,8 +1257,13 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
- gboolean filtered)
+@@ -1263,8 +1284,13 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
{
IBusWaylandIMPrivate *priv;
+ IBusXkbKeymap *active_key;
+ xkb_mod_mask_t mods_depressed = 0, new_mods_depressed = 0;
+ xkb_mod_mask_t mods_locked;
+ xkb_layout_index_t group;
@@ -177,20 +121,20 @@ index 367b07c5..fa72ce4e 100644
g_return_val_if_fail (IBUS_IS_WAYLAND_IM (wlim), FALSE);
priv = ibus_wayland_im_get_instance_private (wlim);
-@@ -1229,39 +1283,123 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
- }
- if (!priv->state)
+@@ -1288,49 +1314,132 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
+ active_key = &priv->key_user;
+ if (!active_key->state)
return FALSE;
-+ mods_depressed = xkb_state_serialize_mods (priv->state,
++ mods_depressed = xkb_state_serialize_mods (active_key->state,
+ XKB_STATE_DEPRESSED |
+ XKB_STATE_LATCHED);
+ new_mods_depressed = mods_depressed;
-+ mods_locked = xkb_state_serialize_mods (priv->state,
++ mods_locked = xkb_state_serialize_mods (active_key->state,
+ XKB_STATE_MODS_LOCKED);
+ /* XKB group layout is configured in the system keymap but not the
+ * user keymap which always includes a single layout.
+ */
-+ group = xkb_state_serialize_layout (priv->state_system,
++ group = xkb_state_serialize_layout (priv->key_sys.state,
+ XKB_STATE_LAYOUT_LOCKED);
if (!filtered) {
-#if 0
@@ -201,7 +145,7 @@ index 367b07c5..fa72ce4e 100644
- filtered = TRUE;
- }
-#else
-+ system_sym = xkb_state_key_get_one_sym (priv->state_system, code);
++ system_sym = xkb_state_key_get_one_sym (priv->key_sys.state, code);
switch (sym) {
- case IBUS_ISO_Level2_Latch:
- case IBUS_ISO_Level3_Latch:
@@ -215,7 +159,7 @@ index 367b07c5..fa72ce4e 100644
+ case IBUS_KEY_ISO_Level3_Latch:
+ case IBUS_KEY_ISO_Level3_Shift:
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-+ new_mods_depressed |= priv->mod5_mask;
++ new_mods_depressed |= active_key->mod5_mask;
+ if (sym != system_sym)
+ priv->is_virtual_latch_state = TRUE;
+ filtered = TRUE;
@@ -226,7 +170,7 @@ index 367b07c5..fa72ce4e 100644
+ case IBUS_KEY_ISO_Level5_Latch:
+ case IBUS_KEY_ISO_Level5_Shift:
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-+ new_mods_depressed |= priv->mod3_mask;
++ new_mods_depressed |= active_key->mod3_mask;
+ if (sym != system_sym)
+ priv->is_virtual_latch_state = TRUE;
+ filtered = TRUE;
@@ -235,9 +179,9 @@ index 367b07c5..fa72ce4e 100644
+ case IBUS_KEY_Shift_L:
+ case IBUS_KEY_Shift_R:
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
-+ new_mods_depressed |= priv->shift_mask;
++ new_mods_depressed |= active_key->shift_mask;
+ else
-+ new_mods_depressed &= ~priv->shift_mask;
++ new_mods_depressed &= ~active_key->shift_mask;
+ break;
default:;
}
@@ -253,8 +197,18 @@ index 367b07c5..fa72ce4e 100644
+ }
#endif
}
-- if (!filtered && (state != WL_KEYBOARD_KEY_STATE_RELEASED)) {
-- ch = xkb_state_key_get_utf32 (priv->state, code);
+- /* In case `use_sys_keymap` is %TRUE, IBus does not commit ASCII chars
+- * but forwards the key events to the focused application here.
+- * Because some applications treat the printable keys as control keys,
+- * E.g. game apps "hjkl" use the cursor move like VI mode.
+- * Unfortunately the Wayland input-method protocol does not provide
+- * the fallback logic after apps handle the key events like GTK3/2
+- * IM modules. But The input-method always should handles key events
+- * prior to apps.
+- */
+- if (!filtered && (state != WL_KEYBOARD_KEY_STATE_RELEASED) &&
+- !priv->use_sys_keymap) {
+- ch = xkb_state_key_get_utf32 (active_key->state, code);
- if (!(modifiers & IBUS_MODIFIER_MASK & ~IBUS_SHIFT_MASK) &&
- ch && ch != '\n' && ch != '\b' && ch != '\r' && ch != '\t' &&
- ch != '\033' && ch != '\x7f') {
@@ -265,7 +219,7 @@ index 367b07c5..fa72ce4e 100644
+ if (state != WL_KEYBOARD_KEY_STATE_RELEASED) {
+ ch = ibus_keyval_to_unicode (sym);
+ if (ch == 0 || g_unichar_iscntrl (ch))
-+ ch = xkb_state_key_get_utf32 (priv->state, code);
++ ch = xkb_state_key_get_utf32 (active_key->state, code);
+/* No text with Control & Alt & Super keys */
+#ifndef GDK_WINDOWING_QUARTZ
+# define _IBUS_NO_TEXT_INPUT_MOD_MASK (\
@@ -276,7 +230,16 @@ index 367b07c5..fa72ce4e 100644
+#endif
+ if ((!filtered && !(modifiers & _IBUS_NO_TEXT_INPUT_MOD_MASK) &&
+ !g_unichar_iscntrl (ch)) || filtered) {
-+ if (!filtered) {
++ /* In case `use_sys_keymap` is %TRUE, IBus does not commit ASCII chars
++ * but forwards the key events to the focused application here.
++ * Because some applications treat the printable keys as control keys,
++ * E.g. game apps "hjkl" use the cursor move like VI mode.
++ * Unfortunately the Wayland input-method protocol does not provide
++ * the fallback logic after apps handle the key events like GTK3/2
++ * IM modules. But The input-method always should handles key events
++ * prior to apps.
++ */
++ if (!filtered && !priv->use_sys_keymap) {
+ gchar buff[8] = { 0, };
+ buff[g_unichar_to_utf8 (ch, buff)] = '\0';
+ ibus_wayland_im_commit_text (wlim, buff);
@@ -291,14 +254,14 @@ index 367b07c5..fa72ce4e 100644
+ * I'm not clarified with "level3(ralt_switch)" in us XKB keymaps.
+ */
+ if (modifiers & IBUS_MOD3_MASK) {
-+ new_mods_depressed &= ~priv->mod3_mask;
++ new_mods_depressed &= ~active_key->mod3_mask;
+ clear_virtual_state = TRUE;
+ }
+ if (modifiers & IBUS_MOD5_MASK) {
-+ new_mods_depressed &= ~priv->mod5_mask;
++ new_mods_depressed &= ~active_key->mod5_mask;
+ clear_virtual_state = TRUE;
+ }
- }
++ }
+#undef _IBUS_NO_TEXT_INPUT_MOD_MASK
+ }
+ if (priv->is_virtual_latch_state) {
@@ -308,33 +271,35 @@ index 367b07c5..fa72ce4e 100644
+ 0,
+ mods_locked,
+ group);
-+ }
+ }
+ if (clear_virtual_state)
+ priv->is_virtual_latch_state = FALSE;
+ }
+ if (!priv->is_virtual_latch_state ||
+ (state != WL_KEYBOARD_KEY_STATE_RELEASED)) {
-+ xkb_state_update_key (priv->state, code,
++ xkb_state_update_key (active_key->state, code,
+ (state == WL_KEYBOARD_KEY_STATE_RELEASED)
+ ? XKB_KEY_UP : XKB_KEY_DOWN);
}
-- xkb_state_update_key (priv->state, code,
+- xkb_state_update_key (active_key->state, code,
- (state == WL_KEYBOARD_KEY_STATE_RELEASED)
- ? XKB_KEY_UP : XKB_KEY_DOWN);
return filtered;
}
-@@ -1706,12 +1844,31 @@ input_method_keyboard_key (void *data,
+@@ -1777,12 +1886,32 @@ input_method_keyboard_key (void *data,
/* xkb_key_get_syms() does not return the capital syms with Shift key. */
- if (priv->state_system)
- event.sym = xkb_state_key_get_one_sym (priv->state_system, code);
-- if (event.sym != IBUS_KEY_Multi_key)
+ if (priv->key_sys.state)
+ event.sym = xkb_state_key_get_one_sym (priv->key_sys.state, code);
+- if (event.sym != IBUS_KEY_Multi_key && priv->key_user.state)
+- event.sym = xkb_state_key_get_one_sym (priv->key_user.state, code);
+ switch (event.sym) {
+ case IBUS_KEY_Multi_key:
+ case IBUS_KEY_ISO_Next_Group:
+ break;
+ default:
- event.sym = xkb_state_key_get_one_sym (priv->state, code);
++ if (priv->key_user.state)
++ event.sym = xkb_state_key_get_one_sym (priv->key_user.state, code);
+ }
event.modifiers = priv->modifiers;
if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
@@ -348,8 +313,8 @@ index 367b07c5..fa72ce4e 100644
+ G_STRFUNC,
+ key_serial, time, key,
+ event.sym,
-+ xkb_state_key_get_one_sym (priv->state, code),
-+ xkb_state_key_get_one_sym (priv->state_system, code),
++ xkb_state_key_get_one_sym (priv->key_user.state, code),
++ xkb_state_key_get_one_sym (priv->key_sys.state, code),
+ event.modifiers, state ? "press" : "release");
+ fflush (priv->log);
+ }
@@ -357,12 +322,52 @@ index 367b07c5..fa72ce4e 100644
key_event_check_repeat (wlim, &event);
switch (_use_sync_mode) {
-@@ -1740,11 +1897,47 @@ input_method_keyboard_modifiers (void *data,
+@@ -1796,6 +1925,29 @@ input_method_keyboard_key (void *data,
+ }
- g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim));
- priv = ibus_wayland_im_get_instance_private (wlim);
-- xkb_state_update_mask (priv->state, mods_depressed,
-- mods_latched, mods_locked, 0, 0, group);
+
++/**
++ * input_method_keyboard_modifiers:
++ *
++ * This is a common API of input_method_keyboard_modifiers_v1() and
++ * input_method_keyboard_modifiers_v2().
++ * If you configure multiple XKB layouts in the system with
++ * /etc/vconsole.conf file, you can switch the active layout with
++ * the XKB options and @group is changed with the shortcut key like
++ * "grp:lalt_lshift_toggle" but If you click the keyboard icon in
++ * Plasma KDE and change the active layout with GUI, @group is not
++ * changed and I assume it's a bug [1].
++ * Currently there are two cases of the combinations of the IBus keymap and
++ * the system keymap supported by IBus:
++ * 1. Always Same keymaps
++ * E.g. IBus keymap is "lv(tilde)" and system one is "lv(tilde)"
++ * 2. System keymap is "US" and switch IBus keymaps with Super-space key
++ * E.g. IBus keymap is "lv(tilde)" and system one is "us"
++ * So you should use both XKB option keys and IBus shortcutkeys to switch the
++ * keymaps to change both XKB keymaps and IBus keymaps but you should not
++ * click the keyboard icon in KDE.
++ *
++ * [1] https://bugs.kde.org/show_bug.cgi?id=518371
++ */
+ static void
+ input_method_keyboard_modifiers (void *data,
+ struct zwp_keyboard_union *keyboard,
+@@ -1816,27 +1968,53 @@ input_method_keyboard_modifiers (void *data,
+ active_key = &priv->key_sys;
+ else
+ active_key = &priv->key_user;
+- if (priv->key_user.state) {
+- xkb_state_update_mask (priv->key_user.state, mods_depressed,
+- mods_latched, mods_locked, 0, 0, group);
+- }
+- /* Pressing XKB group key likes Alt_R with grp:toggle calls
+- * input_method_keyboard_modifiers() with the updated `group`
+- * and need to update priv->key_sys.state to switch the XKB group
+- * in the system keymap.
+- *
+- * XKB group key can switch `group` but clicking the keyboard icon
+- * of KDE does not change `group` at present. Maybe a bug in the
+- * KDE Wayland compositor.
+ /* Do not reset Latch modifiers by system in case the system keymap
+ * has no the Latch key.
+ * In case the user keymap is "lv(tilde)" and the system one is "us",
@@ -373,43 +378,52 @@ index 367b07c5..fa72ce4e 100644
+ * "lv(tilde)".
+ * So `is_virtual_latch_state` keeps the virtual state of the latch keys
+ * not to override the state of the "us" keymap.
-+ */
+ */
+- if (priv->key_sys.state) {
+- xkb_state_update_mask (priv->key_sys.state, mods_depressed,
+- mods_latched, mods_locked, 0, 0, group);
+ if (!priv->is_virtual_latch_state || key_serial == 0) {
-+ xkb_state_update_mask (priv->state, mods_depressed,
-+ mods_latched, mods_locked, 0, 0, group);
++ if (priv->key_user.state) {
++ xkb_state_update_mask (priv->key_user.state, mods_depressed,
++ mods_latched, mods_locked, 0, 0, group);
++ }
+ /* Pressing XKB group key likes Alt_R with grp:toggle calls
+ * input_method_keyboard_modifiers() with the updated `group`
-+ * and need to update priv->state_system to switch the XKB group
++ * and need to update priv->key_sys.state to switch the XKB group
+ * in the system keymap.
+ *
+ * XKB group key can switch `group` but clicking the keyboard icon
+ * of KDE does not change `group` at present. Maybe a bug in the
+ * KDE Wayland compositor.
+ */
-+ xkb_state_update_mask (priv->state_system, mods_depressed,
-+ mods_latched, mods_locked, 0, 0, group);
++ if (priv->key_sys.state) {
++ xkb_state_update_mask (priv->key_sys.state, mods_depressed,
++ mods_latched, mods_locked, 0, 0, group);
++ }
+ }
+ if (active_key->state) {
++ /* CapsLock needs XKB_STATE_MODS_LOCKED */
+ mask = xkb_state_serialize_mods (active_key->state,
+ XKB_STATE_DEPRESSED |
+- XKB_STATE_LATCHED);
++ XKB_STATE_LATCHED |
++ XKB_STATE_MODS_LOCKED);
+ }
-+ /* CapsLock needs XKB_STATE_MODS_LOCKED */
- mask = xkb_state_serialize_mods (priv->state,
- XKB_STATE_DEPRESSED |
-- XKB_STATE_LATCHED);
-+ XKB_STATE_LATCHED |
-+ XKB_STATE_MODS_LOCKED);
+ if (priv->verbose) {
++ struct xkb_state *state = active_key->state;
+ fprintf (priv->log, "Update modifiers serial:%u depress:%X latch:%X "
+ "lock:%X group:%X orig_depre:%X orig_latch:%X "
+ "orig_lock:%X\n",
+ key_serial, mods_depressed, mods_latched, mods_locked, group,
-+ xkb_state_serialize_mods (priv->state, XKB_STATE_DEPRESSED),
-+ xkb_state_serialize_mods (priv->state, XKB_STATE_LATCHED),
-+ xkb_state_serialize_mods (priv->state, XKB_STATE_MODS_LOCKED));
++ xkb_state_serialize_mods (state, XKB_STATE_DEPRESSED),
++ xkb_state_serialize_mods (state, XKB_STATE_LATCHED),
++ xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED));
+ fflush (priv->log);
-+ }
+ }
priv->modifiers = 0;
- if (mask & priv->shift_mask)
-@@ -1770,6 +1963,9 @@ input_method_keyboard_modifiers (void *data,
- if (mask & priv->meta_mask)
+@@ -1863,6 +2041,9 @@ input_method_keyboard_modifiers (void *data,
+ if (mask & active_key->meta_mask)
priv->modifiers |= IBUS_META_MASK;
+ if (!key_serial)
@@ -418,12 +432,10 @@ index 367b07c5..fa72ce4e 100644
switch (priv->version) {
case INPUT_METHOD_V1:
zwp_input_method_context_v1_modifiers (priv->context, key_serial,
-@@ -2748,7 +2944,18 @@ ibus_wayland_im_constructor (GType type,
- if (desc)
- keymap = create_user_xkb_keymap (priv->xkb_context, desc);
- if (keymap && !ibus_wayland_im_update_xkb_state (wlim, keymap))
-- xkb_keymap_unref (keymap);
-+ g_clear_pointer (&keymap, xkb_keymap_unref);
+@@ -2886,6 +3067,17 @@ ibus_wayland_im_constructor (GType type,
+ keymap)) {
+ g_clear_pointer (&keymap, xkb_keymap_unref);
+ }
+ if (priv->verbose) {
+ if (!desc) {
+ fprintf (priv->log, "Constructor has No global engine\n");
@@ -431,7 +443,7 @@ index 367b07c5..fa72ce4e 100644
+ fprintf (priv->log, "Constructor engine %s keymap:%s state:%s\n",
+ ibus_engine_desc_get_name (desc),
+ keymap ? "TRUE" : "FALSE",
-+ priv->state ? "TRUE" : "FALSE");
++ priv->key_user.state ? "TRUE" : "FALSE");
+ }
+ fflush (priv->log);
+ }
@@ -441,23 +453,23 @@ index 367b07c5..fa72ce4e 100644
--
2.53.0
-From 1276114d10d70cf8f4e489518cab82bbe3ac59cb Mon Sep 17 00:00:00 2001
+From 5fe640b170e09579b8b1955c5cad4aa4a6d1c464 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 29 May 2026 17:36:32 +0900
-Subject: [PATCH 2/9] client/wayland: Refactor ibus_wayland_im_post_key()
+Date: Mon, 15 Jun 2026 11:50:38 +0900
+Subject: [PATCH 2/4] client/wayland: Refactor ibus_wayland_im_post_key()
Separate 3 functions.
Closes: rhbz#2444009
---
- client/wayland/ibuswaylandim.c | 346 +++++++++++++++++++++------------
- 1 file changed, 227 insertions(+), 119 deletions(-)
+ client/wayland/ibuswaylandim.c | 371 +++++++++++++++++++++------------
+ 1 file changed, 243 insertions(+), 128 deletions(-)
diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
-index fa72ce4e..425574bd 100644
+index 237f50ef..2cc2079b 100644
--- a/client/wayland/ibuswaylandim.c
+++ b/client/wayland/ibuswaylandim.c
-@@ -359,6 +359,71 @@ ibus_wayland_im_commit_text (IBusWaylandIM *wlim,
+@@ -367,6 +367,81 @@ ibus_wayland_im_commit_text (IBusWaylandIM *wlim,
}
@@ -467,6 +479,7 @@ index fa72ce4e..425574bd 100644
+ uint32_t modifiers,
+ uint32_t state,
+ xkb_keysym_t sym,
++ IBusXkbKeymap *active_key,
+ gboolean filtered,
+ xkb_mod_mask_t *new_mods_depressed,
+ gboolean *clear_virtual_state)
@@ -483,7 +496,7 @@ index fa72ce4e..425574bd 100644
+
+ ch = ibus_keyval_to_unicode (sym);
+ if (ch == 0 || g_unichar_iscntrl (ch))
-+ ch = xkb_state_key_get_utf32 (priv->state, code);
++ ch = xkb_state_key_get_utf32 (active_key->state, code);
+
+/* No text with Control & Alt & Super keys */
+#ifndef GDK_WINDOWING_QUARTZ
@@ -495,7 +508,16 @@ index fa72ce4e..425574bd 100644
+#endif
+ if ((!filtered && !(modifiers & _IBUS_NO_TEXT_INPUT_MOD_MASK) &&
+ !g_unichar_iscntrl (ch)) || filtered) {
-+ if (!filtered) {
++ /* In case `use_sys_keymap` is %TRUE, IBus does not commit ASCII chars
++ * but forwards the key events to the focused application here.
++ * Because some applications treat the printable keys as control keys,
++ * E.g. game apps "hjkl" use the cursor move like VI mode.
++ * Unfortunately the Wayland input-method protocol does not provide
++ * the fallback logic after apps handle the key events like GTK3/2
++ * IM modules. But The input-method always should handles key events
++ * prior to apps.
++ */
++ if (!filtered && !priv->use_sys_keymap) {
+ gchar buff[8] = { 0, };
+ buff[g_unichar_to_utf8 (ch, buff)] = '\0';
+ ibus_wayland_im_commit_text (wlim, buff);
@@ -510,13 +532,13 @@ index fa72ce4e..425574bd 100644
+ */
+ if (modifiers & IBUS_MOD3_MASK) {
+ if (new_mods_depressed)
-+ *new_mods_depressed &= ~priv->mod3_mask;
++ *new_mods_depressed &= ~active_key->mod3_mask;
+ if (clear_virtual_state)
+ *clear_virtual_state = TRUE;
+ }
+ if (modifiers & IBUS_MOD5_MASK) {
+ if (new_mods_depressed)
-+ *new_mods_depressed &= ~priv->mod5_mask;
++ *new_mods_depressed &= ~active_key->mod5_mask;
+ if (clear_virtual_state)
+ *clear_virtual_state = TRUE;
+ }
@@ -529,7 +551,7 @@ index fa72ce4e..425574bd 100644
static void
ibus_wayland_im_key (IBusWaylandIM *wlim,
uint32_t key_serial,
-@@ -423,6 +488,146 @@ ibus_wayland_im_keysym (IBusWaylandIM *wlim,
+@@ -431,6 +506,149 @@ ibus_wayland_im_keysym (IBusWaylandIM *wlim,
}
@@ -551,6 +573,7 @@ index fa72ce4e..425574bd 100644
+ uint32_t modifiers,
+ uint32_t state,
+ xkb_keysym_t sym,
++ IBusXkbKeymap *active_key,
+ gboolean filtered,
+ xkb_mod_mask_t *mods_depressed)
+{
@@ -563,6 +586,7 @@ index fa72ce4e..425574bd 100644
+ return filtered;
+
+ g_assert (IBUS_IS_WAYLAND_IM (wlim));
++ g_assert (active_key);
+ g_assert (mods_depressed);
+
+ priv = ibus_wayland_im_get_instance_private (wlim);
@@ -572,7 +596,7 @@ index fa72ce4e..425574bd 100644
+ g_warning ("IBus modifiers %X is different from XKB depressed %X",
+ modifiers, new_mods_depressed);
+ }
-+ system_sym = xkb_state_key_get_one_sym (priv->state_system, code);
++ system_sym = xkb_state_key_get_one_sym (priv->key_sys.state, code);
+ switch (sym) {
+ case IBUS_KEY_ISO_Level2_Latch:
+ filtered = TRUE;
@@ -583,7 +607,7 @@ index fa72ce4e..425574bd 100644
+ case IBUS_KEY_ISO_Level3_Latch:
+ case IBUS_KEY_ISO_Level3_Shift:
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-+ new_mods_depressed |= priv->mod5_mask;
++ new_mods_depressed |= active_key->mod5_mask;
+ if (sym != system_sym)
+ priv->is_virtual_latch_state = TRUE;
+ filtered = TRUE;
@@ -594,7 +618,7 @@ index fa72ce4e..425574bd 100644
+ case IBUS_KEY_ISO_Level5_Latch:
+ case IBUS_KEY_ISO_Level5_Shift:
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-+ new_mods_depressed |= priv->mod3_mask;
++ new_mods_depressed |= active_key->mod3_mask;
+ if (sym != system_sym)
+ priv->is_virtual_latch_state = TRUE;
+ filtered = TRUE;
@@ -603,9 +627,9 @@ index fa72ce4e..425574bd 100644
+ case IBUS_KEY_Shift_L:
+ case IBUS_KEY_Shift_R:
+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
-+ new_mods_depressed |= priv->shift_mask;
++ new_mods_depressed |= active_key->shift_mask;
+ else
-+ new_mods_depressed &= ~priv->shift_mask;
++ new_mods_depressed &= ~active_key->shift_mask;
+ break;
+ default:;
+ }
@@ -633,6 +657,7 @@ index fa72ce4e..425574bd 100644
+ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
+ uint32_t key,
+ uint32_t state,
++ IBusXkbKeymap *active_key,
+ xkb_mod_mask_t mods_depressed,
+ xkb_mod_mask_t new_mods_depressed,
+ gboolean clear_virtual_state)
@@ -645,12 +670,12 @@ index fa72ce4e..425574bd 100644
+ g_assert (IBUS_IS_WAYLAND_IM (wlim));
+
+ priv = ibus_wayland_im_get_instance_private (wlim);
-+ mods_locked = xkb_state_serialize_mods (priv->state,
++ mods_locked = xkb_state_serialize_mods (active_key->state,
+ XKB_STATE_MODS_LOCKED);
+ /* XKB group layout is configured in the system keymap but not the
+ * user keymap which always includes a single layout.
+ */
-+ group = xkb_state_serialize_layout (priv->state_system,
++ group = xkb_state_serialize_layout (priv->key_sys.state,
+ XKB_STATE_LAYOUT_LOCKED);
+
+ if (priv->is_virtual_latch_state) {
@@ -666,7 +691,7 @@ index fa72ce4e..425574bd 100644
+ }
+ if (!priv->is_virtual_latch_state ||
+ (state != WL_KEYBOARD_KEY_STATE_RELEASED)) {
-+ xkb_state_update_key (priv->state, code,
++ xkb_state_update_key (active_key->state, code,
+ (state == WL_KEYBOARD_KEY_STATE_RELEASED)
+ ? XKB_KEY_UP : XKB_KEY_DOWN);
+ }
@@ -676,10 +701,10 @@ index fa72ce4e..425574bd 100644
static void
_context_commit_text_cb (IBusInputContext *context,
IBusText *text,
-@@ -1257,12 +1462,7 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
- gboolean filtered)
+@@ -1284,12 +1502,7 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
{
IBusWaylandIMPrivate *priv;
+ IBusXkbKeymap *active_key;
- xkb_mod_mask_t mods_depressed = 0, new_mods_depressed = 0;
- xkb_mod_mask_t mods_locked;
- xkb_layout_index_t group;
@@ -690,19 +715,19 @@ index fa72ce4e..425574bd 100644
gboolean clear_virtual_state = FALSE;
g_return_val_if_fail (IBUS_IS_WAYLAND_IM (wlim), FALSE);
-@@ -1287,119 +1487,27 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
+@@ -1318,128 +1531,30 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
XKB_STATE_DEPRESSED |
XKB_STATE_LATCHED);
new_mods_depressed = mods_depressed;
-- mods_locked = xkb_state_serialize_mods (priv->state,
+- mods_locked = xkb_state_serialize_mods (active_key->state,
- XKB_STATE_MODS_LOCKED);
- /* XKB group layout is configured in the system keymap but not the
- * user keymap which always includes a single layout.
- */
-- group = xkb_state_serialize_layout (priv->state_system,
+- group = xkb_state_serialize_layout (priv->key_sys.state,
- XKB_STATE_LAYOUT_LOCKED);
- if (!filtered) {
-- system_sym = xkb_state_key_get_one_sym (priv->state_system, code);
+- system_sym = xkb_state_key_get_one_sym (priv->key_sys.state, code);
- switch (sym) {
- case IBUS_KEY_ISO_Level2_Latch:
- filtered = TRUE;
@@ -713,7 +738,7 @@ index fa72ce4e..425574bd 100644
- case IBUS_KEY_ISO_Level3_Latch:
- case IBUS_KEY_ISO_Level3_Shift:
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-- new_mods_depressed |= priv->mod5_mask;
+- new_mods_depressed |= active_key->mod5_mask;
- if (sym != system_sym)
- priv->is_virtual_latch_state = TRUE;
- filtered = TRUE;
@@ -724,7 +749,7 @@ index fa72ce4e..425574bd 100644
- case IBUS_KEY_ISO_Level5_Latch:
- case IBUS_KEY_ISO_Level5_Shift:
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-- new_mods_depressed |= priv->mod3_mask;
+- new_mods_depressed |= active_key->mod3_mask;
- if (sym != system_sym)
- priv->is_virtual_latch_state = TRUE;
- filtered = TRUE;
@@ -733,9 +758,9 @@ index fa72ce4e..425574bd 100644
- case IBUS_KEY_Shift_L:
- case IBUS_KEY_Shift_R:
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
-- new_mods_depressed |= priv->shift_mask;
+- new_mods_depressed |= active_key->shift_mask;
- else
-- new_mods_depressed &= ~priv->shift_mask;
+- new_mods_depressed &= ~active_key->shift_mask;
- break;
- default:;
- }
@@ -754,7 +779,7 @@ index fa72ce4e..425574bd 100644
- if (state != WL_KEYBOARD_KEY_STATE_RELEASED) {
- ch = ibus_keyval_to_unicode (sym);
- if (ch == 0 || g_unichar_iscntrl (ch))
-- ch = xkb_state_key_get_utf32 (priv->state, code);
+- ch = xkb_state_key_get_utf32 (active_key->state, code);
-/* No text with Control & Alt & Super keys */
-#ifndef GDK_WINDOWING_QUARTZ
-# define _IBUS_NO_TEXT_INPUT_MOD_MASK (\
@@ -765,7 +790,16 @@ index fa72ce4e..425574bd 100644
-#endif
- if ((!filtered && !(modifiers & _IBUS_NO_TEXT_INPUT_MOD_MASK) &&
- !g_unichar_iscntrl (ch)) || filtered) {
-- if (!filtered) {
+- /* In case `use_sys_keymap` is %TRUE, IBus does not commit ASCII chars
+- * but forwards the key events to the focused application here.
+- * Because some applications treat the printable keys as control keys,
+- * E.g. game apps "hjkl" use the cursor move like VI mode.
+- * Unfortunately the Wayland input-method protocol does not provide
+- * the fallback logic after apps handle the key events like GTK3/2
+- * IM modules. But The input-method always should handles key events
+- * prior to apps.
+- */
+- if (!filtered && !priv->use_sys_keymap) {
- gchar buff[8] = { 0, };
- buff[g_unichar_to_utf8 (ch, buff)] = '\0';
- ibus_wayland_im_commit_text (wlim, buff);
@@ -780,11 +814,11 @@ index fa72ce4e..425574bd 100644
- * I'm not clarified with "level3(ralt_switch)" in us XKB keymaps.
- */
- if (modifiers & IBUS_MOD3_MASK) {
-- new_mods_depressed &= ~priv->mod3_mask;
+- new_mods_depressed &= ~active_key->mod3_mask;
- clear_virtual_state = TRUE;
- }
- if (modifiers & IBUS_MOD5_MASK) {
-- new_mods_depressed &= ~priv->mod5_mask;
+- new_mods_depressed &= ~active_key->mod5_mask;
- clear_virtual_state = TRUE;
- }
- }
@@ -803,7 +837,7 @@ index fa72ce4e..425574bd 100644
- }
- if (!priv->is_virtual_latch_state ||
- (state != WL_KEYBOARD_KEY_STATE_RELEASED)) {
-- xkb_state_update_key (priv->state, code,
+- xkb_state_update_key (active_key->state, code,
- (state == WL_KEYBOARD_KEY_STATE_RELEASED)
- ? XKB_KEY_UP : XKB_KEY_DOWN);
- }
@@ -812,6 +846,7 @@ index fa72ce4e..425574bd 100644
+ modifiers,
+ state,
+ sym,
++ active_key,
+ filtered,
+ &new_mods_depressed);
+ filtered = ibus_wayland_im_commit_key_event (wlim,
@@ -819,12 +854,14 @@ index fa72ce4e..425574bd 100644
+ modifiers,
+ state,
+ sym,
++ active_key,
+ filtered,
+ &new_mods_depressed,
+ &clear_virtual_state);
+ ibus_wayland_im_update_virtual_xkb_state (wlim,
+ key,
+ state,
++ active_key,
+ mods_depressed,
+ new_mods_depressed,
+ clear_virtual_state);
@@ -834,648 +871,10 @@ index fa72ce4e..425574bd 100644
--
2.53.0
-From 5ec5a8c428cb64be6491be1d765ab6e15dd7c172 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 29 May 2026 17:42:51 +0900
-Subject: [PATCH 3/9] client/wayland: Separate system xkb_state from user one
-
-The modifier masks could be different by keymaps when
-xkb_map_mod_get_index(keymap, ...) is called and now the keymaps
-and states are separated between the system and user.
-
-Also xkb_state_ref() would not be good because the internal keymaps
-are not ref-counted so now use xkb_state_new(xkb_keymap_ref(keymap))
-instead.
-
-Fixes: https://github.com/ibus/ibus/pull/2869#discussion_r3099963386
----
- client/wayland/ibuswaylandim.c | 277 ++++++++++++++++++++-------------
- 1 file changed, 166 insertions(+), 111 deletions(-)
-
-diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
-index 425574bd..2c022548 100644
---- a/client/wayland/ibuswaylandim.c
-+++ b/client/wayland/ibuswaylandim.c
-@@ -98,9 +98,28 @@ struct _IBusWaylandSeat
- gboolean active;
- gboolean pending_activate;
- gboolean pending_deactivate;
-- gboolean has_keymap;
-+ gboolean has_compositor_keymap;
- };
-
-+typedef struct _IBusXkbKeymap
-+{
-+ int32_t fd;
-+ struct xkb_keymap *keymap;
-+ struct xkb_state *state;
-+
-+ xkb_mod_mask_t shift_mask;
-+ xkb_mod_mask_t lock_mask;
-+ xkb_mod_mask_t control_mask;
-+ xkb_mod_mask_t mod1_mask;
-+ xkb_mod_mask_t mod2_mask;
-+ xkb_mod_mask_t mod3_mask;
-+ xkb_mod_mask_t mod4_mask;
-+ xkb_mod_mask_t mod5_mask;
-+ xkb_mod_mask_t super_mask;
-+ xkb_mod_mask_t hyper_mask;
-+ xkb_mod_mask_t meta_mask;
-+} IBusXkbKeymap;
-+
- typedef struct _IBusWaylandIMPrivate IBusWaylandIMPrivate;
- struct _IBusWaylandIMPrivate
- {
-@@ -140,21 +159,8 @@ struct _IBusWaylandIMPrivate
-
- struct xkb_context *xkb_context;
-
-- struct xkb_keymap *keymap;
-- struct xkb_state *state;
-- struct xkb_state *state_system;
--
-- xkb_mod_mask_t shift_mask;
-- xkb_mod_mask_t lock_mask;
-- xkb_mod_mask_t control_mask;
-- xkb_mod_mask_t mod1_mask;
-- xkb_mod_mask_t mod2_mask;
-- xkb_mod_mask_t mod3_mask;
-- xkb_mod_mask_t mod4_mask;
-- xkb_mod_mask_t mod5_mask;
-- xkb_mod_mask_t super_mask;
-- xkb_mod_mask_t hyper_mask;
-- xkb_mod_mask_t meta_mask;
-+ IBusXkbKeymap key_user;
-+ IBusXkbKeymap key_sys;
-
- uint32_t im_serial;
- int32_t repeat_rate;
-@@ -365,6 +371,7 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
- uint32_t modifiers,
- uint32_t state,
- xkb_keysym_t sym,
-+ IBusXkbKeymap *active_key,
- gboolean filtered,
- xkb_mod_mask_t *new_mods_depressed,
- gboolean *clear_virtual_state)
-@@ -381,7 +388,7 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
-
- ch = ibus_keyval_to_unicode (sym);
- if (ch == 0 || g_unichar_iscntrl (ch))
-- ch = xkb_state_key_get_utf32 (priv->state, code);
-+ ch = xkb_state_key_get_utf32 (active_key->state, code);
-
- /* No text with Control & Alt & Super keys */
- #ifndef GDK_WINDOWING_QUARTZ
-@@ -408,13 +415,13 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
- */
- if (modifiers & IBUS_MOD3_MASK) {
- if (new_mods_depressed)
-- *new_mods_depressed &= ~priv->mod3_mask;
-+ *new_mods_depressed &= ~active_key->mod3_mask;
- if (clear_virtual_state)
- *clear_virtual_state = TRUE;
- }
- if (modifiers & IBUS_MOD5_MASK) {
- if (new_mods_depressed)
-- *new_mods_depressed &= ~priv->mod5_mask;
-+ *new_mods_depressed &= ~active_key->mod5_mask;
- if (clear_virtual_state)
- *clear_virtual_state = TRUE;
- }
-@@ -445,11 +452,11 @@ ibus_wayland_im_key (IBusWaylandIM *wlim,
- case INPUT_METHOD_V2:
- /* wlroots/types/wlr_virtual_keyboard_v1.c:virtual_keyboard_key()
- * returns "Cannot send a keypress before defining a keymap"
-- * if `has_keymap` is %FALSE.
-+ * if `has_compositor_keymap` is %FALSE.
- */
- if (!priv->seat)
- break;
-- if (priv->seat->has_keymap) {
-+ if (priv->seat->has_compositor_keymap) {
- zwp_virtual_keyboard_v1_key (priv->seat->virtual_keyboard,
- time, key, state);
- }
-@@ -506,6 +513,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
- uint32_t modifiers,
- uint32_t state,
- xkb_keysym_t sym,
-+ IBusXkbKeymap *active_key,
- gboolean filtered,
- xkb_mod_mask_t *mods_depressed)
- {
-@@ -518,6 +526,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
- return filtered;
-
- g_assert (IBUS_IS_WAYLAND_IM (wlim));
-+ g_assert (active_key);
- g_assert (mods_depressed);
-
- priv = ibus_wayland_im_get_instance_private (wlim);
-@@ -527,7 +536,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
- g_warning ("IBus modifiers %X is different from XKB depressed %X",
- modifiers, new_mods_depressed);
- }
-- system_sym = xkb_state_key_get_one_sym (priv->state_system, code);
-+ system_sym = xkb_state_key_get_one_sym (priv->key_sys.state, code);
- switch (sym) {
- case IBUS_KEY_ISO_Level2_Latch:
- filtered = TRUE;
-@@ -538,7 +547,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
- case IBUS_KEY_ISO_Level3_Latch:
- case IBUS_KEY_ISO_Level3_Shift:
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-- new_mods_depressed |= priv->mod5_mask;
-+ new_mods_depressed |= active_key->mod5_mask;
- if (sym != system_sym)
- priv->is_virtual_latch_state = TRUE;
- filtered = TRUE;
-@@ -549,7 +558,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
- case IBUS_KEY_ISO_Level5_Latch:
- case IBUS_KEY_ISO_Level5_Shift:
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
-- new_mods_depressed |= priv->mod3_mask;
-+ new_mods_depressed |= active_key->mod3_mask;
- if (sym != system_sym)
- priv->is_virtual_latch_state = TRUE;
- filtered = TRUE;
-@@ -558,9 +567,9 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
- case IBUS_KEY_Shift_L:
- case IBUS_KEY_Shift_R:
- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
-- new_mods_depressed |= priv->shift_mask;
-+ new_mods_depressed |= active_key->shift_mask;
- else
-- new_mods_depressed &= ~priv->shift_mask;
-+ new_mods_depressed &= ~active_key->shift_mask;
- break;
- default:;
- }
-@@ -588,6 +597,7 @@ static void
- ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
- uint32_t key,
- uint32_t state,
-+ IBusXkbKeymap *active_key,
- xkb_mod_mask_t mods_depressed,
- xkb_mod_mask_t new_mods_depressed,
- gboolean clear_virtual_state)
-@@ -600,12 +610,12 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
- g_assert (IBUS_IS_WAYLAND_IM (wlim));
-
- priv = ibus_wayland_im_get_instance_private (wlim);
-- mods_locked = xkb_state_serialize_mods (priv->state,
-+ mods_locked = xkb_state_serialize_mods (active_key->state,
- XKB_STATE_MODS_LOCKED);
- /* XKB group layout is configured in the system keymap but not the
- * user keymap which always includes a single layout.
- */
-- group = xkb_state_serialize_layout (priv->state_system,
-+ group = xkb_state_serialize_layout (priv->key_sys.state,
- XKB_STATE_LAYOUT_LOCKED);
-
- if (priv->is_virtual_latch_state) {
-@@ -621,7 +631,7 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
- }
- if (!priv->is_virtual_latch_state ||
- (state != WL_KEYBOARD_KEY_STATE_RELEASED)) {
-- xkb_state_update_key (priv->state, code,
-+ xkb_state_update_key (active_key->state, code,
- (state == WL_KEYBOARD_KEY_STATE_RELEASED)
- ? XKB_KEY_UP : XKB_KEY_DOWN);
- }
-@@ -1276,47 +1286,53 @@ create_system_xkb_keymap (struct xkb_context *xkb_context,
-
-
- static gboolean
--ibus_wayland_im_update_xkb_state (IBusWaylandIM *wlim,
-- struct xkb_keymap *keymap)
-+ibus_xkb_keymap_update_with_keymap (IBusXkbKeymap *ibus_keymap,
-+ struct xkb_keymap *keymap,
-+ int32_t fd)
- {
-- IBusWaylandIMPrivate *priv;
- struct xkb_state *state;
-
-- g_return_val_if_fail (IBUS_IS_WAYLAND_IM (wlim), FALSE);
-- priv = ibus_wayland_im_get_instance_private (wlim);
-+ g_return_val_if_fail (ibus_keymap, FALSE);
- g_return_val_if_fail (keymap, FALSE);
- g_return_val_if_fail ((state = xkb_state_new (keymap)), FALSE);
-
-- priv->shift_mask =
-+ if (ibus_keymap->state)
-+ xkb_state_unref (ibus_keymap->state);
-+ if (ibus_keymap->keymap) {
-+ xkb_keymap_unref (ibus_keymap->keymap);
-+ if (ibus_keymap->fd) {
-+ close (ibus_keymap->fd);
-+ ibus_keymap->fd = 0;
-+ }
-+ }
-+ ibus_keymap->keymap = keymap;
-+ ibus_keymap->state = state;
-+ if (fd > 0)
-+ ibus_keymap->fd = fd;
-+
-+ ibus_keymap->shift_mask =
- 1 << xkb_map_mod_get_index (keymap, "Shift");
-- priv->lock_mask =
-+ ibus_keymap->lock_mask =
- 1 << xkb_map_mod_get_index (keymap, "Lock");
-- priv->control_mask =
-+ ibus_keymap->control_mask =
- 1 << xkb_map_mod_get_index (keymap, "Control");
-- priv->mod1_mask =
-+ ibus_keymap->mod1_mask =
- 1 << xkb_map_mod_get_index (keymap, "Mod1");
-- priv->mod2_mask =
-+ ibus_keymap->mod2_mask =
- 1 << xkb_map_mod_get_index (keymap, "Mod2");
-- priv->mod3_mask =
-+ ibus_keymap->mod3_mask =
- 1 << xkb_map_mod_get_index (keymap, "Mod3");
-- priv->mod4_mask =
-+ ibus_keymap->mod4_mask =
- 1 << xkb_map_mod_get_index (keymap, "Mod4");
-- priv->mod5_mask =
-+ ibus_keymap->mod5_mask =
- 1 << xkb_map_mod_get_index (keymap, "Mod5");
-- priv->super_mask =
-+ ibus_keymap->super_mask =
- 1 << xkb_map_mod_get_index (keymap, "Super");
-- priv->hyper_mask =
-+ ibus_keymap->hyper_mask =
- 1 << xkb_map_mod_get_index (keymap, "Hyper");
-- priv->meta_mask =
-+ ibus_keymap->meta_mask =
- 1 << xkb_map_mod_get_index (keymap, "Meta");
-
-- if (priv->state)
-- xkb_state_unref (priv->state);
-- if (priv->keymap)
-- xkb_keymap_unref (priv->keymap);
-- priv->keymap = keymap;
-- priv->state = state;
--
- return TRUE;
- }
-
-@@ -1337,13 +1353,16 @@ _bus_global_engine_changed_cb (IBusBus *bus,
- g_assert (desc);
- g_assert (!g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name));
- keymap = create_user_xkb_keymap (priv->xkb_context, desc);
-- if (keymap && !ibus_wayland_im_update_xkb_state (wlim, keymap))
-+ if (keymap && !ibus_xkb_keymap_update_with_keymap (&priv->key_user,
-+ keymap,
-+ 0)) {
- g_clear_pointer (&keymap, xkb_keymap_unref);
-+ }
- if (priv->verbose) {
- fprintf (priv->log, "New engine:%s keymap:%s state:%s\n",
- ibus_engine_desc_get_name (desc),
- keymap ? "TRUE" : "FALSE",
-- priv->state ? "TRUE" : "FALSE");
-+ priv->key_user.state ? "TRUE" : "FALSE");
- fflush (priv->log);
- }
- g_object_unref (desc);
-@@ -1360,8 +1379,6 @@ input_method_keyboard_keymap (void *data,
- IBusWaylandIM *wlim = data;
- IBusWaylandIMPrivate *priv;
- struct xkb_keymap *keymap;
-- struct xkb_state *prev_state = NULL;
-- gboolean has_new_state = FALSE;
-
- if (!IBUS_IS_WAYLAND_IM (wlim)) {
- close (fd);
-@@ -1377,42 +1394,38 @@ input_method_keyboard_keymap (void *data,
- zwp_virtual_keyboard_v1_keymap (priv->seat->virtual_keyboard,
- format, fd, size);
- /* wlroots/types/wlr_virtual_keyboard_v1.c:virtual_keyboard_keymap()
-- * sets %TRUE to `has_keymap`.
-+ * sets %TRUE to `has_compositor_keymap`.
- */
-- priv->seat->has_keymap = TRUE;
-+ priv->seat->has_compositor_keymap = TRUE;
- }
-- if (priv->keymap && priv->state && priv->state_system) {
-+ if (priv->key_user.keymap && priv->key_user.state && priv->key_sys.state) {
- close (fd);
- return;
- }
- keymap = create_system_xkb_keymap (priv->xkb_context, format, fd, size);
-- if (priv->state)
-- prev_state = xkb_state_ref (priv->state);
-- if (keymap)
-- has_new_state = ibus_wayland_im_update_xkb_state (wlim, keymap);
-- if (priv->state) {
-- if (has_new_state) {
-- priv->state_system = xkb_state_ref (priv->state);
-- /* prev->state is user prev->state_system is system */
-- if (prev_state) {
-- xkb_state_unref (priv->state);
-- priv->state = prev_state;
-- }
-- } else {
-- if (prev_state)
-- xkb_state_unref (prev_state);
-- if (keymap)
-- g_clear_pointer (&keymap, xkb_keymap_unref);
-- }
-- } else if (keymap) {
-+ if (keymap &&
-+ !ibus_xkb_keymap_update_with_keymap (&priv->key_sys,
-+ xkb_keymap_ref (keymap),
-+ fd)) {
-+ xkb_keymap_unref (keymap);
-+ g_clear_pointer (&keymap, xkb_keymap_unref);
-+ close (fd);
-+ }
-+ if (keymap && !priv->key_user.state &&
-+ !ibus_xkb_keymap_update_with_keymap (&priv->key_user,
-+ xkb_keymap_ref (keymap),
-+ 0)) {
-+ xkb_keymap_unref (keymap);
- g_clear_pointer (&keymap, xkb_keymap_unref);
- }
-+ if (keymap)
-+ xkb_keymap_unref (keymap);
- if (priv->verbose) {
- fprintf (priv->log, "System keymap format:%u fd:%d size:%u "
- "keymap:%s state:%s\n",
- format, fd, size,
- keymap ? "TRUE" : "FALSE",
-- priv->state ? "TRUE" : "FALSE");
-+ priv->key_sys.state ? "TRUE" : "FALSE");
- fflush (priv->log);
- }
- }
-@@ -1462,6 +1475,7 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
- gboolean filtered)
- {
- IBusWaylandIMPrivate *priv;
-+ IBusXkbKeymap *active_key;
- xkb_mod_mask_t mods_depressed, new_mods_depressed;
- gboolean clear_virtual_state = FALSE;
-
-@@ -1481,9 +1495,13 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
- default:
- g_assert_not_reached ();
- }
-- if (!priv->state)
-- return FALSE;
-- mods_depressed = xkb_state_serialize_mods (priv->state,
-+ if (priv->use_sys_keymap)
-+ active_key = &priv->key_sys;
-+ else
-+ active_key = &priv->key_user;
-+ if (!active_key->state)
-+ return FALSE;
-+ mods_depressed = xkb_state_serialize_mods (active_key->state,
- XKB_STATE_DEPRESSED |
- XKB_STATE_LATCHED);
- new_mods_depressed = mods_depressed;
-@@ -1492,6 +1510,7 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
- modifiers,
- state,
- sym,
-+ active_key,
- filtered,
- &new_mods_depressed);
- filtered = ibus_wayland_im_commit_key_event (wlim,
-@@ -1499,12 +1518,14 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
- modifiers,
- state,
- sym,
-+ active_key,
- filtered,
- &new_mods_depressed,
- &clear_virtual_state);
- ibus_wayland_im_update_virtual_xkb_state (wlim,
- key,
- state,
-+ active_key,
- mods_depressed,
- new_mods_depressed,
- clear_virtual_state);
-@@ -1928,8 +1949,10 @@ input_method_keyboard_key (void *data,
-
- g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim));
- priv = ibus_wayland_im_get_instance_private (wlim);
-- if (!priv->state)
-+ if (!priv->key_user.state) {
-+ ibus_wayland_im_key (wlim, key_serial, time, key, state);
- return;
-+ }
-
- if (!priv->ibuscontext) {
- gboolean retval = ibus_wayland_im_post_key (wlim,
-@@ -1950,14 +1973,14 @@ input_method_keyboard_key (void *data,
- code = key + 8;
- event.sym = 0;
- /* xkb_key_get_syms() does not return the capital syms with Shift key. */
-- if (priv->state_system)
-- event.sym = xkb_state_key_get_one_sym (priv->state_system, code);
-+ if (priv->key_sys.state)
-+ event.sym = xkb_state_key_get_one_sym (priv->key_sys.state, code);
- switch (event.sym) {
- case IBUS_KEY_Multi_key:
- case IBUS_KEY_ISO_Next_Group:
- break;
- default:
-- event.sym = xkb_state_key_get_one_sym (priv->state, code);
-+ event.sym = xkb_state_key_get_one_sym (priv->key_user.state, code);
- }
- event.modifiers = priv->modifiers;
- if (state == WL_KEYBOARD_KEY_STATE_RELEASED)
-@@ -1971,8 +1994,8 @@ input_method_keyboard_key (void *data,
- G_STRFUNC,
- key_serial, time, key,
- event.sym,
-- xkb_state_key_get_one_sym (priv->state, code),
-- xkb_state_key_get_one_sym (priv->state_system, code),
-+ xkb_state_key_get_one_sym (priv->key_user.state, code),
-+ xkb_state_key_get_one_sym (priv->key_sys.state, code),
- event.modifiers, state ? "press" : "release");
- fflush (priv->log);
- }
-@@ -1990,6 +2013,29 @@ input_method_keyboard_key (void *data,
- }
-
-
-+/**
-+ * input_method_keyboard_modifiers:
-+ *
-+ * This is a common API of input_method_keyboard_modifiers_v1() and
-+ * input_method_keyboard_modifiers_v2().
-+ * If you configure multiple XKB layouts in the system with
-+ * /etc/vconsole.conf file, you can switch the active layout with
-+ * the XKB options and @group is changed with the shortcut key like
-+ * "grp:lalt_lshift_toggle" but If you click the keyboard icon in
-+ * Plasma KDE and change the active layout with GUI, @group is not
-+ * changed and I assume it's a bug [1].
-+ * Currently there are two cases of the combinations of the IBus keymap and
-+ * the system keymap supported by IBus:
-+ * 1. Always Same keymaps
-+ * E.g. IBus keymap is "lv(tilde)" and system one is "lv(tilde)"
-+ * 2. System keymap is "US" and switch IBus keymaps with Super-space key
-+ * E.g. IBus keymap is "lv(tilde)" and system one is "us"
-+ * So you should use both XKB option keys and IBus shortcutkeys to switch the
-+ * keymaps to change both XKB keymaps and IBus keymaps but you should not
-+ * click the keyboard icon in KDE.
-+ *
-+ * [1] https://bugs.kde.org/show_bug.cgi?id=518371
-+ */
- static void
- input_method_keyboard_modifiers (void *data,
- struct zwp_keyboard_union *keyboard,
-@@ -2001,10 +2047,15 @@ input_method_keyboard_modifiers (void *data,
- {
- IBusWaylandIM *wlim = data;
- IBusWaylandIMPrivate *priv;
-+ IBusXkbKeymap *active_key;
- xkb_mod_mask_t mask;
-
- g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim));
- priv = ibus_wayland_im_get_instance_private (wlim);
-+ if (priv->use_sys_keymap)
-+ active_key = &priv->key_sys;
-+ else
-+ active_key = &priv->key_user;
- /* Do not reset Latch modifiers by system in case the system keymap
- * has no the Latch key.
- * In case the user keymap is "lv(tilde)" and the system one is "us",
-@@ -2017,58 +2068,59 @@ input_method_keyboard_modifiers (void *data,
- * not to override the state of the "us" keymap.
- */
- if (!priv->is_virtual_latch_state || key_serial == 0) {
-- xkb_state_update_mask (priv->state, mods_depressed,
-+ xkb_state_update_mask (priv->key_user.state, mods_depressed,
- mods_latched, mods_locked, 0, 0, group);
- /* Pressing XKB group key likes Alt_R with grp:toggle calls
- * input_method_keyboard_modifiers() with the updated `group`
-- * and need to update priv->state_system to switch the XKB group
-+ * and need to update priv->key_sys.state to switch the XKB group
- * in the system keymap.
- *
- * XKB group key can switch `group` but clicking the keyboard icon
- * of KDE does not change `group` at present. Maybe a bug in the
- * KDE Wayland compositor.
- */
-- xkb_state_update_mask (priv->state_system, mods_depressed,
-+ xkb_state_update_mask (priv->key_sys.state, mods_depressed,
- mods_latched, mods_locked, 0, 0, group);
- }
- /* CapsLock needs XKB_STATE_MODS_LOCKED */
-- mask = xkb_state_serialize_mods (priv->state,
-+ mask = xkb_state_serialize_mods (active_key->state,
- XKB_STATE_DEPRESSED |
- XKB_STATE_LATCHED |
- XKB_STATE_MODS_LOCKED);
- if (priv->verbose) {
-+ struct xkb_state *state = active_key->state;
- fprintf (priv->log, "Update modifiers serial:%u depress:%X latch:%X "
- "lock:%X group:%X orig_depre:%X orig_latch:%X "
- "orig_lock:%X\n",
- key_serial, mods_depressed, mods_latched, mods_locked, group,
-- xkb_state_serialize_mods (priv->state, XKB_STATE_DEPRESSED),
-- xkb_state_serialize_mods (priv->state, XKB_STATE_LATCHED),
-- xkb_state_serialize_mods (priv->state, XKB_STATE_MODS_LOCKED));
-+ xkb_state_serialize_mods (state, XKB_STATE_DEPRESSED),
-+ xkb_state_serialize_mods (state, XKB_STATE_LATCHED),
-+ xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED));
- fflush (priv->log);
- }
-
- priv->modifiers = 0;
-- if (mask & priv->shift_mask)
-+ if (mask & active_key->shift_mask)
- priv->modifiers |= IBUS_SHIFT_MASK;
-- if (mask & priv->lock_mask)
-+ if (mask & active_key->lock_mask)
- priv->modifiers |= IBUS_LOCK_MASK;
-- if (mask & priv->control_mask)
-+ if (mask & active_key->control_mask)
- priv->modifiers |= IBUS_CONTROL_MASK;
-- if (mask & priv->mod1_mask)
-+ if (mask & active_key->mod1_mask)
- priv->modifiers |= IBUS_MOD1_MASK;
-- if (mask & priv->mod2_mask)
-+ if (mask & active_key->mod2_mask)
- priv->modifiers |= IBUS_MOD2_MASK;
-- if (mask & priv->mod3_mask)
-+ if (mask & active_key->mod3_mask)
- priv->modifiers |= IBUS_MOD3_MASK;
-- if (mask & priv->mod4_mask)
-+ if (mask & active_key->mod4_mask)
- priv->modifiers |= IBUS_MOD4_MASK;
-- if (mask & priv->mod5_mask)
-+ if (mask & active_key->mod5_mask)
- priv->modifiers |= IBUS_MOD5_MASK;
-- if (mask & priv->super_mask)
-+ if (mask & active_key->super_mask)
- priv->modifiers |= IBUS_SUPER_MASK;
-- if (mask & priv->hyper_mask)
-+ if (mask & active_key->hyper_mask)
- priv->modifiers |= IBUS_HYPER_MASK;
-- if (mask & priv->meta_mask)
-+ if (mask & active_key->meta_mask)
- priv->modifiers |= IBUS_META_MASK;
-
- if (!key_serial)
-@@ -2083,11 +2135,11 @@ input_method_keyboard_modifiers (void *data,
- case INPUT_METHOD_V2:
- /* wlroots/types/wlr_virtual_keyboard_v1.c:virtual_keyboard_modifiers()
- * returns "Cannot send a modifier state before defining a keymap"
-- * if `has_keymap` is %FALSE.
-+ * if `has_compositor_keymap` is %FALSE.
- */
- if (!priv->seat)
- break;
-- if (priv->seat->has_keymap) {
-+ if (priv->seat->has_compositor_keymap) {
- zwp_virtual_keyboard_v1_modifiers (priv->seat->virtual_keyboard,
- mods_depressed, mods_latched,
- mods_locked, group);
-@@ -2372,7 +2424,7 @@ input_method_activate (void *data,
- /* Regenerating `virtual_keyboard` causes `size` = 0 in
- * input_method_keyboard_keymap() with focus changes in Sway session.
- */
-- priv->seat->has_keymap = FALSE;
-+ priv->seat->has_compositor_keymap = FALSE;
- priv->seat->keyboard_v2 = zwp_input_method_v2_grab_keyboard (
- input_method->u.input_method_v2);
- zwp_input_method_keyboard_grab_v2_add_listener (
-@@ -3051,8 +3103,11 @@ ibus_wayland_im_constructor (GType type,
- desc = ibus_bus_get_global_engine (priv->ibusbus);
- if (desc)
- keymap = create_user_xkb_keymap (priv->xkb_context, desc);
-- if (keymap && !ibus_wayland_im_update_xkb_state (wlim, keymap))
-+ if (keymap && !ibus_xkb_keymap_update_with_keymap (&priv->key_user,
-+ keymap,
-+ 0)) {
- g_clear_pointer (&keymap, xkb_keymap_unref);
-+ }
- if (priv->verbose) {
- if (!desc) {
- fprintf (priv->log, "Constructor has No global engine\n");
-@@ -3060,7 +3115,7 @@ ibus_wayland_im_constructor (GType type,
- fprintf (priv->log, "Constructor engine %s keymap:%s state:%s\n",
- ibus_engine_desc_get_name (desc),
- keymap ? "TRUE" : "FALSE",
-- priv->state ? "TRUE" : "FALSE");
-+ priv->key_user.state ? "TRUE" : "FALSE");
- }
- fflush (priv->log);
- }
---
-2.53.0
-
-From 65520b9c20943ff6d3b290b9ca41ed370e94cdf2 Mon Sep 17 00:00:00 2001
+From 36ab2bc5bf6881632d09d0be23b95401dfdea2a4 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 29 May 2026 17:43:17 +0900
-Subject: [PATCH 4/9] client/wayland: Refactor ISO_Level[3|5]_Shift state
+Date: Wed, 17 Jun 2026 19:51:08 +0900
+Subject: [PATCH 3/4] client/wayland: Refactor ISO_Level[3|5]_Shift state
The states of ISO Shift keys should be cleared when the key is released
against ISO Latch keys. E.g. "RALT" key in "lv(tilde)" keymap.
@@ -1492,10 +891,10 @@ Closes: rhbz#2444009
1 file changed, 127 insertions(+), 12 deletions(-)
diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
-index 2c022548..cd92a988 100644
+index 2cc2079b..571c7b05 100644
--- a/client/wayland/ibuswaylandim.c
+++ b/client/wayland/ibuswaylandim.c
-@@ -62,6 +62,13 @@ typedef enum
+@@ -64,6 +64,13 @@ typedef enum
INPUT_METHOD_V2,
} IMProtocolVersion;
@@ -1509,7 +908,7 @@ index 2c022548..cd92a988 100644
struct zwp_input_method_context_union {
union {
struct zwp_input_method_context_v1 *context_v1;
-@@ -161,6 +168,8 @@ struct _IBusWaylandIMPrivate
+@@ -163,6 +170,8 @@ struct _IBusWaylandIMPrivate
IBusXkbKeymap key_user;
IBusXkbKeymap key_sys;
@@ -1518,7 +917,7 @@ index 2c022548..cd92a988 100644
uint32_t im_serial;
int32_t repeat_rate;
-@@ -339,6 +348,28 @@ ibus_wayland_source_new (struct wl_display *display)
+@@ -341,6 +350,28 @@ ibus_wayland_source_new (struct wl_display *display)
}
@@ -1547,7 +946,7 @@ index 2c022548..cd92a988 100644
static void
ibus_wayland_im_commit_text (IBusWaylandIM *wlim,
const char *str)
-@@ -515,7 +546,8 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
+@@ -526,7 +557,8 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
xkb_keysym_t sym,
IBusXkbKeymap *active_key,
gboolean filtered,
@@ -1557,7 +956,7 @@ index 2c022548..cd92a988 100644
{
IBusWaylandIMPrivate *priv;
uint32_t code = key + 8;
-@@ -528,6 +560,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
+@@ -539,6 +571,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
g_assert (IBUS_IS_WAYLAND_IM (wlim));
g_assert (active_key);
g_assert (mods_depressed);
@@ -1565,7 +964,7 @@ index 2c022548..cd92a988 100644
priv = ibus_wayland_im_get_instance_private (wlim);
new_mods_depressed = *mods_depressed;
-@@ -543,25 +576,87 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
+@@ -554,25 +587,87 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
break;
/* Level3_latch is caused by TLDE key in lv(tilde) keymap.
* Level3_Shift is caused by Alt key in lv(tilde) keymap.
@@ -1663,7 +1062,7 @@ index 2c022548..cd92a988 100644
}
break;
case IBUS_KEY_Shift_L:
-@@ -635,6 +730,23 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
+@@ -646,6 +741,23 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
(state == WL_KEYBOARD_KEY_STATE_RELEASED)
? XKB_KEY_UP : XKB_KEY_DOWN);
}
@@ -1687,15 +1086,15 @@ index 2c022548..cd92a988 100644
}
-@@ -1350,6 +1462,7 @@ _bus_global_engine_changed_cb (IBusBus *bus,
+@@ -1351,6 +1463,7 @@ _bus_global_engine_changed_cb (IBusBus *bus,
g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim));
priv = ibus_wayland_im_get_instance_private (wlim);
desc = ibus_bus_get_global_engine (bus);
+ ibus_wayland_im_reset_modifiers (wlim);
g_assert (desc);
g_assert (!g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name));
- keymap = create_user_xkb_keymap (priv->xkb_context, desc);
-@@ -1512,7 +1625,8 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
+ /* Always update priv->key_user even if priv->use_sys_keymap is %FALSE
+@@ -1538,7 +1651,8 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
sym,
active_key,
filtered,
@@ -1705,7 +1104,7 @@ index 2c022548..cd92a988 100644
filtered = ibus_wayland_im_commit_key_event (wlim,
key,
modifiers,
-@@ -2378,6 +2492,7 @@ _create_input_context_done (GObject *object,
+@@ -2411,6 +2525,7 @@ _create_input_context_done (GObject *object,
TRUE);
}
ibus_input_context_focus_in (priv->ibuscontext);
@@ -1716,10 +1115,11 @@ index 2c022548..cd92a988 100644
--
2.53.0
-From e81da9e11e6ff3847d6b84fec0cff9fcf1565663 Mon Sep 17 00:00:00 2001
+From 507c11b947f59be10b997ad4522024fcc2552845 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 29 May 2026 17:43:26 +0900
-Subject: [PATCH 5/9] client/wayland: Fix infinite dead_diaeresis with fr(ergol) keymap
+Date: Mon, 15 Jun 2026 11:50:53 +0900
+Subject: [PATCH 4/4] client/wayland: Fix infinite dead_diaeresis with
+ fr(ergol) keymap
Typing the key <AD09> twice gives different keysyms between KeyPress
and KeyRelease events and causes the reverse order of KeyPress and
@@ -1730,14 +1130,14 @@ the key <AD09> twice.
Closes: #2894
---
- client/wayland/ibuswaylandim.c | 227 +++++++++++++++++++++++----------
- 1 file changed, 163 insertions(+), 64 deletions(-)
+ client/wayland/ibuswaylandim.c | 245 +++++++++++++++++++++++----------
+ 1 file changed, 172 insertions(+), 73 deletions(-)
diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
-index cd92a988..1e1e272c 100644
+index 571c7b05..9c69439a 100644
--- a/client/wayland/ibuswaylandim.c
+++ b/client/wayland/ibuswaylandim.c
-@@ -69,6 +69,12 @@ typedef enum {
+@@ -71,6 +71,12 @@ typedef enum {
IBUS_KEY_ISO_LEVEL_5
} IBusKeyIsoLevelValue;
@@ -1750,7 +1150,7 @@ index cd92a988..1e1e272c 100644
struct zwp_input_method_context_union {
union {
struct zwp_input_method_context_v1 *context_v1;
-@@ -168,12 +174,14 @@ struct _IBusWaylandIMPrivate
+@@ -170,12 +176,14 @@ struct _IBusWaylandIMPrivate
IBusXkbKeymap key_user;
IBusXkbKeymap key_sys;
@@ -1767,7 +1167,7 @@ index cd92a988..1e1e272c 100644
GCancellable *cancellable;
};
-@@ -358,8 +366,10 @@ ibus_wayland_im_reset_modifiers (IBusWaylandIM *wlim)
+@@ -360,8 +368,10 @@ ibus_wayland_im_reset_modifiers (IBusWaylandIM *wlim)
priv = ibus_wayland_im_get_instance_private (wlim);
priv->is_virtual_latch_state = FALSE;
@@ -1780,7 +1180,7 @@ index cd92a988..1e1e272c 100644
if (priv->key_user.state && priv->key_sys.state) {
group = xkb_state_serialize_layout (priv->key_sys.state,
XKB_STATE_LAYOUT_LOCKED);
-@@ -405,7 +415,8 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
+@@ -407,7 +417,8 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
IBusXkbKeymap *active_key,
gboolean filtered,
xkb_mod_mask_t *new_mods_depressed,
@@ -1790,7 +1190,7 @@ index cd92a988..1e1e272c 100644
{
IBusWaylandIMPrivate *priv;
uint32_t code = key + 8;
-@@ -414,9 +425,6 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
+@@ -416,9 +427,6 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
g_return_val_if_fail (IBUS_IS_WAYLAND_IM (wlim), filtered);
priv = ibus_wayland_im_get_instance_private (wlim);
@@ -1800,13 +1200,22 @@ index cd92a988..1e1e272c 100644
ch = ibus_keyval_to_unicode (sym);
if (ch == 0 || g_unichar_iscntrl (ch))
ch = xkb_state_key_get_utf32 (active_key->state, code);
-@@ -429,14 +437,19 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
+@@ -431,23 +439,28 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
# define _IBUS_NO_TEXT_INPUT_MOD_MASK (\
IBUS_CONTROL_MASK | IBUS_MOD2_MASK | IBUS_MOD4_MASK)
#endif
- if ((!filtered && !(modifiers & _IBUS_NO_TEXT_INPUT_MOD_MASK) &&
- !g_unichar_iscntrl (ch)) || filtered) {
-- if (!filtered) {
+- /* In case `use_sys_keymap` is %TRUE, IBus does not commit ASCII chars
+- * but forwards the key events to the focused application here.
+- * Because some applications treat the printable keys as control keys,
+- * E.g. game apps "hjkl" use the cursor move like VI mode.
+- * Unfortunately the Wayland input-method protocol does not provide
+- * the fallback logic after apps handle the key events like GTK3/2
+- * IM modules. But The input-method always should handles key events
+- * prior to apps.
+- */
+- if (!filtered && !priv->use_sys_keymap) {
- gchar buff[8] = { 0, };
- buff[g_unichar_to_utf8 (ch, buff)] = '\0';
- ibus_wayland_im_commit_text (wlim, buff);
@@ -1818,7 +1227,16 @@ index cd92a988..1e1e272c 100644
+ }
+#undef _IBUS_NO_TEXT_INPUT_MOD_MASK
+
-+ if (!filtered && !g_unichar_iscntrl (ch)) {
++ /* In case `use_sys_keymap` is %TRUE, IBus does not commit ASCII chars
++ * but forwards the key events to the focused application here.
++ * Because some applications treat the printable keys as control keys,
++ * E.g. game apps "hjkl" use the cursor move like VI mode.
++ * Unfortunately the Wayland input-method protocol does not provide
++ * the fallback logic after apps handle the key events like GTK3/2
++ * IM modules. But The input-method always should handles key events
++ * prior to apps.
++ */
++ if (!filtered && !g_unichar_iscntrl (ch) && !priv->use_sys_keymap) {
+ gchar buff[8] = { 0, };
+ buff[g_unichar_to_utf8 (ch, buff)] = '\0';
+ ibus_wayland_im_commit_text (wlim, buff);
@@ -1828,7 +1246,7 @@ index cd92a988..1e1e272c 100644
/* If `filtered` is %TRUE, the keysym can be eaten for the compose
* preedit by IBus XKB engine. E.g. AltGr-Shift-V key produces
* `Level3_Shift' and `Greek_OMEGA` keysym with "us(symbolic)" keymap.
-@@ -445,19 +458,42 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
+@@ -456,19 +469,42 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
* I'm not clarified with "level3(ralt_switch)" in us XKB keymaps.
*/
if (modifiers & IBUS_MOD3_MASK) {
@@ -1876,7 +1294,7 @@ index cd92a988..1e1e272c 100644
return filtered;
}
-@@ -547,7 +583,8 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
+@@ -558,7 +594,8 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
IBusXkbKeymap *active_key,
gboolean filtered,
xkb_mod_mask_t *mods_depressed,
@@ -1886,7 +1304,7 @@ index cd92a988..1e1e272c 100644
{
IBusWaylandIMPrivate *priv;
uint32_t code = key + 8;
-@@ -561,6 +598,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
+@@ -572,6 +609,7 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
g_assert (active_key);
g_assert (mods_depressed);
g_assert (clear_virtual_state);
@@ -1894,7 +1312,7 @@ index cd92a988..1e1e272c 100644
priv = ibus_wayland_im_get_instance_private (wlim);
new_mods_depressed = *mods_depressed;
-@@ -585,13 +623,19 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
+@@ -596,13 +634,19 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
switch (sym) {
case IBUS_KEY_ISO_Level3_Latch:
@@ -1916,7 +1334,7 @@ index cd92a988..1e1e272c 100644
new_mods_depressed |= active_key->mod3_mask;
break;
default:
-@@ -602,61 +646,70 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
+@@ -613,61 +657,70 @@ ibus_wayland_im_update_virtual_depressed (IBusWaylandIM *wlim,
filtered = TRUE;
} else {
IBusKeyIsoLevelValue current_level = IBUS_KEY_ISO_LEVEL_INVALID;
@@ -2020,7 +1438,7 @@ index cd92a988..1e1e272c 100644
}
break;
case IBUS_KEY_Shift_L:
-@@ -695,7 +748,8 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
+@@ -706,7 +759,8 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
IBusXkbKeymap *active_key,
xkb_mod_mask_t mods_depressed,
xkb_mod_mask_t new_mods_depressed,
@@ -2030,7 +1448,7 @@ index cd92a988..1e1e272c 100644
{
IBusWaylandIMPrivate *priv;
uint32_t code = key + 8;
-@@ -724,8 +778,9 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
+@@ -735,8 +789,9 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
if (clear_virtual_state)
priv->is_virtual_latch_state = FALSE;
}
@@ -2042,7 +1460,7 @@ index cd92a988..1e1e272c 100644
xkb_state_update_key (active_key->state, code,
(state == WL_KEYBOARD_KEY_STATE_RELEASED)
? XKB_KEY_UP : XKB_KEY_DOWN);
-@@ -740,7 +795,8 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
+@@ -751,7 +806,8 @@ ibus_wayland_im_update_virtual_xkb_state (IBusWaylandIM *wlim,
/* "de(T3)" keymap gives the pressed "Level3_Shift" keysym and
* sets both MOD3(Level5) and MOD5(Level3) states after
* xkb_state_update_key() is called with the keypress.
@@ -2052,7 +1470,7 @@ index cd92a988..1e1e272c 100644
*/
if (G_UNLIKELY (new_mods_depressed != new2_mods_depressed)) {
xkb_state_update_mask (active_key->state, new_mods_depressed,
-@@ -1591,6 +1647,7 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
+@@ -1617,6 +1673,7 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
IBusXkbKeymap *active_key;
xkb_mod_mask_t mods_depressed, new_mods_depressed;
gboolean clear_virtual_state = FALSE;
@@ -2060,7 +1478,7 @@ index cd92a988..1e1e272c 100644
g_return_val_if_fail (IBUS_IS_WAYLAND_IM (wlim), FALSE);
priv = ibus_wayland_im_get_instance_private (wlim);
-@@ -1626,7 +1683,8 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
+@@ -1652,7 +1709,8 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
active_key,
filtered,
&new_mods_depressed,
@@ -2070,7 +1488,7 @@ index cd92a988..1e1e272c 100644
filtered = ibus_wayland_im_commit_key_event (wlim,
key,
modifiers,
-@@ -1635,14 +1693,16 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
+@@ -1661,14 +1719,16 @@ ibus_wayland_im_post_key (IBusWaylandIM *wlim,
active_key,
filtered,
&new_mods_depressed,
@@ -2089,7 +1507,7 @@ index cd92a988..1e1e272c 100644
return filtered;
}
-@@ -2021,6 +2081,21 @@ key_event_check_repeat (IBusWaylandIM *wlim,
+@@ -2047,6 +2107,21 @@ key_event_check_repeat (IBusWaylandIM *wlim,
g_clear_pointer (&repeating_event.ibus_object_path, g_free);
if (!priv->ibuscontext)
return FALSE;
@@ -2111,7 +1529,7 @@ index cd92a988..1e1e272c 100644
source = g_timeout_source_new (priv->repeat_delay);
g_source_attach (source, NULL);
g_source_unref (source);
-@@ -2034,6 +2109,30 @@ key_event_check_repeat (IBusWaylandIM *wlim,
+@@ -2060,6 +2135,30 @@ key_event_check_repeat (IBusWaylandIM *wlim,
g_source_set_callback (source, _process_key_event_repeat_delay_cb,
&repeating_event, NULL);
} else {
@@ -2145,642 +1563,3 @@ index cd92a988..1e1e272c 100644
--
2.53.0
-From 66c3b4a02e975c230ed8eaab3dd0311e40da7b7b Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 29 May 2026 17:43:35 +0900
-Subject: [PATCH 6/9] client/wayland: Implement IBusWaylandIM:use-system-keymap
-
-Support to use the session keymap forcibly regardless of IBus XKB
-engines. Also let each application handle ASCII keys since the Wayland
-input-method protocol does not support to handle keys after applications
-handle one.
----
- client/wayland/ibuswaylandim.c | 43 ++++++++++++++++++++++++++++++----
- 1 file changed, 38 insertions(+), 5 deletions(-)
-
-diff --git a/client/wayland/ibuswaylandim.c b/client/wayland/ibuswaylandim.c
-index 1e1e272c..5762f10b 100644
---- a/client/wayland/ibuswaylandim.c
-+++ b/client/wayland/ibuswaylandim.c
-@@ -47,7 +47,8 @@ enum {
- PROP_BUS,
- PROP_DISPLAY,
- PROP_LOG,
-- PROP_VERBOSE
-+ PROP_VERBOSE,
-+ PROP_USE_SYS_KEYMAP
- };
-
- enum {
-@@ -138,6 +139,7 @@ struct _IBusWaylandIMPrivate
- {
- FILE *log;
- gboolean verbose;
-+ gboolean use_sys_keymap;
- struct wl_display *display;
- IMProtocolVersion version;
-
-@@ -443,7 +445,16 @@ ibus_wayland_im_commit_key_event (IBusWaylandIM *wlim,
- }
- #undef _IBUS_NO_TEXT_INPUT_MOD_MASK
-
-- if (!filtered && !g_unichar_iscntrl (ch)) {
-+ /* In case `use_sys_keymap` is %TRUE, IBus does not commit ASCII chars
-+ * but forwards the key events to the focused application here.
-+ * Because some applications treat the printable keys as control keys,
-+ * E.g. game apps "hjkl" use the cursor move like VI mode.
-+ * Unfortunately the Wayland input-method protocol does not provide
-+ * the fallback logic after apps handle the key events like GTK3/2
-+ * IM modules. But The input-method always should handles key events
-+ * prior to apps.
-+ */
-+ if (!filtered && !g_unichar_iscntrl (ch) && !priv->use_sys_keymap) {
- gchar buff[8] = { 0, };
- buff[g_unichar_to_utf8 (ch, buff)] = '\0';
- ibus_wayland_im_commit_text (wlim, buff);
-@@ -1512,7 +1523,7 @@ _bus_global_engine_changed_cb (IBusBus *bus,
- {
- IBusWaylandIMPrivate *priv;
- IBusEngineDesc *desc;
-- struct xkb_keymap *keymap;
-+ struct xkb_keymap *keymap = NULL;
-
- g_return_if_fail (IBUS_IS_BUS (bus));
- g_return_if_fail (IBUS_IS_WAYLAND_IM (wlim));
-@@ -1521,7 +1532,8 @@ _bus_global_engine_changed_cb (IBusBus *bus,
- ibus_wayland_im_reset_modifiers (wlim);
- g_assert (desc);
- g_assert (!g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name));
-- keymap = create_user_xkb_keymap (priv->xkb_context, desc);
-+ if (!priv->use_sys_keymap)
-+ keymap = create_user_xkb_keymap (priv->xkb_context, desc);
- if (keymap && !ibus_xkb_keymap_update_with_keymap (&priv->key_user,
- keymap,
- 0)) {
-@@ -3179,6 +3191,21 @@ ibus_wayland_im_class_init (IBusWaylandIMClass *class)
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-+ /**
-+ * IBusWaylandIM:use-system-keymap:
-+ *
-+ * Use system keymap.
-+ * %TRUE if the session keymap is used forcibly instead of keymaps of the
-+ * IBus XKB engines, otherwise %FALSE.
-+ */
-+ g_object_class_install_property (gobject_class,
-+ PROP_USE_SYS_KEYMAP,
-+ g_param_spec_boolean ("use-system-keymap",
-+ "use system keymap",
-+ "Use system keymap",
-+ FALSE,
-+ G_PARAM_READWRITE));
-+
- /* install signals */
- /* this module can call ibus_input_context_focus_in() and the focus-in
- * signal can reach the IBus panel and this also can call
-@@ -3315,7 +3342,7 @@ ibus_wayland_im_constructor (GType type,
- return NULL;
- }
- desc = ibus_bus_get_global_engine (priv->ibusbus);
-- if (desc)
-+ if (desc && !priv->use_sys_keymap)
- keymap = create_user_xkb_keymap (priv->xkb_context, desc);
- if (keymap && !ibus_xkb_keymap_update_with_keymap (&priv->key_user,
- keymap,
-@@ -3408,6 +3435,9 @@ ibus_wayland_im_set_property (IBusWaylandIM *wlim,
- g_assert (!priv->verbose);
- priv->verbose = g_value_get_boolean (value);
- break;
-+ case PROP_USE_SYS_KEYMAP:
-+ priv->use_sys_keymap = g_value_get_boolean (value);
-+ break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (wlim, prop_id, pspec);
- }
-@@ -3437,6 +3467,9 @@ ibus_wayland_im_get_property (IBusWaylandIM *wlim,
- case PROP_VERBOSE:
- g_value_set_boolean (value, priv->verbose);
- break;
-+ case PROP_USE_SYS_KEYMAP:
-+ g_value_set_boolean (value, priv->use_sys_keymap);
-+ break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (wlim, prop_id, pspec);
- }
---
-2.53.0
-
-From 88463fcfedb017a47e5493726d15510fc7239138 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 29 May 2026 17:43:43 +0900
-Subject: [PATCH 7/9] ui/gtk3: Support use-system-keyboard-layout for Wayland
-
----
- ui/gtk3/application.vala | 7 +++++++
- ui/gtk3/panel.vala | 7 ++++---
- 2 files changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/ui/gtk3/application.vala b/ui/gtk3/application.vala
-index a9962685..d82bcc76 100644
---- a/ui/gtk3/application.vala
-+++ b/ui/gtk3/application.vala
-@@ -39,6 +39,7 @@ class Application {
- #if USE_GDK_WAYLAND
- private static ulong m_bus_connected_id;
- private static ulong m_realize_surface_id;
-+ private static ulong m_use_system_keymap_id;
- private static ulong m_ibus_focus_in_id;
- private static ulong m_ibus_focus_out_id;
- private static string m_user;
-@@ -115,6 +116,8 @@ class Application {
- if (m_wayland_im != null) {
- m_realize_surface_id = m_panel.realize_surface.connect(
- (w, s) => this.set_wayland_surface(s));
-+ m_use_system_keymap_id = m_panel.use_system_keymap.connect(
-+ (w, b) => m_wayland_im.use_system_keymap = b);
- m_ibus_focus_in_id = m_wayland_im.ibus_focus_in.connect(
- (w, o) => m_panel.set_wayland_object_path(o));
- m_ibus_focus_out_id = m_wayland_im.ibus_focus_out.connect(
-@@ -146,6 +149,10 @@ class Application {
- GLib.SignalHandler.disconnect(m_panel, m_realize_surface_id);
- m_realize_surface_id = 0;
- }
-+ if (m_use_system_keymap_id != 0) {
-+ GLib.SignalHandler.disconnect(m_panel, m_use_system_keymap_id);
-+ m_use_system_keymap_id = 0;
-+ }
- if (m_ibus_focus_in_id != 0) {
- GLib.SignalHandler.disconnect(m_wayland_im, m_ibus_focus_in_id);
- m_ibus_focus_in_id = 0;
-diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
-index a13b8773..a416a6ef 100644
---- a/ui/gtk3/panel.vala
-+++ b/ui/gtk3/panel.vala
-@@ -104,9 +104,7 @@ class Panel : IBus.PanelService {
- #if USE_GDK_WAYLAND
- private string? m_wayland_object_path;
- public signal void realize_surface(void *surface);
-- public signal void update_shortcut_keys(
-- IBus.ProcessKeyEventData[] data,
-- BindingCommon.KeyEventFuncType ftype);
-+ public signal void use_system_keymap(bool use_sys_keymap);
- #endif
-
- public Panel(IBus.Bus bus,
-@@ -747,6 +745,9 @@ class Panel : IBus.PanelService {
- private void set_use_system_keyboard_layout() {
- m_use_system_keyboard_layout =
- m_settings_general.get_boolean("use-system-keyboard-layout");
-+#if USE_GDK_WAYLAND
-+ use_system_keymap(m_use_system_keyboard_layout);
-+#endif
- }
-
- private void set_embed_preedit_text() {
---
-2.53.0
-
-From 07bc6f7a3f13d2113e347fb4c917f12d4a2f0ec1 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Fri, 29 May 2026 18:26:54 +0900
-Subject: [PATCH 8/9] src: Update IS_DEAD_KEY()
-
-export IS_DEAD_KEY() in ibusinternal.h for ibus-wayland.
-Add engine/test-dead.py to compare ibusinternal.h and ibuskeysyms.h
----
- configure.ac | 13 ++++
- engine/Makefile.am | 10 ++-
- engine/meson.build | 16 ++--
- engine/test-dead.py | 136 ++++++++++++++++++++++++++++++++++
- meson.options | 5 ++
- src/ibuscomposetable.c | 15 ++--
- src/ibusenginesimple.c | 4 +-
- src/ibusenginesimpleprivate.h | 12 +--
- src/ibusinternal.h | 11 ++-
- 9 files changed, 200 insertions(+), 22 deletions(-)
- create mode 100755 engine/test-dead.py
-
-diff --git a/configure.ac b/configure.ac
-index a59ebe47..88c6d8fd 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -793,6 +793,18 @@ PKG_CHECK_MODULES(XFIXES,
- [have_xfixes="no (libXfixes version is lower than 6)"]
- )
-
-+# --enable-distro-tests
-+AC_ARG_ENABLE(distro-tests,
-+ AS_HELP_STRING([--enable-distro-tests],
-+ [Enable to test distro files]),
-+ [enable_distro_tests=$enableval],
-+ [enable_distro_tests=no]
-+)
-+AM_CONDITIONAL([ENABLE_DISTRO_TESTS], [test x"$enable_distro_tests" = x"yes"])
-+if test x"$enable_distro_tests" = x"no"; then
-+ enable_distro_tests="no (disabled, use --enable-distro-tests to enable)"
-+fi
-+
- # --enable-install-tests
- AC_ARG_ENABLE(install-tests,
- AS_HELP_STRING([--enable-install-tests],
-@@ -1069,6 +1081,7 @@ Build options:
- XFixes client disconnect $have_xfixes
- Install systemd service $enable_systemd
- Run test cases $enable_tests
-+ Distro tests $enable_distro_tests
- Install tests $enable_install_tests
- ])
- AS_IF([test $HAS_OUTPUT_TAIL -eq 1],
-diff --git a/engine/Makefile.am b/engine/Makefile.am
-index 3e4d045f..02d65c26 100644
---- a/engine/Makefile.am
-+++ b/engine/Makefile.am
-@@ -4,7 +4,7 @@
- #
- # Copyright (c) 2010-2016, Google Inc. All rights reserved.
- # Copyright (c) 2007-2016 Peng Huang <shawn.p.huang@gmail.com>
--# Copyright (c) 2013-2025 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+# Copyright (c) 2013-2026 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
-@@ -57,11 +57,18 @@ AM_VALAFLAGS = \
- --target-glib="$(VALA_TARGET_GLIB_VERSION)" \
- $(NULL)
-
-+TESTS_ENVIRONMENT = \
-+ lib_srcdir=$(srcdir)/../src \
-+ $(NULL)
-+
- TESTS =
-
-+if ENABLE_DISTRO_TESTS
-+TESTS += test-dead.py
- if ENABLE_PYGNOME_DESKTOP
- TESTS += test-gnome.py
- endif
-+endif
-
- libexec_PROGRAMS = \
- ibus-engine-simple \
-@@ -99,6 +106,7 @@ EXTRA_DIST = \
- gensimple.py \
- iso639converter.py \
- simple.xml.in \
-+ test-dead.py \
- test-gnome.py \
- $(NULL)
-
-diff --git a/engine/meson.build b/engine/meson.build
-index a6ab5b4e..887c9c42 100644
---- a/engine/meson.build
-+++ b/engine/meson.build
-@@ -40,17 +40,21 @@ simple_xml = custom_target('simple.xml',
- install_dir: pkgdatadir / 'component',
- )
-
--if get_option('tests')
-- pyoverrides_tests = [
-- {
-- 'name': 'test-gnome',
-- },
-+disrro_tests_env = {
-+ 'lib_srcdir': source_root / 'src',
-+}
-+
-+if get_option('tests') and get_option('distro-tests')
-+ distro_tests = [
-+ { 'name': 'test-dead', },
-+ { 'name': 'test-gnome', },
- ]
-
-- foreach _test : pyoverrides_tests
-+ foreach _test : distro_tests
- timeout = _test.get('timeout', 30)
- test(_test['name'], files([python.full_path()])[0],
- args: [ meson.current_source_dir() / '@0@.py'.format(_test['name']) ],
-+ env: environment(disrro_tests_env),
- suite: 'engine',
- timeout: timeout,
- )
-diff --git a/engine/test-dead.py b/engine/test-dead.py
-new file mode 100755
-index 00000000..4f351ee8
---- /dev/null
-+++ b/engine/test-dead.py
-@@ -0,0 +1,136 @@
-+#!/usr/bin/python3
-+# vim:set fileencoding=utf-8 et sts=4 sw=4:
-+#
-+# ibus - Intelligent Input Bus for Linux / Unix OS
-+#
-+# Copyright © 2026 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
-+# License as published by the Free Software Foundation; either
-+# version 2.1 of the License, or (at your option) any later version.
-+#
-+# This library is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# Lesser General Public License for more details.
-+#
-+# You should have received a copy of the GNU Lesser General Public
-+# License along with this library. If not, see <http://www.gnu.org/licenses/>.
-+
-+# Check src/ibusinternal.h:IS_DEAD_KEY()
-+
-+import os, sys
-+from pathlib import Path
-+
-+class TestDeadKey:
-+ __srcdir = None
-+ __prgname = None
-+ __is_dead_key_file = Path('ibusinternal.h')
-+ __dead_keys_file = Path('ibuskeysyms.h')
-+ __max_dead_line = None
-+ __max_dead_key = None
-+ __max_dead_val = 0
-+ __min_dead_line = None
-+ __min_dead_key = None
-+ __min_dead_val = 0xffff
-+
-+ @classmethod
-+ def parse_args(cls):
-+ arg0 = Path(sys.argv[0])
-+ cls.__srcdir = arg0.parent.parent
-+ cls.__prgname = arg0.name
-+ lib_srcdir = os.getenv('lib_srcdir')
-+ if len(sys.argv) > 1:
-+ cls.__srcdir = Path(sys.argv[1])
-+ elif lib_srcdir != None:
-+ cls.__srcdir = Path(lib_srcdir)
-+ if str(cls.__srcdir) == '':
-+ cls.__srcdir = Path('.')
-+
-+ def tests(self):
-+ print('TAP version 14')
-+ print('1..1')
-+ dead_keys_path = self.__srcdir / self.__dead_keys_file
-+ if not dead_keys_path.exists():
-+ print(f'fail Not found {str(dead_keys_path)}', file=sys.stderr)
-+ sys.exit(1)
-+ is_dead_key_path = self.__srcdir / self.__is_dead_key_file
-+ if not is_dead_key_path.exists():
-+ print(f'fail Not found {str(is_dead_key_path)}', file=sys.stderr)
-+ sys.exit(1)
-+ self.read_dead_keys_file(dead_keys_path)
-+ if self.read_is_dead_key_file(is_dead_key_path):
-+ print(f'ok 1 /{self.__prgname}')
-+ else:
-+ sys.exit(1)
-+
-+ def read_dead_keys_file(self, dead_keys_path):
-+ with dead_keys_path.open() as f:
-+ for line in f:
-+ elements = line.split()
-+ if len(elements) < 3:
-+ continue
-+ if elements[0] != '#define':
-+ continue
-+ if not elements[1].startswith('IBUS_KEY_dead'):
-+ continue
-+ val = int(elements[2], 16)
-+ if self.__max_dead_val < val:
-+ self.__max_dead_val = val
-+ self.__max_dead_line = line
-+ self.__max_dead_key = elements[1]
-+ if self.__min_dead_val > val:
-+ self.__min_dead_val = val
-+ self.__min_dead_line = line
-+ self.__min_dead_key = elements[1]
-+ if self.__min_dead_val >= self.__max_dead_val:
-+ print(f'fail {self.__min_dead_line} < {self.__max_dead_line}',
-+ file=sys.stderr)
-+ sys.exit(1)
-+
-+ def read_is_dead_key_file(self, is_dead_key_path):
-+ has_definition = False
-+ min_key = ''
-+ max_key = ''
-+ with is_dead_key_path.open() as f:
-+ for line in f:
-+ elements = line.split()
-+ if not has_definition:
-+ if len(elements) < 2:
-+ continue
-+ if elements[0] != '#define':
-+ continue
-+ if elements[1].startswith('IS_DEAD_KEY('):
-+ has_definition = True
-+ # ((k) >= IBUS_KEY_dead_min && (k) <= IBUS_KEY_dead_max)
-+ else:
-+ if len(elements) < 7:
-+ continue
-+ min_key = elements[2]
-+ max_key = elements[6]
-+ if max_key[len(max_key) - 1] == ')':
-+ max_key = max_key[:len(max_key) - 1]
-+ break
-+ is_failed = False
-+ print(f'# min: {min_key} < max: {max_key}')
-+ if self.__min_dead_key != min_key:
-+ print(f'fail min of IS_DEAD_KEY() is %s but min in %s is %s' % \
-+ (min_key, str(self.__dead_keys_file), self.__min_dead_key),
-+ file=sys.stderr)
-+ is_failed = True
-+ if self.__max_dead_key != max_key:
-+ print(f'fail max of IS_DEAD_KEY() is %s but max in %s is %s' % \
-+ (max_key, str(self.__dead_keys_file), self.__max_dead_key),
-+ file=sys.stderr)
-+ is_failed = True
-+ return not is_failed
-+
-+
-+def main():
-+ TestDeadKey.parse_args()
-+ obj = TestDeadKey()
-+ obj.tests()
-+ sys.exit(0)
-+
-+main()
-diff --git a/meson.options b/meson.options
-index 8aab81ef..b5932044 100644
---- a/meson.options
-+++ b/meson.options
-@@ -3,6 +3,11 @@ option('tests',
- value: true,
- description: 'Build tests',
- )
-+option('distro-tests',
-+ type: 'boolean',
-+ value: false,
-+ description: 'Enable to test distro files',
-+)
- option('tests-exclude-suites',
- type: 'string',
- value: '',
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index 93262f3a..24096a70 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -36,6 +36,7 @@
- #include "ibustypes.h"
-
- #include "ibusenginesimpleprivate.h"
-+#include "ibusinternal.h"
-
-
- #define IBUS_COMPOSE_TABLE_MAGIC "IBusComposeTable"
-@@ -101,8 +102,8 @@ parse_compose_value (IBusComposeData *compose_data,
- const char *val,
- const char *line)
- {
-- char *head, *end, *p;
-- char *ustr = NULL;
-+ const char *head, *end, *p;
-+ char *ustr = NULL, *comment;
- gunichar *uchars = NULL, *up;
- GError *error = NULL;
- int n_uchars = 0;
-@@ -165,7 +166,9 @@ parse_compose_value (IBusComposeData *compose_data,
-
- g_free (ustr);
- g_free (uchars);
-- compose_data->comment = g_strdup (g_strstrip (end + 1));
-+ comment = g_strdup (end + 1);
-+ compose_data->comment = g_strdup (g_strstrip (comment));
-+ g_free (comment);
-
- return TRUE;
-
-@@ -1991,7 +1994,7 @@ ibus_compose_table_check (const IBusComposeTableEx *table,
- int row_stride = table->max_seq_len + 2;
- const guint16 *data_first;
- int n_seqs;
-- guint16 *seq;
-+ const guint16 *seq, *prev_seq;
-
- if (compose_finish)
- *compose_finish = FALSE;
-@@ -2020,8 +2023,6 @@ ibus_compose_table_check (const IBusComposeTableEx *table,
- if (seq == NULL)
- return FALSE;
-
-- guint16 *prev_seq;
--
- /* Back up to the first sequence that matches to make sure
- * we find the exact match if their is one.
- */
-@@ -2034,7 +2035,7 @@ ibus_compose_table_check (const IBusComposeTableEx *table,
-
- /* complete sequence */
- if (n_compose == table->max_seq_len || seq[n_compose] == 0) {
-- guint16 *next_seq;
-+ const guint16 *next_seq;
- gunichar value = 0;
- int num = 0;
- int index = 0;
-diff --git a/src/ibusenginesimple.c b/src/ibusenginesimple.c
-index 1eeccd52..c05e281c 100644
---- a/src/ibusenginesimple.c
-+++ b/src/ibusenginesimple.c
-@@ -28,12 +28,14 @@
- #include "ibuscomposetable.h"
- #include "ibusemoji.h"
- #include "ibusenginesimple.h"
--#include "ibusenginesimpleprivate.h"
-
- #include "ibuskeys.h"
- #include "ibuskeysyms.h"
- #include "ibusutil.h"
-
-+#include "ibusenginesimpleprivate.h"
-+#include "ibusinternal.h"
-+
- #include <memory.h>
- #include <stdlib.h>
- #include <glib/gi18n-lib.h>
-diff --git a/src/ibusenginesimpleprivate.h b/src/ibusenginesimpleprivate.h
-index c3f92920..c63522fe 100644
---- a/src/ibusenginesimpleprivate.h
-+++ b/src/ibusenginesimpleprivate.h
-@@ -35,12 +35,6 @@ G_BEGIN_DECLS
- */
- #define IBUS_COMPOSE_ERROR (ibus_compose_error_quark ())
-
--/* Checks if a keysym is a dead key. Dead key keysym values are defined in
-- * ibuskeysyms.h and the first is GDK_KEY_dead_grave.
-- */
--#define IS_DEAD_KEY(k) \
-- ((k) >= IBUS_KEY_dead_grave && (k) <= IBUS_KEY_dead_greek)
--
-
- struct _IBusComposeTablePrivate
- {
-@@ -57,8 +51,10 @@ struct _IBusComposeTablePrivate
- * Since: 1.5.33
- * Stability: Unstable
- */
-+G_GNUC_INTERNAL
- GQuark ibus_compose_error_quark (void);
- guint ibus_compose_key_flag (guint key);
-+G_GNUC_INTERNAL
- gboolean ibus_check_algorithmically (const guint *compose_buffer,
- int n_compose,
- gunichar *output);
-@@ -67,11 +63,13 @@ GVariant *
- (IBusComposeTableEx
- *compose_table,
- gboolean reverse_endian);
-+G_GNUC_INTERNAL
- IBusComposeTableEx *
- ibus_compose_table_deserialize
- (const char *contents,
- gsize length,
- guint16 *saved_version);
-+G_GNUC_INTERNAL
- gboolean ibus_compose_table_check (const IBusComposeTableEx *table,
- guint *compose_buffer,
- int n_compose,
-@@ -79,6 +77,7 @@ gboolean ibus_compose_table_check (const IBusComposeTableEx *table,
- gboolean *compose_match,
- GString *output,
- gboolean is_32bit);
-+G_GNUC_INTERNAL
- gunichar ibus_keysym_to_unicode (guint keysym,
- gboolean combining,
- gboolean *need_space);
-@@ -88,6 +87,7 @@ gunichar ibus_keysym_to_unicode (guint keysym,
- * Since: 1.5.33
- * Stability: Unstable
- */
-+G_GNUC_INTERNAL
- gunichar ibus_keysym_to_unicode_with_layout
- (guint keysym,
- gboolean combining,
-diff --git a/src/ibusinternal.h b/src/ibusinternal.h
-index c2637ab5..04553236 100644
---- a/src/ibusinternal.h
-+++ b/src/ibusinternal.h
-@@ -62,5 +62,14 @@
- G_GNUC_INTERNAL void
- ibus_g_variant_get_child_string (GVariant *variant, gsize index, char **str);
-
--#endif
-+#ifdef IBUS_KEY_dead_grave
-+#ifdef IBUS_KEY_dead_longsolidusoverlay
-+/* Checks if a keysym is a dead key. Dead key keysym values are defined in
-+ * ibuskeysyms.h and the first is GDK_KEY_dead_grave.
-+ */
-+#define IS_DEAD_KEY(k) \
-+ ((k) >= IBUS_KEY_dead_grave && (k) <= IBUS_KEY_dead_longsolidusoverlay)
-+#endif /* IBUS_KEY_dead_longsolidusoverlay */
-+#endif /* IBUS_KEY_dead_grave */
-
-+#endif
---
-2.53.0
-
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ibus-HEAD.patch
diff --git a/ibus.spec b/ibus.spec
index 096548d..5b7ba51 100644
--- a/ibus.spec
+++ b/ibus.spec
@@ -46,9 +46,9 @@
%global dbus_python_version 0.83.0
Name: ibus
-Version: 1.5.35~alpha1
+Version: 1.5.35~alpha2
# https://github.com/fedora-infra/rpmautospec/issues/101
-Release: 8%{?dist}
+Release: 1%{?dist}
Summary: Intelligent Input Bus for Linux OS
License: LGPL-2.1-or-later
URL: https://github.com/ibus/%name/wiki
@@ -57,7 +57,6 @@ Source1: https://github.com/ibus/%name/releases/download/%{source_version
Source2: %{name}-xinput
Source3: %{name}.conf.5
# Patch0: %%{name}-HEAD.patch
-Patch0: %{name}-HEAD.patch
Patch1: %{name}-2444009-wayland-xkb-lv-tilde.patch
# Under testing #1349148 #1385349 #1350291 #1406699 #1432252 #1601577
Patch2: %{name}-1385349-segv-bus-proxy.patch
@@ -545,6 +544,9 @@ dconf update || :
%{_datadir}/installed-tests/ibus
%changelog
+* Fri Jun 19 2026 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.35~alpha2-1
+- Bump to 1.5.35-alpha2
+
* Wed Jun 10 2026 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.35~alpha1-8
- Delete gobject-introspection
diff --git a/ibus.tar.xz.sha256sum b/ibus.tar.xz.sha256sum
index 2e17ae4..65ad647 100644
--- a/ibus.tar.xz.sha256sum
+++ b/ibus.tar.xz.sha256sum
@@ -1 +1 @@
-eeab1c15c58d87e65959f88122f745b55a6e36ca2e2ccb4e5c36ebc1895e2c25 *ibus-1.5.35-alpha1.tar.xz
+1b00e8c19896ed1c6b436c8dc2fb686d6a80f2d8412cd7662a990a632dd35c3b *ibus-1.5.35-alpha2.tar.xz
diff --git a/sources b/sources
index 3680370..95b1049 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (ibus-1.5.35-alpha1.tar.xz) = dc0fe479ac4087ae792df3d7016f06663be364df7f8e004988e4d1d03c9b7a02f73914a1daab3ce6e6ab6a97499bc24146b4a7f5d5aba87444b761e4ea2356c9
+SHA512 (ibus-1.5.35-alpha2.tar.xz) = b1eb0983d62fe2e9bf0a72be59f5f6a30d97186a7b2b41a22cb9e55218f4b8dc153101e86897ded173d063524118081a18b32a54d217a27e2dfb76fa2743bae1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-06-19 12:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-19 12:15 [rpms/ibus] rawhide: Bump to 1.5.35-alpha2 Takao Fujiwara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox