Wednesday, June 6, 2007

Key Reassignment Done

After many hours of research and coding I finally got the key reassignment capabilities in. Though it turned out to be a simpler task than I had expected, it still had its own series of bumps and surprises along the way.

The first and obvious bump was for me to become familiar enough with how things work to be able to utilize and modify the current code to make it do what I want it to do. But like I said above, this was one of the simpler things in the end. The association of keys to actions is setup like this. Every GntWidget is a GntBindable. GntBindable is associated with GntBindableClass. GntBindableClass contains three hash tables. The first we won't bother talking about here, but the other two are of interest to us.

The first table contains (name,Action) key/value pairs. The names are strings like "gained-focus", "window-moved", "key-pressed", etc. The Actions are the the functions performed. The second table contains (key,ActionParam). The keys are simply strings that represent keystrokes entered by the user. Then the ActionParam contain an action and parameters that are passed to that action.

So now when a key is pressed, the associated ActionParam is looked up from the related hash table and it is executed, simple as that. Sure there are some tricky things to happen along the way as far as what gets to execute the action, the window manager, a window, or a widget inside that window, but that's beyond the scope of this post. Maybe someday when I have nothing to write about, I'll post some more information on that.

Now that you have a basic understanding of how actions are performed based on keystrokes, I can tell you how assigning new key combinations to actions is done. When the user types alt-/ or alt-\ for widget or window manager reassignments, respectively, a list of available actions are displayed. From there a user scrolls to the desired action and hits . The needed information is given to a new window. This information being, ActionName, original key combination, and the GntBindable being modified; keep in mind that the window manager is a GntBindable also. From there we can get the GntBindableClass. The user then types in a new keystroke and selects the Bind button.

To replace a key assignment, two reassignments need to be done. First we reassign the old keystrokes to activate a NULL action. The reassignment function treats this as a delete action and deletes the (oldKeys, ActionParam) entry in the table. Then a second call to the same function is made with the new key combination. From the name, an Action is retrieved from the (name,Action) hash table. An ActionParam is created by associating this action with the parameters passed in. At this point, no actions make use of parameters, so this process will have to be modified slightly later to pass along needed parameters. Then it simply puts an entry in the (key, ActionParam) table with the new keys and the new ActionParam.

Sure one could argue that a function that takes two key combinations could change the key from the old to the new combinations. But since this is done very seldom, there isn't much of a need for this function. Maybe someday, it will be added.

So there you have it, this is how key reassignment is done. Feel free to ask some questions if certain parts are unclear. I will give some updates in a while, since this process still has some refining to do, such as some windows have special keystrokes they handle.

1 comment:

Rodrigo said...
This comment has been removed by a blog administrator.