Introducing Gdk Key Table

Having defined all of this behavior, I broke the problem down into smaller particulars:

  1. A widget's key table (GdkKeyTable) - The repository of all actions and corresponding keys.
  2. Each table's many key entries (GdkKeyEntry) - a description of a possible action and the list of all keys that will trigger said action.
  3. Each entry's key combinations (GdkKeyKey).
I then created the following structures (shown from the bottom, up):

GdkKeyKey:

GdkKeyEntry:

GdkKeyTable:


How the Key Table Works

When a program starts and the loads all of its necessary widgets from the gtk+ library, each widget that uses the key table system goes through the following ordeal:

  1. It builds its initial key table, filled with all the actions the key table can handle.
  2. User-configuration piggybacks on gtkrc. When the gtk configuration files are loaded, any key table information (i put mine in my ~/.gtkrc) is loaded into a table of key tables local to gtkrc.
  3. After the widget initializes itself and gtkrc has read all of the necessary configuration, the widget hands its keytable to gtkrc, asking it to change whatever is appropriate.
  4. gtkrc looks for a key table in its local hash with the same name as the key table it is handed (hence each table needs a unique name).
  5. If such a table is found, it looks for entries its local key table with strings matching those in the key table it is handed (hence each entry needs a unique name).
  6. For each entry that matches one in the incoming table, the local set of keys is copied over the keys on the incoming table, remapping the keys. User entries that do not match any existing entries are ignored.

Now that the key table for our widget is initialized, we just have to wait for a key press to come in. This is handled through gtk+'s happy signal passing. I have no real idea how it works. I just enjoy it. In the end, a function is triggered. I talk about that function on one or the other of these pages, so I will not repeat it here.

So our widget has been called to act on a key press. Here is what it should do:

  1. Lookup the incoming event in its table.
  2. If an entry is found with a key combination matching that of the incoming event, it's unique integer ID is returned. If no matching key combination can be found in the table, -1 is returned (and is usually ignored so that the event will be passed on down the chain, to some other widget that might use it).
  3. From this a simple switch or if statement can be made to act appropriately upon the event.