N900 portrait keyboard for Witter
Recently Nokia released the much awaited pr 1.2 firmware for the N900, and among the many bug fixes and tweaks, came the ability to easily rotate applications to portrait by hitting ctrl+shift+r, then closing the keyboard and rotating to portrait. This feature had the knock on effect that I started to look seriously at portrait support in Witter, where upon I quickly found a pre-canned python module that I could just include to get persistent portrait support available from the talk.maemo.org forums
No sooner had I got witter in portrait mode, than the obvious next step was suggested…. what about some way to actually tweet in portrait. For those not familiar with Maemo and the N900, although it does now support some appliactions such as the browser going portrait, there is no system wide on screen keyboard for portrait use. There is one for landscape (despite having a physical keyboard for landscape use) but not in portrait. this has left application developers to provide their own. This is deeply dissatisfying as an approach, however keen to provide a meaningful portrait use for Witter, I decided to go ahead and implement my own.
So how to go about it? Well it actually not very hard at all, just very boring. Basically a ‘keyboard’ is just a bunch of buttons, all wired to emit a signal with a single letter, number or symbol associated. So that’s 26 button definitions, 3 lines per definition (create object, set title, connect signal to emit character) just to do all the lower case letters. So far that’s a little under 600 lines of code, to provide upper and lower case letters, plus a keyboard with numbers and some of the more obvious symbols, plus some mode shifting buttons. Most of this is of course copy’n'paste work, with single character adjustments but in a desire to not have generic and confusing object names I also had to name all of them appropriately. In all it was a couple of hours work.
The implementation is a fairly simple architecture, The main witter layout has a single gtk.VBox which is the main contained for the keyboard. It defaults to empty and invisible.
Each keyboard layout comes with two methods, one to define all the objects, and a wrapper which calls it then requests that the gtk.VBox and all it’s children become visible. This is separated into two because it is helpful to be able to initialise the keyboard objects separately from choosing whether they should currently be visible or not. The main definition method starts by destroying everything already inside the top level gtk.VBox. This means each layout can have a different number of rows as wells as different content in them.
Each button is created like this:
q = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT,
hildon.BUTTON_ARRANGEMENT_VERTICAL)
q.set_title(‘q’)
q.connect(“clicked”, self.TypeLetter, “q”)
The interesting code actually occurs in TypeLetter, because there are a few subtle behaviours that people expect from a text entry field that aren’t that obvious. For instance you want to be able to select any point in the existing string, and enter or delete text from that point, not just add characters onto the end.
def TypeLetter(self, widget, letter): #get the position of the current cursor pos = self.tweetText.get_position() #get the current text string text = self.tweetText.get_text() #if passed special delete eye catcher we are actually deleteing characters if (letter =="*delete*"): self.tweetText.set_text(text[0:pos-1]+text[pos:len(text)]) self.setCursorAt(pos-1); else: #normal entry of text at the selected pos self.tweetText.set_text(text[0:pos]+letter+text[pos:len(text)]) self.setCursorAt(pos+1);
So you have to basically split the existing string around the position of the cursor and either insert or delete characters at that point, and leave the cursor set in the appropriate position.
All of this goes to make a keyboard that looks something like this:

The remaining question is how to launch the keyboard when you want it. At the moment in Witter I have re-purposed a PLUS icon in the top row of buttons, so that in portrait mode it displays or hides the portrait keyboard. (whenever the orientation changes I store a current orientation value so that this code can tell whether it should be displaying the portrait keyboard or not) However ideally it would be hooked off of the text entry field gaining or losing focus, I just haven’t figured that bit out yet.
Trackbacks
- Twitter on the N900
- A Portrait Keyboard Comes To Witter – Why Can’t Nokia Put In One That All Apps Can Use? | The MeeGo Blog - Formerly Maemo Central
- A Portrait Keyboard Comes To Witter – Why Can’t Nokia Put In One That All Apps Can Use? | Maemo Nokia N900
- Pinguins Móveis » Blog Archive » Pinguins de fim-de-semana
- Witter si aggiorna e aggiunge anche la tastiera portrait su schermo

GtkWidget has “focus-in-event” and “focus-out-event” signals that you might want to connect to to monitor the entry’s focus.
http://www.pygtk.org/docs/pygtk/class-gtkwidget.html#signal-gtkwidget–focus-in-event
Cheers, that works like a charm, 0.3.4-4 uploading now, with keyboard triggered on those events. Thanks for saving me the time to find them.
Would look and presumably work better if character buttons were same width. ‘I’ for example looks very slim considering it’s likely to be used more often
quite so, I simply haven’t bothered to do the maths yet to figure out the consistent fixed width for each row based on button sized. particularly asI’ve not necessarily settled on the layout, or finished adding symbol buttons yet. But I will certainly fix the width at some point soon.
If you are using a gtk.HBox for the horizontal layout of a button row, you can use the “homogeneous” property (set to “True”) of it to divide the width equally to all child widgets. Alternatively, use “set_size_request” on the buttons to set a minimum width for the buttons.
Another awesome tip, thank you. It really does make life faster to have people tell you the options you need
cuts down on all the boring research bit. Witter 0.3.4-5 uploaded with the top 3 rows of the keyboard layout set to homogeneous.
Hey!
Great work! I love it! Very usable and finger friendly
Is there anyway to package this as a separate app. with a singular copy-all and delete-all buttons. Much like suggested before, It would be open all the time and accessible via multitasking. I would type my text and press the copy-all button end embed it into the email, note, sms, app or whatever I was looking to type in!
Any chance?
B.
Nice idea, I guess it would be possible to write a specific app with nothing but a text entry field and a keyboard.
I’ll give it some thought, the main issue would be how do you paste the content in the desired place? there is no way to provide it as something that would integrate with other apps.
I yet doesn’t understand why this hasn’t been integrated on the last firmware update of Maemo. It isn’t so much dificult it seems.
Well just read carefully through the post and then this thread: http://talk.maemo.org/showthread.php?p=702588
It isn’t as simple as it seems.