]> Dogcows Code - chaz/openbox/commitdiff
so close to keybindings. wont link for now.
authorDana Jansens <danakj@orodu.net>
Mon, 30 Dec 2002 22:27:46 +0000 (22:27 +0000)
committerDana Jansens <danakj@orodu.net>
Mon, 30 Dec 2002 22:27:46 +0000 (22:27 +0000)
otk/display.hh
scripts/clientmotion.py
src/actions.cc
src/bindings.cc
src/bindings.hh
src/openbox.cc
src/python.cc
src/python.hh
src/screen.cc

index 7f5ab02d0b55daf96385ab430152de3e60129361..9b3d6b31fd58afe94af51019f9fc46b340479ad4 100644 (file)
@@ -113,6 +113,11 @@ public:
                   bool allow_scroll_lock);
   static void ungrabButton(unsigned int button, unsigned int modifiers,
                     Window grab_window);
+  static void grabKey(unsigned int keycode, unsigned int modifiers,
+                  Window grab_window, bool owner_events,
+                  int pointer_mode, int keyboard_mode, bool allow_scroll_lock);
+  static void ungrabKey(unsigned int button, unsigned int modifiers,
+                        Window grab_window);
 };
 
 }
index 60de370bf13b02c77fdf9d1cccc51194c8ad0dcf..4571c2fd1286e35b985e0259b0ccd291171dfe9e 100644 (file)
@@ -31,47 +31,32 @@ def def_motion_release(action, win, type, modifiers, button, xroot, yroot,
                                delete_Rect(i[3])
                        posqueue.remove(i)
                        break
-       
-       #  ButtonPressAction *a = 0;
-       #  for (int i=0; i<BUTTONS; ++i) {
-       #    if (_posqueue[i]->button == e.button)
-       #      a = _posqueue[i];
-       #    if (a) // found one and removed it
-       #      _posqueue[i] = _posqueue[i+1];
-       #  }
-       #  if (a) { // found one
-       #    _posqueue[BUTTONS-1] = a;
-       #    a->button = 0;
-       #  }
-
-
-def def_motion(action, win, type, modifiers, xroot, yroot, time):
-       client = Openbox_findClient(openbox, win)
-       if not client: return
 
+def def_do_motion(client, xroot, yroot):
        global posqueue
        dx = xroot - posqueue[0][1]
        dy = yroot - posqueue[0][2]
-       #  _dx = x_root - _posqueue[0]->pos.x();
-       #  _dy = y_root - _posqueue[0]->pos.y();
+       area = posqueue[0][3] # A Rect
+       OBClient_move(client, Rect_x(area) + dx, Rect_y(area) + dy)
 
+def def_do_resize(client, xroot, yroot, archor_corner):
+       global posqueue
+       dx = xroot - posqueue[0][1]
+       dy = yroot - posqueue[0][2]
        area = posqueue[0][3] # A Rect
+       OBClient_resize(client, anchor_corner,
+                       Rect_width(area) - dx, Rect_height(area) + dy)
+
+def def_motion(action, win, type, modifiers, xroot, yroot, time):
+       client = Openbox_findClient(openbox, win)
+       if not client: return
+
        if (type == Type_Titlebar) or (type == Type_Label):
-               OBClient_move(client, Rect_x(area) + dx, Rect_y(area) + dy)
-               #      c->move(_posqueue[0]->clientarea.x() + _dx,
-               #              _posqueue[0]->clientarea.y() + _dy);
+               def_do_move(client, xroot, yroot)
        elif type == Type_LeftGrip:
-               OBClient_resize(client, OBClient_TopRight,
-                               Rect_width(area) - dx, Rect_height(area) + dy)
-               #      c->resize(OBClient::TopRight,
-               #        _posqueue[0]->clientarea.width() - _dx,
-               #        _posqueue[0]->clientarea.height() + _dy);
+               def_do_resize(client, xroot, yroot, OBClient_TopRight)
        elif type == Type_RightGrip:
-               OBClient_resize(client, OBClient_TopLeft,
-                               Rect_width(area) + dx, Rect_height(area) + dy)
-               #      c->resize(OBClient::TopLeft,
-               #        _posqueue[0]->clientarea.width() + _dx,
-               #        _posqueue[0]->clientarea.height() + _dy);
+               def_do_resize(client, xroot, yroot, OBClient_TopLeft)
 
 def def_enter(action, win, type, modifiers):
        client = Openbox_findClient(openbox, win)
index 716b033bfbbaf122af7d685fc922541f0e804cac..cbce4f12d540621665fc043941bbe2a4f66f62e2 100644 (file)
@@ -9,6 +9,7 @@
 #include "openbox.hh"
 #include "client.hh"
 #include "python.hh"
+#include "bindings.hh"
 #include "otk/display.hh"
 
 #include <stdio.h>
@@ -41,6 +42,9 @@ void OBActions::buttonPressHandler(const XButtonEvent &e)
   python_callback(Action_ButtonPress, e.window,
                   (OBWidget::WidgetType)(w ? w->type():-1),
                   e.state, e.button, e.x_root, e.y_root, e.time);
+  if (w && w->type() == OBWidget::Type_Frame) // a binding
+    Openbox::instance->bindings()->fire(Action_ButtonPress, e.window,
+                                        e.state, e.button, e.time);
     
   if (_button) return; // won't count toward CLICK events
 
@@ -59,6 +63,9 @@ void OBActions::buttonReleaseHandler(const XButtonEvent &e)
   python_callback(Action_ButtonRelease, e.window,
                   (OBWidget::WidgetType)(w ? w->type():-1),
                   e.state, e.button, e.x_root, e.y_root, e.time);
+  if (w && w->type() == OBWidget::Type_Frame) // a binding
+    Openbox::instance->bindings()->fire(Action_ButtonRelease, e.window,
+                                        e.state, e.button, e.time);
 
   // not for the button we're watching?
   if (_button != e.button) return;
@@ -78,6 +85,9 @@ void OBActions::buttonReleaseHandler(const XButtonEvent &e)
   python_callback(Action_Click, e.window,
                   (OBWidget::WidgetType)(w ? w->type():-1),
                   e.state, e.button, e.time);
+  if (w && w->type() == OBWidget::Type_Frame) // a binding
+    Openbox::instance->bindings()->fire(Action_Click, e.window,
+                                        e.state, e.button, e.time);
 
   if (e.time - _release.time < DOUBLECLICKDELAY &&
       _release.win == e.window && _release.button == e.button) {
@@ -86,7 +96,10 @@ void OBActions::buttonReleaseHandler(const XButtonEvent &e)
     python_callback(Action_DoubleClick, e.window,
                   (OBWidget::WidgetType)(w ? w->type():-1),
                   e.state, e.button, e.time);
-
+    if (w && w->type() == OBWidget::Type_Frame) // a binding
+      Openbox::instance->bindings()->fire(Action_DoubleClick, e.window,
+                                          e.state, e.button, e.time);
+    
     // reset so you cant triple click for 2 doubleclicks
     _release.win = 0;
     _release.button = 0;
@@ -128,13 +141,11 @@ void OBActions::leaveHandler(const XCrossingEvent &e)
 
 void OBActions::keyPressHandler(const XKeyEvent &e)
 {
-  OBWidget *w = dynamic_cast<OBWidget*>
-    (Openbox::instance->findHandler(e.window));
+//  OBWidget *w = dynamic_cast<OBWidget*>
+//    (Openbox::instance->findHandler(e.window));
 
-  // run the KEY guile hook
-  python_callback(Action_KeyPress, e.window,
-                  (OBWidget::WidgetType)(w ? w->type():-1),
-                  e.state, e.keycode);
+  Openbox::instance->bindings()->fire(Action_KeyPress, e.window,
+                                      e.state, e.keycode, e.time);
 }
 
 
index 1a102b5452b78c30e65a05f6716bbc36f9e885d9..6d1d420ecf71c81c5ebc0d9af4b3e62153561cc0 100644 (file)
@@ -5,6 +5,11 @@
 #endif
 
 #include "bindings.hh"
+#include "screen.hh"
+#include "openbox.hh"
+#include "client.hh"
+#include "frame.hh"
+#include "python.hh"
 #include "otk/display.hh"
 
 extern "C" {
@@ -170,6 +175,8 @@ OBBindings::OBBindings()
 
 OBBindings::~OBBindings()
 {
+  grabMouseOnAll(false); // ungrab everything
+  grabKeys(false);
   remove_all();
 }
 
@@ -188,14 +195,17 @@ bool OBBindings::add_mouse(const std::string &button, int id)
     p = p->next_sibling;
     newp = &p->next_sibling;
   }
-  display();
+
+  grabMouseOnAll(false); // ungrab everything
+  
   *newp = new BindingTree(id);
-  display();
   (*newp)->text = button;
   (*newp)->chain = false;
   (*newp)->binding.key = n.binding.key;
   (*newp)->binding.modifiers = n.binding.modifiers;
+
+  grabMouseOnAll(true);
+  
   return true;
 }
 
@@ -204,6 +214,12 @@ int OBBindings::remove_mouse(const std::string &button)
 {
   (void)button;
   assert(false); // XXX: function not implemented yet
+
+  grabMouseOnAll(false); // ungrab everything
+
+  // do shit...
+  
+  grabMouseOnAll(true);
 }
 
 
@@ -261,6 +277,7 @@ int OBBindings::find_key(BindingTree *search) const {
   return -1; // it just isn't in here
 }
 
+
 bool OBBindings::add_key(const StringVect &keylist, int id)
 {
   BindingTree *tree;
@@ -274,9 +291,13 @@ bool OBBindings::add_key(const StringVect &keylist, int id)
     return false;
   }
 
+  grabKeys(false);
+  
   // assimilate this built tree into the main tree
   assimilate(tree); // assimilation destroys/uses the tree
 
+  grabKeys(true); 
   return true;
 }
 
