buttons: change grabbing method

We stop grabbing buttons on root windows. We select button press and
release events, and then we check that we have a bindings for them.
This allow to simply grab buttons on client once, and not redo such
things on arrange or mouse-over-window changes.

Most window managers do like this, anyway.

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-02-24 17:32:48 +01:00
parent 5154cfc19f
commit 8745d691fe
7 changed files with 12 additions and 49 deletions

View File

@ -513,7 +513,9 @@ main(int argc, char **argv)
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
| XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW
| XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_PROPERTY_CHANGE, | XCB_EVENT_MASK_PROPERTY_CHANGE
| XCB_EVENT_MASK_BUTTON_PRESS
| XCB_EVENT_MASK_BUTTON_RELEASE,
xcursor_new(globalconf.connection, XC_left_ptr) xcursor_new(globalconf.connection, XC_left_ptr)
}; };

View File

@ -2076,6 +2076,8 @@ luaA_client_buttons(lua_State *L)
if(lua_gettop(L) == 2) if(lua_gettop(L) == 2)
luaA_button_array_set(L, 2, buttons); luaA_button_array_set(L, 2, buttons);
window_buttons_grab((*client)->win, &(*client)->buttons);
return luaA_button_array_get(L, buttons); return luaA_button_array_get(L, buttons);
} }

15
event.c
View File

@ -201,21 +201,22 @@ event_handle_button(void *data, xcb_connection_t *connection, xcb_button_press_e
/* return even if no widget match */ /* return even if no widget match */
return 0; return 0;
} }
else if((c = client_getbywin(ev->event)))
if((c = client_getbywin(ev->event)))
{ {
event_handle_mouse_button(c, ev->response_type, ev->detail, ev->state, &c->buttons); event_handle_mouse_button(c, ev->response_type, ev->detail, ev->state, &c->buttons);
xcb_allow_events(globalconf.connection, xcb_allow_events(globalconf.connection,
XCB_ALLOW_REPLAY_POINTER, XCB_ALLOW_REPLAY_POINTER,
XCB_CURRENT_TIME); XCB_CURRENT_TIME);
} }
else else if(ev->child == XCB_NONE)
{
for(screen = 0; screen < nb_screen; screen++) for(screen = 0; screen < nb_screen; screen++)
if(xutil_screen_get(connection, screen)->root == ev->event) if(xutil_screen_get(connection, screen)->root == ev->event)
{ {
event_handle_mouse_button(NULL, ev->response_type, ev->detail, ev->state, &globalconf.buttons); event_handle_mouse_button(NULL, ev->response_type, ev->detail, ev->state, &globalconf.buttons);
return 0; return 0;
} }
}
return 0; return 0;
} }
@ -498,7 +499,6 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
xcb_enter_notify_event_t *ev) xcb_enter_notify_event_t *ev)
{ {
client_t *c; client_t *c;
xembed_window_t *emwin;
widget_t *w; widget_t *w;
wibox_t *wibox; wibox_t *wibox;
@ -525,7 +525,6 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
else if((c = client_getbytitlebarwin(ev->event)) else if((c = client_getbytitlebarwin(ev->event))
|| (c = client_getbywin(ev->event))) || (c = client_getbywin(ev->event)))
{ {
window_buttons_grab(c->win, ev->root, &c->buttons);
/* The idea behind saving pointer_x and pointer_y is Bob Marley powered. /* The idea behind saving pointer_x and pointer_y is Bob Marley powered.
* this will allow us top drop some EnterNotify events and thus not giving * this will allow us top drop some EnterNotify events and thus not giving
* focus to windows appering under the cursor without a cursor move */ * focus to windows appering under the cursor without a cursor move */
@ -538,12 +537,6 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
luaA_dofunction(globalconf.L, globalconf.hooks.mouse_enter, 1, 0); luaA_dofunction(globalconf.L, globalconf.hooks.mouse_enter, 1, 0);
} }
} }
else if((emwin = xembed_getbywin(&globalconf.embedded, ev->event)))
xcb_ungrab_button(globalconf.connection, XCB_BUTTON_INDEX_ANY,
xutil_screen_get(connection, emwin->phys_screen)->root,
XCB_BUTTON_MASK_ANY);
else if(ev->event == ev->root)
window_root_buttons_grab(ev->root);
return 0; return 0;
} }

View File

