Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GTK regression: ibus 1.5.31 dead keys on Wayland broken #5494

Closed
mitchellh opened this issue Feb 1, 2025 · 16 comments · Fixed by #5550
Closed

GTK regression: ibus 1.5.31 dead keys on Wayland broken #5494

mitchellh opened this issue Feb 1, 2025 · 16 comments · Fixed by #5550
Labels
input Keyboard or mouse input os/linux
Milestone

Comments

@mitchellh
Copy link
Contributor

1.1.0 breaks dead keys on ibus 1.5.31 in Hyprland (non-GNOME). The initial modifier character shows but the final character eats up input. Example:

`  + a = both are eaten up
´ + e = both are eaten up
¨ + space = both are eaten up

and so on...

I had to downgrade to 1.0.1. I'm running on Arch with the following:

Ghostty 1.0.1-arch

Version
  - version: 1.0.1-arch
  - channel: tip
Build Config
  - Zig version: 0.13.0
  - build mode : builtin.OptimizeMode.ReleaseFast
  - app runtime: apprt.Runtime.gtk
  - font engine: font.main.Backend.fontconfig_freetype
  - renderer   : renderer.OpenGL
  - libxev     : main.Backend.io_uring
  - GTK version:
    build      : 4.16.12
    runtime    : 4.16.12
  - libadwaita : enabled
    build      : 1.6.3
    runtime    : 1.6.4
  - libX11     : enabled

ibus versions:

pacman -Q | grep ibus
ibus 1.5.31-2
libibus 1.5.31-2

Other GTK4/Adwaita apps are working fine, so are browsers, etc. I'm running on Hyprland, but I assume this happens in other places too. I'll try GNOME and report back. EDIT: 1.1.0 works in GNOME, but not Hyprland.

So, I kept digging. The difference between GNOME and Hyprland on the same system is that Hyprland doesn't start ibus, so the changes between 1.0.3 and 1.1.0 are dependent on ibus being running. Digging further...

Originally posted by @tomaspinho in #5324 (comment)

@mitchellh
Copy link
Contributor Author

I haven't confirmed this but multiple people have reported it, so we should look at it for 1.1.1

@mitchellh mitchellh added this to the 1.1.1 milestone Feb 1, 2025
@mitchellh mitchellh added os/linux input Keyboard or mouse input labels Feb 1, 2025
@miyl
Copy link

miyl commented Feb 1, 2025

It also breaks if ibus/fcitx aren't installed/used, and I assume 1.1.0 didn't intend to introduce ibus as a hard dependency.

Also running arch + wayland (hyprland), so no GNOME.

@McKael
Copy link

McKael commented Feb 1, 2025

Indeed there is a regression with the Simple GTK builtin Input Method (see discussion #5375 (comment)), I do not think it is specific to ibus 1.5.31.

@rajayonin
Copy link

I'm running GNOME on Wayland without ibus installed, had no problems on v1.0.1, but the issue appeared when upgrading to v1.1.0 (see #5375 (reply in thread)). Installing ibus and running ibus start fixed it.

@McKael
Copy link

McKael commented Feb 1, 2025

In the case of IMContextSimple, I suspect the input does not get committed here:
https://github.com/ghostty-org/ghostty/blob/c5508e7d/src/apprt/gtk/Surface.zig#L1939-L1951
in gtkInputCommit because self.im_composing is false and self.in_keyevent is true, so we return on line 1950.

With ibus 1.5.27-5 from Debian, im_composing is true and the input gets committed. (I can't test ibus 1.5.31.)

I have an ugly workaround that seems to fix it in my environment (it probably breaks some others, ask a professional before using it), FWIW:

--- a/src/apprt/gtk/Surface.zig
+++ b/src/apprt/gtk/Surface.zig
@@ -1932,23 +1932,7 @@ fn gtkInputCommit(
     const self = userdataSelf(ud.?);
     const str = std.mem.sliceTo(bytes, 0);

-    // If we're in a keyEvent (i.e. a keyboard event) and we're not composing,
-    // then this is just a normal key press resulting in UTF-8 text. We
-    // want the keyEvent to handle this so that the UTF-8 text can be associated
-    // with a keyboard event.
-    if (!self.im_composing and self.in_keyevent) {
-        if (str.len > self.im_buf.len) {
-            log.warn("not enough buffer space for input method commit", .{});
-            return;
-        }
-
-        // Copy our committed text to the buffer
-        @memcpy(self.im_buf[0..str.len], str);
-        self.im_len = @intCast(str.len);
-
-        // log.debug("input commit len={}", .{self.im_len});
-        return;
-    }
+    if (str.len == 0) return;

     // If we reach this point from above it means we're composing OR
     // not in a keypress. In either case, we want to commit the text

@Diego-0110
Copy link

It seems that the bug can be reproduced just by stopping the ibus daemon (ibus exit).
I've done this in Ubuntu 24.04 and also in 24.10 and works.

Searching for the cause, I found out that, when ibus is off, the dead key commit is treated as a normal key commit like pressing a, so calling c.gtk_im_context_filter_keypress doesn't imply that the preedited characters will be committed. In this case self.im_len will be > 0 and was_composing true, so the characters will be ignored because of the line 1716 of src/apprt/gtk/Surface.zig file: if (was_composing) return true; .

The solution I found is this:

--- a/src/apprt/gtk/Surface.zig
+++ b/src/apprt/gtk/Surface.zig
@@ -1713,7 +1713,7 @@ pub fn keyEvent(
             // Example: enable Japanese input method, press "konn" and then
             // press enter. The final enter should not be encoded and "konn"
             // (in hiragana) should be written as "こん".
-            if (was_composing) return true;
+            if (was_composing and self.im_len == 0) return true;

             // Not composing and our input method buffer is empty. This could
             // mean that the input method reacted to this event by activating

@luccahuguet
Copy link

happening on Cosmic popos (wayland) as well

 lucca@pop-os 
 ------------ 
 OS: Pop!_OS 24.04 
 Host: pop-os 
 Uptime: 57 minute(s) 
 Kernel: 6.9.3-76060903-generic 
 System OS version: 24.04 
 NB CPUs: 4 
 CPU: Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz @ 3499 GHz 
 GPU #1: HD Graphics 620 
 GPU #2: GM108M [GeForce 940MX] 
 Memory: 7660/15776 MiB 
  
 ████████████████████████ 
 ████████████████████████ 

@ardasevinc
Copy link

[Gnome on Wayland; Arch Linux]

my CTRL + shift + T shortcut for toggling window decorations stopped working with 1.1.0. is this related?

@polirritmico
Copy link

I confirm that this patch fixes the issue on my Gentoo system. Thanks @Diego-0110!

@iniw
Copy link

iniw commented Feb 3, 2025

Also noticing this issue on GNOME + Wayland without ibus installed. All dead keys have stopped working after upgrading to 1.1.0. Installing ibus (1.5.30 on NixOS 24.11) fixes the issue.

karitham added a commit to karitham/dotfiles that referenced this issue Feb 3, 2025
@xsteadfastx
Copy link

no wayland here still eats up the `in nixos.