@@ -301,6 +322,14 @@ int OBBindings::remove_key(const StringVect &keylist)
 {
   (void)keylist;
   assert(false); // XXX: function not implemented yet
+
+  grabKeys(false);
+  _curpos = &_keytree;
+
+  // do shit here...
+  
+  grabKeys(true);
+
 }
 
 
@@ -352,4 +381,89 @@ void OBBindings::process(unsigned int modifiers, unsigned int key)
   }
 }
 
+
+void OBBindings::grabMouse(bool grab, const OBClient *client)
+{
+  BindingTree *p = _mousetree;
+  while (p) {
+    if (grab)
+      otk::OBDisplay::grabButton(p->binding.key, p->binding.modifiers,
+                                 client->frame->window(), false,
+                                 ButtonMotionMask | ButtonPressMask |
+                                 ButtonReleaseMask, GrabModeAsync,
+                                 GrabModeAsync, None, None, false);
+    else
+      otk::OBDisplay::ungrabButton(p->binding.key, p->binding.modifiers,
+                                   client->frame->window());
+    p = p->next_sibling;
+  }
+}
+
+
+void OBBindings::grabMouseOnAll(bool grab)
+{
+  for (int i = 0; i < Openbox::instance->screenCount(); ++i) {
+    OBScreen *s = Openbox::instance->screen(i);
+    assert(s);
+    OBScreen::ClientList::iterator it, end = s->clients.end();
+    for (it = s->clients.begin(); it != end; ++it)
+      grabMouse(grab, *it);
+  }
+}
+
+
+void OBBindings::grabKeys(bool grab)
+{
+  for (int i = 0; i < Openbox::instance->screenCount(); ++i) {
+    Window root = otk::OBDisplay::screenInfo(i)->rootWindow();
+
+    BindingTree *p = _curpos->first_child;
+    while (p) {
+      if (grab)
+        otk::OBDisplay::grabKey(p->binding.key, p->binding.modifiers,
+                                root, false, GrabModeAsync, GrabModeAsync,
+                                false);
+      else
+        otk::OBDisplay::ungrabKey(p->binding.key, p->binding.modifiers,
+                                  root);
+      p = p->next_sibling;
+    }
+  }
+}
+
+
+void OBBindings::fire(OBActions::ActionType type, Window window,
+                      unsigned int modifiers, unsigned int key, Time time)
+{
+  if (type == OBActions::Action_KeyPress) {
+    BindingTree *p = _curpos->first_child;
+    while (p) {
+      if (p->binding.key == key && p->binding.modifiers == modifiers) {
+        if (p->chain) {
+          grabKeys(false);
+          _curpos = p;
+          grabKeys(true);
+        } else {
+          python_callback_binding(p->id, type, window, modifiers, key, time);
+          _curpos = &_keytree;
+        }
+        break;
+      }
+      p = p->next_sibling;
+    }
+    
+    assert(false);
+  } else {
+    BindingTree *p = _mousetree;
+    while (p) {
+      if (p->binding.key == key && p->binding.modifiers == modifiers) {
+        python_callback_binding(p->id, type, window, modifiers, key, time);
+        break;
+      }
+      p = p->next_sibling;
+    }
+  }
+}
+
+
 }
