Home · API Reference · Modules
MeeGo Input Method Framework Internals

Overview

In this document "widget" refers to text entry widget which is used in application.

Architecture

Features

This chapter describes the communication conducted between input method and widget when performing a feature.

RPC functions prefixed with im:: are defined on the input method side, whereas functions prefixed with app:: are defined on the widget side.

The Input method UI is shown when the MInputContext instance receives a QEvent::RequestSoftwareInputPanel event. It is hidden again when the MInputContext instance receives a QEvent::CloseSoftwareInputPanel event. In practice such events happen when an editable widget receives or loses the input focus.

The application calls (via the MInputContext instance) the following RPC functions on the input method side:

  • im::activateContext [MInputContextDBusConnection::activateContext?]
  • im::showOnFocus [MInputContextDBusConnection::showInputMethod?]

Then input method reports to the MInputContext instance whether the input method wants to compose all raw key event from hardware keyboard or not. A common use case is input method support for non-latin languages. Here, the input method calls app::setComposingTextInput(bool). This function could be called again if required by the input method, e.g., when an input method plugin was changed.

Additionally, if the application gains a visualization priority higher than the input method, the input method is hidden temporarily. A use case of this is a long-pressed MTextEdit widget, which triggers a zoom-in. The input method will be hidden for the duration of that zoom-in. When the MTextEdit widget enters the release state, a zoom-out is triggered and the input method becomes visible again.

To gain such a visualization priority, the application sets the M::VisualizationPriorityQuery property in its inputMethodQuery() function. The MInputContext instance queries the property during setFocusWidget() and update(). Depending on the current value of the property, it then calls im::visualizationPriorityChanged on the input method side. The input method can then decide about its visibility.

Key Event Filtering

All key events received are filtered in MInputContext::filterEvent. This is done mainly to support features meant for hardware keyboard UI interaction.

Upon interception of a key event, the MInputContext instance may cancel the event and redirect it back to input method. It can also choose to construct another key event and use the stored modifier state, then sending the event back to the widget - regardless of the actual modifier key state in the hardware - using QApplication::sendEvent().

Modifier Keys

This section only applies in the hardware keyboard mode. On-screen keyboard with direct key event mode activated should not be applicable here, as the modifier key state is already stored on the input method side.

In DirectUI, all modifier keys are sticky, meaning that the key state is kept even when the key is released.

There are three modifier key states:

  • CLEAR: the modifier key is not active
  • LATCHED: the modifier key is active until other key is pressed and released
  • LOCKED: the modifier key is LATCHED until the same modifier key is pressed and released

The diagram below describes the transitions of the modifier key states:

+-------------------------------------+
| |
| ^
V |
NORMAL +-(pressed)-> LATCHED -(non-modifier key is pressed+released)
^ | ^
| | |
| | |
| | |
| +-(pressed+released) -> LATCHED -+
| |
| V
| |
| (same modifier key is pressed+released)
| |
| V
| LOCKED
| |
| |
| (same modifier key is pressed+released)
| |
| |
+-------------------------------------+

For certain widget content types, modifier keys may be activated when the widget receives the input focus. For example, given a number content type, the Fn modifier is LATCHED initially.

The MInputContext instance keeps the modifier key states (Ctrl, Shift, Sym and Fn) until the widget loses the input focus again.

Dead Key Composition

If the MInputContext instance receives a dead key composition key event (Qt::Key_Dead_*), it then needs to compose the event with the normal key event it receives next. The composited key event will be sent by the MInputContext instance, instead.

Other Compositions

If the input method wants to compose text input by itself, all incoming (queued?) key events are cancelled and redirected to the input method. The input method then sends the composed text either as pre-edit, as commit string, or as key event as described in the "Typing" section.

Typing

There are three modes of typing:

Pre-edit String

The pre-edit string is composed as the user types. It is not part of the text entry, although it is displayed within a text entry. In practice, this string represents a candidate word that can be selected by the user. If selected, the candidate word is send to the text entry, replacing the partially typed word of the user. Candidate words are created by the word prediction or error correction driver. Candidate words might change as the user continues to type.

The input method calls the app::updatePreedit RPC function when updating the pre-edit string. The receiver of the call, a MInputContext instance, constructs a QInputMethodEvent event, along with the formatting attributes of the pre-edit string. It then forwards the event to the currently focused widget (obtained via focusWidget()), using QApplication::sendEvent(). The emission of the widget's changed signal shall be blocked temporarily.

Commit string

The commit string is the result of an input method interaction which is sent to a widget. It becomes part of the text entry's content.

The input method calls the app::commitString() RPC function to send a commit string. The receiver of this call, a MInputContext instance, constructs a QInputMethodEvent event and sends the commit string with that event. It then forwards the event to the currently focused widget (obtained via focusWidget()), using QApplication::sendEvent(). The widget may now emit a textChanged signalThe event is then sent to current focusWidget() with QApplication::sendEvent. The widget may now emits an event telling that the content is changed.

Key event

Input method can send a constructed key event to a widget by calling app::keyEvent RPC function. Upon receiving this call MInputContext construct a QKeyEvent and sends that to it's focusWidget() with QCoreApplication::sendEvent().

If current input method mode is M::InputMethodModeDirect, then the input method sends key event instead of sending pre-edit or commit string.

Pre-edit injection

