Monday, September 26, 2011

wxWidgets keyboard handling

The cross platform code that isn't.

A couple of weeks ago, another piece of wxWidgets infrastructure in the Alter Aeon client was replaced with custom code.  This time, it was the bulk of the keyboard handling code that fell in battle.

In theory, the wxWidgets keyPressEvent is where you should trap out various key combinations; things like 'a', the escape key, and 'control-c' pairs.  Certainly under linux, nearly all of these worked correctly, and the ones that didn't were obscure and not really worth hunting down.  When I first ported to Win32, all that changed.

In Win32 builds, a lot of keys were not handled by the key press event.  You'd press the key combination, and nothing would happen.  It was like the operating system was trapping out the key combination and never bothering to pass it up the stack.  As it turns out, that's pretty much exactly what was happening.

I did eventually get the Win32 builds to work by intercepting a handful of keys at the keyDownEvent and keyUpEvent layers.  When I finally found these, it was hugely helpful; in the end, I trapped on the order of 30 key combinations to do away with things like annoying system beeps and idiotic behavior of the default keystrokes, in addition to handling our own special control combinations.

Enter Mac OSX.  Enter a whole new raft of keyboard weirdness.  I hacked on this for about an hour, and quickly realized that I was on the path to madness.  The code was becoming a rat's nest of ifdefs with key combinations trapped out in multiple different layers in different operating systems.

About the only thing that could be called consistent between any of the operating systems was that the keyDownEvent and keyUpEvent were always reliable.  The solution then seemed obvious:  move everything down into the keyDownEvent, and ignore everything else.  Intercept the keyboard control -before- wxWidgets could do anything stupid with it.

Keyboard control now works consistently and reliably on all three platforms.

No comments: