Thursday 18 August 2016

Project conclusion

This summer I have been developing a new keyboard system for Mixxx as part of this year's Google summer of Code program. My initial project was to make a keyboard mapping GUI, but the backend turned out to be more complex than expected. To be more specific, it was the internationalization that stretched the original plan as described in the project proposal. However, although I did not make the GUI, the keyboard does work. And all its mappings work on all supported keyboard layouts because of a new key-sequence translation system I made.

The code I've written during this GSoC can be found here:
PULL REQUEST

Keyboard Controller

The base of this new keyboard system is the KeyboardController, a new Mixxx controller type whose life cycle is regulated in the ControllerManager, just like every other controller. Its task is to communicate with the KeyboardEventFilter, which is installed to various widgets as an event filter listening for key events as well for keyboard layout change- and focus events. It is updated by KeyboardController about current mappings whenever the mappings change in KeyboardController's current KeyboardControllerPreset.

When the user presses a key sequence known to KeyboardEventFilter, it passes the ConfigKey bound to the pressed key sequence to KeyboardController, which then does or does not set the Mixxx control, depending on whether the controller is enabled or not. The user can enable / disable it both via controller preferences and via main menu bar's Enable Keyboard Shortcuts checkbox.

KeyboardShortcuts
In Mixxx, we distinct ordinary keyboard shortcuts from shortcuts that are bound directly to QActions with QAction::setShortcut(). These type of shortcuts belong to the [KeyboardShortcuts] group and are processed neither by KeyboardController nor by KeboardEventFilter, but by the QActions themselves. Also, they are not translated by our own translation system but by QTranslator. This translation is possible because these mappings are Qt Standard Shortcuts. These [KeyboardShortcuts] shortcuts are managed by the KeyboardShortcutsUpdater, which is sent a signal when new mappings are loaded. 

Tooltips
Keyboard shortcut info in tooltips is updated by the TooltipShortcutsUpdater, which is sent a signal whenever new mappings are loaded.

Keyboard presets and key translations

Keyboard mappings are stored to disk as *.kbd.xml files and can hold mappings for multiple keyboard layouts. However, it usually just contains info for one layout. That's because Mixxx is now able to translate key sequence from one keyboard layout to the other, runtime. Therefore, it's now possible to start Mixxx with layout en_US, switch to ru_RU and then to el_GR and the keyboard and its mappings will keep working on each switch. Naturally, tooltips are also updated.

The translation system uses layout translation tables, which are generated by a tool I made that reads the current keyboard layout map from X and generated both layouts.cpp and layouts.h. The tool uses the X11 API and therefore it does only work on Linux.

Migration

The kbdcfg_to_kbdxml tool can be given multiple legacy config files (one per layout) and outputs one single *.kbd.xml file. The tool is also given the layout translation tables file, so that it can explicitly add mappings for specific layouts or leave them out, depending on whether the specific mapping is translatable or not. This tool is used to create Keyboard-Default.kbd.xml, the default keyboard preset.

No comments:

Post a Comment