From 91c7e5c378b1a639c6f5383915ed68b36b7735d4 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 24 Jan 2003 07:37:26 +0000 Subject: [PATCH] allow python to grab the keyboard. have release events go to the grabs callback. remove the modifier from teh state when a modifier key is the one being released --- otk/display.cc | 23 ++++---- otk/display.hh | 4 ++ scripts/focus.py | 47 ++++++++++++++-- src/actions.cc | 37 ++++++++++++- src/actions.hh | 1 + src/bindings.cc | 92 +++++++++++++++++++++---------- src/bindings.hh | 8 ++- src/client.cc | 2 +- src/openbox.py | 10 +++- src/openbox_wrap.cc | 130 ++++++++++++++++++++++++++++---------------- src/python.cc | 20 +++++++ src/python.hh | 20 +++++-- src/screen.hh | 1 - 13 files changed, 289 insertions(+), 106 deletions(-) diff --git a/otk/display.cc b/otk/display.cc index af03801e..be8696bf 100644 --- a/otk/display.cc +++ b/otk/display.cc @@ -128,16 +128,15 @@ DISPLAY environment variable approriately.\n\n")); #endif // XINERAMA // get lock masks that are defined by the display (not constant) - XModifierKeymap *modmap; - - modmap = XGetModifierMapping(_display); - if (modmap && modmap->max_keypermod > 0) { + _modmap = XGetModifierMapping(_display); + assert(_modmap); + if (_modmap && _modmap->max_keypermod > 0) { const int mask_table[] = { ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask }; const size_t size = (sizeof(mask_table) / sizeof(mask_table[0])) * - modmap->max_keypermod; + _modmap->max_keypermod; // get the values of the keyboard lock modifiers // Note: Caps lock is not retrieved the same way as Scroll and Num lock // since it doesn't need to be. @@ -145,17 +144,15 @@ DISPLAY environment variable approriately.\n\n")); const KeyCode scroll_lock = XKeysymToKeycode(_display, XK_Scroll_Lock); for (size_t cnt = 0; cnt < size; ++cnt) { - if (! modmap->modifiermap[cnt]) continue; + if (! _modmap->modifiermap[cnt]) continue; - if (num_lock == modmap->modifiermap[cnt]) - _num_lock_mask = mask_table[cnt / modmap->max_keypermod]; - if (scroll_lock == modmap->modifiermap[cnt]) - _scroll_lock_mask = mask_table[cnt / modmap->max_keypermod]; + if (num_lock == _modmap->modifiermap[cnt]) + _num_lock_mask = mask_table[cnt / _modmap->max_keypermod]; + if (scroll_lock == _modmap->modifiermap[cnt]) + _scroll_lock_mask = mask_table[cnt / _modmap->max_keypermod]; } } - if (modmap) XFreeModifiermap(modmap); - _mask_list[0] = 0; _mask_list[1] = LockMask; _mask_list[2] = _num_lock_mask; @@ -181,6 +178,8 @@ Display::~Display() while (_grab_count > 0) ungrab(); + XFreeModifiermap(_modmap); + for (int i = 0; i < ScreenCount(_display); ++i) { delete _rendercontrol_list[i]; delete _screeninfo_list[i]; diff --git a/otk/display.hh b/otk/display.hh index 0879ce32..e8613a04 100644 --- a/otk/display.hh +++ b/otk/display.hh @@ -47,6 +47,9 @@ private: //! The value of the mask for the ScrollLock modifier unsigned int _scroll_lock_mask; + //! The key codes for the modifier keys + XModifierKeymap *_modmap; + //! The number of requested grabs on the display int _grab_count; @@ -102,6 +105,7 @@ public: inline unsigned int numLockMask() const { return _num_lock_mask; } inline unsigned int scrollLockMask() const { return _scroll_lock_mask; } + const XModifierKeymap *modifierMap() const { return _modmap; } inline ::Display* operator*() const { return _display; } diff --git a/scripts/focus.py b/scripts/focus.py index 79da5a21..53abf190 100644 --- a/scripts/focus.py +++ b/scripts/focus.py @@ -8,7 +8,8 @@ ob_focus_fallback = 0 # maintain a list of clients, stacked in focus order ob_clients = [] # maintaint he current focused window -ob_focused = 0; +ob_focused = 0 +ob_hold_client_list = 0 def ob_new_win(data): global ob_clients @@ -22,12 +23,14 @@ def ob_close_win(data): def ob_focused(data): global ob_clients if data.client: - win = data.client.window() - ob_focused = win - # move it to the top - ob_clients.remove(win) - ob_clients.insert(0, win) + if not ob_hold_client_list: + win = data.client.window() + ob_focused = win + # move it to the top + ob_clients.remove(win) + ob_clients.insert(0, win) elif ob_focus_fallback: + ob_old_client_list = 0 # something is wrong.. stop holding # pass around focus ob_focused = 0 desktop = openbox.screen(data.screen).desktop() @@ -41,6 +44,38 @@ ebind(EventNewWindow, ob_new_win) ebind(EventCloseWindow, ob_close_win) ebind(EventFocus, ob_focused) +ob_cyc_mask = 0 +ob_cyc_key = 0; + +def focus_next_stacked_grab(data): + global ob_cyc_mask; + global ob_cyc_key; + + if data.action == EventKeyRelease: + print "release: " + str(ob_cyc_mask) + "..." + str(data.state) + # have all the modifiers this started with been released? + if not ob_cyc_mask & data.state: + kungrab() # ungrab ourself + print "UNGRABBED!" + else: + print "press: " + str(ob_cyc_mask) + "..." + str(data.state) + \ + "..." + data.key + if ob_cyc_key == data.key: + print "CYCLING!!" + +def focus_next_stacked(data, forward=1): + global ob_cyc_mask; + global ob_cyc_key; + ob_cyc_mask = data.state + ob_cyc_key = data.key + + kgrab(focus_next_stacked_grab) + print "GRABBED!" + focus_next_stacked_grab(data) # start with the first press + +def focus_prev_stacked(data): + return + def focus_next(data, num=1, forward=1): """Focus the next (or previous, with forward=0) window in a linear order.""" diff --git a/src/actions.cc b/src/actions.cc index 65546167..e2999b76 100644 --- a/src/actions.cc +++ b/src/actions.cc @@ -206,6 +206,7 @@ void Actions::leaveHandler(const XCrossingEvent &e) void Actions::keyPressHandler(const XKeyEvent &e) { + printf("press\n"); otk::EventHandler::keyPressHandler(e); // kill off the Button1Mask etc, only want the modifiers @@ -213,7 +214,41 @@ void Actions::keyPressHandler(const XKeyEvent &e) Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask); openbox->bindings()-> fireKey(otk::display->findScreen(e.root)->screen(), - state, e.keycode, e.time); + state, e.keycode, e.time, EventKeyPress); +} + + +void Actions::keyReleaseHandler(const XKeyEvent &e) +{ + printf("release\n"); + otk::EventHandler::keyReleaseHandler(e); + + // kill off the Button1Mask etc, only want the modifiers + unsigned int state = e.state & (ControlMask | ShiftMask | Mod1Mask | + Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask); + + // remove from the state the mask of the modifier being released, if it is + // a modifier key being released (XXX this is a little ugly..) + const XModifierKeymap *map = otk::display->modifierMap(); + const int mask_table[] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, + Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask + }; + KeyCode *kp = map->modifiermap; + for (int i = 0, n = sizeof(mask_table)/sizeof(mask_table[0]); i < n; ++i) { + for (int k = 0; k < map->max_keypermod; ++k) { + if (*kp == e.keycode) { // found the keycode + state &= ~mask_table[i]; // remove the mask for it + i = n; // cause the first loop to break; + break; // get outta here! + } + ++kp; + } + } + + openbox->bindings()-> + fireKey(otk::display->findScreen(e.root)->screen(), + state, e.keycode, e.time, EventKeyRelease); } diff --git a/src/actions.hh b/src/actions.hh index 8fb728df..552d1a65 100644 --- a/src/actions.hh +++ b/src/actions.hh @@ -76,6 +76,7 @@ public: virtual void leaveHandler(const XCrossingEvent &e); virtual void keyPressHandler(const XKeyEvent &e); + virtual void keyReleaseHandler(const XKeyEvent &e); virtual void motionHandler(const XMotionEvent &e); diff --git a/src/bindings.cc b/src/bindings.cc index 2ce8c8e4..c5a9f896 100644 --- a/src/bindings.cc +++ b/src/bindings.cc @@ -147,7 +147,8 @@ KeyBindingTree *Bindings::buildtree(const StringVect &keylist, Bindings::Bindings() : _curpos(&_keytree), _resetkey(0,0), - _timer((otk::Timer *) 0) + _timer((otk::Timer *) 0), + _keybgrab_callback(0) { // setResetKey("C-g"); // set the default reset key } @@ -371,38 +372,73 @@ void Bindings::grabKeys(bool grab) } +bool Bindings::grabKeyboard(PyObject *callback) +{ + assert(callback); + if (_keybgrab_callback) return false; // already grabbed + + int screen = openbox->screen(0)->number(); + Window root = otk::display->screenInfo(screen)->rootWindow(); + if (XGrabKeyboard(**otk::display, root, false, GrabModeAsync, + GrabModeAsync, CurrentTime)) + return false; + printf("****GRABBED****\n"); + _keybgrab_callback = callback; + return true; +} + + +void Bindings::ungrabKeyboard() +{ + if (!_keybgrab_callback) return; // not grabbed + + _keybgrab_callback = 0; + XUngrabKeyboard(**otk::display, CurrentTime); + printf("****UNGRABBED****\n"); +} + + void Bindings::fireKey(int screen, unsigned int modifiers, unsigned int key, - Time time) + Time time, KeyAction action) { - if (key == _resetkey.key && modifiers == _resetkey.modifiers) { - resetChains(this); + if (_keybgrab_callback) { + Client *c = openbox->focusedClient(); + KeyData data(screen, c, time, modifiers, key, action); + python_callback(_keybgrab_callback, &data); } else { - KeyBindingTree *p = _curpos->first_child; - while (p) { - if (p->binding.key == key && p->binding.modifiers == modifiers) { - if (p->chain) { - if (_timer) - delete _timer; - _timer = new otk::Timer(5000, // 5 second timeout - (otk::Timer::TimeoutHandler)resetChains, - this); - // grab the server here to make sure no key pressed go missed - otk::display->grab(); - grabKeys(false); - _curpos = p; - grabKeys(true); - otk::display->ungrab(); - } else { - Client *c = openbox->focusedClient(); - KeyData data(screen, c, time, modifiers, key); - CallbackList::iterator it, end = p->callbacks.end(); - for (it = p->callbacks.begin(); it != end; ++it) - python_callback(*it, &data); - resetChains(this); + // KeyRelease events only occur during keyboard grabs + if (action == EventKeyRelease) return; + + if (key == _resetkey.key && modifiers == _resetkey.modifiers) { + resetChains(this); + } else { + KeyBindingTree *p = _curpos->first_child; + while (p) { + if (p->binding.key == key && p->binding.modifiers == modifiers) { + if (p->chain) { + if (_timer) + delete _timer; + _timer = new otk::Timer(5000, // 5 second timeout + (otk::Timer::TimeoutHandler)resetChains, + this); + // grab the server here to make sure no key pressed go missed + otk::display->grab(); + grabKeys(false); + _curpos = p; + grabKeys(true); + otk::display->ungrab(); + } else { + Client *c = openbox->focusedClient(); + KeyData data(screen, c, time, modifiers, key, action); + CallbackList::iterator it, end = p->callbacks.end(); + for (it = p->callbacks.begin(); it != end; ++it) + python_callback(*it, &data); + resetChains(this); + } + break; } - break; + p = p->next_sibling; } - p = p->next_sibling; } } } diff --git a/src/bindings.hh b/src/bindings.hh index 32f422ff..a9e8c986 100644 --- a/src/bindings.hh +++ b/src/bindings.hh @@ -83,6 +83,8 @@ private: Client *client); CallbackList _eventlist[NUM_EVENTS]; + + PyObject *_keybgrab_callback; public: //! Initializes an Bindings object @@ -111,12 +113,16 @@ public: //! Removes all key bindings void removeAllKeys(); - void fireKey(int screen, unsigned int modifiers,unsigned int key, Time time); + void fireKey(int screen, unsigned int modifiers,unsigned int key, Time time, + KeyAction action); void setResetKey(const std::string &key); void grabKeys(bool grab); + bool grabKeyboard(PyObject *callback); + void ungrabKeyboard(); + bool addButton(const std::string &but, MouseContext context, MouseAction action, PyObject *callback); diff --git a/src/client.cc b/src/client.cc index 2372a26d..fb4b924d 100644 --- a/src/client.cc +++ b/src/client.cc @@ -1435,7 +1435,7 @@ void Client::unmapHandler(const XUnmapEvent &e) { if (ignore_unmaps) { #ifdef DEBUG - printf("Ignored UnmapNotify for 0x%lx (event 0x%lx)\n", e.window, e.event); +// printf("Ignored UnmapNotify for 0x%lx (event 0x%lx)\n", e.window, e.event); #endif // DEBUG ignore_unmaps--; return; diff --git a/src/openbox.py b/src/openbox.py index aad74eb1..b4a42e74 100644 --- a/src/openbox.py +++ b/src/openbox.py @@ -904,17 +904,19 @@ NUM_MOUSE_ACTION = _openbox.NUM_MOUSE_ACTION KC_Menu = _openbox.KC_Menu KC_All = _openbox.KC_All NUM_KEY_CONTEXT = _openbox.NUM_KEY_CONTEXT +EventKeyPress = _openbox.EventKeyPress +EventKeyRelease = _openbox.EventKeyRelease +NUM_KEY_ACTION = _openbox.NUM_KEY_ACTION EventEnterWindow = _openbox.EventEnterWindow EventLeaveWindow = _openbox.EventLeaveWindow EventPlaceWindow = _openbox.EventPlaceWindow EventNewWindow = _openbox.EventNewWindow EventCloseWindow = _openbox.EventCloseWindow -EventUrgentWindow = _openbox.EventUrgentWindow EventStartup = _openbox.EventStartup EventShutdown = _openbox.EventShutdown -EventKey = _openbox.EventKey EventFocus = _openbox.EventFocus EventBell = _openbox.EventBell +EventUrgentWindow = _openbox.EventUrgentWindow NUM_EVENTS = _openbox.NUM_EVENTS class MouseData(_object): __swig_setmethods__ = {} @@ -1049,6 +1051,10 @@ mbind = _openbox.mbind kbind = _openbox.kbind +kgrab = _openbox.kgrab + +kungrab = _openbox.kungrab + ebind = _openbox.ebind set_reset_key = _openbox.set_reset_key diff --git a/src/openbox_wrap.cc b/src/openbox_wrap.cc index 86f737cb..08525f20 100644 --- a/src/openbox_wrap.cc +++ b/src/openbox_wrap.cc @@ -677,38 +677,37 @@ SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { #define SWIGTYPE_p_XConfigureEvent swig_types[29] #define SWIGTYPE_p_XRectangle swig_types[30] #define SWIGTYPE_p_otk__ustring swig_types[31] -#define SWIGTYPE_p_std__string swig_types[32] -#define SWIGTYPE_p_XCrossingEvent swig_types[33] -#define SWIGTYPE_p_otk__Display swig_types[34] -#define SWIGTYPE_p_Display swig_types[35] -#define SWIGTYPE_p_XMappingEvent swig_types[36] -#define SWIGTYPE_p_otk__EventHandler swig_types[37] -#define SWIGTYPE_p_XReparentEvent swig_types[38] -#define SWIGTYPE_p_otk__EventDispatcher swig_types[39] -#define SWIGTYPE_p_ob__Bindings swig_types[40] -#define SWIGTYPE_p_ob__Openbox swig_types[41] -#define SWIGTYPE_p_ob__Actions swig_types[42] -#define SWIGTYPE_p_otk__Widget swig_types[43] -#define SWIGTYPE_p_XEvent swig_types[44] -#define SWIGTYPE_p_otk__Property swig_types[45] -#define SWIGTYPE_p_PyObject swig_types[46] -#define SWIGTYPE_p_otk__ScreenInfo swig_types[47] -#define SWIGTYPE_p_otk__RenderStyle swig_types[48] -#define SWIGTYPE_p_ob__EventData swig_types[49] -#define SWIGTYPE_p_XCreateWindowEvent swig_types[50] -#define SWIGTYPE_p_XDestroyWindowEvent swig_types[51] -#define SWIGTYPE_p_otk__Property__StringVect swig_types[52] -#define SWIGTYPE_p_ob__WidgetBase swig_types[53] -#define SWIGTYPE_p_otk__Atoms swig_types[54] -#define SWIGTYPE_p_XKeyEvent swig_types[55] -#define SWIGTYPE_p_int swig_types[56] -#define SWIGTYPE_p_otk__Strut swig_types[57] -#define SWIGTYPE_p_unsigned_long swig_types[58] -#define SWIGTYPE_p_p_unsigned_long swig_types[59] -#define SWIGTYPE_p_XMotionEvent swig_types[60] -#define SWIGTYPE_p_XButtonEvent swig_types[61] -#define SWIGTYPE_p_XSelectionEvent swig_types[62] -static swig_type_info *swig_types[64]; +#define SWIGTYPE_p_XCrossingEvent swig_types[32] +#define SWIGTYPE_p_otk__Display swig_types[33] +#define SWIGTYPE_p_Display swig_types[34] +#define SWIGTYPE_p_XMappingEvent swig_types[35] +#define SWIGTYPE_p_otk__EventHandler swig_types[36] +#define SWIGTYPE_p_XReparentEvent swig_types[37] +#define SWIGTYPE_p_otk__EventDispatcher swig_types[38] +#define SWIGTYPE_p_ob__Bindings swig_types[39] +#define SWIGTYPE_p_ob__Openbox swig_types[40] +#define SWIGTYPE_p_ob__Actions swig_types[41] +#define SWIGTYPE_p_otk__Widget swig_types[42] +#define SWIGTYPE_p_XEvent swig_types[43] +#define SWIGTYPE_p_otk__Property swig_types[44] +#define SWIGTYPE_p_PyObject swig_types[45] +#define SWIGTYPE_p_otk__ScreenInfo swig_types[46] +#define SWIGTYPE_p_otk__RenderStyle swig_types[47] +#define SWIGTYPE_p_ob__EventData swig_types[48] +#define SWIGTYPE_p_XCreateWindowEvent swig_types[49] +#define SWIGTYPE_p_XDestroyWindowEvent swig_types[50] +#define SWIGTYPE_p_otk__Property__StringVect swig_types[51] +#define SWIGTYPE_p_ob__WidgetBase swig_types[52] +#define SWIGTYPE_p_otk__Atoms swig_types[53] +#define SWIGTYPE_p_XKeyEvent swig_types[54] +#define SWIGTYPE_p_int swig_types[55] +#define SWIGTYPE_p_otk__Strut swig_types[56] +#define SWIGTYPE_p_unsigned_long swig_types[57] +#define SWIGTYPE_p_p_unsigned_long swig_types[58] +#define SWIGTYPE_p_XMotionEvent swig_types[59] +#define SWIGTYPE_p_XButtonEvent swig_types[60] +#define SWIGTYPE_p_XSelectionEvent swig_types[61] +static swig_type_info *swig_types[63]; /* -------- TYPES TABLE (END) -------- */ @@ -11115,15 +11114,16 @@ static PyObject *_wrap_KeyData_state_get(PyObject *self, PyObject *args) { static PyObject *_wrap_KeyData_key_set(PyObject *self, PyObject *args) { PyObject *resultobj; ob::KeyData *arg1 = (ob::KeyData *) 0 ; - std::string *arg2 = (std::string *) 0 ; + char *arg2 ; PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - if(!PyArg_ParseTuple(args,(char *)"OO:KeyData_key_set",&obj0,&obj1)) goto fail; + if(!PyArg_ParseTuple(args,(char *)"Os:KeyData_key_set",&obj0,&arg2)) goto fail; if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__KeyData,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_std__string,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - if (arg1) (arg1)->key = *arg2; - + { + if (arg1->key) delete [] arg1->key; + arg1->key = (char *) (new char[strlen(arg2)+1]); + strcpy((char *) arg1->key,arg2); + } Py_INCREF(Py_None); resultobj = Py_None; return resultobj; fail: @@ -11134,14 +11134,14 @@ static PyObject *_wrap_KeyData_key_set(PyObject *self, PyObject *args) { static PyObject *_wrap_KeyData_key_get(PyObject *self, PyObject *args) { PyObject *resultobj; ob::KeyData *arg1 = (ob::KeyData *) 0 ; - std::string *result; + char *result; PyObject * obj0 = 0 ; if(!PyArg_ParseTuple(args,(char *)"O:KeyData_key_get",&obj0)) goto fail; if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__KeyData,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - result = (std::string *)& ((arg1)->key); + result = (char *) ((arg1)->key); - resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_std__string, 0); + resultobj = result ? PyString_FromString(result) : Py_BuildValue((char*)""); return resultobj; fail: return NULL; @@ -11156,7 +11156,7 @@ static PyObject *_wrap_KeyData_action_set(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args,(char *)"Oi:KeyData_action_set",&obj0,&arg2)) goto fail; if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__KeyData,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; - if (arg1) (arg1)->action = (ob::EventAction )arg2; + if (arg1) (arg1)->action = (ob::KeyAction )arg2; Py_INCREF(Py_None); resultobj = Py_None; return resultobj; @@ -11189,13 +11189,14 @@ static PyObject *_wrap_new_KeyData(PyObject *self, PyObject *args) { Time arg3 ; unsigned int arg4 ; unsigned int arg5 ; + int arg6 ; ob::KeyData *result; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; - if(!PyArg_ParseTuple(args,(char *)"iOOOO:new_KeyData",&arg1,&obj1,&obj2,&obj3,&obj4)) goto fail; + if(!PyArg_ParseTuple(args,(char *)"iOOOOi:new_KeyData",&arg1,&obj1,&obj2,&obj3,&obj4,&arg6)) goto fail; if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__Client,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; arg3 = (Time) PyInt_AsLong(obj2); if (PyErr_Occurred()) SWIG_fail; @@ -11203,7 +11204,7 @@ static PyObject *_wrap_new_KeyData(PyObject *self, PyObject *args) { if (PyErr_Occurred()) SWIG_fail; arg5 = (unsigned int) PyInt_AsLong(obj4); if (PyErr_Occurred()) SWIG_fail; - result = (ob::KeyData *)new ob::KeyData(arg1,arg2,arg3,arg4,arg5); + result = (ob::KeyData *)new ob::KeyData(arg1,arg2,arg3,arg4,arg5,(ob::KeyAction )arg6); resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ob__KeyData, 1); return resultobj; @@ -11270,6 +11271,37 @@ static PyObject *_wrap_kbind(PyObject *self, PyObject *args) { } +static PyObject *_wrap_kgrab(PyObject *self, PyObject *args) { + PyObject *resultobj; + PyObject *arg1 = (PyObject *) 0 ; + PyObject *result; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:kgrab",&obj0)) goto fail; + arg1 = obj0; + result = (PyObject *)ob::kgrab(arg1); + + resultobj = result; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_kungrab(PyObject *self, PyObject *args) { + PyObject *resultobj; + PyObject *result; + + if(!PyArg_ParseTuple(args,(char *)":kungrab")) goto fail; + result = (PyObject *)ob::kungrab(); + + resultobj = result; + return resultobj; + fail: + return NULL; +} + + static PyObject *_wrap_ebind(PyObject *self, PyObject *args) { PyObject *resultobj; int arg1 ; @@ -11825,6 +11857,8 @@ static PyMethodDef SwigMethods[] = { { (char *)"KeyData_swigregister", KeyData_swigregister, METH_VARARGS }, { (char *)"mbind", _wrap_mbind, METH_VARARGS }, { (char *)"kbind", _wrap_kbind, METH_VARARGS }, + { (char *)"kgrab", _wrap_kgrab, METH_VARARGS }, + { (char *)"kungrab", _wrap_kungrab, METH_VARARGS }, { (char *)"ebind", _wrap_ebind, METH_VARARGS }, { (char *)"set_reset_key", _wrap_set_reset_key, METH_VARARGS }, { (char *)"send_client_msg", _wrap_send_client_msg, METH_VARARGS }, @@ -11899,7 +11933,6 @@ static swig_type_info _swigt__p_XCirculateEvent[] = {{"_p_XCirculateEvent", 0, " static swig_type_info _swigt__p_XConfigureEvent[] = {{"_p_XConfigureEvent", 0, "XConfigureEvent *", 0},{"_p_XConfigureEvent"},{0}}; static swig_type_info _swigt__p_XRectangle[] = {{"_p_XRectangle", 0, "XRectangle *", 0},{"_p_XRectangle"},{0}}; static swig_type_info _swigt__p_otk__ustring[] = {{"_p_otk__ustring", 0, "otk::ustring *", 0},{"_p_otk__ustring"},{0}}; -static swig_type_info _swigt__p_std__string[] = {{"_p_std__string", 0, "std::string *", 0},{"_p_std__string"},{0}}; static swig_type_info _swigt__p_XCrossingEvent[] = {{"_p_XCrossingEvent", 0, "XCrossingEvent *", 0},{"_p_XCrossingEvent"},{0}}; static swig_type_info _swigt__p_otk__Display[] = {{"_p_otk__Display", 0, "otk::Display *", 0},{"_p_otk__Display"},{0}}; static swig_type_info _swigt__p_Display[] = {{"_p_Display", 0, "Display *", 0},{"_p_Display"},{0}}; @@ -11964,7 +11997,6 @@ _swigt__p_XCirculateEvent, _swigt__p_XConfigureEvent, _swigt__p_XRectangle, _swigt__p_otk__ustring, -_swigt__p_std__string, _swigt__p_XCrossingEvent, _swigt__p_otk__Display, _swigt__p_Display, @@ -12085,17 +12117,19 @@ static swig_const_info swig_const_table[] = { { SWIG_PY_INT, (char *)"KC_Menu", (long) ob::KC_Menu, 0, 0, 0}, { SWIG_PY_INT, (char *)"KC_All", (long) ob::KC_All, 0, 0, 0}, { SWIG_PY_INT, (char *)"NUM_KEY_CONTEXT", (long) ob::NUM_KEY_CONTEXT, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"EventKeyPress", (long) ob::EventKeyPress, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"EventKeyRelease", (long) ob::EventKeyRelease, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"NUM_KEY_ACTION", (long) ob::NUM_KEY_ACTION, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventEnterWindow", (long) ob::EventEnterWindow, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventLeaveWindow", (long) ob::EventLeaveWindow, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventPlaceWindow", (long) ob::EventPlaceWindow, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventNewWindow", (long) ob::EventNewWindow, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventCloseWindow", (long) ob::EventCloseWindow, 0, 0, 0}, -{ SWIG_PY_INT, (char *)"EventUrgentWindow", (long) ob::EventUrgentWindow, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventStartup", (long) ob::EventStartup, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventShutdown", (long) ob::EventShutdown, 0, 0, 0}, -{ SWIG_PY_INT, (char *)"EventKey", (long) ob::EventKey, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventFocus", (long) ob::EventFocus, 0, 0, 0}, { SWIG_PY_INT, (char *)"EventBell", (long) ob::EventBell, 0, 0, 0}, +{ SWIG_PY_INT, (char *)"EventUrgentWindow", (long) ob::EventUrgentWindow, 0, 0, 0}, { SWIG_PY_INT, (char *)"NUM_EVENTS", (long) ob::NUM_EVENTS, 0, 0, 0}, { SWIG_PY_INT, (char *)"X_PROTOCOL", (long) 11, 0, 0, 0}, { SWIG_PY_INT, (char *)"X_PROTOCOL_REVISION", (long) 0, 0, 0, 0}, diff --git a/src/python.cc b/src/python.cc index 9905dec5..a89fa467 100644 --- a/src/python.cc +++ b/src/python.cc @@ -123,6 +123,26 @@ PyObject *ebind(ob::EventAction action, PyObject *func) Py_INCREF(Py_None); return Py_None; } +PyObject *kgrab(PyObject *func) +{ + if (!PyCallable_Check(func)) { + PyErr_SetString(PyExc_TypeError, "Invalid callback function."); + return NULL; + } + + if (!ob::openbox->bindings()->grabKeyboard(func)) { + PyErr_SetString(PyExc_RuntimeError,"Unable to grab keybaord."); + return NULL; + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject *kungrab() +{ + ob::openbox->bindings()->ungrabKeyboard(); + Py_INCREF(Py_None); return Py_None; +} + PyObject *kbind(PyObject *keylist, ob::KeyContext context, PyObject *func) { if (!PyCallable_Check(func)) { diff --git a/src/python.hh b/src/python.hh index d8b943e7..91d89b8a 100644 --- a/src/python.hh +++ b/src/python.hh @@ -53,6 +53,12 @@ enum KeyContext { NUM_KEY_CONTEXT }; +enum KeyAction { + EventKeyPress, + EventKeyRelease, + NUM_KEY_ACTION +}; + enum EventAction { EventEnterWindow, EventLeaveWindow, @@ -61,10 +67,9 @@ enum EventAction { EventCloseWindow, EventStartup, EventShutdown, - EventKey, EventFocus, EventBell, - EventUrgentNotify, + EventUrgentWindow, NUM_EVENTS }; @@ -148,18 +153,18 @@ public: Client *client; Time time; unsigned int state; - std::string key; - EventAction action; // this is here so that all the Data structs have .action + char *key; + KeyAction action; KeyData(int screen, Client *client, Time time, unsigned int state, - unsigned int key) { + unsigned int key, KeyAction action) { this->screen = screen; this->client = client; this->time = time; this->state = state; this->key = XKeysymToString(XKeycodeToKeysym(**otk::display, key, 0)); - this->action = EventKey; + this->action = action; } }; @@ -187,6 +192,9 @@ PyObject *mbind(const std::string &button, ob::MouseContext context, PyObject *kbind(PyObject *keylist, ob::KeyContext context, PyObject *func); +PyObject *kgrab(PyObject *func); +PyObject *kungrab(); + PyObject *ebind(ob::EventAction action, PyObject *func); void set_reset_key(const std::string &key); diff --git a/src/screen.hh b/src/screen.hh index 37e56cf1..b64a5199 100644 --- a/src/screen.hh +++ b/src/screen.hh @@ -26,7 +26,6 @@ extern "C" { namespace ob { class Client; -class RootWindow; //! Manages a single screen /*! -- 2.39.2