index 81b7075db29330402f1de88c5c3d1df66a57d7ea..3fbf3b8d773718b6598f95d334738998e8ac8d64 100644 (file)
@@ -6,11 +6,15 @@
   @brief I dunno.. some binding stuff?
 */
 
+#include "actions.hh"
+
 #include <string>
 #include <vector>
 
 namespace ob {
 
+class OBClient;
+
 typedef struct Binding {
   unsigned int modifiers;
   unsigned int key;
@@ -54,8 +58,11 @@ private:
   int find_key(BindingTree *search) const;
   bool translate(const std::string &str, Binding &b, bool askey) const;
   BindingTree *buildtree(const StringVect &keylist, int id) const;
-  void OBBindings::assimilate(BindingTree *node);
+  void assimilate(BindingTree *node);
+
+  void grabMouseOnAll(bool grab);
+  void grabKeys(bool grab);
+  
 public:
   //! Initializes an OBBinding object
   OBBindings();
@@ -109,6 +116,11 @@ public:
   //      for reseting too...)
 
   void display();
+
+  void fire(OBActions::ActionType type, Window window, unsigned int modifiers,
+            unsigned int key, Time time);
+
+  void grabMouse(bool grab, const OBClient *client);
 };
 
 }
index e7ffb76bf76fe305619c3ff1b956724b6ec0376c..f5166ba758b82e8f6e7f0709e6edf0b97fe3f404 100644 (file)
@@ -163,11 +163,10 @@ Openbox::Openbox(int argc, char **argv)
   v.push_back("C-a");
   _bindings->add_key(v, 3);
 