xsteadfastx added a commit to xsteadfastx/dotfiles that referenced this issue Feb 3, 2025
@ecocode
Copy link
Collaborator

ecocode commented Feb 3, 2025

I confirm that this patch resolves the same issue on swaywm on Fedora.

The solution I found is this:

--- a/src/apprt/gtk/Surface.zig
+++ b/src/apprt/gtk/Surface.zig
@@ -1713,7 +1713,7 @@ pub fn keyEvent(
// Example: enable Japanese input method, press "konn" and then
// press enter. The final enter should not be encoded and "konn"
// (in hiragana) should be written as "こん".

  •        if (was_composing) return true;
    
  •        if (was_composing and self.im_len == 0) return true;
    
           // Not composing and our input method buffer is empty. This could
           // mean that the input method reacted to this event by activating
    

@gheritarish
Copy link

I ran into the same issue, somehow decided to bisect before looking at similar issues (actually, no, but didn't think I had the problem for all dead keys, I only noticed it when trying a git show HEAD^, and was searching for this specific key).

Config: EndeavourOS, no ibus, running i3-wm.

Bisect result was this commit: 52936b9b681e92f7bab37c3ec341be0013f591da (if that can help).
I tried this fix, and it solved the issue.

@mitchellh
Copy link
Contributor Author

mitchellh commented Feb 3, 2025

Okay looking into this. Someone may have stated this earlier I didn't read all the comments. I'm going to look into ibus 1.5.31 and no ibus separately. Starting with no ibus because it's easier to just stop it.

Here are the GTK events (no Ghostty stuff here):

With no ibus on Wayland (broken):

  1. Press '
  2. Preedit start
  3. Preedit change
  4. Press a
  5. Preedit change
  6. Preedit end
  7. Commit

With ibus (1.5.30) on Wayland (working):

  1. Press '
  2. Preedit start
  3. Preedit change
  4. Press a
  5. Commit
  6. Preedit change (to empty)
  7. Preedit end

Lord.

mitchellh added a commit that referenced this issue Feb 3, 2025
Fixes #5494

When ibus/fcitx is not running (the GTK "simple" input method is
active), the preedit end event triggers _before_ the commit event. For
both ibus/fcitx, the opposite is true. We were relying on this ordering.

This commit changes the GTK input handling to not rely on this ordering.
Instead, we encode our composing state into the boolean state of whether
a key event is pressed. This happens before ANY input method events are
triggered.

Tested dead key handling on: X11/Wayland, ibus/fcitx/none.
@mitchellh
Copy link
Contributor Author

mitchellh commented Feb 3, 2025

Fix up in #5550

mitchellh added a commit that referenced this issue Feb 3, 2025
Fixes #5494

When ibus/fcitx is not running (the GTK "simple" input method is
active), the preedit end event triggers _before_ the commit event. For
both ibus/fcitx, the opposite is true. We were relying on this ordering.

This commit changes the GTK input handling to not rely on this ordering.
Instead, we encode our composing state into the boolean state of whether
a key event is pressed. This happens before ANY input method events are
triggered.

Tested dead key handling on: X11/Wayland, ibus/fcitx/none.
mitchellh added a commit that referenced this issue Feb 3, 2025
Fixes #5494

When ibus/fcitx is not running (the GTK "simple" input method is
active), the preedit end event triggers _before_ the commit event. For
both ibus/fcitx, the opposite is true. We were relying on this ordering.

This commit changes the GTK input handling to not rely on this ordering.
Instead, we encode our composing state into the boolean state of whether
a key event is pressed. This happens before ANY input method events are
triggered.

Tested dead key handling on: X11/Wayland, ibus/fcitx/none.
mitchellh added a commit that referenced this issue Feb 3, 2025
Fixes #5494

When ibus/fcitx is not running (the GTK "simple" input method is
active), the preedit end event triggers _before_ the commit event. For
both ibus/fcitx, the opposite is true. We were relying on this ordering.

This commit changes the GTK input handling to not rely on this ordering.
Instead, we encode our composing state into the boolean state of whether
a key event is pressed. This happens before ANY input method events are
triggered.

Tested dead key handling on: X11/Wayland, ibus/fcitx/none.
mitchellh added a commit that referenced this issue Feb 3, 2025
Fixes #5494

When ibus/fcitx is not running (the GTK "simple" input method is
active), the preedit end event triggers _before_ the commit event. For
both ibus/fcitx, the opposite is true. We were relying on this ordering.

This commit changes the GTK input handling to not rely on this ordering.
Instead, we encode our composing state into the boolean state of whether
a key event is pressed. This happens before ANY input method events are
triggered.

Tested dead key handling on: X11/Wayland, ibus/fcitx/none.
@tomaspinho
Copy link

tomaspinho commented Feb 3, 2025

Amazing, testing this later. Thank you so much for all you do! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
input Keyboard or mouse input os/linux
Projects
None yet
Development

Successfully merging a pull request may close this issue.