don't let KeyRelease events propagate to windows

This commit is contained in:
Mark Tiefenbruck 2008-09-28 01:26:21 -07:00
parent c8022b3bdb
commit 04a1d2a83b
7 changed files with 33 additions and 40 deletions

View file

@ -56,7 +56,6 @@ public:
virtual void leaveNotifyEvent(XCrossingEvent &) { }
virtual void enterNotifyEvent(XCrossingEvent &) { }
virtual void notifyUngrabKeyboard() { }
virtual void grabButtons() { }
};

View file

@ -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:

View file

@ -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);

View file

@ -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;

View file

@ -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();

View file

@ -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

View file

@ -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