-  _bindings->add_mouse("A-1", 1);
+  _bindings->add_mouse("C-1", 1);
 
   printf("CHAINS:\n");
   _bindings->display();
-  ::exit(0);
 
   setMasterHandler(_actions); // set as the master event handler
 
index ed71463c8489f1b68ddd9aee5dc69aa1481a94c0..a9b94811cccb18e04e5ce3503ae09fac84d9d44b 100644 (file)
@@ -16,7 +16,8 @@ static FunctionList mousefuncs;
 
 bool python_register(int action, PyObject *callback)
 {
-  if (action < 0 || action >= OBActions::NUM_ACTIONS) {
+  if (action < 0 || action >= OBActions::NUM_ACTIONS ||
+      action == OBActions::Action_KeyPress) {
     PyErr_SetString(PyExc_AssertionError, "Invalid action type.");
     return false;
   }
@@ -37,7 +38,8 @@ bool python_register(int action, PyObject *callback)
 
 bool python_preregister(int action, PyObject *callback)
 {
-  if (action < 0 || action >= OBActions::NUM_ACTIONS) {
+  if (action < 0 || action >= OBActions::NUM_ACTIONS ||
+      action == OBActions::Action_KeyPress) {
     PyErr_SetString(PyExc_AssertionError, "Invalid action type.");
     return false;
   }
@@ -58,7 +60,8 @@ bool python_preregister(int action, PyObject *callback)
 
 bool python_unregister(int action, PyObject *callback)
 {
-  if (action < 0 || action >= OBActions::NUM_ACTIONS) {
+  if (action < 0 || action >= OBActions::NUM_ACTIONS ||
+      action == OBActions::Action_KeyPress) {
     PyErr_SetString(PyExc_AssertionError, "Invalid action type.");
     return false;
   }
@@ -243,4 +246,36 @@ bool python_unbind_all()
 }
 
 
+void python_callback_binding(int id, OBActions::ActionType action,
+                             Window window, unsigned int state,
+                             unsigned int keybutton, Time time)
+{
+  PyObject *func;
+  
+  assert(action >= 0 && action < OBActions::NUM_ACTIONS);
+
+  if (action == OBActions::Action_KeyPress)
+    func = keyfuncs[id];
+  else
+    func = mousefuncs[id];
+
+  if (!func) return;
+
+  PyObject *arglist;
+  PyObject *result;
+
+  arglist = Py_BuildValue("iliil", action, window, state, keybutton, time);
+
+  // call the callback
+  result = PyEval_CallObject(func, arglist);
+  if (result) {
+    Py_DECREF(result);
+  } else {
+    // an exception occured in the script, display it
+    PyErr_Print();
+  }
+
+  Py_DECREF(arglist);
+}
+
 }
index 2332add0afb3c2a82cdab488c9f764c4b184ba13..b868c4722078301b3d759bcd40c3da0b242cbfaa 100644 (file)
@@ -17,8 +17,16 @@ extern "C" {
 namespace ob {
 
 //! Add a python callback funtion to the back of the hook list
+/*!
+  Registering functions for KeyPress events is pointless. Use python_bind_key
+  instead to do this.
+*/
 bool python_register(int action, PyObject *callback);
 //! Add a python callback funtion to the front of the hook list
+/*!
+  Registering functions for KeyPress events is pointless. Use python_bind_key
+  instead to do this.
+*/
 bool python_preregister(int action, PyObject *callback);
 //! Remove a python callback function from the hook list
 bool python_unregister(int action, PyObject *callback);
@@ -37,6 +45,11 @@ bool python_bind_key(PyObject *keylist, PyObject *callback);
 bool python_unbind_key(PyObject *keylist);
 
 //! Adds a mouse binding
+/*!
+  Bindings do not generate motion events. You can only handle motion events by
+  using register to set a function for all motion events. Bindings do generate
+  ButtonPress, ButtonRelease, Click, and DoubleClick events.
+*/
 bool python_bind_mouse(const std::string &button, PyObject *callback);
 
 bool python_unbind_mouse(const std::string &button);
@@ -49,6 +62,10 @@ void python_callback(OBActions::ActionType action, Window window,
                      long d1 = LONG_MIN, long d2 = LONG_MIN,
                      long d3 = LONG_MIN, long d4 = LONG_MIN);
 
+void python_callback_binding(int id, OBActions::ActionType action,
+                             Window window, unsigned int state,
+                             unsigned int keybutton, Time time);
+
 }
 
 #endif // __python_hh
index d61b501d8bf40ce77c96dcd5d6f8657de21be01a..e4518fba3b4af1595b0719ba546033c97676d44f 100644 (file)
@@ -22,6 +22,7 @@ extern "C" {
 #include "client.hh"
 #include "openbox.hh"
 #include "frame.hh"
+#include "bindings.hh"
 #include "otk/display.hh"
 
 static bool running;
@@ -400,6 +401,9 @@ void OBScreen::manageWindow(Window window)
   clients.push_back(client);
   // update the root properties
   setClientList();
+
+  // grab buttons/keys on the window
+  Openbox::instance->bindings()->grabMouse(true, client);
 }
 
 
@@ -407,6 +411,9 @@ void OBScreen::unmanageWindow(OBClient *client)
 {
   OBFrame *frame = client->frame;
 
+  // ungrab buttons/keys on the window
+  Openbox::instance->bindings()->grabMouse(false, client);
+
   // XXX: pass around focus if this window was focused
 
   // remove from the wm's map
This page took 0.040719 seconds and 4 git commands to generate.