Bug 339467

Summary: Input method / IME / ibus support doesn't seem to work well in KF5 version
Product: [Applications] kate Reporter: Eike Hein <hein>
Component: generalAssignee: KWrite Developers <kwrite-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: lbeltrame, simonandric5
Priority: NOR    
Version: Git   
Target Milestone: ---   
Platform: Other   
OS: Linux   
URL: https://bugreports.qt-project.org/browse/QTBUG-41640
Latest Commit: Version Fixed In:

Description Eike Hein 2014-09-27 19:23:17 UTC
Distro: Fedora 21 Alpha
Qt version: Self-compiled 5.3 branch tip, reports as 5.3.3.
KF 5 version: Self-compiled master branch tip, reports as 5.3.0.
Kate version: Self-compiled master branch tip, reports as 5.0.0.
ibus version: 1.5.9 (Fedora packages)

I've noticed that ibus is very uncomfortable to use with the KF5 version of Kate. I'm using ibus to type Korean's Hangul alphabet, in which individual letters get grouped into blocks that are formed and replaced in-place as keys are pressed.

This is the block "han": 한

It consists of the letters: ㅎ, ㅏ and ㄴ

So as you are typing, it is supposed to iterate through these steps: ㅎ, 하, 한

Side note: On a en_US or de_DE labeled keyboard, the above is typed "gks".

However, this inline replacement behavior is not working in Kate. Instead, the cursor advances by one character (for all three keypresses), but no text is shown until the Space key is pressed, then the fully-formed block appears. This is very cumbersome to use, since it makes it impossible to spot and correct typos on the fly.

It works with other KF5 apps on my system, as well as Qt 4 apps and GTK+ apps.

Steps to reproduce:

1. Install ibus, ibus-qt and ibus-hangul.
2. For Qt 5, make sure that you have platforminputcontexts/libibusplatforminputcontextplugin.so in your plugins dir. It's included in the qtbase source tree.
2. Make sure ibus-daemon is running (e.g. ibus-daemon -drx).
3. Run ibus-setup and add Korean to the language list.
4. Depending on your distro, ibus may be using an X11Embed tray icon, which Plasma Desktop 5 no longer supports. Install and run something like wmsystemtray to get a floating window with legacy tray icons.
5. Use the tray icon to switch to Korean.
6. Make sure your environment is set up correctly:

export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus

7. Run Kate in this environment.
8. On an en_US or de_DE hardware keyboard, type the letters "gks" in sequence.

Expected result:

Keypresses and expected full document result:

1. g -> "ㅎ", cursor positioned after.
2. k -> "하", cursor positioned after.
3. s -> "한", cursor positioned after.
4. Space -> "한 ", cursor positioned after.

Actual result:

1. g -> " ", cursor positioned after.
2. k -> " ", cursor positioned after.
3. s -> " ", cursor positioned after.
4. Space -> "한", cursor positioned after.

Reproducible: Always
Comment 1 Eike Hein 2014-09-27 19:27:52 UTC
Addendum: A KF5-based testcase that works fine is e.g. Konversation, which uses KTextEdit (not KTextEditor) for its input line. It also works well with Konsole, which uses a custom text widget. It also works fine in KLineEdit's like Kate's own Find field. That's why I concluded the bug must be specific to the input handling in Kate's text widget.

Another tip: If you can't get the ibus tray icon to work, the default shortcut to cycle through the input language list is Super+Space (i.e. Left Winkey+Space, usually). You still need to add Korean in ibus-setup first.
Comment 2 Eike Hein 2014-09-27 19:50:02 UTC
Another note: I can also rule out font-related problems such as missing fonts or failing glyph substitution. My fontconfig is set up for my preferred monospace font to fall through[1] to Nanum Gothic Coding, which has all the required glyphs. But also when I select it directly, or other fonts like Noto Sans CJK KR, the behavior remains the same. The Konversation testcase is fine with all of those fonts.

By implication, if you find yourself lacking Hangul-supporting fonts to test this: Your distro likely has the Nanum or Noto fonts packaged, both are suitable :).

