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:
parent
fc49e28025
commit
ee1fe4dd59
35
event.c
35
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;
|
||||
|
||||
|
|
|
@ -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
41
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;
|
||||
|
|
3
mouse.h
3
mouse.h
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue