]> Dogcows Code - chaz/openbox/blobdiff - src/bindings.cc
don't grab for motion/releases on the client window, i don't get them anyways.
[chaz/openbox] / src / bindings.cc
index 6e5b147e612191eb053045c12020c7b2db8da268..7c13ca64f9eba8e3290817a14eb9b7f51e8a7726 100644 (file)
@@ -243,12 +243,15 @@ bool OBBindings::addKey(const StringVect &keylist, PyObject *callback)
     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);
@@ -273,6 +276,8 @@ bool OBBindings::removeKey(const StringVect &keylist, PyObject *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;
@@ -281,6 +286,8 @@ bool OBBindings::removeKey(const StringVect &keylist, PyObject *callback)
       Py_XDECREF(*it);
       
       grabKeys(true);
+      otk::OBDisplay::ungrab();
+      
       return true;
     }
   }
@@ -292,10 +299,13 @@ void OBBindings::setResetKey(const std::string &key)
 {
   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();
   }
 }
 
@@ -370,18 +380,18 @@ void OBBindings::fireKey(int screen, unsigned int modifiers, unsigned int key,
       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(screen, 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;
@@ -394,9 +404,12 @@ void OBBindings::fireKey(int screen, unsigned int modifiers, unsigned int key,
 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();
 }
 
 
@@ -469,23 +482,26 @@ void OBBindings::grabButton(bool grab, const Binding &b, MouseContext context,
 {
   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);
 }
@@ -499,11 +515,10 @@ void OBBindings::grabButtons(bool grab, OBClient *client)
   }
 }
 
-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);
   }
   
@@ -514,7 +529,7 @@ void OBBindings::fireButton(ButtonData *data)
       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);
     }
 }
 
@@ -524,7 +539,11 @@ bool OBBindings::addEvent(EventAction action, PyObject *callback)
   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;
@@ -542,6 +561,11 @@ bool OBBindings::removeEvent(EventAction action, PyObject *callback)
   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;
@@ -561,7 +585,7 @@ void OBBindings::fireEvent(EventData *data)
 {
   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);
 }
 
 }
This page took 0.026829 seconds and 4 git commands to generate.