diff options
author | Mark Tiefenbruck <mark@fluxbox.org> | 2008-09-28 08:26:21 (GMT) |
---|---|---|
committer | Mark Tiefenbruck <mark@fluxbox.org> | 2008-09-28 08:26:21 (GMT) |
commit | 04a1d2a83b96eb6d1b1958e4f3e25ffdf295aa4d (patch) | |
tree | efeb502c24025cd090629ae36d330fa882a41403 | |
parent | c8022b3bdb90259352d08838576e98b559a9db68 (diff) | |
download | fluxbox-04a1d2a83b96eb6d1b1958e4f3e25ffdf295aa4d.zip fluxbox-04a1d2a83b96eb6d1b1958e4f3e25ffdf295aa4d.tar.bz2 |
don't let KeyRelease events propagate to windows
-rw-r--r-- | src/FbTk/EventHandler.hh | 1 | ||||
-rw-r--r-- | src/FbTk/EventManager.cc | 23 | ||||
-rw-r--r-- | src/FbTk/EventManager.hh | 3 | ||||
-rw-r--r-- | src/FocusControl.cc | 2 | ||||
-rw-r--r-- | src/Keys.cc | 11 | ||||
-rw-r--r-- | src/Screen.cc | 30 | ||||
-rw-r--r-- | 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: | |||
56 | virtual void leaveNotifyEvent(XCrossingEvent &) { } | 56 | virtual void leaveNotifyEvent(XCrossingEvent &) { } |
57 | virtual void enterNotifyEvent(XCrossingEvent &) { } | 57 | virtual void enterNotifyEvent(XCrossingEvent &) { } |
58 | 58 | ||
59 | virtual void notifyUngrabKeyboard() { } | ||
60 | virtual void grabButtons() { } | 59 | virtual void grabButtons() { } |
61 | }; | 60 | }; |
62 | 61 | ||
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) { | |||
65 | return m_eventhandlers[win]; | 65 | return m_eventhandlers[win]; |
66 | } | 66 | } |
67 | 67 | ||
68 | bool EventManager::grabKeyboard(EventHandler &ev, Window win) { | 68 | bool EventManager::grabKeyboard(Window win) { |
69 | if (m_grabbing_keyboard) | ||
70 | ungrabKeyboard(); | ||
71 | |||
72 | int ret = XGrabKeyboard(App::instance()->display(), win, False, | 69 | int ret = XGrabKeyboard(App::instance()->display(), win, False, |
73 | GrabModeAsync, GrabModeAsync, CurrentTime); | 70 | GrabModeAsync, GrabModeAsync, CurrentTime); |
74 | 71 | return (ret == Success); | |
75 | if (ret == Success) { | ||
76 | m_grabbing_keyboard = &ev; | ||
77 | return true; | ||
78 | } | ||
79 | return false; | ||
80 | } | 72 | } |
81 | 73 | ||
82 | void EventManager::ungrabKeyboard() { | 74 | void EventManager::ungrabKeyboard() { |
83 | XUngrabKeyboard(App::instance()->display(), CurrentTime); | 75 | XUngrabKeyboard(App::instance()->display(), CurrentTime); |
84 | if (m_grabbing_keyboard) | ||
85 | m_grabbing_keyboard->notifyUngrabKeyboard(); | ||
86 | m_grabbing_keyboard = 0; | ||
87 | } | 76 | } |
88 | 77 | ||
89 | Window EventManager::getEventWindow(XEvent &ev) { | 78 | Window EventManager::getEventWindow(XEvent &ev) { |
@@ -190,10 +179,14 @@ void EventManager::dispatch(Window win, XEvent &ev, bool parent) { | |||
190 | evhand->exposeEvent(ev.xexpose); | 179 | evhand->exposeEvent(ev.xexpose); |
191 | break; | 180 | break; |
192 | case EnterNotify: | 181 | case EnterNotify: |
193 | evhand->enterNotifyEvent(ev.xcrossing); | 182 | if (ev.xcrossing.mode != NotifyGrab && |
183 | ev.xcrossing.mode != NotifyUngrab) | ||
184 | evhand->enterNotifyEvent(ev.xcrossing); | ||
194 | break; | 185 | break; |
195 | case LeaveNotify: | 186 | case LeaveNotify: |
196 | evhand->leaveNotifyEvent(ev.xcrossing); | 187 | if (ev.xcrossing.mode != NotifyGrab && |
188 | ev.xcrossing.mode != NotifyUngrab) | ||
189 | evhand->leaveNotifyEvent(ev.xcrossing); | ||
197 | break; | 190 | break; |
198 | default: | 191 | default: |
199 | evhand->handleEvent(ev); | 192 | 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: | |||
42 | void add(EventHandler &ev, Window win) { registerEventHandler(ev, win); } | 42 | void add(EventHandler &ev, Window win) { registerEventHandler(ev, win); } |
43 | void remove(Window win) { unregisterEventHandler(win); } | 43 | void remove(Window win) { unregisterEventHandler(win); } |
44 | 44 | ||
45 | bool grabKeyboard(EventHandler &ev, Window win); | 45 | bool grabKeyboard(Window win); |
46 | void ungrabKeyboard(); | 46 | void ungrabKeyboard(); |
47 | EventHandler *grabbingKeyboard() { return m_grabbing_keyboard; } | ||
48 | 47 | ||
49 | EventHandler *find(Window win); | 48 | EventHandler *find(Window win); |
50 | 49 | ||
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, | |||
91 | const ClientPattern *pat, bool cycle_reverse) { | 91 | const ClientPattern *pat, bool cycle_reverse) { |
92 | 92 | ||
93 | if (!m_cycling_list) { | 93 | if (!m_cycling_list) { |
94 | if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard()) | 94 | if (m_screen.isCycling()) |
95 | // only set this when we're waiting for modifiers | 95 | // only set this when we're waiting for modifiers |
96 | m_cycling_list = &window_list; | 96 | m_cycling_list = &window_list; |
97 | m_was_iconic = 0; | 97 | 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, | |||
510 | // grab "None Escape" to exit keychain in the middle | 510 | // grab "None Escape" to exit keychain in the middle |
511 | unsigned int esc = FbTk::KeyUtil::getKey("Escape"); | 511 | unsigned int esc = FbTk::KeyUtil::getKey("Escape"); |
512 | 512 | ||
513 | // if focus changes, windows will get NotifyWhileGrabbed, | ||
514 | // which they tend to ignore | ||
515 | if (temp_key && type == KeyPress && | ||
516 | !FbTk::EventManager::instance()->grabbingKeyboard()) | ||
517 | XUngrabKeyboard(Fluxbox::instance()->display(), CurrentTime); | ||
518 | |||
519 | if (temp_key && !temp_key->keylist.empty()) { // emacs-style | 513 | if (temp_key && !temp_key->keylist.empty()) { // emacs-style |
520 | if (!saved_keymode) | 514 | if (!saved_keymode) |
521 | saved_keymode = m_keylist; | 515 | saved_keymode = m_keylist; |
@@ -536,6 +530,11 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, | |||
536 | return false; | 530 | return false; |
537 | } | 531 | } |
538 | 532 | ||
533 | // if focus changes, windows will get NotifyWhileGrabbed, | ||
534 | // which they tend to ignore | ||
535 | if (type == KeyPress) | ||
536 | XUngrabKeyboard(Fluxbox::instance()->display(), CurrentTime); | ||
537 | |||
539 | WinClient *old = WindowCmd<void>::client(); | 538 | WinClient *old = WindowCmd<void>::client(); |
540 | WindowCmd<void>::setClient(current); | 539 | WindowCmd<void>::setClient(current); |
541 | temp_key->m_command->execute(); | 540 | 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) { | |||
856 | } | 856 | } |
857 | 857 | ||
858 | void BScreen::keyPressEvent(XKeyEvent &ke) { | 858 | void BScreen::keyPressEvent(XKeyEvent &ke) { |
859 | Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, | 859 | if (Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, |
860 | Keys::GLOBAL|Keys::ON_DESKTOP); | 860 | Keys::GLOBAL|Keys::ON_DESKTOP)) |
861 | // re-grab keyboard, so we don't pass KeyRelease to clients | ||
862 | FbTk::EventManager::instance()->grabKeyboard(rootWindow().window()); | ||
863 | |||
861 | } | 864 | } |
862 | 865 | ||
863 | void BScreen::keyReleaseEvent(XKeyEvent &ke) { | 866 | void BScreen::keyReleaseEvent(XKeyEvent &ke) { |
864 | if (!m_cycling) | 867 | if (m_cycling) { |
865 | return; | 868 | unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state); |
869 | state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); | ||
870 | |||
871 | if (state) // still cycling | ||
872 | return; | ||
866 | 873 | ||
867 | unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state); | 874 | m_cycling = false; |
868 | state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); | 875 | focusControl().stopCyclingFocus(); |
876 | } | ||
869 | 877 | ||
870 | if (!state) // all modifiers were released | 878 | FbTk::EventManager::instance()->ungrabKeyboard(); |
871 | FbTk::EventManager::instance()->ungrabKeyboard(); | ||
872 | } | 879 | } |
873 | 880 | ||
874 | void BScreen::buttonPressEvent(XButtonEvent &be) { | 881 | void BScreen::buttonPressEvent(XButtonEvent &be) { |
@@ -880,11 +887,6 @@ void BScreen::buttonPressEvent(XButtonEvent &be) { | |||
880 | 0, be.time); | 887 | 0, be.time); |
881 | } | 888 | } |
882 | 889 | ||
883 | void BScreen::notifyUngrabKeyboard() { | ||
884 | m_cycling = false; | ||
885 | focusControl().stopCyclingFocus(); | ||
886 | } | ||
887 | |||
888 | void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { | 890 | void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { |
889 | // get modifiers from event that causes this for focus order cycling | 891 | // get modifiers from event that causes this for focus order cycling |
890 | XEvent ev = Fluxbox::instance()->lastEvent(); | 892 | XEvent ev = Fluxbox::instance()->lastEvent(); |
@@ -896,7 +898,7 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { | |||
896 | 898 | ||
897 | if (!m_cycling && mods) { | 899 | if (!m_cycling && mods) { |
898 | m_cycling = true; | 900 | m_cycling = true; |
899 | FbTk::EventManager::instance()->grabKeyboard(*this, rootWindow().window()); | 901 | FbTk::EventManager::instance()->grabKeyboard(rootWindow().window()); |
900 | } | 902 | } |
901 | 903 | ||
902 | if (mods == 0) // can't stacked cycle unless there is a mod to grab | 904 | 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: | |||
237 | void keyPressEvent(XKeyEvent &ke); | 237 | void keyPressEvent(XKeyEvent &ke); |
238 | void keyReleaseEvent(XKeyEvent &ke); | 238 | void keyReleaseEvent(XKeyEvent &ke); |
239 | void buttonPressEvent(XButtonEvent &be); | 239 | void buttonPressEvent(XButtonEvent &be); |
240 | void notifyUngrabKeyboard(); | ||
241 | 240 | ||
242 | /** | 241 | /** |
243 | * Cycles focus of windows | 242 | * Cycles focus of windows |
@@ -247,6 +246,8 @@ public: | |||
247 | */ | 246 | */ |
248 | void cycleFocus(int opts = 0, const ClientPattern *pat = 0, bool reverse = false); | 247 | void cycleFocus(int opts = 0, const ClientPattern *pat = 0, bool reverse = false); |
249 | 248 | ||
249 | bool isCycling() const { return m_cycling; } | ||
250 | |||
250 | /** | 251 | /** |
251 | * Creates an empty menu with specified label | 252 | * Creates an empty menu with specified label |
252 | * @param label for the menu | 253 | * @param label for the menu |