X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fbindings.cc;h=e6f98f79688fcdbfe5cef113e629abce5ae3142a;hb=7f561a6a7acee71d55eecc9ed2bd278147ce2536;hp=167d0a854439ded9415da00bde70c404bc3b7fb5;hpb=7c8c9e998ffc3a9b22e15feeffe77823142ce531;p=chaz%2Fopenbox diff --git a/src/bindings.cc b/src/bindings.cc index 167d0a85..e6f98f79 100644 --- a/src/bindings.cc +++ b/src/bindings.cc @@ -1,8 +1,6 @@ // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif +#include "config.h" #include "bindings.hh" #include "screen.hh" @@ -18,24 +16,30 @@ extern "C" { #define _(str) gettext(str) } +#include #include namespace ob { static bool buttonvalue(const std::string &button, unsigned int *val) { - if (button == "Left" || button == "1" || button == "Button1") { - *val |= Button1; - } else if (button == "Middle" || button == "2" || button == "Button2") { - *val |= Button2; - } else if (button == "Right" || button == "3" || button == "Button3") { - *val |= Button3; - } else if (button == "Up" || button == "4" || button == "Button4") { - *val |= Button4; - } else if (button == "Down" || button == "5" || button == "Button5") { - *val |= Button5; - } else - return false; + if (button == "Left") + *val = 1; + else if (button == "Middle") + *val = 2; + else if (button == "Right") + *val = 3; + else if (button == "Up") + *val = 4; + else if (button == "Down") + *val = 5; + else { + // try convert to number + int i = atoi(button.c_str()); + if (i <= 0) + return false; + *val = i; + } return true; } @@ -147,9 +151,10 @@ Bindings::Bindings() : _curpos(&_keytree), _resetkey(0,0), _timer((otk::Timer *) 0), - _keybgrab_callback(0, 0) + _keybgrab_callback(0, 0), + _grabbed(0) { -// setResetKey("C-g"); // set the default reset key + setResetKey("C-g"); // set the default reset key } @@ -157,7 +162,10 @@ Bindings::~Bindings() { if (_timer) delete _timer; - + if (_grabbed) { + _grabbed = false; + XUngrabKeyboard(**otk::display, CurrentTime); + } removeAllKeys(); //removeAllButtons(); // this is done by each client as they are unmanaged removeAllEvents(); @@ -298,13 +306,8 @@ void Bindings::setResetKey(const std::string &key) { Binding b(0, 0); if (translate(key, b)) { - // grab the server here to make sure no key pressed go missed - otk::display->grab(); - grabKeys(false); _resetkey.key = b.key; _resetkey.modifiers = b.modifiers; - grabKeys(true); - otk::display->ungrab(); } } @@ -343,28 +346,17 @@ void Bindings::grabKeys(bool grab) Screen *sc = openbox->screen(i); if (!sc) continue; // not a managed screen Window root = otk::display->screenInfo(i)->rootWindow(); - - KeyBindingTree *p = _curpos->first_child; + if (!grab) { + otk::display->ungrabAllKeys(root); + continue; + } + KeyBindingTree *p = _keytree.first_child; while (p) { - if (grab) { - otk::display->grabKey(p->binding.key, p->binding.modifiers, - root, false, GrabModeAsync, GrabModeAsync, - false); - } - else - otk::display->ungrabKey(p->binding.key, p->binding.modifiers, - root); + otk::display->grabKey(p->binding.key, p->binding.modifiers, + root, false, GrabModeAsync, GrabModeSync, + false); p = p->next_sibling; } - - if (_resetkey.key) - if (grab) - otk::display->grabKey(_resetkey.key, _resetkey.modifiers, - root, false, GrabModeAsync, GrabModeAsync, - false); - else - otk::display->ungrabKey(_resetkey.key, _resetkey.modifiers, - root); } } @@ -392,7 +384,8 @@ void Bindings::ungrabKeyboard() if (!_keybgrab_callback.callback) return; // not grabbed _keybgrab_callback = KeyCallbackData(0, 0); - XUngrabKeyboard(**otk::display, CurrentTime); + if (!_grabbed) /* don't release out from under keychains */ + XUngrabKeyboard(**otk::display, CurrentTime); XUngrabPointer(**otk::display, CurrentTime); } @@ -423,12 +416,13 @@ void Bindings::fireKey(int screen, unsigned int modifiers, unsigned int key, KeyData data(screen, c, time, modifiers, key, action); _keybgrab_callback.fire(&data); } - + // KeyRelease events only occur during keyboard grabs if (action == KeyAction::Release) return; if (key == _resetkey.key && modifiers == _resetkey.modifiers) { resetChains(this); + XAllowEvents(**otk::display, AsyncKeyboard, CurrentTime); } else { KeyBindingTree *p = _curpos->first_child; while (p) { @@ -439,18 +433,23 @@ void Bindings::fireKey(int screen, unsigned int modifiers, unsigned int key, _timer = new otk::Timer(5000, // 5 second timeout (otk::Timer::TimeoutHandler)resetChains, this); - // grab the server here to make sure no key presses get missed - otk::display->grab(); - grabKeys(false); + if (!_grabbed && !_keybgrab_callback.callback) { + Window root = otk::display->screenInfo(screen)->rootWindow(); + //grab should never fail because we should have a sync grab at + //this point + XGrabKeyboard(**otk::display, root, 0, GrabModeAsync, + GrabModeSync, CurrentTime); + } + _grabbed = true; _curpos = p; - grabKeys(true); - otk::display->ungrab(); + XAllowEvents(**otk::display, AsyncKeyboard, CurrentTime); } else { Client *c = openbox->focusedClient(); KeyData data(screen, c, time, modifiers, key, action); KeyCallbackList::iterator it, end = p->callbacks.end(); for (it = p->callbacks.begin(); it != end; ++it) it->fire(&data); + XAllowEvents(**otk::display, AsyncKeyboard, CurrentTime); resetChains(this); } break; @@ -466,12 +465,12 @@ void Bindings::resetChains(Bindings *self) delete self->_timer; self->_timer = (otk::Timer *) 0; } - // grab the server here to make sure no key pressed go missed - otk::display->grab(); - self->grabKeys(false); self->_curpos = &self->_keytree; - self->grabKeys(true); - otk::display->ungrab(); + if (self->_grabbed) { + self->_grabbed = false; + if (!self->_keybgrab_callback.callback) + XUngrabKeyboard(**otk::display, CurrentTime); + } }