i3: ibus with input method not shared among windows causes massive re-grabbing churn when switching windows

Hello. When using ibus launched by ibus-daemon -drx from the .xinitrc, with the option to “Share the same input method among all applications” disabled, switching windows causes noticable lag. This is especially annoying on my low-powered laptop where it can take up to half a second to switch windows.

The cause is apparently i3 re-grabbing all bindings many times over on every switch. Attached is a log file capturing the situation. Note it is over 11 000 lines long, generated by a single window switch.

i3log.txt | https://clbin.com/ML9na

I have reproduced this issue both with the default config and my own, with the i3-gaps package currently in archlinux repos, the gaps-next master branch, the i3 master branch and have been experiencing it for over a year on multiple machines. As such, I believe the specific version is irrelevant to the problem. I don’t know whether any particular version of i3 first introduced the issue, as it was already present when I started using ibus. Nevertheless, this is the version of i3 which generated the attached log:

Binary i3 version:  4.17.1-135-g07d5fc76 (2020-01-18, branch "gaps-next") © 2009 Michael Stapelberg and contributors
Running i3 version: 4.17.1-135-g07d5fc76 (2020-01-18, branch "gaps-next") (pid 2154)
Loaded i3 config: /home/sammko/.config/i3/config (Last modified: Tue 28 Jan 2020 21:32:32 CET, 98729 seconds ago)

The i3 binary you just called: /usr/bin/i3
The i3 binary you are running: i3

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 4
  • Comments: 22 (5 by maintainers)

Commits related to this issue

Most upvoted comments

After caching was added in libxkbcommon, and Firefox patched, this issue is longer that severe for me. The ibus mode with remembering layouts is still causes noticeable lag, but it is not as bad as it was (I don’t really use the mode, however).

I guess in my case Firefox was the main culprit, as hammering the X server slows it down for everyone.

I’ll try to collect more profile data to analyze whether things can optimized further, but I can now live with it as things are now.

This is indeed a local server.

I believe this problem is not limited to configurations where “shared input method” is disabled. Disabling this mode merely makes it more apparent. I can reproduce this lag with “shared input method” enabled by switching the input method and immediately trying to switch to other window: the switching will be delayed the same way.

I have traced what’s happening a bit, and here are my observations:

handle_event is called with type==xkb_base && state->xkbType == XCB_XKB_NEW_KEYBOARD_NOTIFY 8 times every time input method is changed. Each call takes ~60 ms to complete, which is bad on its own, but having it eight times brings the lag to almost 0.5 s.

By looking at the profile and flame graph, the slow function with the most “self” time is _xcb_map_remove.

handle_event type=85 xkbType=0 (67 ms, 110 _xcb_map_remove calls)
handle_event type=85 xkbType=0 (57 ms, 80 _xcb_map_remove calls)
handle_event type=85 xkbType=0 (51 ms, 57 _xcb_map_remove calls)
handle_event type=85 xkbType=0 (60 ms, 62 _xcb_map_remove calls)
handle_event type=85 xkbType=0 (67 ms, 68 _xcb_map_remove calls)
handle_event type=85 xkbType=0 (67 ms, 67 _xcb_map_remove calls)
handle_event type=85 xkbType=0 (68 ms, 73 _xcb_map_remove calls)
handle_event type=85 xkbType=0 (69 ms, 75 _xcb_map_remove calls)

flamegraph