summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-02-11 21:05:50 +0000
committerDana Jansens <danakj@orodu.net>2003-02-11 21:05:50 +0000
commite429ce39deaf4a8d5975e871af0530634ea2a63e (patch)
tree1c564182db8bcc76d056dc165355477176051564 /src
parent4eaa65510b26d342c5419e6081bcecaa0ec8aa24 (diff)
new key code with keyboard grabs and such, thanks to ManMower. Kills the "key leak" bug, and makes everything work better and faster! woot
Diffstat (limited to 'src')
-rw-r--r--src/bindings.cc75
-rw-r--r--src/bindings.hh4
2 files changed, 38 insertions, 41 deletions
diff --git a/src/bindings.cc b/src/bindings.cc
index 138aba81..8c915f4e 100644
--- a/src/bindings.cc
+++ b/src/bindings.cc
@@ -145,9 +145,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
}
@@ -155,7 +156,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();
@@ -296,13 +300,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();
}
}
@@ -341,28 +340,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);
}
}
@@ -390,7 +378,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);
}
@@ -421,12 +410,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) {
@@ -437,18 +427,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);
- _curpos = p;
- grabKeys(true);
- otk::display->ungrab();
+ 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;
+ }
+ 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;
@@ -464,12 +459,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);
+ }
}
diff --git a/src/bindings.hh b/src/bindings.hh
index 53565c38..f45e5ca3 100644
--- a/src/bindings.hh
+++ b/src/bindings.hh
@@ -116,7 +116,9 @@ private:
EventCallbackList _eventlist[EventAction::NUM_EVENT_ACTION];
KeyCallbackData _keybgrab_callback;
-
+
+ bool _grabbed;
+
public:
//! Initializes an Bindings object
Bindings();