]> Dogcows Code - chaz/openbox/blobdiff - src/bindings.cc
clean up transient's parent's reference in destructor
[chaz/openbox] / src / bindings.cc
index 007b03347561a43a79aca40c26abc09e6e4b42eb..6a135b6d6821a94c4e2b812741529371af171730 100644 (file)
@@ -142,11 +142,14 @@ OBBindings::OBBindings()
   : _curpos(&_keytree),
     _resetkey(0,0),
     _timer(Openbox::instance->timerManager(),
-           (otk::OBTimeoutHandler)reset, this)
+           (otk::OBTimeoutHandler)resetChains, this)
 {
   _timer.setTimeout(5000); // chains reset after 5 seconds
   
-  setResetKey("C-g"); // set the default reset key
+//  setResetKey("C-g"); // set the default reset key
+
+  for (int i = 0; i < NUM_EVENTS; ++i)
+    _events[i] = 0;
 }
 
 
@@ -155,6 +158,7 @@ OBBindings::~OBBindings()
   grabKeys(false);
   removeAllKeys();
   removeAllButtons();
+  removeAllEvents();
 }
 
 
@@ -325,13 +329,14 @@ void OBBindings::grabKeys(bool grab)
       p = p->next_sibling;
     }
 
-    if (grab)
-      otk::OBDisplay::grabKey(_resetkey.key, _resetkey.modifiers,
-                              root, true, GrabModeAsync, GrabModeAsync,
-                              false);
-    else
-      otk::OBDisplay::ungrabKey(_resetkey.key, _resetkey.modifiers,
-                                root);
+    if (_resetkey.key)
+      if (grab)
+        otk::OBDisplay::grabKey(_resetkey.key, _resetkey.modifiers,
+                                root, false, GrabModeAsync, GrabModeAsync,
+                                false);
+      else
+        otk::OBDisplay::ungrabKey(_resetkey.key, _resetkey.modifiers,
+                                  root);
   }
 }
 
@@ -402,7 +407,14 @@ bool OBBindings::addButton(const std::string &but, MouseContext context,
     bind->binding.key = b.key;
     bind->binding.modifiers = b.modifiers;
     _buttons[context].push_back(bind);
-    // XXX GRAB the new button everywhere!
+    // grab the button on all clients
+    for (int sn = 0; sn < Openbox::instance->screenCount(); ++sn) {
+      OBScreen *s = Openbox::instance->screen(sn);
+      OBClient::List::iterator c_it, c_end = s->clients.end();
+      for (c_it = s->clients.begin(); c_it != c_end; ++c_it) {
+        grabButton(true, bind->binding, context, *c_it);
+      }
+    }
   } else
     bind = *it;
   Py_XDECREF(bind->callback[action]); // if it was already bound, unbind it
@@ -413,52 +425,62 @@ bool OBBindings::addButton(const std::string &but, MouseContext context,
 
 void OBBindings::removeAllButtons()
 {
-  // XXX: UNGRAB shits
   for (int i = i; i < NUM_MOUSE_CONTEXT; ++i) {
     ButtonBindingList::iterator it, end = _buttons[i].end();
-    for (it = _buttons[i].begin(); it != end; ++it)
+    for (it = _buttons[i].begin(); it != end; ++it) {
       for (int a = 0; a < NUM_MOUSE_ACTION; ++a) {
         Py_XDECREF((*it)->callback[a]);
         (*it)->callback[a] = 0;
       }
+      // ungrab the button on all clients
+      for (int sn = 0; sn < Openbox::instance->screenCount(); ++sn) {
+        OBScreen *s = Openbox::instance->screen(sn);
+        OBClient::List::iterator c_it, c_end = s->clients.end();
+        for (c_it = s->clients.begin(); c_it != c_end; ++c_it) {
+          grabButton(false, (*it)->binding, (MouseContext)i, *c_it);
+        }
+      }
+    }
   }
 }
 
+void OBBindings::grabButton(bool grab, const Binding &b, MouseContext context,
+                            OBClient *client)
+{
+  Window win;
+  int mode = GrabModeAsync;
+  switch(context) {
+  case MC_Frame:
+    win = client->frame->window();
+    break;
+  case MC_Window:
+    win = client->frame->plate();
+    mode = GrabModeSync; // this is handled in fireButton
+    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);
+  else
+    otk::OBDisplay::ungrabButton(b.key, b.modifiers, win);
+}
+
 void OBBindings::grabButtons(bool grab, OBClient *client)
 {
   for (int i = 0; i < NUM_MOUSE_CONTEXT; ++i) {
-    Window win;
-    int mode = GrabModeAsync;
-    switch (i) {
-    case MC_Frame:
-      win = client->frame->window();
-      break;
-    case MC_Window:
-      win = client->frame->plate();
-      mode = GrabModeSync; // this is handled in fireButton
-      break;
-    default:
-      // any other elements already get button events, don't grab on them
-      continue;
-    }
     ButtonBindingList::iterator it, end = _buttons[i].end();
     for (it = _buttons[i].begin(); it != end; ++it)
-      if (grab)
-        otk::OBDisplay::grabButton((*it)->binding.key,
-                                   (*it)->binding.modifiers, win, false,
-                                   ButtonPressMask | ButtonMotionMask |
-                                   ButtonReleaseMask, mode, GrabModeAsync,
-                                   None, None, false);
-      else
-        otk::OBDisplay::ungrabButton((*it)->binding.key,
-                                     (*it)->binding.modifiers, win);
+      grabButton(grab, (*it)->binding, (MouseContext)i, client);
   }
 }
 
 void OBBindings::fireButton(ButtonData *data)
 {
-  printf("but.mods %d.%d\n", data->button, data->state);
-  
   if (data->context == MC_Window) {
     // these are grabbed in Sync mode to allow the press to be normal to the
     // client
@@ -474,4 +496,42 @@ void OBBindings::fireButton(ButtonData *data)
     }
 }
 
+
+bool OBBindings::addEvent(EventAction action, PyObject *callback)
+{
+  if (action < 0 || action >= NUM_EVENTS) {
+    return false;
+  }
+
+  Py_XDECREF(_events[action]);
+  _events[action] = callback;
+  Py_INCREF(callback);
+  return true;
+}
+
+bool OBBindings::removeEvent(EventAction action)
+{
+  if (action < 0 || action >= NUM_EVENTS) {
+    return false;
+  }
+  
+  Py_XDECREF(_events[action]);
+  _events[action] = 0;
+  return true;
+}
+
+void OBBindings::removeAllEvents()
+{
+  for (int i = 0; i < NUM_EVENTS; ++i) {
+    Py_XDECREF(_events[i]);
+    _events[i] = 0;
+  }
+}
+
+void OBBindings::fireEvent(EventData *data)
+{
+  if (_events[data->action])
+    python_callback(_events[data->action], (PyObject*)data);
+}
+
 }
This page took 0.02658 seconds and 4 git commands to generate.