From: Dana Jansens Date: Wed, 26 Mar 2003 15:02:08 +0000 (+0000) Subject: not using CurrentTime anywhere X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=f29dd7e0cd0ceef0bfe95c865b6b22d34b065b7b;p=chaz%2Fopenbox not using CurrentTime anywhere --- diff --git a/openbox/client.c b/openbox/client.c index 3ebfcd60..61635145 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -1934,7 +1934,7 @@ gboolean client_focus(Client *self) if (self->can_focus) XSetInputFocus(ob_display, self->window, RevertToNone, - CurrentTime); + event_lasttime); if (self->focus_notify) { XEvent ce; @@ -1944,7 +1944,7 @@ gboolean client_focus(Client *self) ce.xclient.window = self->window; ce.xclient.format = 32; ce.xclient.data.l[0] = prop_atoms.wm_take_focus; - ce.xclient.data.l[1] = CurrentTime; + ce.xclient.data.l[1] = event_lasttime; ce.xclient.data.l[2] = 0l; ce.xclient.data.l[3] = 0l; ce.xclient.data.l[4] = 0l; @@ -1972,6 +1972,7 @@ void client_set_focused(Client *self, gboolean focused) if (focus_client != self) focus_set_client(self); } else { + event_unfocustime = event_lasttime; if (focus_client == self) focus_set_client(NULL); } diff --git a/openbox/event.c b/openbox/event.c index fa5f29ff..5c948783 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -24,6 +24,7 @@ static void event_handle_root(XEvent *e); static void event_handle_client(Client *c, XEvent *e); Time event_lasttime = 0; +Time event_unfocustime = 0; /*! The value of the mask for the NumLock modifier */ unsigned int NumLockMask; diff --git a/openbox/event.h b/openbox/event.h index e88fd12d..b3d14859 100644 --- a/openbox/event.h +++ b/openbox/event.h @@ -5,6 +5,9 @@ /*! Time at which the last event with a timestamp occured. */ extern Time event_lasttime; +/*! Time at which the last event with a timestamp occured before we tried to + unfocus a window. */ +extern Time event_unfocustime; /*! The value of the mask for the NumLock modifier */ extern unsigned int NumLockMask; diff --git a/openbox/focus.c b/openbox/focus.c index 8a6db00a..d9ed80bc 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -62,7 +62,8 @@ void focus_set_client(Client *client) if (client == NULL) { /* when nothing will be focused, send focus to the backup target */ - XSetInputFocus(ob_display, focus_backup, RevertToNone, event_lasttime); + XSetInputFocus(ob_display, focus_backup, RevertToNone, + event_unfocustime); } old = focus_client; diff --git a/openbox/grab.c b/openbox/grab.c index ab38f27b..f90eb6b5 100644 --- a/openbox/grab.c +++ b/openbox/grab.c @@ -17,13 +17,13 @@ void grab_keyboard(gboolean grab) if (kgrabs++ == 0) { g_message("GRABBING KEYBOARD %d", kgrabs); XGrabKeyboard(ob_display, ob_root, 0, GrabModeAsync, GrabModeSync, - CurrentTime); + event_lasttime); } else g_message("NOT GRABBING KEYBOARD %d", kgrabs); } else if (kgrabs > 0) { if (--kgrabs == 0) { g_message("UNGRABBING KEYBOARD %d", kgrabs); - XUngrabKeyboard(ob_display, CurrentTime); + XUngrabKeyboard(ob_display, event_lasttime); } else g_message("NOT UNGRABBING KEYBOARD %d", kgrabs); } @@ -34,10 +34,10 @@ void grab_pointer(gboolean grab, Cursor cur) if (grab) { if (pgrabs++ == 0) XGrabPointer(ob_display, ob_root, False, 0, GrabModeAsync, - GrabModeAsync, FALSE, cur, CurrentTime); + GrabModeAsync, FALSE, cur, event_lasttime); } else if (pgrabs > 0) { if (--pgrabs == 0) - XUngrabPointer(ob_display, CurrentTime); + XUngrabPointer(ob_display, event_lasttime); } } diff --git a/openbox/keyboard.c b/openbox/keyboard.c deleted file mode 100644 index 70ac3ffc..00000000 --- a/openbox/keyboard.c +++ /dev/null @@ -1,297 +0,0 @@ -#include "focus.h" -#include "openbox.h" -#include "keyboard.h" -#include "clientwrap.h" - -#include -#include -#ifdef HAVE_STRING_H -# include -#endif - -typedef struct KeyBindingTree { - guint state; - guint key; - GList *keylist; - PyObject *func; - - /* the next binding in the tree at the same level */ - struct KeyBindingTree *next_sibling; - /* the first child of this binding (next binding in a chained sequence).*/ - struct KeyBindingTree *first_child; -} KeyBindingTree; - - -static KeyBindingTree *firstnode, *curpos; -static guint reset_key, reset_state; -static gboolean grabbed, user_grabbed; -static PyObject *grab_func; - -/*************************************************************************** - - Define the type 'KeyboardData' - - ***************************************************************************/ - -typedef struct KeyboardData { - PyObject_HEAD - PyObject *keychain; - guint state; - guint keycode; - gboolean press; -} KeyboardData; - -staticforward PyTypeObject KeyboardDataType; - -/*************************************************************************** - - Type methods/struct - - ***************************************************************************/ - -static PyObject *keybdata_new(PyObject *keychain, guint state, - guint keycode, gboolean press) -{ - KeyboardData *data = PyObject_New(KeyboardData, &KeyboardDataType); - data->keychain = keychain; - Py_INCREF(keychain); - data->state = state; - data->keycode = keycode; - data->press = press; - return (PyObject*) data; -} - -static void keybdata_dealloc(KeyboardData *self) -{ - Py_DECREF(self->keychain); - PyObject_Del((PyObject*)self); -} - -static PyObject *keybdata_getattr(KeyboardData *self, char *name) -{ - if (!strcmp(name, "keychain")) { - Py_INCREF(self->keychain); - return self->keychain; - } else if (!strcmp(name, "state")) - return PyInt_FromLong(self->state); - else if (!strcmp(name, "keycode")) - return PyInt_FromLong(self->keycode); - else if (!strcmp(name, "press")) - return PyInt_FromLong(!!self->press); - - PyErr_Format(PyExc_AttributeError, "no such attribute '%s'", name); - return NULL; -} - -static PyTypeObject KeyboardDataType = { - PyObject_HEAD_INIT(NULL) - 0, - "KeyboardData", - sizeof(KeyboardData), - 0, - (destructor) keybdata_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc) keybdata_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -/***************************************************************************/ - - - -static gboolean grab_keyboard(gboolean grab) -{ - gboolean ret = TRUE; - - g_message("grab_keyboard(%s). grabbed: %d", (grab?"True":"False"),grabbed); - - user_grabbed = grab; - if (!grabbed) { - if (grab) - ret = XGrabKeyboard(ob_display, ob_root, 0, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess; - else - XUngrabKeyboard(ob_display, CurrentTime); - } - return ret; -} - -/*************************************************************************** - - Define the type 'Keyboard' - - ***************************************************************************/ - -#define IS_KEYBOARD(v) ((v)->ob_type == &KeyboardType) -#define CHECK_KEYBOARD(self, funcname) { \ - if (!IS_KEYBOARD(self)) { \ - PyErr_SetString(PyExc_TypeError, \ - "descriptor '" funcname "' requires a 'Keyboard' " \ - "object"); \ - return NULL; \ - } \ -} - -typedef struct Keyboard { - PyObject_HEAD -} Keyboard; - -staticforward PyTypeObject KeyboardType; - - -static PyObject *keyb_clearBinds(Keyboard *self, PyObject *args) -{ - CHECK_KEYBOARD(self, "clearBinds"); - if (!PyArg_ParseTuple(args, ":clearBinds")) - return NULL; - clearall(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *keyb_grab(Keyboard *self, PyObject *args) -{ - PyObject *func; - - CHECK_KEYBOARD(self, "grab"); - if (!PyArg_ParseTuple(args, "O:grab", &func)) - return NULL; - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_ValueError, "expected a callable object"); - return NULL; - } - if (!grab_keyboard(TRUE)) { - PyErr_SetString(PyExc_RuntimeError, "failed to grab keyboard"); - return NULL; - } - grab_func = func; - Py_INCREF(grab_func); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *keyb_ungrab(Keyboard *self, PyObject *args) -{ - CHECK_KEYBOARD(self, "ungrab"); - if (!PyArg_ParseTuple(args, ":ungrab")) - return NULL; - grab_keyboard(FALSE); - Py_XDECREF(grab_func); - grab_func = NULL; - Py_INCREF(Py_None); - return Py_None; -} - -#define METH(n, d) {#n, (PyCFunction)keyb_##n, METH_VARARGS, #d} - -static PyMethodDef KeyboardMethods[] = { - METH(bind, - "bind(keychain, func)\n\n" - "Binds a key-chain to a function. The keychain is a tuple of strings " - "which define a chain of key presses. Each member of the tuple has " - "the format [Modifier-]...[Key]. Modifiers can be 'mod1', 'mod2', " - "'mod3', 'mod4', 'mod5', 'control', and 'shift'. The keys on your " - "keyboard that are bound to each of these modifiers can be found by " - "running 'xmodmap'. The Key can be any valid key definition. Key " - "definitions can be found by running 'xev', pressing the key while " - "its window is focused, and watching its output. Here are some " - "examples of valid keychains: ('a'), ('F7'), ('control-a', 'd'), " - "('control-mod1-x', 'control-mod4-g'), ('F1', 'space'). The func " - "must have a definition similar to 'def func(keydata, client)'. A " - "keychain cannot be bound to more than one function."), - METH(clearBinds, - "clearBinds()\n\n" - "Removes all bindings that were previously made by bind()."), - METH(grab, - "grab(func)\n\n" - "Grabs the entire keyboard, causing all possible keyboard events to " - "be passed to the given function. CAUTION: Be sure when you grab() " - "that you also have an ungrab() that will execute, or you will not " - "be able to type until you restart Openbox. The func must have a " - "definition similar to 'def func(keydata)'. The keyboard cannot be " - "grabbed if it is already grabbed."), - METH(ungrab, - "ungrab()\n\n" - "Ungrabs the keyboard. The keyboard cannot be ungrabbed if it is not " - "grabbed."), - { NULL, NULL, 0, NULL } -}; - -/*************************************************************************** - - Type methods/struct - - ***************************************************************************/ - -static void keyb_dealloc(PyObject *self) -{ - PyObject_Del(self); -} - -static PyTypeObject KeyboardType = { - PyObject_HEAD_INIT(NULL) - 0, - "Keyboard", - sizeof(Keyboard), - 0, - (destructor) keyb_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -/**************************************************************************/ - -void keyboard_startup() -{ - PyObject *input, *inputdict, *ptr; - gboolean b; - - curpos = firstnode = NULL; - grabbed = user_grabbed = FALSE; - - b = translate("C-G", &reset_state, &reset_key); - g_assert(b); - - KeyboardType.ob_type = &PyType_Type; - KeyboardType.tp_methods = KeyboardMethods; - PyType_Ready(&KeyboardType); - PyType_Ready(&KeyboardDataType); - - /* get the input module/dict */ - input = PyImport_ImportModule("input"); /* new */ - g_assert(input != NULL); - inputdict = PyModule_GetDict(input); /* borrowed */ - g_assert(inputdict != NULL); - - /* add a Keyboard instance to the input module */ - ptr = (PyObject*) PyObject_New(Keyboard, &KeyboardType); - PyDict_SetItemString(inputdict, "Keyboard", ptr); - Py_DECREF(ptr); - - Py_DECREF(input); -} - -void keyboard_shutdown() -{ - if (grabbed || user_grabbed) { - grabbed = FALSE; - grab_keyboard(FALSE); - } - grab_keys(FALSE); - destroytree(firstnode); - firstnode = NULL; -} - diff --git a/openbox/keyboard.h b/openbox/keyboard.h deleted file mode 100644 index 464606b2..00000000 --- a/openbox/keyboard.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __keyboard_h -#define __keyboard_h - -#include - -void keyboard_startup(); -void keyboard_shutdown(); - -guint keyboard_translate_modifier(char *str); - -void keyboard_event(XKeyEvent *e); - -#endif diff --git a/openbox/pointer.c b/openbox/pointer.c deleted file mode 100644 index d2407685..00000000 --- a/openbox/pointer.c +++ /dev/null @@ -1,740 +0,0 @@ -#include "pointer.h" -#include "keyboard.h" -#include "frame.h" -#include "engine.h" -#include "openbox.h" -#include "hooks.h" -#include "configwrap.h" - -#include -#include -#include /* for PyMemberDef stuff */ -#ifdef HAVE_STDLIB_H -# include -#endif - -typedef enum { - Action_Press, - Action_Release, - Action_Click, - Action_DoubleClick, - Action_Motion, - NUM_ACTIONS -} Action; - -/* GData of GSList*s of PointerBinding*s. */ -static GData *bound_contexts; -static gboolean grabbed; -PyObject *grab_func; - -struct foreach_grab_temp { - Client *client; - gboolean grab; -}; - -typedef struct { - guint state; - guint button; - Action action; - char *name; - GSList *funcs[NUM_ACTIONS]; -} PointerBinding; - -/*************************************************************************** - - Define the type 'ButtonData' - - ***************************************************************************/ - -typedef struct PointerData { - PyObject_HEAD - Action action; - GQuark context; - char *button; - guint state; - guint buttonnum; - int posx, posy; - int pressposx, pressposy; - int pcareax, pcareay, pcareaw, pcareah; -} PointerData; - -staticforward PyTypeObject PointerDataType; - -/*************************************************************************** - - Type methods/struct - - ***************************************************************************/ - -static PyObject *ptrdata_new(char *button, GQuark context, Action action, - guint state, guint buttonnum, int posx, int posy, - int pressposx, int pressposy, int pcareax, - int pcareay, int pcareaw, int pcareah) -{ - PointerData *self = PyObject_New(PointerData, &PointerDataType); - self->button = g_strdup(button); - self->context = context; - self->action = action; - self->state = state; - self->buttonnum = buttonnum; - self->posx = posx; - self->posy = posy; - self->pressposx = pressposx; - self->pressposy = pressposy; - self->pcareax = pcareax; - self->pcareay = pcareay; - self->pcareaw = pcareaw; - self->pcareah = pcareah; - return (PyObject*) self; -} - -static void ptrdata_dealloc(PointerData *self) -{ - g_free(self->button); - PyObject_Del((PyObject*)self); -} - -static PyObject *ptrdata_getattr(PointerData *self, char *name) -{ - if (!strcmp(name, "button")) - return PyString_FromString(self->button); - if (!strcmp(name, "action")) - return PyInt_FromLong(self->action); - if (!strcmp(name, "context")) - return PyString_FromString(g_quark_to_string(self->context)); - if (!strcmp(name, "state")) - return PyInt_FromLong(self->state); - if (!strcmp(name, "buttonnum")) - return PyInt_FromLong(self->buttonnum); - - if (self->action == Action_Motion) { /* the rest are only for motions */ - if (!strcmp(name, "pos")) { - PyObject *pos = PyTuple_New(2); - PyTuple_SET_ITEM(pos, 0, PyInt_FromLong(self->posx)); - PyTuple_SET_ITEM(pos, 1, PyInt_FromLong(self->posy)); - return pos; - } - if (!strcmp(name, "presspos")) { - PyObject *presspos = PyTuple_New(2); - PyTuple_SET_ITEM(presspos, 0, PyInt_FromLong(self->pressposx)); - PyTuple_SET_ITEM(presspos, 1, PyInt_FromLong(self->pressposy)); - return presspos; - } - if (!strcmp(name, "pressclientarea")) { - if (self->pcareaw < 0) { /* < 0 indicates no client */ - Py_INCREF(Py_None); - return Py_None; - } else { - PyObject *ca = PyTuple_New(4); - PyTuple_SET_ITEM(ca, 0, PyInt_FromLong(self->pcareax)); - PyTuple_SET_ITEM(ca, 1, PyInt_FromLong(self->pcareay)); - PyTuple_SET_ITEM(ca, 2, PyInt_FromLong(self->pcareaw)); - PyTuple_SET_ITEM(ca, 3, PyInt_FromLong(self->pcareah)); - return ca; - } - } - } - - PyErr_Format(PyExc_AttributeError, "no such attribute '%s'", name); - return NULL; -} - -static PyTypeObject PointerDataType = { - PyObject_HEAD_INIT(NULL) - 0, - "PointerData", - sizeof(PointerData), - 0, - (destructor) ptrdata_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - (getattrfunc) ptrdata_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -/***************************************************************************/ - -static gboolean translate(char *str, guint *state, guint *button) -{ - char **parsed; - char *l; - int i; - gboolean ret = FALSE; - - parsed = g_strsplit(str, "-", -1); - - /* first, find the button (last token) */ - l = NULL; - for (i = 0; parsed[i] != NULL; ++i) - l = parsed[i]; - if (l == NULL) - goto translation_fail; - - /* figure out the mod mask */ - *state = 0; - for (i = 0; parsed[i] != l; ++i) { - guint m = keyboard_translate_modifier(parsed[i]); - if (!m) goto translation_fail; - *state |= m; - } - - /* figure out the button */ - *button = atoi(l); - if (!*button) { - g_warning("Invalid button '%s' in pointer binding.", l); - goto translation_fail; - } - - ret = TRUE; - -translation_fail: - g_strfreev(parsed); - return ret; -} - -static void grab_button(Client *client, guint state, guint button, - GQuark context, gboolean grab) -{ - Window win; - int mode = GrabModeAsync; - unsigned int mask; - - if (context == g_quark_try_string("frame")) { - win = client->frame->window; - mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask; - } else if (context == g_quark_try_string("client")) { - win = client->frame->plate; - mode = GrabModeSync; /* this is handled in pointer_event */ - mask = ButtonPressMask; /* can't catch more than this with Sync mode - the release event is manufactured in - pointer_fire */ - } else return; - - if (grab) - XGrabButton(ob_display, button, state, win, FALSE, mask, mode, - GrabModeAsync, None, None); - else - XUngrabButton(ob_display, button, state, win); -} - -static void foreach_grab(GQuark key, gpointer data, gpointer user_data) -{ - struct foreach_grab_temp *d = user_data; - GSList *it; - for (it = data; it != NULL; it = it->next) { - PointerBinding *b = it->data; - grab_button(d->client, b->state, b->button, key, d->grab); - } -} - -void pointer_grab_all(Client *client, gboolean grab) -{ - struct foreach_grab_temp bt; - bt.client = client; - bt.grab = grab; - g_datalist_foreach(&bound_contexts, foreach_grab, &bt); -} - -static void grab_all_clients(gboolean grab) -{ - GSList *it; - - for (it = client_list; it != NULL; it = it->next) - pointer_grab_all(it->data, grab); -} - -static gboolean grab_pointer(gboolean grab) -{ - gboolean ret = TRUE; - if (grab) - ret = XGrabPointer(ob_display, ob_root, FALSE, (ButtonPressMask | - ButtonReleaseMask | - ButtonMotionMask | - PointerMotionMask), - GrabModeAsync, GrabModeAsync, None, None, - CurrentTime) == GrabSuccess; - else - XUngrabPointer(ob_display, CurrentTime); - if (ret) grabbed = grab; - return ret; -} - -static void foreach_clear(GQuark key, gpointer data, gpointer user_data) -{ - GSList *it; - user_data = user_data; - for (it = data; it != NULL; it = it->next) { - int i; - - PointerBinding *b = it->data; - for (i = 0; i < NUM_ACTIONS; ++i) - while (b->funcs[i] != NULL) { - Py_DECREF((PyObject*)b->funcs[i]->data); - b->funcs[i] = g_slist_delete_link(b->funcs[i], b->funcs[i]); - } - g_free(b->name); - g_free(b); - } - g_slist_free(data); -} - -static void clearall() -{ - grab_all_clients(FALSE); - g_datalist_foreach(&bound_contexts, foreach_clear, NULL); -} - -static void fire_event(char *button, GQuark context, Action action, - guint state, guint buttonnum, int posx, int posy, - int pressposx, int pressposy, int pcareax, - int pcareay, int pcareaw, int pcareah, - PyObject *client, GSList *functions) -{ - PyObject *ptrdata, *args, *ret; - GSList *it; - - ptrdata = ptrdata_new(button, context, action, - state, buttonnum, posx, posy, pressposx, pressposy, - pcareax, pcareay, pcareaw, pcareah); - args = Py_BuildValue("OO", ptrdata, client); - - if (grabbed) { - ret = PyObject_CallObject(grab_func, args); - if (ret == NULL) PyErr_Print(); - Py_XDECREF(ret); - } else { - for (it = functions; it != NULL; it = it->next) { - ret = PyObject_CallObject(it->data, args); - if (ret == NULL) PyErr_Print(); - Py_XDECREF(ret); - } - } - - Py_DECREF(args); - Py_DECREF(ptrdata); -} - -void pointer_event(XEvent *e, Client *c) -{ - static guint button = 0, lastbutton = 0; - static Time time = 0; - static Rect carea; - static guint pressx, pressy; - GQuark contextq; - gboolean click = FALSE, dblclick = FALSE; - PyObject *client; - GString *str = g_string_sized_new(0); - guint state; - GSList *it = NULL; - PointerBinding *b = NULL; - guint drag_threshold; - - drag_threshold = configwrap_get_int("input", "drag_threshold"); - - contextq = engine_get_context(c, e->xany.window); - - /* pick a button, figure out clicks/double clicks */ - switch (e->type) { - case ButtonPress: - if (!button) { - button = e->xbutton.button; - if (c != NULL) carea = c->frame->area; - else carea.width = -1; /* indicates no client */ - pressx = e->xbutton.x_root; - pressy = e->xbutton.y_root; - } - state = e->xbutton.state; - break; - case ButtonRelease: - state = e->xbutton.state; - break; - case MotionNotify: - state = e->xmotion.state; - break; - default: - g_assert_not_reached(); - return; - } - - if (!grabbed) { - for (it = g_datalist_id_get_data(&bound_contexts, contextq); - it != NULL; it = it->next) { - b = it->data; - if (b->state == state && b->button == button) - break; - } - /* if not grabbed and not bound, then nothing to do! */ - if (it == NULL) return; - } - - if (c) client = clientwrap_new(c); - else client = Py_None; - - /* build the button string */ - if (state & ControlMask) g_string_append(str, "C-"); - if (state & ShiftMask) g_string_append(str, "S-"); - if (state & Mod1Mask) g_string_append(str, "Mod1-"); - if (state & Mod2Mask) g_string_append(str, "Mod2-"); - if (state & Mod3Mask) g_string_append(str, "Mod3-"); - if (state & Mod4Mask) g_string_append(str, "Mod4-"); - if (state & Mod5Mask) g_string_append(str, "Mod5-"); - g_string_append_printf(str, "%d", button); - - /* figure out clicks/double clicks */ - switch (e->type) { - case ButtonRelease: - if (button == e->xbutton.button) { - /* determine if this is a valid 'click'. Its not if the release is - not over the window, or if a drag occured. */ - if (ABS(e->xbutton.x_root - pressx) < drag_threshold && - ABS(e->xbutton.y_root - pressy) < drag_threshold && - e->xbutton.x >= 0 && e->xbutton.y >= 0) { - int junk; - Window wjunk; - guint ujunk, w, h; - XGetGeometry(ob_display, e->xany.window, &wjunk, &junk, &junk, - &w, &h, &ujunk, &ujunk); - if (e->xbutton.x < (signed)w && e->xbutton.y < (signed)h) - click =TRUE; - } - - /* determine if this is a valid 'double-click' */ - if (click) { - if (lastbutton == button && - e->xbutton.time - - configwrap_get_int("input", "double_click_rate") < time) { - dblclick = TRUE; - lastbutton = 0; - } else - lastbutton = button; - } else - lastbutton = 0; - time = e->xbutton.time; - pressx = pressy = 0; - button = 0; - carea.x = carea.y = carea.width = carea.height = 0; - } - break; - } - - /* fire off the events */ - switch (e->type) { - case ButtonPress: - fire_event(str->str, contextq, Action_Press, - state, button, 0, 0, 0, 0, 0, 0, 0, 0, - client, b == NULL ? NULL : b->funcs[Action_Press]); - break; - case ButtonRelease: - fire_event(str->str, contextq, Action_Release, - state, button, 0, 0, 0, 0, 0, 0, 0, 0, - client, b == NULL ? NULL : b->funcs[Action_Release]); - break; - case MotionNotify: - /* watch out for the drag threshold */ - if (ABS(e->xmotion.x_root - pressx) < drag_threshold && - ABS(e->xmotion.y_root - pressy) < drag_threshold) - break; - fire_event(str->str, contextq, Action_Motion, - state, button, e->xmotion.x_root, - e->xmotion.y_root, pressx, pressy, - carea.x, carea.y, carea.width, carea.height, - client, b == NULL ? NULL : b->funcs[Action_Motion]); - break; - } - - if (click) - fire_event(str->str, contextq, Action_Click, - state, button, 0, 0, 0, 0, 0, 0, 0, 0, - client, b == NULL ? NULL : b->funcs[Action_Click]); - if (dblclick) - fire_event(str->str, contextq, Action_DoubleClick, - state, button, 0, 0, 0, 0, 0, 0, 0, 0, - client, b == NULL ? NULL : b->funcs[Action_DoubleClick]); - - g_string_free(str, TRUE); - if (client != Py_None) { Py_DECREF(client); } - - if (contextq == g_quark_try_string("client")) { - /* Replay the event, so it goes to the client*/ - XAllowEvents(ob_display, ReplayPointer, CurrentTime); - /* generate a release event since we don't get real ones */ - if (e->type == ButtonPress) { - e->type = ButtonRelease; - pointer_event(e, c); - } - } -} - -/*************************************************************************** - - Define the type 'Pointer' - - ***************************************************************************/ - -#define IS_POINTER(v) ((v)->ob_type == &PointerType) -#define CHECK_POINTER(self, funcname) { \ - if (!IS_POINTER(self)) { \ - PyErr_SetString(PyExc_TypeError, \ - "descriptor '" funcname "' requires a 'Pointer' " \ - "object"); \ - return NULL; \ - } \ -} - -typedef struct Pointer { - PyObject_HEAD - Action press; - Action release; - Action click; - Action doubleclick; - Action motion; -} Pointer; - -staticforward PyTypeObject PointerType; - -static PyObject *ptr_bind(Pointer *self, PyObject *args) -{ - char *buttonstr; - char *contextstr; - guint state, button; - PointerBinding *b; - GSList *it; - GQuark context; - PyObject *func; - Action action; - int i; - - CHECK_POINTER(self, "grab"); - if (!PyArg_ParseTuple(args, "ssiO:grab", - &buttonstr, &contextstr, &action, &func)) - return NULL; - - if (!translate(buttonstr, &state, &button)) { - PyErr_SetString(PyExc_ValueError, "invalid button"); - return NULL; - } - - context = g_quark_try_string(contextstr); - if (!context) { - PyErr_SetString(PyExc_ValueError, "invalid context"); - return NULL; - } - - if (action < 0 || action >= NUM_ACTIONS) { - PyErr_SetString(PyExc_ValueError, "invalid action"); - return NULL; - } - - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_ValueError, "expected a callable object"); - return NULL; - } - - for (it = g_datalist_id_get_data(&bound_contexts, context); - it != NULL; it = it->next){ - b = it->data; - if (b->state == state && b->button == button) { - /* already bound */ - b->funcs[action] = g_slist_append(b->funcs[action], func); - Py_INCREF(Py_None); - return Py_None; - } - } - - grab_all_clients(FALSE); - - /* add the binding */ - b = g_new(PointerBinding, 1); - b->state = state; - b->button = button; - b->name = g_strdup(buttonstr); - for (i = 0; i < NUM_ACTIONS; ++i) - if (i != (signed)action) b->funcs[i] = NULL; - b->funcs[action] = g_slist_append(NULL, func); - g_datalist_id_set_data(&bound_contexts, context, - g_slist_append(g_datalist_id_get_data(&bound_contexts, context), b)); - grab_all_clients(TRUE); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *ptr_clearBinds(Pointer *self, PyObject *args) -{ - CHECK_POINTER(self, "clearBinds"); - if (!PyArg_ParseTuple(args, ":clearBinds")) - return NULL; - clearall(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *ptr_grab(Pointer *self, PyObject *args) -{ - PyObject *func; - - CHECK_POINTER(self, "grab"); - if (!PyArg_ParseTuple(args, "O:grab", &func)) - return NULL; - if (!PyCallable_Check(func)) { - PyErr_SetString(PyExc_ValueError, "expected a callable object"); - return NULL; - } - if (!grab_pointer(TRUE)) { - PyErr_SetString(PyExc_RuntimeError, "failed to grab pointer"); - return NULL; - } - grab_func = func; - Py_INCREF(grab_func); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject *ptr_ungrab(Pointer *self, PyObject *args) -{ - CHECK_POINTER(self, "ungrab"); - if (!PyArg_ParseTuple(args, ":ungrab")) - return NULL; - grab_pointer(FALSE); - Py_XDECREF(grab_func); - grab_func = NULL; - Py_INCREF(Py_None); - return Py_None; -} - -#define METH(n, d) {#n, (PyCFunction)ptr_##n, METH_VARARGS, #d} - -static PyMethodDef PointerMethods[] = { - METH(bind, - "bind(button, context, func)\n\n" - "Binds a pointer button for a context to a function. See the " - "Terminology section for a decription and list of common contexts. " - "The button is a string which defines a modifier and button " - "combination with the format [Modifier-]...[Button]. Modifiers can " - "be 'mod1', 'mod2', 'mod3', 'mod4', 'mod5', 'control', and 'shift'. " - "The keys on your keyboard that are bound to each of these modifiers " - "can be found by running 'xmodmap'. The button is the number of the " - "button. Button numbers can be found by running 'xev', pressing the " - "button with the pointer over its window, and watching its output. " - "Here are some examples of valid buttons: 'control-1', '2', " - "'mod1-shift-5'. The func must have a definition similar to " - "'def func(keydata, client)'. A button and context may be bound to " - "more than one function."), - METH(clearBinds, - "clearBinds()\n\n" - "Removes all bindings that were previously made by bind()."), - METH(grab, - "grab(func)\n\n" - "Grabs the pointer device, causing all possible pointer events to be " - "sent to the given function. CAUTION: Be sure when you grab() that " - "you also have an ungrab() that will execute, or you will not be " - "able to use the pointer device until you restart Openbox. The func " - "must have a definition similar to 'def func(keydata)'. The pointer " - "cannot be grabbed if it is already grabbed."), - METH(ungrab, - "ungrab()\n\n" - "Ungrabs the pointer. The pointer cannot be ungrabbed if it is not " - "grabbed."), - { NULL, NULL, 0, NULL } -}; - -static PyMemberDef PointerMembers[] = { - {"Action_Press", T_INT, offsetof(Pointer, press), READONLY, - "a pointer button press"}, - {"Action_Release", T_INT, offsetof(Pointer, release), READONLY, - "a pointer button release"}, - {"Action_Click", T_INT, offsetof(Pointer, click), READONLY, - "a pointer button click (press-release)"}, - {"Action_DoubleClick", T_INT, offsetof(Pointer, doubleclick), READONLY, - "a pointer button double-click"}, - {"Action_Motion", T_INT, offsetof(Pointer, motion), READONLY, - "a pointer drag"}, - {NULL} -}; - -/*************************************************************************** - - Type methods/struct - - ***************************************************************************/ - -static void ptr_dealloc(PyObject *self) -{ - PyObject_Del(self); -} - -static PyTypeObject PointerType = { - PyObject_HEAD_INIT(NULL) - 0, - "Pointer", - sizeof(Pointer), - 0, - (destructor) ptr_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -/**************************************************************************/ - -void pointer_startup() -{ - PyObject *input, *inputdict; - Pointer *ptr; - - grabbed = FALSE; - configwrap_add_int("input", "double_click_rate", "Double-Click Rate", - "An integer containing the number of milliseconds in " - "which 2 clicks must be received to cause a " - "double-click event.", 300); - configwrap_add_int("input", "drag_threshold", "Drag Threshold", - "An integer containing the number of pixels a drag " - "must go before motion events start getting generated. " - "Once a drag has begun, the button release will not " - "count as a click event.", 3); - g_datalist_init(&bound_contexts); - - PointerType.ob_type = &PyType_Type; - PointerType.tp_methods = PointerMethods; - PointerType.tp_members = PointerMembers; - PyType_Ready(&PointerType); - PyType_Ready(&PointerDataType); - - /* get the input module/dict */ - input = PyImport_ImportModule("input"); /* new */ - g_assert(input != NULL); - inputdict = PyModule_GetDict(input); /* borrowed */ - g_assert(inputdict != NULL); - - /* add a Pointer instance to the input module */ - ptr = PyObject_New(Pointer, &PointerType); - ptr->press = Action_Press; - ptr->release = Action_Release; - ptr->click = Action_Click; - ptr->doubleclick = Action_DoubleClick; - ptr->motion = Action_Motion; - PyDict_SetItemString(inputdict, "Pointer", (PyObject*) ptr); - Py_DECREF(ptr); - - Py_DECREF(input); -} - -void pointer_shutdown() -{ - if (grabbed) - grab_pointer(FALSE); - clearall(); - g_datalist_clear(&bound_contexts); -} - diff --git a/openbox/pointer.h b/openbox/pointer.h deleted file mode 100644 index 2f068972..00000000 --- a/openbox/pointer.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __pointer_h -#define __pointer_h - -#include "client.h" -#include - -void pointer_startup(); -void pointer_shutdown(); - -void pointer_grab_all(Client *client, gboolean grab); - -void pointer_event(XEvent *e, Client *c); - -#endif diff --git a/plugins/keyboard/keyboard.c b/plugins/keyboard/keyboard.c index 22ea5556..7e2df475 100644 --- a/plugins/keyboard/keyboard.c +++ b/plugins/keyboard/keyboard.c @@ -1,6 +1,7 @@ #include "../../kernel/focus.h" #include "../../kernel/dispatch.h" #include "../../kernel/openbox.h" +#include "../../kernel/event.h" #include "../../kernel/grab.h" #include "../../kernel/action.h" #include "tree.h" @@ -40,7 +41,7 @@ static void reset_chains() grabbed = FALSE; grab_keyboard(FALSE); } else - XAllowEvents(ob_display, AsyncKeyboard, CurrentTime); + XAllowEvents(ob_display, AsyncKeyboard, event_lasttime); } gboolean kbind(GList *keylist, Action *action) @@ -102,7 +103,8 @@ static void press(ObEvent *e, void *foo) if (!grabbed) { grab_keyboard(TRUE); grabbed = TRUE; - XAllowEvents(ob_display, AsyncKeyboard, CurrentTime); + XAllowEvents(ob_display, AsyncKeyboard, + event_lasttime); } curpos = p; } else { diff --git a/plugins/mouse/mouse.c b/plugins/mouse/mouse.c index 0a967205..6165744f 100644 --- a/plugins/mouse/mouse.c +++ b/plugins/mouse/mouse.c @@ -1,6 +1,7 @@ #include "../../kernel/openbox.h" #include "../../kernel/dispatch.h" #include "../../kernel/action.h" +#include "../../kernel/event.h" #include "../../kernel/client.h" #include "../../kernel/frame.h" #include "../../kernel/grab.h" @@ -219,7 +220,7 @@ static void event(ObEvent *e, void *foo) if (context == g_quark_try_string("client")) { /* Replay the event, so it goes to the client*/ - XAllowEvents(ob_display, ReplayPointer, CurrentTime); + XAllowEvents(ob_display, ReplayPointer, event_lasttime); /* Fall through to the release case! */ } else break;