MTextEdit widget requires that if a word is clicked then it needs to be turned into a pre-edit, so it can be changed into another word with error correction feature. When this happens, the clicked word is removed and the widget constructs a MPreeditInjection event and sends it to input context. If the event is accepted, e.g. if the error correction is enabled, then the incoming word enclosed in the event is treated as pre-edit. In MInputContext side, upon receiving this event, a QInputMethodEvent will be constructed with the word as a new pre-edit string and sent to the widget. MInputContext will then call im::setPreedit() RPC function to inform the input method about the new pre-edit string. Upon receiving the new pre-edit string, the input method will decide appropriate styling for the pre-edit and call app::sendPreeditString() RPC function. Please note that pre-edit becomes truly active only after input method has called app::sendPreeditString() RPC function. This means that update() will be called only after app::sendPreeditString() RPC function has been called and therefore input method will not know the true state of the widget (e.g. cursor position and surrounding text) before.

Copy and paste

MInputContext connects itself to widget's signal which called "copyAvailable(bool)" if exists. Whenever this signal is emitted, MInputContext calls im::setCopyPasteButton RPC function [MInputContextDBusConnection::setCopyPasteState?] to update the visibility of Copy/Paste button in the input method's toolbar. If system clipboard has text content, the Paste button is shown instead of Copy button.

When the Copy button is clicked, input method calls app::copy RPC function. Upon receiving this call, MInputContext calls widget's "copy" function if available, otherwise it just sends ctrl-c combination key event to the widget.

When the Paste button is clicked, input method calls app::paste RPC function. Upon receiving this call, MInputContext calls widget's "paste" function if available, otherwise it just sends ctrl-v combination key event to the widget.

Setting

Input mode

The framework supports two modes: M::InputMethodModeNormal and M::InputMethodModeDirect [MInputContextDBusConnection::inputMethodMode?]. If the widget wants direct key event instead of getting the text using pre-edit/commit string, it can set the mode to M::InputMethodModeDirect, otherwise, the M::InputMethodModeNormal which is the default value will be used at all times.

The widget can set the mode by answering the M::ImModeQuery query with the value according to the current mode when asked in inputMethodQuery method. [MTextEdit has the following properties: inputMethodCorrectionEnabled, inputMethodPredictionEnabled, inputMethodAutoCapitalizationEnabled - there is no inputMethodQuery] The input method obtains the current widget's mode by calling app::inputMethodMode RPC function.

Autocapitalization

Autocapitalization regarding the input method means that upper case typing shall be activated if:

  • It starts a sentence
  • A sentence ends with a punctuation mark ("?!.") and is followed by at least one space [better: "whitespace character", e.g., also newlines?] (detailed behaviour is available from the UI specification)

In widget's inputMethodQuery method, the widget returns the status of this feature when asked with M::ImAutoCapitalizationEnabledQuery.

The input method can get the widget's autocapitalization state by calling app::autoCapitalizationEnabled RPC function [MTextEdit::inputMethodAutoCapitalizationEnabled].

Error correction

When the error correction feature is active, the input method always feeds the currently typed word to the error correction driver. Thhe suggested word is then constructed as a pre-edit string. This is done for every update on the input method side, e.g. when a key on the virtual keyboard is pressed.

In widget's inputMethodQuery method, the widget returns the status of this feature when asked with M::ImCorrectionEnabledQuery.

The input method can get the widget's autocapitalization state by calling app::correctionEnabled RPC function [MTextEdit::inputMethodCorrectionEnabled].

This feature can be disabled/enabled globally according to setting [which?]. The input method can override the state of this feature on the widget side by calling app::setGlobalCorrectionEnabled RPC function.

Word prediction

This is similar to error correction, but the key/string entered by user will be treated as commit string and the rest of the word predicted by the engine will be treated as pre-edit string. THIS IS NOT (YET) IMPLEMENTED IN INPUT METHOD SIDE.

In widget's inputMethodQuery method, the widget returns the status of this feature when asked with M::ImPredictionEnabledQuery.

Input method can get the widget's autocapitalization state by calling app::predictionEnabled RPC function [MTextEdit::inputMethodPredictionEnabled].

Error correction candidates

If error correction feature is enabled and mouse clicked is happening on a pre-edit word, then a candidate list of the word shall be displayed on the screen. To do this, in it's mouseHandler MInputContext asks the widget about the pre-edit rectangle by passing M::PreeditRectangleQuery to current focusWidget's inputMethodQuery. MInputContext calls im::mouseClickedOnPreedit RPC along with the rectangle. Input method then decide what to do with that.

Text entry types

The widget can determine its content type. It returns the content type when asked with M::ContentTypeQuery in its inputMethodQuery method.

Toolbar

The text entry widget can ask the input method to put a custom widget into a toolbar (which will be part of the input method UI). This widget, called "toolbar widget", is essentially a declarative widget written in XML. It is compiled into into a widget by the plugin during the loading of the plugin. Details can be found in the Input Method Toolbar. Toolbar widgets will appear in the toolbar only when instructed by the text entry widget. One use case is rich text editing. The rich text entry could show Bold, Italic, Underline and other buttons to control the rich text editing in the toolbar.

The input method shows/hides the toolbar widgets upon receiving events as defined in the toolbar widget's XML data.

When an event takes place on a toolbar widget, the input method sends a sequence of actions defined as defined in the XML data. The list below describes the actions and how it is handled by input method:

  • sendKeySequence: input method constructs key events and process it as described above
  • sendString: input method sends the word described as commit string
  • copy: input method asks the widget to copy selected text into clipboard
  • paste: input method asks the widget to paste from clipboard
  • sendCommand: input method passes the defined command to app::toolbarWidgetCommand RPC function

The widget can change the attributes of an item in toolbar. Except the NAME attribute, all others attributes can be changed by the widget in runtime. To change an attribute, a widget call im::setToolbarItemAttribute() RPC function.

The widget can also get the attribute on an item in toolbar by calling im::toolbarItemAttribute() RPC function.

See also
toolbar

Copyright © 2011 Nokia Corporation
Maliit