Sunday, May 27, 2007

How to support input method in KDE/Qt application.

Author: Takumi ASAKI

Sometimes additional code is necessary to support input method in KDE/Qt application. This document will explain what's input method and how to support input method.

What's input method?

Input method is system to help user's keyboard input. Using input method, user can input characters that can not input from keyboard directly, and reduce cost of keyboard input. Input method is necessary for the user wants to input CJK(Chinese, Japanese, and Korean) and other language's characters.

In X Window System, XIM(X Input Method) is standard input method. Qt and KDE support XIM. But XIM is legacy system and lacks some features modern input method should have.

So, the input method systems other than XIM are developing now. IIIMF(Internet Intranet Input Method Framework), UIM(Universal Input Method), and SCIM(Smart Common Input Method platform).

Gtk+ supports these input methods using immodule. Qt supports only XIM. But immodule for Qt project tries to introduce immodule to Qt.

What's immodule?

immodule is plugable module for input method. It supports several input methods and can change input method dynamically.

Original Qt(without immodule patch) supports XIM only. So, user has to use XIM-bridge(ex. htt, uim-xim) when user wants to use the other input method. But with immodule patched Qt, user can use favorite input method directly.

Qt4(next major version of Qt) will take the result of the immodule for Qt project, and support immodule. If developer wants to support input method correct, sometimes some input method related code is necessary.

When do you need writing code to support input method?

case A)

Your application doesn't need input text.

You don't need to do anything.

case B)

Your application need input text. And you use only input widget in KDE or Qt library. (ex. QLineEdit, QTextEdit, and more)

You don't need to do anything. KDE and QT library's input widget supports input method correct. There is no need of additional code.

case C)

Your application need input text. And you want to support keyboard input in your own widget. (ex. kate, konsole, kolourpaint, koffice, and more)

You need writing code to support input method. See next section.

How to support input method in KDE/Qt application.

If you want to support keyboard input in your own widget(case C), you need writing code to support input method.

Step A)

Set inputMethodEnabled property to ture. inputMethodEnabled property can enable/disable input method. And default is false except some input widgets. If your widget accepts input from input method, set it to true using QWidget::setInputMethodEnabled() method.

setInputMethodEnabled( true );

note: Original qt can use input method even when inputMethodEnabled property is false. (original qt ignore this property.) it's bug(maybe) and it confuses user. ( When widget doesn't accept text input(e.g. QLabel, QPushButton), I can open input method's window on that widget. ) So qt with immodule check this property to use input method. If your qt is without immodule, it seems to do not need this step. But this is needed.

Step B)

Set microFocusHint for input method can get position of input place.

When widget shows or moves cursor, you should set microFocusHint using QWidget::setMicroFosucHint().

microFocusHint is a hint that input method get place of input. It's help for input method shows additional information at suitable place when user uses input method.

Step C)

Accpet QKeyEvent's text.

Create your widget's keyPressEvent() event handler. And check QKeyEvent::text() for input method's input.

When QKeyEvent::text() is not empty, widget should accept it as user input.

note: QKeyEvent::text() is used when user uses XIM and OverTheSpot style. If user uses OnTheSpot style or other input method, we can't get input method's input using this way. See Step D).

Step D)

Implement QIMEvent handlers.

Input method's inputs are sent by QIMEvent when user uses input method other than OverTheSpot style XIM.

Please see QIMEvent's document for detail. You should reimplement QWidget::imStartEvent(), QWidget::imComposeEvent(), and QWidget::imEndEvent().

QWidget::imStartEvent()
Remember cursor position to show composing string. (QIMEvent doesn't have it.)
QWidget::imComposeEvent()
Remember composing string(QIMEvent::text()) and cursor position(QIMEvent::cursorPos()) in it and selecting string length(QIMEvent::selectionLength). Then show it as composing(preedit) strings.
QWidget::imEndEvent()
In imEndEvent(), QIMEvent sends final text user commits. Accept QIMEvent::text() as final text.

Maybe that's all of input method support.

Please read and comment it.

1 comment:

herbertwonghk said...

Jay,

I am looking for input method for Farsi. I am using QT and Linxs plateform