Revert "Support more than 5 mouse buttons" (FS#1082)

This reverts commit bd8158495e.

The idea was to track the current list of pressed and depressed mouse buttons,
because we get button events for more than 5 buttons, but can only query the
state of the first 5 buttons.

However, there are cases where we see button presses, but won't see the
corresponding release event. This is quite bad.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2013-03-29 16:07:13 +01:00
parent fc49e28025
commit ee1fe4dd59
6 changed files with 41 additions and 53 deletions

35
event.c
View File

@ -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;

View File

@ -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 */

41
mouse.c
View File

@ -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;

View File

@ -26,7 +26,8 @@
#include <xcb/xcb.h>
#include <lua.h>
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

View File

@ -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.

View File

@ -26,6 +26,7 @@
#include <xcb/xcb.h>
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