- KeyBindingTree *p = _curpos->first_child;
- while (p) {
- if (p->binding.key == key && p->binding.modifiers == modifiers) {
- if (p->chain) {
- _timer.start(); // start/restart the timer
- grabKeys(false);
- _curpos = p;
- grabKeys(true);
- } else {
- Window win = None;
- OBClient *c = Openbox::instance->focusedClient();
- if (c) win = c->window();
- KeyData *data = new_key_data(win, time, modifiers, key);
- python_callback(p->callback, (PyObject*)data);
- Py_DECREF((PyObject*)data);
- resetChains(this);
+ // KeyRelease events only occur during keyboard grabs
+ if (action == EventKeyRelease) return;
+
+ if (key == _resetkey.key && modifiers == _resetkey.modifiers) {
+ resetChains(this);
+ } else {
+ KeyBindingTree *p = _curpos->first_child;
+ while (p) {
+ if (p->binding.key == key && p->binding.modifiers == modifiers) {
+ if (p->chain) {
+ if (_timer)
+ delete _timer;
+ _timer = new otk::Timer(5000, // 5 second timeout
+ (otk::Timer::TimeoutHandler)resetChains,
+ this);
+ // grab the server here to make sure no key pressed go missed
+ otk::display->grab();
+ grabKeys(false);
+ _curpos = p;
+ grabKeys(true);
+ otk::display->ungrab();
+ } else {
+ Client *c = openbox->focusedClient();
+ KeyData data(screen, c, time, modifiers, key, action);
+ CallbackList::iterator it, end = p->callbacks.end();
+ for (it = p->callbacks.begin(); it != end; ++it)
+ python_callback(*it, &data);
+ resetChains(this);
+ }
+ break;