don't let KeyRelease events propagate to windows
This commit is contained in:
parent
c8022b3bdb
commit
04a1d2a83b
7 changed files with 33 additions and 40 deletions
|
@ -56,7 +56,6 @@ public:
|
||||||
virtual void leaveNotifyEvent(XCrossingEvent &) { }
|
virtual void leaveNotifyEvent(XCrossingEvent &) { }
|
||||||
virtual void enterNotifyEvent(XCrossingEvent &) { }
|
virtual void enterNotifyEvent(XCrossingEvent &) { }
|
||||||
|
|
||||||
virtual void notifyUngrabKeyboard() { }
|
|
||||||
virtual void grabButtons() { }
|
virtual void grabButtons() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -65,25 +65,14 @@ EventHandler *EventManager::find(Window win) {
|
||||||
return m_eventhandlers[win];
|
return m_eventhandlers[win];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EventManager::grabKeyboard(EventHandler &ev, Window win) {
|
bool EventManager::grabKeyboard(Window win) {
|
||||||
if (m_grabbing_keyboard)
|
|
||||||
ungrabKeyboard();
|
|
||||||
|
|
||||||
int ret = XGrabKeyboard(App::instance()->display(), win, False,
|
int ret = XGrabKeyboard(App::instance()->display(), win, False,
|
||||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
return (ret == Success);
|
||||||
if (ret == Success) {
|
|
||||||
m_grabbing_keyboard = &ev;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::ungrabKeyboard() {
|
void EventManager::ungrabKeyboard() {
|
||||||
XUngrabKeyboard(App::instance()->display(), CurrentTime);
|
XUngrabKeyboard(App::instance()->display(), CurrentTime);
|
||||||
if (m_grabbing_keyboard)
|
|
||||||
m_grabbing_keyboard->notifyUngrabKeyboard();
|
|
||||||
m_grabbing_keyboard = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Window EventManager::getEventWindow(XEvent &ev) {
|
Window EventManager::getEventWindow(XEvent &ev) {
|
||||||
|
@ -190,10 +179,14 @@ void EventManager::dispatch(Window win, XEvent &ev, bool parent) {
|
||||||
evhand->exposeEvent(ev.xexpose);
|
evhand->exposeEvent(ev.xexpose);
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
evhand->enterNotifyEvent(ev.xcrossing);
|
if (ev.xcrossing.mode != NotifyGrab &&
|
||||||
|
ev.xcrossing.mode != NotifyUngrab)
|
||||||
|
evhand->enterNotifyEvent(ev.xcrossing);
|
||||||
break;
|
break;
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
evhand->leaveNotifyEvent(ev.xcrossing);
|
if (ev.xcrossing.mode != NotifyGrab &&
|
||||||
|
ev.xcrossing.mode != NotifyUngrab)
|
||||||
|
evhand->leaveNotifyEvent(ev.xcrossing);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
evhand->handleEvent(ev);
|
evhand->handleEvent(ev);
|
||||||
|
|
|
@ -42,9 +42,8 @@ public:
|
||||||
void add(EventHandler &ev, Window win) { registerEventHandler(ev, win); }
|
void add(EventHandler &ev, Window win) { registerEventHandler(ev, win); }
|
||||||
void remove(Window win) { unregisterEventHandler(win); }
|
void remove(Window win) { unregisterEventHandler(win); }
|
||||||
|
|
||||||
bool grabKeyboard(EventHandler &ev, Window win);
|
bool grabKeyboard(Window win);
|
||||||
void ungrabKeyboard();
|
void ungrabKeyboard();
|
||||||
EventHandler *grabbingKeyboard() { return m_grabbing_keyboard; }
|
|
||||||
|
|
||||||
EventHandler *find(Window win);
|
EventHandler *find(Window win);
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ void FocusControl::cycleFocus(const FocusableList &window_list,
|
||||||
const ClientPattern *pat, bool cycle_reverse) {
|
const ClientPattern *pat, bool cycle_reverse) {
|
||||||
|
|
||||||
if (!m_cycling_list) {
|
if (!m_cycling_list) {
|
||||||
if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard())
|
if (m_screen.isCycling())
|
||||||
// only set this when we're waiting for modifiers
|
// only set this when we're waiting for modifiers
|
||||||
m_cycling_list = &window_list;
|
m_cycling_list = &window_list;
|
||||||
m_was_iconic = 0;
|
m_was_iconic = 0;
|
||||||
|
|
11
src/Keys.cc
11
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
|
// grab "None Escape" to exit keychain in the middle
|
||||||
unsigned int esc = FbTk::KeyUtil::getKey("Escape");
|
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 (temp_key && !temp_key->keylist.empty()) { // emacs-style
|
||||||
if (!saved_keymode)
|
if (!saved_keymode)
|
||||||
saved_keymode = m_keylist;
|
saved_keymode = m_keylist;
|
||||||
|
@ -536,6 +530,11 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key,
|
||||||
return false;
|
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<void>::client();
|
WinClient *old = WindowCmd<void>::client();
|
||||||
WindowCmd<void>::setClient(current);
|
WindowCmd<void>::setClient(current);
|
||||||
temp_key->m_command->execute();
|
temp_key->m_command->execute();
|
||||||
|
|
|
@ -856,19 +856,26 @@ void BScreen::propertyNotify(Atom atom) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BScreen::keyPressEvent(XKeyEvent &ke) {
|
void BScreen::keyPressEvent(XKeyEvent &ke) {
|
||||||
Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode,
|
if (Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode,
|
||||||
Keys::GLOBAL|Keys::ON_DESKTOP);
|
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) {
|
void BScreen::keyReleaseEvent(XKeyEvent &ke) {
|
||||||
if (!m_cycling)
|
if (m_cycling) {
|
||||||
return;
|
unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state);
|
||||||
|
state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode);
|
||||||
|
|
||||||
unsigned int state = FbTk::KeyUtil::instance().cleanMods(ke.state);
|
if (state) // still cycling
|
||||||
state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode);
|
return;
|
||||||
|
|
||||||
if (!state) // all modifiers were released
|
m_cycling = false;
|
||||||
FbTk::EventManager::instance()->ungrabKeyboard();
|
focusControl().stopCyclingFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
FbTk::EventManager::instance()->ungrabKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BScreen::buttonPressEvent(XButtonEvent &be) {
|
void BScreen::buttonPressEvent(XButtonEvent &be) {
|
||||||
|
@ -880,11 +887,6 @@ void BScreen::buttonPressEvent(XButtonEvent &be) {
|
||||||
0, be.time);
|
0, be.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BScreen::notifyUngrabKeyboard() {
|
|
||||||
m_cycling = false;
|
|
||||||
focusControl().stopCyclingFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
|
void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
|
||||||
// get modifiers from event that causes this for focus order cycling
|
// get modifiers from event that causes this for focus order cycling
|
||||||
XEvent ev = Fluxbox::instance()->lastEvent();
|
XEvent ev = Fluxbox::instance()->lastEvent();
|
||||||
|
@ -896,7 +898,7 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
|
||||||
|
|
||||||
if (!m_cycling && mods) {
|
if (!m_cycling && mods) {
|
||||||
m_cycling = true;
|
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
|
if (mods == 0) // can't stacked cycle unless there is a mod to grab
|
||||||
|
|
|
@ -237,7 +237,6 @@ public:
|
||||||
void keyPressEvent(XKeyEvent &ke);
|
void keyPressEvent(XKeyEvent &ke);
|
||||||
void keyReleaseEvent(XKeyEvent &ke);
|
void keyReleaseEvent(XKeyEvent &ke);
|
||||||
void buttonPressEvent(XButtonEvent &be);
|
void buttonPressEvent(XButtonEvent &be);
|
||||||
void notifyUngrabKeyboard();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cycles focus of windows
|
* Cycles focus of windows
|
||||||
|
@ -247,6 +246,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void cycleFocus(int opts = 0, const ClientPattern *pat = 0, bool reverse = false);
|
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
|
* Creates an empty menu with specified label
|
||||||
* @param label for the menu
|
* @param label for the menu
|
||||||
|
|
Loading…
Reference in a new issue