[SailfishDevel] Creating advanced keyboard layouts with custom input handlers

Arvid Fahlström Myrman behold at behold.se
Tue Jan 7 19:52:10 UTC 2014


Hi,

Thanks for pointing me to jolla-keyboard.qml. From reading that file I was able 
to learn in what order everything happens during an input handler change, and 
through a combination of property change signal handlers and exploiting the 
fact that unknown types result in the keyboard input handler being set to 
pasteInputHandler, I was able to make my custom input handler start 
automatically whenever the keyboard switches to a specific layout. I've 
included the relevant code below for reference in case anyone else is curious 
as to how I went about doing this. The input handler in question is a simple 
proof-of-concept X-SAMPA to IPA converter (http://en.wikipedia.org/wiki/X-SAMPA).

In the future, though, it would be very much appreciated if the KeyboardLayout 
type implemented something along the lines of an "inputHandler" property which 
would then be read by updateInputHandler() to allow any layout to easily 
specify a custom input method without having to rely on volatile 
implementation details.

The code in question:

KeyboardLayout {
    type: "ipa_xsampa"
    
    IPAInputHandler {
        id: ipaInputHandler
    }
    
    Component.onCompleted: init() // called before input handler changes
    
    Connections {
        target: keyboard
        onInputHandlerChanged: handlerChanged()
    }
    
    function init() {
        // force onInputHandlerChanged signal by
        // making sure that the input handler was not
        // previously pasteInputHandler
        if (keyboard.allowLayoutChanges) {
            var oldHandler = keyboard.inputHandler
            keyboard.inputHandler = xt9Handler.item
            oldHandler.active = false
            keyboard.inputHandler.active = true
        }
    }
    
    function handlerChanged() {
        if (keyboard.allowLayoutChanges &&
                keyboard.inputHandler == pasteInputHandler &&
                canvas.layoutRow.layout != null &&
                canvas.layoutRow.layout.type == type) {
            if (!ipaInputHandler.trie_built) {
                ipaInputHandler.build_trie()
            }
            var oldHandler = keyboard.inputHandler
            keyboard.inputHandler = ipaInputHandler
            oldHandler.active = false
            ipaInputHandler.active = true
        }
    }
...
}

Regards,
Arvid

On Tuesday 07 January 2014 10:02:50 Antti Seppälä wrote:
> Hi Arvid,
> 
> Currently there's no non-ungly way to force a keyboard layout to use custom
> input handler as we right now support a limited number of input methods and
> the logic is hard coded.
> 
> If you want to experiment with your own handler (at your own risk), take a
> look at function updateInputHandler() in
> /usr/lib/maliit/plugins/jolla-keyboard.qml, the decision is made there.
> Also remember that all this is unsupported and internal and may completely
> change in future updates.
> 
> br,
>    Antti
> 
> ________________________________________
> From: devel-bounces at lists.sailfishos.org
> [devel-bounces at lists.sailfishos.org] on behalf of Arvid Fahlström Myrman
> [behold at behold.se] Sent: Sunday, January 05, 2014 10:34 AM
> To: devel at lists.sailfishos.org
> Subject: [SailfishDevel] Creating advanced keyboard layouts with custom
> input handlers
> 
> Hi,
> 
> I've been trying to experiment with creating more advanced keyboard layouts
> than ones who simply map one key to one character---more along the lines of
> the Chinese pinyin layout. To that end, I've been investigating the relevant
> QML files located in /usr/share/maliit/plugins/com/jolla/, and I think that
> I've got a decent idea of how they work. In essence, I need to create a
> custom input handler that, instead of querying the Xt9 library for
> potential candidates, implements its own logic.
> 
> However, here I've hit a bit of a snag. Whenever the keyboard is started it
> seems to default to the standard InputHandler input handler, but almost
> immediately after starting, as well as (as far as I can tell) every time
> canvas.layoutRow.switchLayout is called, something somewhere changes the
> input handler to the Xt9InputHandler. If the layout is changed to the
> Chinese pinyin layout, though, the Xt9CpInputHandler is used instead,
> thanks to the magic value "china_pinyin" specified in the type attribute of
> the Chinese keyboard layout (zh_cn_pinyin.qml). However, from what I can
> see there's no straightforward way for a layout to specify a custom input
> handler---the Chinese input handler being hard coded.
> 
> Am I overlooking something? Is it in fact possible to tell the keyboard to
> switch to a specified input handler upon loading a layout? If not, is it
> possible to tell the keyboard *not* to switch to the Xt9InputHandler? If I
> for instance try to set keyboard.inputHandler to an InputHandler in the
> Component.onCompleted attribute in en.qml, I can see how the input handler
> is changed for a fraction of a second before being changed again to the
> Xt9InputHandler. And I'm not sure if there's any non-ugly way to make sure
> that my code changing the input handler to my custom handler is instead run
> immediately after the code that switches the handler to the Xt9InputHandler
> has finished running.
> 
> As an aside, would it be possible for a custom layout to register itself
> without having to edit layout.conf? That would make it much easier to
> provide the layout in the form of a simple RPM package.
> 
> Regards,
> Arvid
> 
> _______________________________________________
> SailfishOS.org Devel mailing list
> _______________________________________________
> SailfishOS.org Devel mailing list



More information about the Devel mailing list