Browse Source

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>
Uli Schlachter 6 years ago
parent
commit
ee1fe4dd59
6 changed files with 41 additions and 53 deletions
  1. 1
    34
      event.c
  2. 0
    2
      globalconf.h
  3. 25
    16
      mouse.c
  4. 2
    1
      mouse.h
  5. 12
    0
      mousegrabber.c
  6. 1
    0
      mousegrabber.h

+ 1
- 34
event.c View File

@@ -113,7 +113,7 @@ event_handle_mousegrabber(int x, int y, uint16_t mask)
113 113
     if(globalconf.mousegrabber != LUA_REFNIL)
114 114
     {
115 115
         lua_rawgeti(globalconf.L, LUA_REGISTRYINDEX, globalconf.mousegrabber);
116
-        luaA_mouse_pushstatus(globalconf.L, x, y);
116
+        mousegrabber_handleevent(globalconf.L, x, y, mask);
117 117
         if(lua_pcall(globalconf.L, 1, 1, 0))
118 118
         {
119 119
             warn("error running function: %s", lua_tostring(globalconf.L, -1));
@@ -156,37 +156,6 @@ event_emit_button(xcb_button_press_event_t *ev)
156 156
     luaA_object_emit_signal(globalconf.L, -5, name, 4);
157 157
 }
158 158
 
159
-/** Update the global button state
160
- * \param response_type XCB_BUTTON_PRESS or XCB_BUTTON_RELEASE
161
- * \param button Button being changed
162
- */
163
-static void
164
-event_update_button_state(uint8_t response_type, uint8_t button)
165
-{
166
-    /* There is no button 0! */
167
-    const unsigned int max_button = sizeof(globalconf.buttons_pressed) * 8;
168
-    uint32_t mask = 1 << (button - 1);
169
-
170
-    if (button > max_button) {
171
-        warn("Button %d pressed, but we only support %d buttons", button, max_button);
172
-        return;
173
-    }
174
-
175
-    switch(response_type & XCB_EVENT_RESPONSE_TYPE_MASK)
176
-    {
177
-    case XCB_BUTTON_PRESS:
178
-        /* Set the (button-1)-st bit */
179
-        globalconf.buttons_pressed |= mask;
180
-        break;
181
-    case XCB_BUTTON_RELEASE:
182
-        /* Clear the (button-1)-st bit */
183
-        globalconf.buttons_pressed &= ~mask;
184
-        break;
185
-    default:
186
-        fatal("Invalid event type");
187
-    }
188
-}
189
-
190 159
 /** The button press event handler.
191 160
  * \param ev The event.
192 161
  */
@@ -198,8 +167,6 @@ event_handle_button(xcb_button_press_event_t *ev)
198 167
 
199 168
     globalconf.timestamp = ev->time;
200 169
 
201
-    event_update_button_state(ev->response_type, ev->detail);
202
-
203 170
     if(event_handle_mousegrabber(ev->root_x, ev->root_y, 1 << (ev->detail - 1 + 8)))
204 171
         return;
205 172
 

+ 0
- 2
globalconf.h View File

@@ -80,8 +80,6 @@ typedef struct
80 80
     button_array_t buttons;
81 81
     /** Modifiers masks */
82 82
     uint16_t numlockmask, shiftlockmask, capslockmask, modeswitchmask;
83
-    /** Bitmask for currently pressed buttons */
84
-    uint32_t buttons_pressed;
85 83
     /** Check for XTest extension */
86 84
     bool have_xtest;
87 85
     /** Clients list */

+ 25
- 16
mouse.c View File

@@ -32,10 +32,11 @@
32 32
  * \param x will be set to the Pointer-x-coordinate relative to window
33 33
  * \param y will be set to the Pointer-y-coordinate relative to window
34 34
  * \param child Will be set to the window under the pointer.
35
+ * \param mask will be set to the current buttons state
35 36
  * \return true on success, false if an error occurred
36 37
  **/
37
-static bool
38
-mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child)
38
+bool
39
+mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask)
39 40
 {
40 41
     xcb_query_pointer_cookie_t query_ptr_c;
41 42
     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
49 50
     *x = query_ptr_r->win_x;
50 51
     *y = query_ptr_r->win_y;
51 52
 
53
+    if(mask)
54
+        *mask = query_ptr_r->mask;
52 55
     if(child)
53 56
         *child = query_ptr_r->child;
54 57
 
@@ -64,10 +67,12 @@ mouse_query_pointer(xcb_window_t window, int16_t *x, int16_t *y, xcb_window_t *c
64 67
  * \param mask This will be set to the current buttons state.
65 68
  * \return True on success, false if an error occurred.
66 69
  */
67
-static inline bool
68
-mouse_query_pointer_root(int16_t *x, int16_t *y, xcb_window_t *child)
70
+static bool
71
+mouse_query_pointer_root(int16_t *x, int16_t *y, xcb_window_t *child, uint16_t *mask)
69 72
 {
70
-    return mouse_query_pointer(globalconf.screen->root, x, y, child);
73
+    xcb_window_t root = globalconf.screen->root;
74
+
75
+    return mouse_query_pointer(root, x, y, child, mask);
71 76
 }
72 77
 
73 78
 /** Set the pointer position.
@@ -100,7 +105,7 @@ luaA_mouse_index(lua_State *L)
100 105
     if (A_STRNEQ(attr, "screen"))
101 106
         return 0;
102 107
 
103
-    if (!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL))
108
+    if (!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, NULL))
104 109
         return 0;
105 110
 
106 111
     screen = screen_getbycoord(mouse_x, mouse_y);
@@ -139,7 +144,7 @@ luaA_mouse_newindex(lua_State *L)
139 144
  * \param mask The button mask.
140 145
  */
141 146
 int
142
-luaA_mouse_pushstatus(lua_State *L, int x, int y)
147
+luaA_mouse_pushstatus(lua_State *L, int x, int y, uint16_t mask)
143 148
 {
144 149
     lua_createtable(L, 0, 2);
145 150
     lua_pushnumber(L, x);
@@ -149,12 +154,15 @@ luaA_mouse_pushstatus(lua_State *L, int x, int y)
149 154
 
150 155
     lua_createtable(L, 5, 0);
151 156
 
152
-    const unsigned int max_button = sizeof(globalconf.buttons_pressed) * 8;
153
-    unsigned int mask = 1;
154
-    for (unsigned int i = 1; i <= max_button; i++, mask <<= 1)
157
+    int i = 1;
158
+
159
+    for(uint16_t maski = XCB_BUTTON_MASK_1; maski <= XCB_BUTTON_MASK_5; maski <<= 1)
155 160
     {
156
-        lua_pushboolean(L, globalconf.buttons_pressed & mask);
157
-        lua_rawseti(L, -2, i);
161
+        if(mask & maski)
162
+            lua_pushboolean(L, true);
163
+        else
164
+            lua_pushboolean(L, false);
165
+        lua_rawseti(L, -2, i++);
158 166
     }
159 167
     lua_setfield(L, -2, "buttons");
160 168
     return 1;
@@ -167,6 +175,7 @@ luaA_mouse_pushstatus(lua_State *L, int x, int y)
167 175
 static int
168 176
 luaA_mouse_coords(lua_State *L)
169 177
 {
178
+    uint16_t mask;
170 179
     int x, y;
171 180
     int16_t mouse_x, mouse_y;
172 181
 
@@ -175,7 +184,7 @@ luaA_mouse_coords(lua_State *L)
175 184
         luaA_checktable(L, 1);
176 185
         bool ignore_enter_notify = (lua_gettop(L) == 2 && luaA_checkboolean(L, 2));
177 186
 
178
-        if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL))
187
+        if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask))
179 188
             return 0;