@ -63,14 +63,8 @@ arrange(int screen)
xutil_screen_get(globalconf.connection, xutil_screen_get(globalconf.connection,
phys_screen)->root); phys_screen)->root);
/* check that the mouse is on a window or not */
if((qp_r = xcb_query_pointer_reply(globalconf.connection, qp_c, NULL))) if((qp_r = xcb_query_pointer_reply(globalconf.connection, qp_c, NULL)))
{ {
if(qp_r->child == XCB_NONE || qp_r->root == qp_r->child)
window_root_buttons_grab(qp_r->root);
else if ((c = client_getbywin(qp_r->child)))
window_buttons_grab(c->win, qp_r->root, &c->buttons);
globalconf.pointer_x = qp_r->root_x; globalconf.pointer_x = qp_r->root_x;
globalconf.pointer_y = qp_r->root_y; globalconf.pointer_y = qp_r->root_y;

1
luaa.c
View File

@ -49,6 +49,7 @@
#include "event.h" #include "event.h"
#include "mouse.h" #include "mouse.h"
#include "selection.h" #include "selection.h"
#include "window.h"
#include "common/socket.h" #include "common/socket.h"
#include "common/buffer.h" #include "common/buffer.h"

View File

@ -102,11 +102,10 @@ window_configure(xcb_window_t win, area_t geometry, int border)
/** Grab or ungrab buttons on a window. /** Grab or ungrab buttons on a window.
* \param win The window. * \param win The window.
* \param root The root window.
* \param buttons The buttons to grab. * \param buttons The buttons to grab.
*/ */
void void
window_buttons_grab(xcb_window_t win, xcb_window_t root, button_array_t *buttons) window_buttons_grab(xcb_window_t win, button_array_t *buttons)
{ {
for(int i = 0; i < buttons->len; i++) for(int i = 0; i < buttons->len; i++)
{ {
@ -123,33 +122,6 @@ window_buttons_grab(xcb_window_t win, xcb_window_t root, button_array_t *buttons
XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE,
buttons->tab[i]->button, buttons->tab[i]->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK); buttons->tab[i]->button, buttons->tab[i]->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK);
} }
xcb_ungrab_button(globalconf.connection, XCB_BUTTON_INDEX_ANY, root, XCB_BUTTON_MASK_ANY);
}
/** Grab all buttons on the root window.
* \param root The root window.
*/
void
window_root_buttons_grab(xcb_window_t root)
{
button_array_t *barr = &globalconf.buttons;
for(int i = 0; i < barr->len; i++)
{
xcb_grab_button(globalconf.connection, false, root, BUTTONMASK,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC, XCB_NONE, XCB_NONE,
barr->tab[i]->button, barr->tab[i]->mod);
xcb_grab_button(globalconf.connection, false, root, BUTTONMASK,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC, XCB_NONE, XCB_NONE,
barr->tab[i]->button, barr->tab[i]->mod | XCB_MOD_MASK_LOCK);
xcb_grab_button(globalconf.connection, false, root, BUTTONMASK,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC, XCB_NONE, XCB_NONE,
barr->tab[i]->button, barr->tab[i]->mod | globalconf.numlockmask);
xcb_grab_button(globalconf.connection, false, root, BUTTONMASK,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC, XCB_NONE, XCB_NONE,
barr->tab[i]->button, barr->tab[i]->mod | globalconf.numlockmask | XCB_MOD_MASK_LOCK);
}
} }
/** Get the opacity of a window. /** Get the opacity of a window.

View File

@ -28,8 +28,7 @@ void window_state_set(xcb_window_t, long);
xcb_get_property_cookie_t window_state_get_unchecked(xcb_window_t); xcb_get_property_cookie_t window_state_get_unchecked(xcb_window_t);
long window_state_get_reply(xcb_get_property_cookie_t); long window_state_get_reply(xcb_get_property_cookie_t);
void window_configure(xcb_window_t, area_t, int); void window_configure(xcb_window_t, area_t, int);
void window_buttons_grab(xcb_window_t, xcb_window_t, button_array_t *); void window_buttons_grab(xcb_window_t, button_array_t *);
void window_root_buttons_grab(xcb_window_t);
double window_opacity_get(xcb_window_t); double window_opacity_get(xcb_window_t);
void window_opacity_set(xcb_window_t, double); void window_opacity_set(xcb_window_t, double);
void window_grabbuttons(xcb_window_t, xcb_window_t, button_array_t *); void window_grabbuttons(xcb_window_t, xcb_window_t, button_array_t *);