Virtual keyboard for the Pi with auto-hide functionality

tjohnson picture tjohnson · Mar 12, 2016 · Viewed 12.7k times · Source

I am using PyGObject to create an UI that will be run on a 7" official RPi touchscreen connected to a Pi 3 running Raspbian. As part of this interface, the UI will need an on-screen keyboard. I am aware of two virtual keyboard programs for the Pi: Matchbox Keyboard and Florence.

The problem is that I want to imitate the behavior of a smartphone keyboard as much as possible, but don't know how to do so. What I want to do is similar to this, except I want the keyboard to auto-hide and to be on top of the main window. How can this be done?

EDIT: I've tried both of these programs and haven't been able to figure out how to achieve this. I can't find an auto-popup option in Matchbox Keyboard, and some people report that it has this capability (here), others say no (here). I assume that some Linux desktop managers support this feature, but not LXDE on the Pi.

Florence seems promising because it has an auto-hide option that sounds like it would do what I want, but when I selected it didn't seem to work.

Answer

tjohnson picture tjohnson · Mar 28, 2016

I finally figured out how to add auto-hide behavior to Matchbox Keyboard. First I read about the --daemon command line argument here which sounded like it would work, but when I tried it the auto-hide feature worked for only some, not all, text entries.

The same README file says:

You can embed matchbox-keyboard into other applications with toolkits that support the XEMBED protocol ( GTK2 for example ).

See examples/matchbox-keyboard-gtk-embed.c for how its done.

I knew about this before but didn't think it would work with PyGObject, until I found out that it does. Adding these lines to my code worked:

p = subprocess.Popen(["matchbox-keyboard", "--xid"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
keyboard = Gtk.Socket()
window.add(keyboard)
keyboard.add_id(int(p.stdout.readline()))

I also created a simple subclass of Gtk.Entry which auto-hides the keyboard when the text entry gains or loses focus:

class TextEntry(Gtk.Entry):
    def __init__(self, window):
        Gtk.Entry.__init__(self)
        self.keyboard = window.keyboard

        self.connect("focus-in-event", self.on_focus_in)
        self.connect("focus-out-event", self.on_focus_out)

    def on_focus_in(self, event, data):
        self.keyboard.show()

    def on_focus_out(self, event, data):
        self.keyboard.hide()