180 189
 
181 190
         x = luaA_getopt_number(L, 1, "x", mouse_x);
@@ -192,10 +201,10 @@ luaA_mouse_coords(lua_State *L)
192 201
         lua_pop(L, 1);
193 202
     }
194 203
 
195
-    if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL))
204
+    if(!mouse_query_pointer_root(&mouse_x, &mouse_y, NULL, &mask))
196 205
         return 0;
197 206
 
198
-    return luaA_mouse_pushstatus(L, mouse_x, mouse_y);
207
+    return luaA_mouse_pushstatus(L, mouse_x, mouse_y, mask);
199 208
 }
200 209
 
201 210
 /** Get the client which is under the pointer.
@@ -210,7 +219,7 @@ luaA_mouse_object_under_pointer(lua_State *L)
210 219
     int16_t mouse_x, mouse_y;
211 220
     xcb_window_t child;
212 221
 
213
-    if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child))
222
+    if(!mouse_query_pointer_root(&mouse_x, &mouse_y, &child, NULL))
214 223
         return 0;
215 224
 
216 225
     drawin_t *drawin;

+ 2
- 1
mouse.h View File

@@ -26,7 +26,8 @@
26 26
 #include <xcb/xcb.h>
27 27
 #include <lua.h>
28 28
 
29
-int luaA_mouse_pushstatus(lua_State *, int, int);
29
+bool mouse_query_pointer(xcb_window_t, int16_t *, int16_t *, xcb_window_t *, uint16_t *);
30
+int luaA_mouse_pushstatus(lua_State *, int, int, uint16_t);
30 31
 
31 32
 #endif
32 33
 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

+ 12
- 0
mousegrabber.c View File

@@ -59,6 +59,18 @@ mousegrabber_grab(xcb_cursor_t cursor)
59 59
     return false;
60 60
 }
61 61
 
62
+/** Handle mouse motion events.
63
+ * \param L Lua stack to push the pointer motion.
64
+ * \param x The received mouse event x component.
65
+ * \param y The received mouse event y component.
66
+ * \param mask The received mouse event bit mask.
67
+ */
68
+void
69
+mousegrabber_handleevent(lua_State *L, int x, int y, uint16_t mask)
70
+{
71
+    luaA_mouse_pushstatus(L, x, y, mask);
72
+}
73
+
62 74
 /** Grab the mouse pointer and list motions, calling callback function at each
63 75
  * motion. The callback function must return a boolean value: true to
64 76
  * continue grabbing, false to stop.

+ 1
- 0
mousegrabber.h View File

@@ -26,6 +26,7 @@
26 26
 #include <xcb/xcb.h>
27 27
 
28 28
 int luaA_mousegrabber_stop(lua_State *);
29
+void mousegrabber_handleevent(lua_State *, int, int, uint16_t);
29 30
 
30 31
 #endif
31 32
 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

Loading…
Cancel
Save