In the beginning, Metacity stored keybindings in GConf. There was one GConf key for each action, and the string value gave the key bound to it. If it was undefined or “disabled”, there would be no key bound to that action.
In 2005, GNOME bug 164831 raised the point that other platforms used several keybindings for some of the actions. For example, the command to show the main menu is alt-f1 in CUA, but ctrl-Esc in Windows. We decided to find a way to support mulitple keybindings for the sake of people transitioning from these systems.
This posed a further problem. There is or was a principle that GConf configuration should be both forwards and backwards compatible. In other words, if you take a Metacity configuration from any point in time, it should work as well as possible with every other version of Metacity, both later and earlier. This meant that we couldn’t change the format of the single string keys. So instead we created two keys: one, the original key, took a single string, and the other, a new key, took a list of strings. This worked, but resulted in everything getting a lot more complicated. It’s not clear that it was ever widely used.
Now, in GNOME bug 621204, there is a laudable move to switch Metacity to using the new GSettings API. The dual nature of the keybinding settings makes this problematic. We could proceed by:
- implementing it exactly as it is currently, even though it’s fiddly;
- removing the ability to use multiple keybindings for the same action, even though that would break compatibility;
- making all keybinding settings be lists of strings;
- making all keybindings be represented by one very large settings, a list of pairs of strings.
Gentle reader, your thoughts on this are welcome, here or on the bug.
Photo © Matthew Boyle, cc-by-nc
(1) sounds like voluntarily breaking stuff at the very point when it can be fixed.
(2) sounds like fixing the wrong thing (getting rid of the problem by removing a feature that introduced it).
(3) seems to be a solution
(4) smells like that database table you saw once. It only had two columns, one for ID and one for anything serializable to XML.
(3) Sounds the most sensible to me.
It would also be great if you could blog about the metacity policy of porting/applying patches that land in Mutter. In addition to some interesting looking bug fixes, some nice stuff has gone in there recently, that I would like to use in metacity;
* side-by-side tiling/aero snap
* cairo/gtk3 compatibility
* allow breaking out from tiling during a mouse resize (i.e. alt resize on tiled windows too)
I’d say that making every setting a list of strings is the right way to do. Since we are already migrating, might as well migrate to the scalable.
And please, do not make a list of lists in a single setting, it’s _Hell_ to work with, unportable, and is just as likely to break in the future.
For example of how not to do it, look at evolution, storing settings as a string of xml inside the gconf keys. Please avoid that kind of crack.
I think the migration to GSettings should be seen as the opportunity to do things right, regardless of backward compatibility. Given that, option 3 seems to be the sensible choice – older versions can keep the complexity in talking to GConf, while newer version can throw it away. The user may have to set up their keybindings again, but that’s a one-off event at worst…
As I noted on the bug, we can potentially choose option (3), which is the one I implemented in the patch, and ensure migration of old settings if we’re motivated enough to write a script for that. There’s already a migration tool (gsettings-data-convert) that could be improved to be able to merge two keys into a single list.