t->callbacks.push_back(callback);
destroytree(tree);
} else {
+ // grab the server here to make sure no key pressed go missed
+ otk::OBDisplay::grab();
grabKeys(false);
// assimilate this built tree into the main tree
assimilate(tree); // assimilation destroys/uses the tree
grabKeys(true);
+ otk::OBDisplay::ungrab();
}
Py_INCREF(callback);
t->callbacks.end(),
callback);
if (it != t->callbacks.end()) {
+ // grab the server here to make sure no key pressed go missed
+ otk::OBDisplay::grab();
grabKeys(false);
_curpos = &_keytree;
Py_XDECREF(*it);
grabKeys(true);
+ otk::OBDisplay::ungrab();
+
return true;
}
}
{
Binding b(0, 0);
if (translate(key, b)) {
+ // grab the server here to make sure no key pressed go missed
+ otk::OBDisplay::grab();
grabKeys(false);
_resetkey.key = b.key;
_resetkey.modifiers = b.modifiers;
grabKeys(true);
+ otk::OBDisplay::ungrab();
}
}
}
-void OBBindings::fireKey(unsigned int modifiers, unsigned int key, Time time)
+void OBBindings::fireKey(int screen, unsigned int modifiers, unsigned int key,
+ Time time)
{
if (key == _resetkey.key && modifiers == _resetkey.modifiers) {
resetChains(this);
if (p->binding.key == key && p->binding.modifiers == modifiers) {
if (p->chain) {
_timer.start(); // start/restart the timer
+ // grab the server here to make sure no key pressed go missed
+ otk::OBDisplay::grab();
grabKeys(false);
_curpos = p;
grabKeys(true);
+ otk::OBDisplay::ungrab();
} else {
- Window win = None;
OBClient *c = Openbox::instance->focusedClient();
- if (c) win = c->window();
- KeyData *data = new_key_data(win, time, modifiers, key);
+ KeyData data(screen, c, time, modifiers, key);
CallbackList::iterator it, end = p->callbacks.end();
for (it = p->callbacks.begin(); it != end; ++it)
- python_callback(*it, (PyObject*)data);
- Py_XDECREF((PyObject*)data);
+ python_callback(*it, &data);
resetChains(this);
}
break;
void OBBindings::resetChains(OBBindings *self)
{
self->_timer.stop();
+ // grab the server here to make sure no key pressed go missed
+ otk::OBDisplay::grab();
self->grabKeys(false);
self->_curpos = &self->_keytree;
self->grabKeys(true);
+ otk::OBDisplay::ungrab();
}
{
Window win;
int mode = GrabModeAsync;
+ unsigned int mask;
switch(context) {
case MC_Frame:
win = client->frame->window();
+ mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask;
break;
case MC_Window:
win = client->frame->plate();
mode = GrabModeSync; // this is handled in fireButton
+ mask = ButtonPressMask; // can't catch more than this with Sync mode
+ // the release event is manufactured by the
+ // master buttonPressHandler
break;
default:
// any other elements already get button events, don't grab on them
return;
}
if (grab)
- otk::OBDisplay::grabButton(b.key, b.modifiers, win, false,
- ButtonPressMask | ButtonMotionMask |
- ButtonReleaseMask, mode, GrabModeAsync,
- None, None, false);
+ otk::OBDisplay::grabButton(b.key, b.modifiers, win, false, mask, mode,
+ GrabModeAsync, None, None, false);
else
otk::OBDisplay::ungrabButton(b.key, b.modifiers, win);
}
}
}
-void OBBindings::fireButton(ButtonData *data)
+void OBBindings::fireButton(MouseData *data)
{
if (data->context == MC_Window) {
- // these are grabbed in Sync mode to allow the press to be normal to the
- // client
+ // Replay the event, so it goes to the client, and ungrab the device.
XAllowEvents(otk::OBDisplay::display, ReplayPointer, data->time);
}
CallbackList::iterator c_it,c_end = (*it)->callbacks[data->action].end();
for (c_it = (*it)->callbacks[data->action].begin();
c_it != c_end; ++c_it)
- python_callback(*c_it, (PyObject*)data);
+ python_callback(*c_it, data);
}
}
if (action < 0 || action >= NUM_EVENTS) {
return false;
}
-
+#ifdef XKB
+ if (action == EventBell && _eventlist[action].empty())
+ XkbSelectEvents(otk::OBDisplay::display, XkbUseCoreKbd,
+ XkbBellNotifyMask, XkbBellNotifyMask);
+#endif // XKB
_eventlist[action].push_back(callback);
Py_INCREF(callback);
return true;
if (it != _eventlist[action].end()) {
Py_XDECREF(*it);
_eventlist[action].erase(it);
+#ifdef XKB
+ if (action == EventBell && _eventlist[action].empty())
+ XkbSelectEvents(otk::OBDisplay::display, XkbUseCoreKbd,
+ XkbBellNotifyMask, 0);
+#endif // XKB
return true;
}
return false;
{
CallbackList::iterator c_it, c_end = _eventlist[data->action].end();
for (c_it = _eventlist[data->action].begin(); c_it != c_end; ++c_it)
- python_callback(*c_it, (PyObject*)data);
+ python_callback(*c_it, data);
}
}