diff --git a/event.c b/event.c index 6c1eff06c..f0f8c5450 100644 --- a/event.c +++ b/event.c @@ -113,7 +113,7 @@ event_handle_mousegrabber(int x, int y, uint16_t mask) if(globalconf.mousegrabber != LUA_REFNIL) { lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, globalconf.mousegrabber); - luaA_mouse_pushstatus(globalconf.L, x, y); + mousegrabber_handleevent(globalconf.L, x, y, mask); if(lua_pcall(globalconf.L, 1, 1, 0)) { warn("error running function: %s", lua_tostring(globalconf.L, -1)); @@ -156,37 +156,6 @@ event_emit_button(xcb_button_press_event_t *ev) luaA_object_emit_signal(globalconf.L, -5, name, 4); } -/** Update the global button state - * \param response_type XCB_BUTTON_PRESS or XCB_BUTTON_RELEASE - * \param button Button being changed - */ -static void -event_update_button_state(uint8_t response_type, uint8_t button) -{ - /* There is no button 0! */ - const unsigned int max_button = sizeof(globalconf.buttons_pressed) * 8; - uint32_t mask = 1 << (button - 1); - - if (button > max_button) { - warn("Button %d pressed, but we only support %d buttons", button, max_button); - return; - } - - switch(response_type & XCB_EVENT_RESPONSE_TYPE_MASK) - { - case XCB_BUTTON_PRESS: - /* Set the (button-1)-st bit */ - globalconf.buttons_pressed |= mask; - break; - case XCB_BUTTON_RELEASE: - /* Clear the (button-1)-st bit */ - globalconf.buttons_pressed &= ~mask; - break; - default: - fatal("Invalid event type"); - } -} - /** The button press event handler. * \param ev The event. */ @@ -198,8 +167,6 @@ event_handle_button(xcb_button_press_event_t *ev) globalconf.timestamp = ev->time; - event_update_button_state(ev->response_type, ev->detail); - if(event_handle_mousegrabber(ev->root_x, ev->root_y, 1 << (ev->detail - 1 + 8))) return; diff --git a/globalconf.h b/globalconf.h index 0a756a50f..7c725a82b 100644 --- a/globalconf.h +++ b/globalconf.h @@ -80,8 +80,6 @@ typedef struct button_array_t buttons; /** Modifiers masks */ uint16_t numlockmask, shiftlockmask, capslockmask, modeswitchmask; - /** Bitmask for currently pressed buttons */ - uint32_t buttons_pressed; /** Check for XTest extension */ bool have_xtest; /** Clients list */ diff --git a/mouse.c b/mouse.c index 5e2cbbef1..8d3785345 100644 --- a/mouse.c +++ b/mouse.c @@ -32,10 +32,11 @@ * \param x will be set to the Pointer-x-coordinate relative to window * \param y will be set to the Pointer-y-coordinate relative to window * \param child Will be set to the window under the pointer. + * \param mask will be set to the current buttons state * \return true on success, false if an error occurred **/ -static bool -mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child) +bool +mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask) { xcb_query_pointer_cookie_t query_ptr_c; xcb_query_pointer_reply_t *query_ptr_r; @@ -49,6 +50,8 @@ mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *c *x = query_ptr_r->win_x; *y = query_ptr_r->win_y; + if(mask) + *mask = query_ptr_r->mask; if(child) *child = query_ptr_r->child; @@ -64,10 +67,12 @@ mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *c * \param mask This will be set to the current buttons state. * \return True on success, false if an error occurred. */ -static inline bool -mouse_query_pointer_root(int16_t *x, int16_t *y, xcb_window_t *child) +static bool +mouse_query_pointer_root(int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask) { - return mouse_query_pointer(globalconf.screen->root, x, y, child); + xcb_window_t root = globalconf.screen->root; + + return mouse_query_pointer(root, x, y, child, mask); } /** Set the pointer position. @@ -100,7 +105,7 @@ luaA_mouse_index(lua_State *L) if (A_STRNEQ(attr, "screen")) return 0; - if (!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL)) + if (!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, NULL)) return 0; screen = screen_getbycoord(mouse_x, mouse_y); @@ -139,7 +144,7 @@ luaA_mouse_newindex(lua_State *L) * \param mask The button mask. */ int -luaA_mouse_pushstatus(lua_State *L, int x, int y) +luaA_mouse_pushstatus(lua_State *L, int x, int y, uint16_t mask) { lua_createtable(L, 0, 2); lua_pushnumber(L, x); @@ -149,12 +154,15 @@ luaA_mouse_pushstatus(lua_State *L, int x, int y) lua_createtable(L, 5, 0); - const unsigned int max_button = sizeof(globalconf.buttons_pressed) * 8; - unsigned int mask = 1; - for (unsigned int i = 1; i <= max_button; i++, mask <<= 1) + int i = 1; + + for(uint16_t maski = XCB_BUTTON_MASK_1; maski <= XCB_BUTTON_MASK_5; maski <<= 1) { - lua_pushboolean(L, globalconf.buttons_pressed & mask); - lua_rawseti(L, -2, i); + if(mask & maski) + lua_pushboolean(L, true); + else + lua_pushboolean(L, false); + lua_rawseti(L, -2, i++); } lua_setfield(L, -2, "buttons"); return 1; @@ -167,6 +175,7 @@ luaA_mouse_pushstatus(lua_State *L, int x, int y) static int luaA_mouse_coords(lua_State *L) { + uint16_t mask; int x, y; int16_t mouse_x, mouse_y; @@ -175,7 +184,7 @@ luaA_mouse_coords(lua_State *L) luaA_checktable(L, 1); bool ignore_enter_notify = (lua_gettop(L) == 2 && luaA_checkboolean(L, 2)); - if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL)) + if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask)) return 0; x = luaA_getopt_number(L, 1, "x", mouse_x); @@ -192,10 +201,10 @@ luaA_mouse_coords(lua_State *L) lua_pop(L, 1); } - if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL)) + if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask)) return 0; - return luaA_mouse_pushstatus(L, mouse_x, mouse_y); + return luaA_mouse_pushstatus(L, mouse_x, mouse_y, mask); } /** Get the client which is under the pointer. @@ -210,7 +219,7 @@ luaA_mouse_object_under_pointer(lua_State *L) int16_t mouse_x, mouse_y; xcb_window_t child; - if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child)) + if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child, NULL)) return 0; drawin_t *drawin; diff --git a/mouse.h b/mouse.h index 99501b7c3..a36848c9a 100644 --- a/mouse.h +++ b/mouse.h @@ -26,7 +26,8 @@ #include #include -int luaA_mouse_pushstatus(lua_State *, int, int); +bool mouse_query_pointer(xcb_window_t, int16_t *, int16_t *, xcb_window_t *, uint16_t *); +int luaA_mouse_pushstatus(lua_State *, int, int, uint16_t); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/mousegrabber.c b/mousegrabber.c index c38132264..98f14ea36 100644 --- a/mousegrabber.c +++ b/mousegrabber.c @@ -59,6 +59,18 @@ mousegrabber_grab(xcb_cursor_t cursor) return false; } +/** Handle mouse motion events. + * \param L Lua stack to push the pointer motion. + * \param x The received mouse event x component. + * \param y The received mouse event y component. + * \param mask The received mouse event bit mask. + */ +void +mousegrabber_handleevent(lua_State *L, int x, int y, uint16_t mask) +{ + luaA_mouse_pushstatus(L, x, y, mask); +} + /** Grab the mouse pointer and list motions, calling callback function at each * motion. The callback function must return a boolean value: true to * continue grabbing, false to stop. diff --git a/mousegrabber.h b/mousegrabber.h index 988d267a7..42a9fb00d 100644 --- a/mousegrabber.h +++ b/mousegrabber.h @@ -26,6 +26,7 @@ #include int luaA_mousegrabber_stop(lua_State *); +void mousegrabber_handleevent(lua_State *, int, int, uint16_t); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80