Functions | |
void | minxlib::keymap::bind (KeyCode k, unsigned int m, const std::string &s) |
Record a user-defined key binding. More... | |
std::string | minxlib::keymap::get (KeyCode k, unsigned int m) |
Return name of user-defined key binding. More... | |
uint32_t | minxlib::keymap::ignore_lock_modifiers (XModifierKeymap *m, Display *d) |
Ignore lock modifiers in key events. More... | |
void | minxlib::keymap::pythonize () |
Setup keymap module's logger. More... | |
This file defines an API for keeping track of the names users have defined for their key bindings and to translate X keyboard events to those names.
void minxlib::keymap::bind | ( | KeyCode | k, |
unsigned int | m, | ||
const std::string & | s | ||
) |
Record a user-defined key binding.
k | The X keycode for the key binding. |
m | The modifier mask for the key binding. |
s | The name of the key binding. |
An important feature of Minx is its support for key bindings. Users specify functions they want executed in response to particular keystrokes. For example, a user may want to launch a terminal window when s/he presses CTRL + ALT + T. This key combination may be specified as "C-A-T" or "A-C-T".
Now, when the user presses CTRL + ALT + T, minxlib will have to translate that keystroke to whatever the user specified. That is, if s/he configured it as "C-A-T", then minxlib will have to return "C-A-T" in the key_press event; similarly, if the key binding was specified as "A-C-T", we will have to return "A-C-T".
In order to perform the translation described above, we have to remember the string supplied to minxlib when the passive grabs are setup for the key bindings (see the implementations of minx.core.wm.wm.configure_x() and minxlib::window::grab_key() for the gory details of how key bindings are configured). Then, when we receive keyboard events from X, we will have to consult the key map to see if it has an entry corresponding to the pressed (or released) key and, if so, report the event as a key binding rather than a simple key press.
This function inserts the user-defined key binding name corresponding to the given keycode and modifier mask into the key map data structure implemented by this module. It is meant to be used by minxlib::window::grab_key(), i.e., when Minx sets up passive grabs for all the user-defined (or default) key bindings.
std::string minxlib::keymap::get | ( | KeyCode | k, |
unsigned int | m | ||
) |
Return name of user-defined key binding.
k | The X keycode for the key binding. |
m | The modifier mask for the key binding. |
To make key bindings work, Minx sets up passive keyboard grabs for the key combinations configured by end-users. Then, when we receive keyboard events from the X server, we check if the event's keycode and modifier mask correspond to one of the passive grabs that was setup earlier on and, if so, report that key binding's user-defined name as part of the keyboard event.
Minx's Python core can then use the key binding name to trigger hooks for that keystroke and not worry about the other low-level details of the keyboard event.
This function returns the name of the key binding corresponding to the supplied keycode and modifier mask. It is meant to be used by the minxlib::key_event_details constructor, i.e., when we're creating a minxlib::event for a keyboard event.
If there is no key binding setup for the given keycode and modifier mask, this function will throw an std::out_of_range exception.
uint32_t minxlib::keymap::ignore_lock_modifiers | ( | XModifierKeymap * | m, |
Display * | d | ||
) |
Ignore lock modifiers in key events.
m | X server's modifier keymap. |
d | X server's interface object. |
Lock modifiers mess up the translation from key events to key binding names. For example, let's say a user has configured Minx to respond to F1 and S-F1. Let's also say that this user's X modifier map has NumLock setup as Mod2 and that the NumLock key is on.
Now, when s/he presses F1 or SHIFT + F1, the resulting key event will have the Mod2 bit set in its modifier mask, i.e., to Minx, the key event will look like Mod2 + F1 or Mod2 + SHIFT + F1 rather than a plain F1 or SHIFT + F1. Consequently, when we combine the key event's keycode and modifier mask to index the internal map storing key bindings, we will get an index for a non-existent key binding, which, of course, means that, while NumLock is on, Minx will not recognize the F1 or SHIFT + F1 key bindings.
The long and short of it is that a modifier key that acts as a lock (Caps Lock, Num Lock, Scroll Lock, etc.) will screw around with key events in such a way as to cause Minx's key binding mechanism to fail. Thus, we want to ignore any modifiers that are tied to such Lock keys.
This function sets up an internal mask to do just that. It is meant to be called early on during Minx's initialization sequence. An ideal time to call it is after connecting to the X server but just before setting up the passive grabs that will make the key bindings mechanism work; that's why it's called from minxlib::window::grab_key().
void minxlib::keymap::pythonize | ( | ) |
Setup keymap module's logger.
The keymap module does not really have anything exposed to Minx's Python core via Boost.Python. However, we do use the Python-based logging infrastructure. That's why we need this "pythonization" function, which is meant to be called by the Boost.Python initialization code in python.cc.