From 04a1d2a83b96eb6d1b1958e4f3e25ffdf295aa4d Mon Sep 17 00:00:00 2001 From: Mark Tiefenbruck Date: Sun, 28 Sep 2008 01:26:21 -0700 Subject: don't let KeyRelease events propagate to windows --- src/FbTk/EventHandler.hh | 1 - src/FbTk/EventManager.cc | 23 ++++++++--------------- src/FbTk/EventManager.hh | 3 +-- src/FocusControl.cc | 2 +- src/Keys.cc | 11 +++++------ src/Screen.cc | 30 ++++++++++++++++-------------- src/Screen.hh | 3 ++- 7 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/FbTk/EventHandler.hh b/src/FbTk/EventHandler.hh index 39ea294..b78e344 100644 --- a/src/FbTk/EventHandler.hh +++ b/src/FbTk/EventHandler.hh @@ -56,7 +56,6 @@ public: virtual void leaveNotifyEvent(XCrossingEvent &) { } virtual void enterNotifyEvent(XCrossingEvent &) { } - virtual void notifyUngrabKeyboard() { } virtual void grabButtons() { } }; diff --git a/src/FbTk/EventManager.cc b/src/FbTk/EventManager.cc index 31d0293..ae52908 100644 --- a/src/FbTk/EventManager.cc +++ b/src/FbTk/EventManager.cc @@ -65,25 +65,14 @@ EventHandler *EventManager::find(Window win) { return m_eventhandlers[win]; } -bool EventManager::grabKeyboard(EventHandler &ev, Window win) { - if (m_grabbing_keyboard) - ungrabKeyboard(); - +bool EventManager::grabKeyboard(Window win) { int ret = XGrabKeyboard(App::instance()->display(), win, False, GrabModeAsync, GrabModeAsync, CurrentTime); - - if (ret == Success) { - m_grabbing_keyboard = &ev; - return true; - } - return false; + return (ret == Success); } void EventManager::ungrabKeyboard() { XUngrabKeyboard(App::instance()->display(), CurrentTime); - if (m_grabbing_keyboard) - m_grabbing_keyboard->notifyUngrabKeyboard(); - m_grabbing_keyboard = 0; } Window EventManager::getEventWindow(XEvent &ev) { @@ -190,10 +179,14 @@ void EventManager::dispatch(Window win, XEvent &ev, bool parent) { evhand->exposeEvent(ev.xexpose); break; case EnterNotify: - evhand->enterNotifyEvent(ev.xcrossing); + if (ev.xcrossing.mode != NotifyGrab && + ev.xcrossing.mode != NotifyUngrab) + evhand->enterNotifyEvent(ev.xcrossing); break; case LeaveNotify: - evhand->leaveNotifyEvent(ev.xcrossing); + if (ev.xcrossing.mode != NotifyGrab && + ev.xcrossing.mode != NotifyUngrab) + evhand->leaveNotifyEvent(ev.xcrossing); break; default: evhand->handleEvent(ev); diff --git a/src/FbTk/EventManager.hh b/src/FbTk/EventManager.hh index 79a25ce..fdcfe9c 100644 --- a/src/FbTk/EventManager.hh +++ b/src/FbTk/EventManager.hh @@ -42,9 +42,8 @@ public: void add(EventHandler &ev, Window win) { registerEventHandler(ev, win); } void remove(Window win) { unregisterEventHandler(win); } - bool grabKeyboard(EventHandler &ev, Window win); + bool grabKeyboard(Window win); void ungrabKeyboard(); - EventHandler *grabbingKeyboard() { return m_grabbing_keyboard; } EventHandler *find(Window win); diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 6533ac1..8a49273 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc @@ -91,7 +91,7 @@ void FocusControl::cycleFocus(const FocusableList &window_list, const ClientPattern *pat, bool cycle_reverse) { if (!m_cycling_list) { - if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard()) + if (m_screen.isCycling()) // only set this when we're waiting for modifiers m_cycling_list = &window_list; m_was_iconic = 0; diff --git a/src/Keys.cc b/src/Keys.cc index b917989..05f1747 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -510,12 +510,6 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, // grab "None Escape" to exit keychain in the middle unsigned int esc = FbTk::KeyUtil::getKey("Escape"); - // if focus changes, windows will get NotifyWhileGrabbed, - // which they tend to ignore - if (temp_key && type == KeyPress && - !FbTk::EventManager::instance()->grabbingKeyboard()) - XUngrabKeyboard(Fluxbox::instance()->display(), CurrentTime); - if (temp_key && !temp_key->keylist.empty()) { // emacs-style if (!saved_keymode) saved_keymode = m_keylist; @@ -536,6 +530,11 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, return false; } + // if focus changes, windows will get NotifyWhileGrabbed, + // which they tend to ignore + if (type == KeyPress) + XUngrabKeyboard(Fluxbox::instance()->display(), CurrentTime); + WinClient *old = WindowCmd::client(); WindowCmd::setClient(current); temp_key->m_command->execute(); diff --git a/src/Screen.cc b/src/Screen.cc index a6e5e84..3d6d479 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -856,19 +856,26 @@ void BScreen::propertyNotify(Atom atom) { } void BScreen::keyPressEvent(XKeyEvent &ke) { - Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, - Keys::GLOBAL|Keys::ON_DESKTOP); + if (Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, + Keys::GLOBAL|Keys::ON_DESKTOP)) + // re-grab keyboard, so we don't pass KeyRelease to clients + FbTk::EventManager::instance()->grabKeyboard(rootWindow().window()); + } void BScreen::keyReleaseEvent(XKeyEvent &ke) { - if (!m_cycling) - return; + if (m_cycling) { + unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state); + state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); + + if (state) // still cycling + return; - unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state); - state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); + m_cycling = false; + focusControl().stopCyclingFocus(); + } - if (!state) // all modifiers were released - FbTk::EventManager::instance()->ungrabKeyboard(); + FbTk::EventManager::instance()->ungrabKeyboard(); } void BScreen::buttonPressEvent(XButtonEvent &be) { @@ -880,11 +887,6 @@ void BScreen::buttonPressEvent(XButtonEvent &be) { 0, be.time); } -void BScreen::notifyUngrabKeyboard() { - m_cycling = false; - focusControl().stopCyclingFocus(); -} - void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { // get modifiers from event that causes this for focus order cycling XEvent ev = Fluxbox::instance()->lastEvent(); @@ -896,7 +898,7 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { if (!m_cycling && mods) { m_cycling = true; - FbTk::EventManager::instance()->grabKeyboard(*this, rootWindow().window()); + FbTk::EventManager::instance()->grabKeyboard(rootWindow().window()); } if (mods == 0) // can't stacked cycle unless there is a mod to grab diff --git a/src/Screen.hh b/src/Screen.hh index a5e80ee..1a77ea6 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -237,7 +237,6 @@ public: void keyPressEvent(XKeyEvent &ke); void keyReleaseEvent(XKeyEvent &ke); void buttonPressEvent(XButtonEvent &be); - void notifyUngrabKeyboard(); /** * Cycles focus of windows @@ -247,6 +246,8 @@ public: */ void cycleFocus(int opts = 0, const ClientPattern *pat = 0, bool reverse = false); + bool isCycling() const { return m_cycling; } + /** * Creates an empty menu with specified label * @param label for the menu -- cgit v0.11.2