all repos — openbox @ e429ce39deaf4a8d5975e871af0530634ea2a63e

openbox fork - make it a bit more like ryudo

new key code with keyboard grabs and such, thanks to ManMower. Kills the "key leak" bug, and makes everything work better and faster! woot
Dana Jansens danakj@orodu.net
commit

e429ce39deaf4a8d5975e871af0530634ea2a63e

parent

4eaa65510b26d342c5419e6081bcecaa0ec8aa24

4 files changed, 44 insertions(+), 41 deletions(-)

jump to
M otk/display.ccotk/display.cc

@@ -300,4 +300,9 @@ XUngrabKey(_display, keycode, modifiers | _mask_list[cnt],

grab_window); } +void Display::ungrabAllKeys(Window grab_window) const +{ + XUngrabKey(_display, AnyKey, AnyModifier, grab_window); +} + }
M otk/display.hhotk/display.hh

@@ -133,6 +133,7 @@ int pointer_mode, int keyboard_mode,

bool allow_scroll_lock) const; void ungrabKey(unsigned int keycode, unsigned int modifiers, Window grab_window) const; + void ungrabAllKeys(Window grab_window) const; }; }
M src/bindings.ccsrc/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 @@ for (int i = 0; i < ScreenCount(**otk::display); ++i) {

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 @@ {

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 @@ Client *c = openbox->focusedClient();

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 @@ delete _timer;

_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 @@ if (self->_timer) {

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); + } }
M src/bindings.hhsrc/bindings.hh

@@ -116,7 +116,9 @@

EventCallbackList _eventlist[EventAction::NUM_EVENT_ACTION]; KeyCallbackData _keybgrab_callback; - + + bool _grabbed; + public: //! Initializes an Bindings object Bindings();