1 = I recently wrote a related blog post, https://blogs.kde.org/2014/09/11/beyond-unicode-closing-gap-support-mixed-character-set-text-kde-workspaces
Comment 3 Eike Hein 2014-09-27 19:52:52 UTC
Luca, can you try if this works any better with fcitx?
Comment 4 Eike Hein 2014-09-27 20:05:57 UTC
I just installed KWrite 4.14.1 to test, and it works fine there. The QInputMethodEvent handling in KateViewInternal may have regressed somehow.
Comment 5 Eike Hein 2014-09-27 20:11:53 UTC
Debug log from KateViewInternal::inputMethodEvent for the four keypresses:

kate(3640)/default KateViewInternal::inputMethodEvent: Event: cursor (0, 0) commit "" preedit "ㅎ" replacement start 0 length 0
kate(3640)/default KateViewInternal::inputMethodEvent: Event: cursor (0, 1) commit "" preedit "하" replacement start 0 length 0
kate(3640)/default KateViewInternal::inputMethodEvent: Event: cursor (0, 1) commit "" preedit "한" replacement start 0 length 0
kate(3640)/default KateViewInternal::inputMethodEvent: Event: cursor (0, 2) commit "" preedit "" replacement start 0 length 0
kate(3640)/default KateViewInternal::inputMethodEvent: Event: cursor (0, 0) commit "한" preedit "" replacement start 0 length 0
kate(3640)/default KateViewInternal::inputMethodEvent: Event: cursor (0, 1) commit "" preedit "" replacement start 0 length 0
kate(3640)/default KateViewInternal::inputMethodEvent: Event: cursor (0, 1) commit "" preedit "" replacement start 0 length 0
Comment 6 Eike Hein 2014-09-27 21:37:14 UTC
I've been debugging this - first I followed all the insert stuff down to TextBuffer, but where it actually goes wrong is in the block starting at line 3686 in kateviewinternal.cpp that tries to style the pre-edit text.

The QInputMethodEvent handed over contains three attributes, two text attributes and a cursor attribute. The second text attribute's QTextFormat has Qt::NoBrush as pen() - and so the text is rendered invisible.

I looked at the source code of the ibus input method plugin in Qt to find out why this happens. The reason is that in ibus' D-Bus format there are distinct attribute types for foreground and background, which are converted into two distinct QTextFormats in the attribute list, which end up cancelling each other out.

There's two ways to address this:

a) Kate could try to merge the two QTextFormats. The problem there is that it technically can't know which attribute is the foreground and which the background, so there's no good way to decide on the right operand order for a formatFoo.merge(formatBar) call.

b) Qt's Ibus input method plugin could smarten up and flatten all of the text attributes handed over by Ibus into a single QTextFormat attribute for the input event.
Comment 7 Eike Hein 2014-09-27 21:41:58 UTC
Qt's docs for QInputMethodEvent state the following in the event of multiple text char formats for the same range: "If several are specified for any character in the string the behaviour is undefined."

I suggest we simply ignore the second in that case. In this concrete situation it ends up being the background attribute, which we presumably don't care about anyway.
Comment 8 Luca Beltrame 2014-09-27 21:50:47 UTC
I don't seem to have any issues with fcitx as IM here. I can input and predict (via "space") just fine, everything is displayed correctly.
Comment 9 Eike Hein 2014-09-27 21:58:41 UTC
Opened a ticket at ibus: https://code.google.com/p/ibus/issues/detail?id=1745
Comment 10 Eike Hein 2014-09-27 22:18:30 UTC
And at Qt, since it appears ibus actually prefers it be tracked there now: https://bugreports.qt-project.org/browse/QTBUG-41640

I also had a look at the equivalent code in the Qt 4 plugin, and it merges all the ibus text attributes into a single QTextCharFormat just like we'd want ...
Comment 11 Eike Hein 2014-09-28 14:44:49 UTC
Proposed Qt patch: https://codereview.qt-project.org/#/c/95964/
Comment 12 Eike Hein 2015-01-15 19:30:19 UTC
This was accepted upstream and included in Qt 5.4.0.