Friday, October 28, 2011

Key overrides in Maliit

After finishing my work on Syncevolution's build system I was asked to get in touch with Maliit. My new task was to write some examples showing how to use dynamic key overrides in both application and plugin side, simplify a bit the use of them in application side and implement key overrides handling for QtQuick plugins.


Key overrides are useful because they allow application author to make action key (this is what we usually call "Enter") of virtual keyboard have different caption (e.g."Send" in an instant messaging application) instead of standard bent arrow icon. Imagine having an application which logs you to some online service - all it could have is two fields, one for login and another one for password. Depending which of this fields has focus the action key caption could be "Next" or "Login" respectively. In fact, I wrote a sort of mockup showing it - it is called twofields:

Twofields example application

There are also examples of C++ and QtQuick plugins reacting to changes of action key caption. You can find them in examples directory in Maliit framework repository.

Simple overriding

Overriding a key from application side is done in three steps:
  1. Create Maliit::AttributeExtension.
  2. Call setAttribute method of Maliit:AttributeExtension.
  3. Bind attribute extension to some input widget.

Previously the third step was a bit messy - you had to subclass an input widget and override its inputMethodQuery() method to return an id of attribute extension:

class MyLineEdit : public QLineEdit {
        : QLineEdit(),
          extension (new Maliit:AttributeExtension)
        extension->setAttribute("/keys/actionKey/label", "Wheee");

    QVariant inputMethodQuery(Qt::InputMethodQuery query) const {
        typedef Maliit::InputMethodQueryExtensions MaliitQuery;

        MaliitQuery maliit_query(static_cast<MaliitQuery>(query));

        switch (maliit_query) {
        case Maliit::InputMethodAttributeExtensionIdQuery:
            return QVariant(extension->id());
            return QLineEdit::inputMethodQuery(query);

    QScopedPointer extension;

Now, forget about the above code. The one below will do:

Maliit:AttributeExtension* extension(new Maliit:AttributeExtension);
QLineEdit* line_edit(new QLineEdit());
extension->setAttribute("/keys/actionKey/label", "Wheee");

All names of properties are in maliit/namespace.h.

Key overrides in QtQuick plugins

QtQuick plugins now also can have overriden action key. It is a matter of some property bindings and setting a default icon or label. Below is very minimal QML code that could represent an action key. Obviously, some styling and sizing should be done also, but were stripped for clarity.

Rectangle {
    id: action_key
    property string caption: MInputMethodQuick.actionKeyOverride.label

    MouseArea {
        id: mouse_area
        anchors.fill: parent
        onReleased: { MInputMethodQuick.activateActionKey() }

    Text {
        anchors.centerIn: parent
        text: caption

    Component.onCompleted: {

Note that only actionKey overrides are supported in QtQuick plugins. There is a plugin that already uses it - meego-keyboard-quick. For those who want to know how to write Maliit plugins in QtQuick, Michael Hasselmann wrote a short tutorial about it.

1 comment:

  1. Some links in this post have not been available, I'm gonna to make a virtual key board (VKB) for our language (Vietnamese) on Meego (Nokia N9), but I never have researched any thing about VKB before, now I'm in a maze, a mess, don't know where to start rightly, can you guide me the right way to learn?
    Now I have the questions are:
    1/ What should I research?
    2/ How can I implement a VKN on Maliit framework?
    3/ How can I change the reaction of the VKB, for an example, when I type two time the "o" character, it should replace "oo" by "ô".
    4/ Can you make an tutorial "how to implement Maliit and customize it" step by step for a newbie?
    --- long to hear your answer ---