aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/FbTk/EventHandler.hh1
-rw-r--r--src/FbTk/EventManager.cc23
-rw-r--r--src/FbTk/EventManager.hh3
-rw-r--r--src/FocusControl.cc2
-rw-r--r--src/Keys.cc11
-rw-r--r--src/Screen.cc30
-rw-r--r--src/Screen.hh3
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
68bool EventManager::grabKeyboard(EventHandler &ev, Window win) { 68bool 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
82void EventManager::ungrabKeyboard() { 74void 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
89Window EventManager::getEventWindow(XEvent &ev) { 78Window 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
858void BScreen::keyPressEvent(XKeyEvent &ke) { 858void 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
863void BScreen::keyReleaseEvent(XKeyEvent &ke) { 866void 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
874void BScreen::buttonPressEvent(XButtonEvent &be) { 881void 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
883void BScreen::notifyUngrabKeyboard() {
884 m_cycling = false;
885 focusControl().stopCyclingFocus();
886}
887
888void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) { 890void 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