all repos — openbox @ d4853f108c1d22c344c1cb9a8a8b7cdc46648983

openbox fork - make it a bit more like ryudo

all broken now. working on adding mouse binding support
Dana Jansens danakj@orodu.net
commit

d4853f108c1d22c344c1cb9a8a8b7cdc46648983

parent

9bf9567283ac26d6f44b48fb85a31078ac73cf21

7 files changed, 266 insertions(+), 85 deletions(-)

jump to
M src/bindings.ccsrc/bindings.cc

@@ -33,11 +33,38 @@

void OBBindings::display() { - if (_tree.first_child) - print_branch(_tree.first_child, ""); + if (_keytree.first_child) { + printf("Key Tree:\n"); + print_branch(_keytree.first_child, ""); + } + if (_mousetree.next_sibling) { + printf("Mouse Tree:\n"); + BindingTree *p = _mousetree.next_sibling; + while (p) { + printf("%d %s\n", p->id, p->text.c_str()); + p = p->next_sibling; + } + } } +static bool buttonvalue(const std::string &button, unsigned int *val) +{ + if (button == "1" || button == "Button1") { + *val |= Button1; + } else if (button == "2" || button == "Button2") { + *val |= Button2; + } else if (button == "3" || button == "Button3") { + *val |= Button3; + } else if (button == "4" || button == "Button4") { + *val |= Button4; + } else if (button == "5" || button == "Button5") { + *val |= Button5; + } else + return false; + return true; +} + static bool modvalue(const std::string &mod, unsigned int *val) { if (mod == "C") { // control

@@ -68,7 +95,7 @@ }

return true; } -bool OBBindings::translate(const std::string &str, Binding &b) +bool OBBindings::translate(const std::string &str, Binding &b, bool askey) { // parse out the base key name std::string::size_type keybegin = str.find_last_of('-');

@@ -83,7 +110,7 @@ end = str.find_first_of('-', begin);

std::string mod(str, begin, end-begin); if (!modvalue(mod, &modval)) { - printf(_("Invalid modifier element in key binding: %s\n"), mod.c_str()); +// printf(_("Invalid modifier element in key binding: %s\n"), mod.c_str()); return false; }

@@ -91,11 +118,15 @@ begin = end + 1;

} // set the binding - KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str())); - if (sym == NoSymbol) return false; b.modifiers = modval; - b.key = XKeysymToKeycode(otk::OBDisplay::display, sym); - return b.key != 0; + if (askey) { + KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str())); + if (sym == NoSymbol) return false; + b.key = XKeysymToKeycode(otk::OBDisplay::display, sym); + return b.key != 0; + } else { + return buttonvalue(key, &b.key); + } } static void destroytree(BindingTree *tree)

@@ -119,7 +150,7 @@ p = ret;

ret = new BindingTree(id); if (!p) ret->chain = false; ret->first_child = p; - if (!translate(*it, ret->binding)) { + if (!translate(*it, ret->binding, true)) { destroytree(ret); ret = 0; break;

@@ -131,6 +162,7 @@ }

OBBindings::OBBindings() + : _curpos(&_keytree) { }

@@ -141,16 +173,48 @@ remove_all();

} +bool OBBindings::add_mouse(const std::string &button, int id) +{ + BindingTree n; + + if (!translate(button, n.binding, false)) + return false; + + BindingTree *p = _mousetree.next_sibling, *last = &_mousetree; + while (p) { + if (p->binding == n.binding) + return false; // conflict + last = p; + p = p->next_sibling; + } + display(); + last->next_sibling = new BindingTree(id); + display(); + last->next_sibling->chain = false; + last->next_sibling->binding.key = n.binding.key; + last->next_sibling->binding.modifiers = n.binding.modifiers; + + return true; +} + + +int OBBindings::remove_mouse(const std::string &button) +{ + (void)button; + assert(false); // XXX: function not implemented yet +} + + void OBBindings::assimilate(BindingTree *node) { BindingTree *a, *b, *tmp, *last; - if (!_tree.first_child) { + if (!_keytree.first_child) { // there are no nodes at this level yet - _tree.first_child = node; + _keytree.first_child = node; return; } else { - a = _tree.first_child; + a = _keytree.first_child; last = a; b = node; while (a) {

@@ -173,9 +237,9 @@ }

} -int OBBindings::find(BindingTree *search) { +int OBBindings::find_key(BindingTree *search) { BindingTree *a, *b; - a = _tree.first_child; + a = _keytree.first_child; b = search; while (a && b) { if (a->binding != b->binding) {

@@ -193,46 +257,14 @@ }

return -1; // it just isn't in here } -/* -static int find(BindingTree *parent, BindingTree *node) { - BindingTree *p, *lastsib, *nextparent, *nextnode = node->first_child; - - if (!parent->first_child) - return -1; - - p = parent->first_child; - while (p) { - if (node->binding == p->binding) { - if (node->chain == p->chain) { - if (!node->chain) { - return p->id; // found it! (return the actual id, not the search's) - } else { - break; // go on to the next child in the chain - } - } else { - return -2; // the chain status' don't match (conflict!) - } - } - p = p->next_sibling; - } - if (!p) return -1; // doesn't exist - - if (node->chain) { - assert(node->first_child); - return find(p, node->first_child); - } else - return -1; // it just isnt in here -} -*/ - -bool OBBindings::add(const StringVect &keylist, int id) +bool OBBindings::add_key(const StringVect &keylist, int id) { BindingTree *tree; if (!(tree = buildtree(keylist, id))) return false; // invalid binding requested - if (find(tree) < -1) { + if (find_key(tree) < -1) { // conflicts with another binding destroytree(tree); return false;

@@ -244,7 +276,7 @@ return true;

} -int OBBindings::find(const StringVect &keylist) +int OBBindings::find_key(const StringVect &keylist) { BindingTree *tree; bool ret;

@@ -252,7 +284,7 @@

if (!(tree = buildtree(keylist, 0))) return false; // invalid binding requested - ret = find(tree) >= 0; + ret = find_key(tree) >= 0; destroytree(tree);

@@ -260,7 +292,7 @@ return ret;

} -int OBBindings::remove(const StringVect &keylist) +int OBBindings::remove_key(const StringVect &keylist) { (void)keylist; assert(false); // XXX: function not implemented yet

@@ -283,8 +315,36 @@

void OBBindings::remove_all() { - if (_tree.first_child) - remove_branch(_tree.first_child); + if (_keytree.first_child) { + remove_branch(_keytree.first_child); + _keytree.first_child = 0; + } + BindingTree *p = _mousetree.next_sibling; + while (p) { + BindingTree *n = p->next_sibling; + delete p; + p = n; + } + _mousetree.next_sibling = 0; +} + + +void OBBindings::process(unsigned int modifiers, unsigned int key) +{ + BindingTree *c = _curpos->first_child; + + while (c) { + if (c->binding.key == key && c->binding.modifiers == modifiers) { + _curpos = c; + break; + } + } + if (c) { + if (!_curpos->chain) { + // XXX execute command for _curpos->id + _curpos = &_keytree; // back to the start + } + } } }
M src/bindings.hhsrc/bindings.hh

@@ -46,10 +46,13 @@ //! A list of strings

typedef std::vector<std::string> StringVect; private: - BindingTree _tree;// root node of the tree (this doesn't have siblings!) + BindingTree _keytree; // root node of the tree (this doesn't have siblings!) + BindingTree *_curpos; // position in the keytree - int find(BindingTree *search); - bool translate(const std::string &str, Binding &b); + BindingTree _mousetree; // this tree is a list. it has only siblings + + int find_key(BindingTree *search); + bool translate(const std::string &str, Binding &b, bool askey); BindingTree *buildtree(const StringVect &keylist, int id); void OBBindings::assimilate(BindingTree *node);

@@ -59,20 +62,35 @@ OBBindings();

//! Destroys the OBBinding object virtual ~OBBindings(); - //! Adds a new binding + //! Adds a new mouse binding + /*! + A binding will fail to be added if the binding already exists, or if the + string is invalid. + @return true if the binding could be added; false if it could not. + */ + bool add_mouse(const std::string &button, int id); + + //! Removes a mouse binding + /*! + @return The id of the binding that was removed, or '< 0' if none were + removed. + */ + int remove_mouse(const std::string &button); + + //! Adds a new key binding /*! A binding will fail to be added if the binding already exists (as part of a chain or not), or if any of the strings in the keylist are invalid. @return true if the binding could be added; false if it could not. */ - bool add(const StringVect &keylist, int id); + bool add_key(const StringVect &keylist, int id); //! Removes a key binding /*! @return The id of the binding that was removed, or '< 0' if none were removed. */ - int remove(const StringVect &keylist); + int remove_key(const StringVect &keylist); //! Removes all key bindings void remove_all();

@@ -82,7 +100,9 @@ /*!

@return -1 if the keybinding was not found but does not conflict with any others; -2 if the keybinding conflicts with another. */ - int find(const StringVect &keylist); + int find_key(const StringVect &keylist); + + void process(unsigned int modifiers, unsigned int key); // XXX: need an exec() function or something that will be used by openbox // and hold state for which chain we're in etc. (it could have a timer
M src/openbox.ccsrc/openbox.cc

@@ -153,12 +153,14 @@ OBBindings::StringVect v;

v.push_back("C-A-x"); v.push_back("C-y"); v.push_back("v"); - _bindings->add(v, 1); + _bindings->add_key(v, 1); v.clear(); // v.push_back("C-x"); // v.push_back("C-z"); v.push_back("a"); - _bindings->add(v, 2); + _bindings->add_key(v, 2); + + _bindings->add_mouse("A-1", 1); printf("CHAINS:\n"); _bindings->display();
M src/openbox.isrc/openbox.i

@@ -56,8 +56,10 @@ %rename(register) ob::python_register;

%rename(preregister) ob::python_preregister; %rename(unregister) ob::python_unregister; %rename(unregister_all) ob::python_unregister_all; -%rename(bind) ob::python_bind; -%rename(unbind) ob::python_unbind; +%rename(bind_key) ob::python_bind_key; +%rename(unbind_key) ob::python_unbind_key; +%rename(bind_mouse) ob::python_bind_mouse; +%rename(unbind_mouse) ob::python_unbind_mouse; %rename(unbind_all) ob::python_unbind_all; %ignore ob::OBScreen::clients;
M src/openbox_wrap.ccsrc/openbox_wrap.cc

@@ -2569,7 +2569,7 @@ return NULL;

} -static PyObject *_wrap_bind(PyObject *self, PyObject *args) { +static PyObject *_wrap_bind_key(PyObject *self, PyObject *args) { PyObject *resultobj; PyObject *arg1 = (PyObject *) 0 ; PyObject *arg2 = (PyObject *) 0 ;

@@ -2577,10 +2577,10 @@ bool result;

PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; - if(!PyArg_ParseTuple(args,(char *)"OO:bind",&obj0,&obj1)) goto fail; + if(!PyArg_ParseTuple(args,(char *)"OO:bind_key",&obj0,&obj1)) goto fail; arg1 = obj0; arg2 = obj1; - result = (bool)ob::python_bind(arg1,arg2); + result = (bool)ob::python_bind_key(arg1,arg2); resultobj = PyInt_FromLong((long)result); return resultobj;

@@ -2589,15 +2589,68 @@ return NULL;

} -static PyObject *_wrap_unbind(PyObject *self, PyObject *args) { +static PyObject *_wrap_unbind_key(PyObject *self, PyObject *args) { PyObject *resultobj; PyObject *arg1 = (PyObject *) 0 ; bool result; PyObject * obj0 = 0 ; - if(!PyArg_ParseTuple(args,(char *)"O:unbind",&obj0)) goto fail; + if(!PyArg_ParseTuple(args,(char *)"O:unbind_key",&obj0)) goto fail; arg1 = obj0; - result = (bool)ob::python_unbind(arg1); + result = (bool)ob::python_unbind_key(arg1); + + resultobj = PyInt_FromLong((long)result); + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_bind_mouse(PyObject *self, PyObject *args) { + PyObject *resultobj; + std::string *arg1 = 0 ; + PyObject *arg2 = (PyObject *) 0 ; + bool result; + std::string temp1 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"OO:bind_mouse",&obj0,&obj1)) goto fail; + { + if (PyString_Check(obj0)) { + temp1 = std::string(PyString_AsString(obj0)); + arg1 = &temp1; + }else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + arg2 = obj1; + result = (bool)ob::python_bind_mouse((std::string const &)*arg1,arg2); + + resultobj = PyInt_FromLong((long)result); + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_unbind_mouse(PyObject *self, PyObject *args) { + PyObject *resultobj; + std::string *arg1 = 0 ; + bool result; + std::string temp1 ; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:unbind_mouse",&obj0)) goto fail; + { + if (PyString_Check(obj0)) { + temp1 = std::string(PyString_AsString(obj0)); + arg1 = &temp1; + }else { + SWIG_exception(SWIG_TypeError, "string expected"); + } + } + result = (bool)ob::python_unbind_mouse((std::string const &)*arg1); resultobj = PyInt_FromLong((long)result); return resultobj;

@@ -2719,8 +2772,10 @@ { (char *)"register", _wrap_register, METH_VARARGS },

{ (char *)"preregister", _wrap_preregister, METH_VARARGS }, { (char *)"unregister", _wrap_unregister, METH_VARARGS }, { (char *)"unregister_all", _wrap_unregister_all, METH_VARARGS }, - { (char *)"bind", _wrap_bind, METH_VARARGS }, - { (char *)"unbind", _wrap_unbind, METH_VARARGS }, + { (char *)"bind_key", _wrap_bind_key, METH_VARARGS }, + { (char *)"unbind_key", _wrap_unbind_key, METH_VARARGS }, + { (char *)"bind_mouse", _wrap_bind_mouse, METH_VARARGS }, + { (char *)"unbind_mouse", _wrap_unbind_mouse, METH_VARARGS }, { (char *)"unbind_all", _wrap_unbind_all, METH_VARARGS }, { NULL, NULL } };
M src/python.ccsrc/python.cc

@@ -11,7 +11,8 @@

typedef std::vector<PyObject*> FunctionList; static FunctionList callbacks[OBActions::NUM_ACTIONS]; -static FunctionList bindfuncs; +static FunctionList keyfuncs; +static FunctionList mousefuncs; bool python_register(int action, PyObject *callback) {

@@ -132,7 +133,7 @@

-bool python_bind(PyObject *keylist, PyObject *callback) +bool python_bind_key(PyObject *keylist, PyObject *callback) { if (!PyList_Check(keylist)) { PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list.");

@@ -156,10 +157,10 @@ }

// the id is what the binding class can call back with so it doesnt have to // worry about the python function pointer - int id = bindfuncs.size(); - if (Openbox::instance->bindings()->add(vectkeylist, id)) { + int id = keyfuncs.size(); + if (Openbox::instance->bindings()->add_key(vectkeylist, id)) { Py_XINCREF(callback); // Add a reference to new callback - bindfuncs.push_back(callback); + keyfuncs.push_back(callback); return true; } else { PyErr_SetString(PyExc_AssertionError,"Unable to create binding. Invalid.");

@@ -167,7 +168,7 @@ return false;

} } -bool python_unbind(PyObject *keylist) +bool python_unbind_key(PyObject *keylist) { if (!PyList_Check(keylist)) { PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list.");

@@ -187,12 +188,48 @@ }

int id; if ((id = - Openbox::instance->bindings()->remove(vectkeylist)) >= 0) { - assert(bindfuncs[id]); // shouldn't be able to remove it twice - Py_XDECREF(bindfuncs[id]); // Dispose of previous callback + Openbox::instance->bindings()->remove_key(vectkeylist)) >= 0) { + assert(keyfuncs[id]); // shouldn't be able to remove it twice + Py_XDECREF(keyfuncs[id]); // Dispose of previous callback // important note: we don't erase the item from the list cuz that would // ruin all the id's that are in use. simply nullify it. - bindfuncs[id] = 0; + keyfuncs[id] = 0; + return true; + } + + return false; +} + +bool python_bind_mouse(const std::string &button, PyObject *callback) +{ + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_AssertionError, "Invalid callback function."); + return false; + } + + // the id is what the binding class can call back with so it doesnt have to + // worry about the python function pointer + int id = mousefuncs.size(); + if (Openbox::instance->bindings()->add_mouse(button, id)) { + Py_XINCREF(callback); // Add a reference to new callback + mousefuncs.push_back(callback); + return true; + } else { + PyErr_SetString(PyExc_AssertionError,"Unable to create binding. Invalid."); + return false; + } +} + +bool python_unbind_mouse(const std::string &button) +{ + int id; + if ((id = + Openbox::instance->bindings()->remove_mouse(button)) >= 0) { + assert(mousefuncs[id]); // shouldn't be able to remove it twice + Py_XDECREF(mousefuncs[id]); // Dispose of previous callback + // important note: we don't erase the item from the list cuz that would + // ruin all the id's that are in use. simply nullify it. + mousefuncs[id] = 0; return true; }
M src/python.hhsrc/python.hh

@@ -26,15 +26,20 @@

//! Removes all python callback functions from the hook list bool python_unregister_all(int action); -//! Add a mouse/keybinding +//! Add a keybinding /*! @param keylist A python list of modifier/key/buttons, in the form: "C-A-space" or "A-Button1" etc. @param callback A python function to call when the binding is used. */ -bool python_bind(PyObject *keylist, PyObject *callback); +bool python_bind_key(PyObject *keylist, PyObject *callback); + +bool python_unbind_key(PyObject *keylist); + +//! Adds a mouse binding +bool python_bind_mouse(const std::string &button, PyObject *callback); -bool python_unbind(PyObject *keylist); +bool python_unbind_mouse(const std::string &button); bool python_unbind_all();