X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fbindings.cc;h=aa9c288d670f341c077bb859548548e914bf8d1c;hb=084d6f4e42396a5d2baf72877b5abf3ae6fef7be;hp=2ce8c8e4304a4e01fa5b56d9a028997cbca56b53;hpb=741c68bb8701c440d9de974456c4a356de4ea6e0;p=chaz%2Fopenbox diff --git a/src/bindings.cc b/src/bindings.cc index 2ce8c8e4..aa9c288d 100644 --- a/src/bindings.cc +++ b/src/bindings.cc @@ -147,7 +147,8 @@ KeyBindingTree *Bindings::buildtree(const StringVect &keylist, Bindings::Bindings() : _curpos(&_keytree), _resetkey(0,0), - _timer((otk::Timer *) 0) + _timer((otk::Timer *) 0), + _keybgrab_callback(0) { // setResetKey("C-g"); // set the default reset key } @@ -371,38 +372,79 @@ void Bindings::grabKeys(bool grab) } +bool Bindings::grabKeyboard(int screen, PyObject *callback) +{ + assert(callback); + if (_keybgrab_callback) return false; // already grabbed + + int i; + for (i = 0; i < openbox->screenCount(); ++i) + if (openbox->screen(screen)->number() == screen) + break; + if (i >= openbox->screenCount()) + return false; // couldn't find the screen.. it's not managed + + Window root = otk::display->screenInfo(i)->rootWindow(); + if (XGrabKeyboard(**otk::display, root, false, GrabModeAsync, + GrabModeSync, CurrentTime)) + return false; + printf("****GRABBED****\n"); + _keybgrab_callback = callback; + return true; +} + + +void Bindings::ungrabKeyboard() +{ + if (!_keybgrab_callback) return; // not grabbed + + _keybgrab_callback = 0; + XUngrabKeyboard(**otk::display, CurrentTime); + printf("****UNGRABBED****\n"); +} + + void Bindings::fireKey(int screen, unsigned int modifiers, unsigned int key, - Time time) + Time time, KeyAction action) { - if (key == _resetkey.key && modifiers == _resetkey.modifiers) { - resetChains(this); + if (_keybgrab_callback) { + Client *c = openbox->focusedClient(); + KeyData data(screen, c, time, modifiers, key, action); + python_callback(_keybgrab_callback, &data); } 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); - CallbackList::iterator it, end = p->callbacks.end(); - for (it = p->callbacks.begin(); it != end; ++it) - python_callback(*it, &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; } - break; + p = p->next_sibling; } - p = p->next_sibling; } } } @@ -527,7 +569,7 @@ void Bindings::grabButtons(bool grab, Client *client) void Bindings::fireButton(MouseData *data) { if (data->context == MC_Window) { - // Replay the event, so it goes to the client, and ungrab the device. + // Replay the event, so it goes to the client XAllowEvents(**otk::display, ReplayPointer, data->time); }