Fix enter/leave events on titlebars

This adds a global variable that tracks the drawable that is currently under the
mouse cursor. This new variable is then used so that we get consistent behavior
for enter/leave signals. Such signals are now also generated when a MotionNotify
event tells us that the pointer is now in a different titlebar.

Before this, it was possible that we did not generate a leave event on a
titlebar since the LeaveNotify contains the cursor position after the leave and
we did not manage to figure out which titlebar was left.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2015-09-17 16:32:56 +02:00 committed by Daniel Hahler
parent 42aea011d2
commit 42e0081958
2 changed files with 47 additions and 18 deletions

63
event.c
View File

@ -411,6 +411,44 @@ event_handle_destroynotify(xcb_destroy_notify_event_t *ev)
} }
} }
/** Record that the given drawable contains the pointer.
*/
static void
event_drawable_under_mouse(lua_State *L, int ud)
{
void *d;
lua_pushvalue(L, ud);
d = luaA_object_ref(L, -1);
if (d == globalconf.drawable_under_mouse)
{
/* Nothing to do */
luaA_object_unref(L, d);
return;
}
if (globalconf.drawable_under_mouse != NULL)
{
/* Emit leave on previous drawable */
luaA_object_push(L, globalconf.drawable_under_mouse);
luaA_object_emit_signal(L, -1, "mouse::leave", 0);
lua_pop(L, 1);
/* Unref the previous drawable */
luaA_object_unref(L, globalconf.drawable_under_mouse);
globalconf.drawable_under_mouse = NULL;
}
if (d != NULL)
{
/* Reference the drawable for leave event later */
globalconf.drawable_under_mouse = d;
/* Emit enter */
luaA_object_emit_signal(L, ud, "mouse::enter", 0);
}
}
/** The motion notify event handler. /** The motion notify event handler.
* \param ev The event. * \param ev The event.
*/ */
@ -439,6 +477,7 @@ event_handle_motionnotify(xcb_motion_notify_event_t *ev)
if (d) if (d)
{ {
luaA_object_push_item(L, -1, d); luaA_object_push_item(L, -1, d);
event_drawable_under_mouse(L, -1);
lua_pushnumber(L, x); lua_pushnumber(L, x);
lua_pushnumber(L, y); lua_pushnumber(L, y);
luaA_object_emit_signal(L, -3, "mouse::move", 2); luaA_object_emit_signal(L, -3, "mouse::move", 2);
@ -451,6 +490,7 @@ event_handle_motionnotify(xcb_motion_notify_event_t *ev)
{ {
luaA_object_push(L, w); luaA_object_push(L, w);
luaA_object_push_item(L, -1, w->drawable); luaA_object_push_item(L, -1, w->drawable);
event_drawable_under_mouse(L, -1);
lua_pushnumber(L, ev->event_x); lua_pushnumber(L, ev->event_x);
lua_pushnumber(L, ev->event_y); lua_pushnumber(L, ev->event_y);
luaA_object_emit_signal(L, -3, "mouse::move", 2); luaA_object_emit_signal(L, -3, "mouse::move", 2);
@ -465,7 +505,6 @@ static void
event_handle_leavenotify(xcb_leave_notify_event_t *ev) event_handle_leavenotify(xcb_leave_notify_event_t *ev)
{ {
lua_State *L = globalconf_get_lua_State(); lua_State *L = globalconf_get_lua_State();
drawin_t *drawin;
client_t *c; client_t *c;
globalconf.timestamp = ev->time; globalconf.timestamp = ev->time;
@ -477,23 +516,11 @@ event_handle_leavenotify(xcb_leave_notify_event_t *ev)
{ {
luaA_object_push(L, c); luaA_object_push(L, c);
luaA_object_emit_signal(L, -1, "mouse::leave", 0); luaA_object_emit_signal(L, -1, "mouse::leave", 0);
drawable_t *d = client_get_drawable(c, ev->event_x, ev->event_y);
if (d)
{
luaA_object_push_item(L, -1, d);
luaA_object_emit_signal(L, -1, "mouse::leave", 0);
lua_pop(L, 1);
}
lua_pop(L, 1);
} }
if((drawin = drawin_getbywin(ev->event))) lua_pushnil(L);
{ event_drawable_under_mouse(L, -1);
luaA_object_push(L, drawin); lua_pop(L, 1);
luaA_object_push_item(L, -1, drawin->drawable);
luaA_object_emit_signal(L, -1, "mouse::leave", 0);
lua_pop(L, 2);
}
} }
/** The enter notify event handler. /** The enter notify event handler.
@ -515,7 +542,7 @@ event_handle_enternotify(xcb_enter_notify_event_t *ev)
{ {
luaA_object_push(L, drawin); luaA_object_push(L, drawin);
luaA_object_push_item(L, -1, drawin->drawable); luaA_object_push_item(L, -1, drawin->drawable);
luaA_object_emit_signal(L, -1, "mouse::enter", 0); event_drawable_under_mouse(L, -1);
lua_pop(L, 2); lua_pop(L, 2);
} }
@ -527,7 +554,7 @@ event_handle_enternotify(xcb_enter_notify_event_t *ev)
if (d) if (d)
{ {
luaA_object_push_item(L, -1, d); luaA_object_push_item(L, -1, d);
luaA_object_emit_signal(L, -1, "mouse::enter", 0); event_drawable_under_mouse(L, -1);
lua_pop(L, 1); lua_pop(L, 1);
} }
lua_pop(L, 1); lua_pop(L, 1);

View File

@ -108,6 +108,8 @@ typedef struct
int keygrabber; int keygrabber;
/** The mouse pointer grabber function */ /** The mouse pointer grabber function */
int mousegrabber; int mousegrabber;
/** The drawable that currently contains the pointer */
drawable_t *drawable_under_mouse;
/** Input focus information */ /** Input focus information */
struct struct
{ {