]> Dogcows Code - chaz/openbox/blobdiff - src/bindings.cc
make the frame window override-redirect
[chaz/openbox] / src / bindings.cc
index d0a06fb032ad019311d1668f4863149483884338..97dd2aa1f8e8b1c183e38ee59e8938e8fe88f9c2 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);
   }
 }
 
@@ -339,7 +344,7 @@ void OBBindings::grabKeys(bool grab)
 void OBBindings::fireKey(unsigned int modifiers, unsigned int key, Time time)
 {
   if (key == _resetkey.key && modifiers == _resetkey.modifiers) {
-    reset(this);
+    resetChains(this);
   } else {
     KeyBindingTree *p = _curpos->first_child;
     while (p) {
@@ -356,7 +361,7 @@ void OBBindings::fireKey(unsigned int modifiers, unsigned int key, Time time)
           KeyData *data = new_key_data(win, time, modifiers, key);
           python_callback(p->callback, (PyObject*)data);
           Py_DECREF((PyObject*)data);
-          reset(this);
+          resetChains(this);
         }
         break;
       }
@@ -365,7 +370,7 @@ void OBBindings::fireKey(unsigned int modifiers, unsigned int key, Time time)
   }
 }
 
-void OBBindings::reset(OBBindings *self)
+void OBBindings::resetChains(OBBindings *self)
 {
   self->_timer.stop();
   self->grabKeys(false);
@@ -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);
+      OBScreen::ClientList::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,45 +425,57 @@ 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);
+        OBScreen::ClientList::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 the plate's buttonPressHandler
-      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);
   }
 }
 
@@ -459,6 +483,12 @@ 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
+    XAllowEvents(otk::OBDisplay::display, ReplayPointer, data->time);
+  }
+  
   ButtonBindingList::iterator it, end = _buttons[data->context].end();
   for (it = _buttons[data->context].begin(); it != end; ++it)
     if ((*it)->binding.key == data->button &&
@@ -468,4 +498,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.024713 seconds and 4 git commands to generate.