keybindings underway. dont work yet
This commit is contained in:
parent
b8653c3ab8
commit
98c4b4cfe5
11 changed files with 554 additions and 8 deletions
|
@ -19,7 +19,7 @@ openbox3_LDADD=-L../otk -lotk @LIBINTL@
|
||||||
|
|
||||||
openbox3_SOURCES= actions.cc client.cc frame.cc openbox.cc screen.cc \
|
openbox3_SOURCES= actions.cc client.cc frame.cc openbox.cc screen.cc \
|
||||||
main.cc rootwindow.cc backgroundwidget.cc labelwidget.cc \
|
main.cc rootwindow.cc backgroundwidget.cc labelwidget.cc \
|
||||||
buttonwidget.cc python.cc openbox_wrap.cc
|
buttonwidget.cc python.cc bindings.cc openbox_wrap.cc
|
||||||
|
|
||||||
MAINTAINERCLEANFILES= Makefile.in
|
MAINTAINERCLEANFILES= Makefile.in
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// -*- mode: C++; indent-tabs-mode: nil; -*-
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "../config.h"
|
# include "../config.h"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// -*- mode: C++; indent-tabs-mode: nil; -*-
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
#ifndef __actions_hh
|
#ifndef __actions_hh
|
||||||
#define __actions_hh
|
#define __actions_hh
|
||||||
|
|
||||||
|
|
257
src/bindings.cc
Normal file
257
src/bindings.cc
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "bindings.hh"
|
||||||
|
#include "otk/display.hh"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ob {
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
static void print_branch(BindingTree *first, std::string str)
|
||||||
|
{
|
||||||
|
BindingTree *p = first;
|
||||||
|
|
||||||
|
while (p) {
|
||||||
|
if (p->first_child)
|
||||||
|
print_branch(p->first_child, str + " " + p->text);
|
||||||
|
printf("%d%s\n", p->id, (str + " " + p->text).c_str());
|
||||||
|
BindingTree *s = p->next_sibling;
|
||||||
|
delete p;
|
||||||
|
p = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBBindings::display()
|
||||||
|
{
|
||||||
|
if (_bindings.first_child)
|
||||||
|
print_branch(_bindings.first_child, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static bool translate(const std::string str, Binding &b)
|
||||||
|
{
|
||||||
|
KeySym sym = XStringToKeysym(const_cast<char *>(str.c_str()));
|
||||||
|
if (sym == NoSymbol) return false;
|
||||||
|
b.modifiers = Mod1Mask;
|
||||||
|
b.key = XKeysymToKeycode(otk::OBDisplay::display, sym);
|
||||||
|
return b.key != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BindingTree *buildtree(const OBBindings::StringVect &keylist, int id)
|
||||||
|
{
|
||||||
|
if (keylist.empty()) return 0; // nothing in the list.. return 0
|
||||||
|
|
||||||
|
BindingTree *ret = new BindingTree(id), *p = 0;
|
||||||
|
|
||||||
|
OBBindings::StringVect::const_iterator it, end = keylist.end();
|
||||||
|
for (it = keylist.begin(); it != end; ++it) {
|
||||||
|
if (p)
|
||||||
|
p = p->first_child = new BindingTree(id);
|
||||||
|
else
|
||||||
|
p = ret; // the first node
|
||||||
|
|
||||||
|
if (!translate(*it, p->binding))
|
||||||
|
break;
|
||||||
|
p->text = *it;
|
||||||
|
}
|
||||||
|
if (it != end) {
|
||||||
|
// build failed.. clean up and return 0
|
||||||
|
p = ret;
|
||||||
|
while (p->first_child) {
|
||||||
|
BindingTree *c = p->first_child;
|
||||||
|
delete p;
|
||||||
|
p = c;
|
||||||
|
}
|
||||||
|
delete p;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// set the proper chain status on the last node
|
||||||
|
p->chain = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("<BUILDING>\n");
|
||||||
|
print_branch(ret);
|
||||||
|
printf("</BUILDING>\n");
|
||||||
|
|
||||||
|
// successfully built a tree
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroytree(BindingTree *tree)
|
||||||
|
{
|
||||||
|
while (tree) {
|
||||||
|
BindingTree *c = tree->first_child;
|
||||||
|
delete tree;
|
||||||
|
tree = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OBBindings::OBBindings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OBBindings::~OBBindings()
|
||||||
|
{
|
||||||
|
remove_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void assimilate(BindingTree *parent, BindingTree *node)
|
||||||
|
{
|
||||||
|
BindingTree *p, *lastsib, *nextparent, *nextnode = node->first_child;
|
||||||
|
|
||||||
|
if (!parent->first_child) {
|
||||||
|
// there are no nodes at this level yet
|
||||||
|
parent->first_child = node;
|
||||||
|
nextparent = node;
|
||||||
|
} else {
|
||||||
|
p = lastsib = parent->first_child;
|
||||||
|
|
||||||
|
while (p->next_sibling) {
|
||||||
|
p = p->next_sibling;
|
||||||
|
lastsib = p; // finds the last sibling
|
||||||
|
if (p->binding == node->binding) {
|
||||||
|
// found an identical binding..
|
||||||
|
assert(node->chain && p->chain);
|
||||||
|
delete node; // kill the one we aren't using
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!p) {
|
||||||
|
// couldn't find an existing binding, use this new one, and insert it
|
||||||
|
// into the list
|
||||||
|
p = lastsib->next_sibling = node;
|
||||||
|
}
|
||||||
|
nextparent = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextnode)
|
||||||
|
assimilate(nextparent, nextnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int find_bind(BindingTree *tree, BindingTree *search) {
|
||||||
|
BindingTree *a, *b;
|
||||||
|
a = tree;
|
||||||
|
b = search;
|
||||||
|
while (a && b) {
|
||||||
|
if (a->binding != b->binding) {
|
||||||
|
a = a->next_sibling;
|
||||||
|
} else {
|
||||||
|
if (a->chain == b->chain) {
|
||||||
|
if (!a->chain)
|
||||||
|
return a->id; // found it! (return the actual id, not the search's)
|
||||||
|
} else
|
||||||
|
return -2; // the chain status' don't match (conflict!)
|
||||||
|
b = b->first_child;
|
||||||
|
a = a->first_child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
BindingTree *tree;
|
||||||
|
|
||||||
|
if (!(tree = buildtree(keylist, id)))
|
||||||
|
return false; // invalid binding requested
|
||||||
|
|
||||||
|
if (find_bind(_bindings.first_child, tree) < -1) {
|
||||||
|
// conflicts with another binding
|
||||||
|
destroytree(tree);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assimilate this built tree into the main tree
|
||||||
|
assimilate(&_bindings, tree); // assimilation destroys/uses the tree
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int OBBindings::find(const StringVect &keylist)
|
||||||
|
{
|
||||||
|
BindingTree *tree;
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
if (!(tree = buildtree(keylist, 0)))
|
||||||
|
return false; // invalid binding requested
|
||||||
|
|
||||||
|
ret = find_bind(_bindings.first_child, tree) >= 0;
|
||||||
|
|
||||||
|
destroytree(tree);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int OBBindings::remove(const StringVect &keylist)
|
||||||
|
{
|
||||||
|
(void)keylist;
|
||||||
|
assert(false); // XXX: function not implemented yet
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void remove_branch(BindingTree *first)
|
||||||
|
{
|
||||||
|
BindingTree *p = first;
|
||||||
|
|
||||||
|
while (p) {
|
||||||
|
if (p->first_child)
|
||||||
|
remove_branch(p->first_child);
|
||||||
|
BindingTree *s = p->next_sibling;
|
||||||
|
delete p;
|
||||||
|
p = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBBindings::remove_all()
|
||||||
|
{
|
||||||
|
if (_bindings.first_child)
|
||||||
|
remove_branch(_bindings.first_child);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
91
src/bindings.hh
Normal file
91
src/bindings.hh
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
|
#ifndef __binding_hh
|
||||||
|
#define __binding_hh
|
||||||
|
|
||||||
|
/*! @file binding.hh
|
||||||
|
@brief I dunno.. some binding stuff?
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ob {
|
||||||
|
|
||||||
|
typedef struct Binding {
|
||||||
|
unsigned int modifiers;
|
||||||
|
unsigned int key;
|
||||||
|
|
||||||
|
bool operator==(struct Binding &b2) { return key == b2.key &&
|
||||||
|
modifiers == b2.modifiers; }
|
||||||
|
bool operator!=(struct Binding &b2) { return key != b2.key ||
|
||||||
|
modifiers != b2.modifiers; }
|
||||||
|
Binding(unsigned int mod, unsigned int k) { modifiers = mod; key = k; }
|
||||||
|
} Binding;
|
||||||
|
|
||||||
|
typedef struct BindingTree {
|
||||||
|
Binding binding;
|
||||||
|
std::string text;
|
||||||
|
int id; // the id given for the binding in add()
|
||||||
|
bool chain; // true if this is a chain to another key (not an action)
|
||||||
|
|
||||||
|
struct BindingTree *next_sibling; // the next binding in the tree at the same
|
||||||
|
// level
|
||||||
|
struct BindingTree *first_child; // the first child of this binding (next
|
||||||
|
// binding in a chained sequence).
|
||||||
|
BindingTree(int id) : binding(0, 0) {
|
||||||
|
this->id = id; chain = true; next_sibling = first_child = 0;
|
||||||
|
}
|
||||||
|
BindingTree() : binding(0, 0) {
|
||||||
|
this->id = -1; chain = true; next_sibling = first_child = 0;
|
||||||
|
}
|
||||||
|
} BindingTree;
|
||||||
|
|
||||||
|
class OBBindings {
|
||||||
|
public:
|
||||||
|
//! A list of strings
|
||||||
|
typedef std::vector<std::string> StringVect;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BindingTree _bindings;// root nodes (these dont have siblings!)
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Initializes an OBBinding object
|
||||||
|
OBBindings();
|
||||||
|
//! Destroys the OBBinding object
|
||||||
|
virtual ~OBBindings();
|
||||||
|
|
||||||
|
//! Adds a new 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);
|
||||||
|
|
||||||
|
//! Removes a key binding
|
||||||
|
/*!
|
||||||
|
@return The id of the binding that was removed, or '< 0' if none were
|
||||||
|
removed.
|
||||||
|
*/
|
||||||
|
int remove(const StringVect &keylist);
|
||||||
|
|
||||||
|
//! Removes all key bindings
|
||||||
|
void remove_all();
|
||||||
|
|
||||||
|
//! Finds a keybinding and returns its id or '< 0' if it isn't found.
|
||||||
|
/*!
|
||||||
|
@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);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// for reseting too...)
|
||||||
|
|
||||||
|
void display();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __binding_hh
|
|
@ -9,6 +9,7 @@
|
||||||
#include "client.hh"
|
#include "client.hh"
|
||||||
#include "screen.hh"
|
#include "screen.hh"
|
||||||
#include "actions.hh"
|
#include "actions.hh"
|
||||||
|
#include "bindings.hh"
|
||||||
#include "otk/property.hh"
|
#include "otk/property.hh"
|
||||||
#include "otk/display.hh"
|
#include "otk/display.hh"
|
||||||
#include "otk/assassin.hh"
|
#include "otk/assassin.hh"
|
||||||
|
@ -145,8 +146,22 @@ Openbox::Openbox(int argc, char **argv)
|
||||||
sigaction(SIGHUP, &action, (struct sigaction *) 0);
|
sigaction(SIGHUP, &action, (struct sigaction *) 0);
|
||||||
|
|
||||||
_property = new otk::OBProperty();
|
_property = new otk::OBProperty();
|
||||||
|
|
||||||
_actions = new OBActions();
|
_actions = new OBActions();
|
||||||
|
_bindings = new OBBindings();
|
||||||
|
|
||||||
|
OBBindings::StringVect v;
|
||||||
|
// v.push_back("C-x");
|
||||||
|
// v.push_back("C-y");
|
||||||
|
v.push_back("v");
|
||||||
|
_bindings->add(v, 1);
|
||||||
|
v.clear();
|
||||||
|
// v.push_back("C-x");
|
||||||
|
// v.push_back("C-z");
|
||||||
|
v.push_back("a");
|
||||||
|
_bindings->add(v, 2);
|
||||||
|
|
||||||
|
_bindings->display();
|
||||||
|
::exit(0);
|
||||||
|
|
||||||
setMasterHandler(_actions); // set as the master event handler
|
setMasterHandler(_actions); // set as the master event handler
|
||||||
|
|
||||||
|
@ -198,6 +213,10 @@ Openbox::~Openbox()
|
||||||
_state = State_Exiting; // time to kill everything
|
_state = State_Exiting; // time to kill everything
|
||||||
|
|
||||||
std::for_each(_screens.begin(), _screens.end(), otk::PointerAssassin());
|
std::for_each(_screens.begin(), _screens.end(), otk::PointerAssassin());
|
||||||
|
|
||||||
|
delete _bindings;
|
||||||
|
delete _actions;
|
||||||
|
delete _property;
|
||||||
|
|
||||||
// close the X display
|
// close the X display
|
||||||
otk::OBDisplay::destroy();
|
otk::OBDisplay::destroy();
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace ob {
|
||||||
class OBScreen;
|
class OBScreen;
|
||||||
class OBClient;
|
class OBClient;
|
||||||
class OBActions;
|
class OBActions;
|
||||||
|
class OBBindings;
|
||||||
|
|
||||||
//! Mouse cursors used throughout Openbox
|
//! Mouse cursors used throughout Openbox
|
||||||
struct Cursors {
|
struct Cursors {
|
||||||
|
@ -121,6 +122,9 @@ private:
|
||||||
//! The action interface through which all user-available actions occur
|
//! The action interface through which all user-available actions occur
|
||||||
OBActions *_actions;
|
OBActions *_actions;
|
||||||
|
|
||||||
|
//! The interface through which keys/buttons are grabbed and handled
|
||||||
|
OBBindings *_bindings;
|
||||||
|
|
||||||
//! Run the application in synchronous mode? (for debugging)
|
//! Run the application in synchronous mode? (for debugging)
|
||||||
bool _sync;
|
bool _sync;
|
||||||
|
|
||||||
|
@ -184,6 +188,9 @@ public:
|
||||||
//! Returns the otk::OBProperty instance for the window manager
|
//! Returns the otk::OBProperty instance for the window manager
|
||||||
inline const otk::OBProperty *property() const { return _property; }
|
inline const otk::OBProperty *property() const { return _property; }
|
||||||
|
|
||||||
|
//! Returns the OBBinding instance for the window manager
|
||||||
|
inline OBBindings *bindings() const { return _bindings; }
|
||||||
|
|
||||||
//! Returns a managed screen
|
//! Returns a managed screen
|
||||||
inline OBScreen *screen(int num) {
|
inline OBScreen *screen(int num) {
|
||||||
assert(num >= 0); assert(num < (signed)_screens.size());
|
assert(num >= 0); assert(num < (signed)_screens.size());
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
%rename(preregister) ob::python_preregister;
|
%rename(preregister) ob::python_preregister;
|
||||||
%rename(unregister) ob::python_unregister;
|
%rename(unregister) ob::python_unregister;
|
||||||
%rename(unregister_all) ob::python_unregister_all;
|
%rename(unregister_all) ob::python_unregister_all;
|
||||||
|
%rename(bind) ob::python_bind;
|
||||||
|
%rename(unbind) ob::python_unbind;
|
||||||
|
%rename(unbind_all) ob::python_unbind_all;
|
||||||
|
|
||||||
%ignore ob::OBScreen::clients;
|
%ignore ob::OBScreen::clients;
|
||||||
%{
|
%{
|
||||||
|
|
|
@ -667,10 +667,11 @@ SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) {
|
||||||
#define SWIGTYPE_p_XDestroyWindowEvent swig_types[19]
|
#define SWIGTYPE_p_XDestroyWindowEvent swig_types[19]
|
||||||
#define SWIGTYPE_p_otk__BImageControl swig_types[20]
|
#define SWIGTYPE_p_otk__BImageControl swig_types[20]
|
||||||
#define SWIGTYPE_p_PyObject swig_types[21]
|
#define SWIGTYPE_p_PyObject swig_types[21]
|
||||||
#define SWIGTYPE_p_ob__MwmHints swig_types[22]
|
#define SWIGTYPE_p_ob__OBBindings swig_types[22]
|
||||||
#define SWIGTYPE_p_otk__Configuration swig_types[23]
|
#define SWIGTYPE_p_ob__MwmHints swig_types[23]
|
||||||
#define SWIGTYPE_p_XUnmapEvent swig_types[24]
|
#define SWIGTYPE_p_otk__Configuration swig_types[24]
|
||||||
static swig_type_info *swig_types[26];
|
#define SWIGTYPE_p_XUnmapEvent swig_types[25]
|
||||||
|
static swig_type_info *swig_types[27];
|
||||||
|
|
||||||
/* -------- TYPES TABLE (END) -------- */
|
/* -------- TYPES TABLE (END) -------- */
|
||||||
|
|
||||||
|
@ -1112,6 +1113,23 @@ static PyObject *_wrap_Openbox_property(PyObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *_wrap_Openbox_bindings(PyObject *self, PyObject *args) {
|
||||||
|
PyObject *resultobj;
|
||||||
|
ob::Openbox *arg1 = (ob::Openbox *) 0 ;
|
||||||
|
ob::OBBindings *result;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args,(char *)"O:Openbox_bindings",&obj0)) goto fail;
|
||||||
|
if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Openbox,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail;
|
||||||
|
result = (ob::OBBindings *)((ob::Openbox const *)arg1)->bindings();
|
||||||
|
|
||||||
|
resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ob__OBBindings, 0);
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *_wrap_Openbox_screen(PyObject *self, PyObject *args) {
|
static PyObject *_wrap_Openbox_screen(PyObject *self, PyObject *args) {
|
||||||
PyObject *resultobj;
|
PyObject *resultobj;
|
||||||
ob::Openbox *arg1 = (ob::Openbox *) 0 ;
|
ob::Openbox *arg1 = (ob::Openbox *) 0 ;
|
||||||
|
@ -2551,6 +2569,57 @@ static PyObject *_wrap_unregister_all(PyObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *_wrap_bind(PyObject *self, PyObject *args) {
|
||||||
|
PyObject *resultobj;
|
||||||
|
PyObject *arg1 = (PyObject *) 0 ;
|
||||||
|
PyObject *arg2 = (PyObject *) 0 ;
|
||||||
|
bool result;
|
||||||
|
PyObject * obj0 = 0 ;
|
||||||
|
PyObject * obj1 = 0 ;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args,(char *)"OO:bind",&obj0,&obj1)) goto fail;
|
||||||
|
arg1 = obj0;
|
||||||
|
arg2 = obj1;
|
||||||
|
result = (bool)ob::python_bind(arg1,arg2);
|
||||||
|
|
||||||
|
resultobj = PyInt_FromLong((long)result);
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *_wrap_unbind(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;
|
||||||
|
arg1 = obj0;
|
||||||
|
result = (bool)ob::python_unbind(arg1);
|
||||||
|
|
||||||
|
resultobj = PyInt_FromLong((long)result);
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *_wrap_unbind_all(PyObject *self, PyObject *args) {
|
||||||
|
PyObject *resultobj;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args,(char *)":unbind_all")) goto fail;
|
||||||
|
result = (bool)ob::python_unbind_all();
|
||||||
|
|
||||||
|
resultobj = PyInt_FromLong((long)result);
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef SwigMethods[] = {
|
static PyMethodDef SwigMethods[] = {
|
||||||
{ (char *)"Openbox_instance", _wrap_Openbox_instance, METH_VARARGS },
|
{ (char *)"Openbox_instance", _wrap_Openbox_instance, METH_VARARGS },
|
||||||
{ (char *)"Cursors_session_set", _wrap_Cursors_session_set, METH_VARARGS },
|
{ (char *)"Cursors_session_set", _wrap_Cursors_session_set, METH_VARARGS },
|
||||||
|
@ -2569,6 +2638,7 @@ static PyMethodDef SwigMethods[] = {
|
||||||
{ (char *)"Openbox_state", _wrap_Openbox_state, METH_VARARGS },
|
{ (char *)"Openbox_state", _wrap_Openbox_state, METH_VARARGS },
|
||||||
{ (char *)"Openbox_timerManager", _wrap_Openbox_timerManager, METH_VARARGS },
|
{ (char *)"Openbox_timerManager", _wrap_Openbox_timerManager, METH_VARARGS },
|
||||||
{ (char *)"Openbox_property", _wrap_Openbox_property, METH_VARARGS },
|
{ (char *)"Openbox_property", _wrap_Openbox_property, METH_VARARGS },
|
||||||
|
{ (char *)"Openbox_bindings", _wrap_Openbox_bindings, METH_VARARGS },
|
||||||
{ (char *)"Openbox_screen", _wrap_Openbox_screen, METH_VARARGS },
|
{ (char *)"Openbox_screen", _wrap_Openbox_screen, METH_VARARGS },
|
||||||
{ (char *)"Openbox_screenCount", _wrap_Openbox_screenCount, METH_VARARGS },
|
{ (char *)"Openbox_screenCount", _wrap_Openbox_screenCount, METH_VARARGS },
|
||||||
{ (char *)"Openbox_cursors", _wrap_Openbox_cursors, METH_VARARGS },
|
{ (char *)"Openbox_cursors", _wrap_Openbox_cursors, METH_VARARGS },
|
||||||
|
@ -2649,6 +2719,9 @@ static PyMethodDef SwigMethods[] = {
|
||||||
{ (char *)"preregister", _wrap_preregister, METH_VARARGS },
|
{ (char *)"preregister", _wrap_preregister, METH_VARARGS },
|
||||||
{ (char *)"unregister", _wrap_unregister, METH_VARARGS },
|
{ (char *)"unregister", _wrap_unregister, METH_VARARGS },
|
||||||
{ (char *)"unregister_all", _wrap_unregister_all, METH_VARARGS },
|
{ (char *)"unregister_all", _wrap_unregister_all, METH_VARARGS },
|
||||||
|
{ (char *)"bind", _wrap_bind, METH_VARARGS },
|
||||||
|
{ (char *)"unbind", _wrap_unbind, METH_VARARGS },
|
||||||
|
{ (char *)"unbind_all", _wrap_unbind_all, METH_VARARGS },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2689,6 +2762,7 @@ static swig_type_info _swigt__p_XPropertyEvent[] = {{"_p_XPropertyEvent", 0, "XP
|
||||||
static swig_type_info _swigt__p_XDestroyWindowEvent[] = {{"_p_XDestroyWindowEvent", 0, "XDestroyWindowEvent *", 0},{"_p_XDestroyWindowEvent"},{0}};
|
static swig_type_info _swigt__p_XDestroyWindowEvent[] = {{"_p_XDestroyWindowEvent", 0, "XDestroyWindowEvent *", 0},{"_p_XDestroyWindowEvent"},{0}};
|
||||||
static swig_type_info _swigt__p_otk__BImageControl[] = {{"_p_otk__BImageControl", 0, "otk::BImageControl *", 0},{"_p_otk__BImageControl"},{0}};
|
static swig_type_info _swigt__p_otk__BImageControl[] = {{"_p_otk__BImageControl", 0, "otk::BImageControl *", 0},{"_p_otk__BImageControl"},{0}};
|
||||||
static swig_type_info _swigt__p_PyObject[] = {{"_p_PyObject", 0, "PyObject *", 0},{"_p_PyObject"},{0}};
|
static swig_type_info _swigt__p_PyObject[] = {{"_p_PyObject", 0, "PyObject *", 0},{"_p_PyObject"},{0}};
|
||||||
|
static swig_type_info _swigt__p_ob__OBBindings[] = {{"_p_ob__OBBindings", 0, "ob::OBBindings *", 0},{"_p_ob__OBBindings"},{0}};
|
||||||
static swig_type_info _swigt__p_ob__MwmHints[] = {{"_p_ob__MwmHints", 0, "ob::MwmHints *", 0},{"_p_ob__MwmHints"},{0}};
|
static swig_type_info _swigt__p_ob__MwmHints[] = {{"_p_ob__MwmHints", 0, "ob::MwmHints *", 0},{"_p_ob__MwmHints"},{0}};
|
||||||
static swig_type_info _swigt__p_otk__Configuration[] = {{"_p_otk__Configuration", 0, "otk::Configuration *", 0},{"_p_otk__Configuration"},{0}};
|
static swig_type_info _swigt__p_otk__Configuration[] = {{"_p_otk__Configuration", 0, "otk::Configuration *", 0},{"_p_otk__Configuration"},{0}};
|
||||||
static swig_type_info _swigt__p_XUnmapEvent[] = {{"_p_XUnmapEvent", 0, "XUnmapEvent *", 0},{"_p_XUnmapEvent"},{0}};
|
static swig_type_info _swigt__p_XUnmapEvent[] = {{"_p_XUnmapEvent", 0, "XUnmapEvent *", 0},{"_p_XUnmapEvent"},{0}};
|
||||||
|
@ -2716,6 +2790,7 @@ _swigt__p_XPropertyEvent,
|
||||||
_swigt__p_XDestroyWindowEvent,
|
_swigt__p_XDestroyWindowEvent,
|
||||||
_swigt__p_otk__BImageControl,
|
_swigt__p_otk__BImageControl,
|
||||||
_swigt__p_PyObject,
|
_swigt__p_PyObject,
|
||||||
|
_swigt__p_ob__OBBindings,
|
||||||
_swigt__p_ob__MwmHints,
|
_swigt__p_ob__MwmHints,
|
||||||
_swigt__p_otk__Configuration,
|
_swigt__p_otk__Configuration,
|
||||||
_swigt__p_XUnmapEvent,
|
_swigt__p_XUnmapEvent,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
|
|
||||||
#include "python.hh"
|
#include "python.hh"
|
||||||
|
#include "openbox.hh"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -10,6 +11,7 @@ namespace ob {
|
||||||
typedef std::vector<PyObject*> FunctionList;
|
typedef std::vector<PyObject*> FunctionList;
|
||||||
|
|
||||||
static FunctionList callbacks[OBActions::NUM_ACTIONS];
|
static FunctionList callbacks[OBActions::NUM_ACTIONS];
|
||||||
|
static FunctionList bindfuncs;
|
||||||
|
|
||||||
bool python_register(int action, PyObject *callback)
|
bool python_register(int action, PyObject *callback)
|
||||||
{
|
{
|
||||||
|
@ -125,4 +127,83 @@ void python_callback(OBActions::ActionType action, Window window,
|
||||||
Py_DECREF(arglist);
|
Py_DECREF(arglist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool python_bind(PyObject *keylist, PyObject *callback)
|
||||||
|
{
|
||||||
|
if (!PyList_Check(keylist)) {
|
||||||
|
PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!PyCallable_Check(callback)) {
|
||||||
|
PyErr_SetString(PyExc_AssertionError, "Invalid callback function.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBBindings::StringVect vectkeylist;
|
||||||
|
for (int i = 0, end = PyList_Size(keylist); i < end; ++i) {
|
||||||
|
PyObject *str = PyList_GetItem(keylist, i);
|
||||||
|
if (!PyString_Check(str)) {
|
||||||
|
PyErr_SetString(PyExc_AssertionError,
|
||||||
|
"Invalid keylist. It must contain only strings.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vectkeylist.push_back(PyString_AsString(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)) {
|
||||||
|
Py_XINCREF(callback); // Add a reference to new callback
|
||||||
|
bindfuncs.push_back(callback);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(PyExc_AssertionError,"Unable to create binding. Invalid.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool python_unbind(PyObject *keylist)
|
||||||
|
{
|
||||||
|
if (!PyList_Check(keylist)) {
|
||||||
|
PyErr_SetString(PyExc_AssertionError, "Invalid keylist. Not a list.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBBindings::StringVect vectkeylist;
|
||||||
|
for (int i = 0, end = PyList_Size(keylist); i < end; ++i) {
|
||||||
|
PyObject *str = PyList_GetItem(keylist, i);
|
||||||
|
if (!PyString_Check(str)) {
|
||||||
|
PyErr_SetString(PyExc_AssertionError,
|
||||||
|
"Invalid keylist. It must contain only strings.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vectkeylist.push_back(PyString_AsString(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
// 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;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool python_unbind_all()
|
||||||
|
{
|
||||||
|
Openbox::instance->bindings()->remove_all();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "actions.hh"
|
#include "actions.hh"
|
||||||
#include "widget.hh"
|
#include "widget.hh"
|
||||||
|
#include "bindings.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
@ -25,6 +26,18 @@ bool python_unregister(int action, PyObject *callback);
|
||||||
//! Removes all python callback functions from the hook list
|
//! Removes all python callback functions from the hook list
|
||||||
bool python_unregister_all(int action);
|
bool python_unregister_all(int action);
|
||||||
|
|
||||||
|
//! Add a mouse/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_unbind(PyObject *keylist);
|
||||||
|
|
||||||
|
bool python_unbind_all();
|
||||||
|
|
||||||
//! Fire a python callback function
|
//! Fire a python callback function
|
||||||
void python_callback(OBActions::ActionType action, Window window,
|
void python_callback(OBActions::ActionType action, Window window,
|
||||||
OBWidget::WidgetType type, unsigned int state,
|
OBWidget::WidgetType type, unsigned int state,
|
||||||
|
|
Loading…
Reference in a new issue