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:
parent
42aea011d2
commit
42e0081958
63
event.c
63
event.c
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue