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 enterNotifyEvent(XCrossingEvent &) { }
|
||||
|
||||
virtual void notifyUngrabKeyboard() { }
|
||||
virtual void grabButtons() { }
|
||||
};
|
||||
|
||||
|
|
|
@ -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,9 +179,13 @@ void EventManager::dispatch(Window win, XEvent &ev, bool parent) {
|
|||
evhand->exposeEvent(ev.xexpose);
|
||||
break;
|
||||
case EnterNotify:
|
||||
if (ev.xcrossing.mode != NotifyGrab &&
|
||||
ev.xcrossing.mode != NotifyUngrab)
|
||||
evhand->enterNotifyEvent(ev.xcrossing);
|
||||
break;
|
||||
case LeaveNotify:
|
||||
if (ev.xcrossing.mode != NotifyGrab &&
|
||||
ev.xcrossing.mode != NotifyUngrab)
|
||||
evhand->leaveNotifyEvent(ev.xcrossing);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
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
|
||||
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<void>::client();
|
||||
WindowCmd<void>::setClient(current);
|
||||
temp_key->m_command->execute();
|
||||
|
|
|
@ -856,18 +856,25 @@ 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) // all modifiers were released
|
||||
if (state) // still cycling
|
||||
return;
|
||||
|
||||
m_cycling = false;
|
||||
focusControl().stopCyclingFocus();
|
||||
}
|
||||
|
||||
FbTk::EventManager::instance()->ungrabKeyboard();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue