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.
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()