return true;
}
-bool OBBindings::translate(const std::string &str, Binding &b) const
+bool OBBindings::translate(const std::string &str, Binding &b,bool askey) const
{
// parse out the base key name
std::string::size_type keybegin = str.find_last_of('-');
// set the binding
b.modifiers = modval;
- KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str()));
- if (sym == NoSymbol) {
- printf(_("Invalid Key name in key binding: %s\n"), key.c_str());
- return false;
+ if (askey) {
+ KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str()));
+ if (sym == NoSymbol) {
+ printf(_("Invalid Key name in key binding: %s\n"), key.c_str());
+ return false;
+ }
+ if (!(b.key = XKeysymToKeycode(otk::OBDisplay::display, sym)))
+ printf(_("No valid keycode for Key in key binding: %s\n"), key.c_str());
+ return b.key != 0;
+ } else {
+ return buttonvalue(key, &b.key);
}
- if (!(b.key = XKeysymToKeycode(otk::OBDisplay::display, sym)))
- printf(_("No valid keycode for Key in key binding: %s\n"), key.c_str());
- return b.key != 0;
}
static void destroytree(BindingTree *tree)
}
}
-BindingTree *OBBindings::buildtree(const StringVect &keylist, int id) const
+BindingTree *OBBindings::buildtree(const StringVect &keylist,
+ PyObject *callback) const
{
if (keylist.empty()) return 0; // nothing in the list.. return 0
StringVect::const_reverse_iterator it, end = keylist.rend();
for (it = keylist.rbegin(); it != end; ++it) {
p = ret;
- ret = new BindingTree(id);
+ ret = new BindingTree(callback);
if (!p) ret->chain = false; // only the first built node
ret->first_child = p;
if (!translate(*it, ret->binding)) {
OBBindings::OBBindings()
- : _curpos(&_tree), _resetkey(0,0)
+ : _curpos(&_tree),
+ _resetkey(0,0),
+ _timer(Openbox::instance->timerManager(),
+ (otk::OBTimeoutHandler)reset, this)
{
+ _timer.setTimeout(5000); // chains reset after 5 seconds
+
setResetKey("C-g"); // set the default reset key
}
OBBindings::~OBBindings()
{
grabKeys(false);
- remove_all();
+ removeAll();
}
}
-int OBBindings::find(BindingTree *search) const {
+PyObject *OBBindings::find(BindingTree *search, bool *conflict) const {
+ *conflict = false;
BindingTree *a, *b;
a = _tree.first_child;
b = search;
} else {
if (a->chain == b->chain) {
if (!a->chain) {
- return a->id; // found it! (return the actual id, not the search's)
+ // found it! (return the actual id, not the search's)
+ return a->callback;
}
} else {
- return -2; // the chain status' don't match (conflict!)
+ *conflict = true;
+ return 0; // the chain status' don't match (conflict!)
}
b = b->first_child;
a = a->first_child;
}
}
- return -1; // it just isn't in here
+ return 0; // it just isn't in here
}
-bool OBBindings::add(const StringVect &keylist, int id)
+bool OBBindings::add(const StringVect &keylist, PyObject *callback)
{
BindingTree *tree;
+ bool conflict;
- if (!(tree = buildtree(keylist, id)))
+ if (!(tree = buildtree(keylist, callback)))
return false; // invalid binding requested
- if (find(tree) != -1) {
+ if (find(tree, &conflict) || conflict) {
// conflicts with another binding
destroytree(tree);
return false;
// assimilate this built tree into the main tree
assimilate(tree); // assimilation destroys/uses the tree
+ Py_INCREF(callback);
+
grabKeys(true);
return true;
}
-int OBBindings::find(const StringVect &keylist)
+bool OBBindings::remove(const StringVect &keylist)
{
+ assert(false); // XXX: function not implemented yet
+
BindingTree *tree;
- bool ret;
+ bool conflict;
if (!(tree = buildtree(keylist, 0)))
return false; // invalid binding requested
- ret = find(tree) >= 0;
-
- destroytree(tree);
-
- return ret;
-}
-
-
-int OBBindings::remove(const StringVect &keylist)
-{
- (void)keylist;
- assert(false); // XXX: function not implemented yet
-
- grabKeys(false);
- _curpos = &_tree;
-
- // do shit here...
-
- grabKeys(true);
+ PyObject *func = find(tree, &conflict);
+ if (func) {
+ grabKeys(false);
+ _curpos = &_tree;
+
+ // XXX do shit here ...
+ Py_DECREF(func);
+
+ grabKeys(true);
+ return true;
+ }
+ return false;
}
if (p->first_child)
remove_branch(p->first_child);
BindingTree *s = p->next_sibling;
+ Py_XDECREF(p->callback);
delete p;
p = s;
}
}
-void OBBindings::remove_all()
+void OBBindings::removeAll()
{
if (_tree.first_child) {
remove_branch(_tree.first_child);
BindingTree *p = _curpos->first_child;
while (p) {
- if (grab)
+ 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);
}
-void OBBindings::fire(Window window, unsigned int modifiers, unsigned int key,
- Time time)
+void OBBindings::fire(unsigned int modifiers, unsigned int key, Time time)
{
if (key == _resetkey.key && modifiers == _resetkey.modifiers) {
- grabKeys(false);
- _curpos = &_tree;
- grabKeys(true);
+ reset(this);
} else {
BindingTree *p = _curpos->first_child;
while (p) {
if (p->binding.key == key && p->binding.modifiers == modifiers) {
if (p->chain) {
+ _timer.start(); // start/restart the timer
grabKeys(false);
_curpos = p;
grabKeys(true);
} else {
- python_callback_binding(p->id, window, modifiers, key, time);
- grabKeys(false);
- _curpos = &_tree;
- grabKeys(true);
+ Window win = None;
+ OBClient *c = Openbox::instance->focusedClient();
+ if (c) win = c->window();
+ python_callback(p->callback, win, modifiers, key, time);
+ reset(this);
}
break;
}
}
}
+void OBBindings::reset(OBBindings *self)
+{
+ self->_timer.stop();
+ self->grabKeys(false);
+ self->_curpos = &self->_tree;
+ self->grabKeys(true);
+}
+
}