diff --git a/event.c b/event.c index a97d7891..370d9ae0 100644 --- a/event.c +++ b/event.c @@ -358,11 +358,19 @@ event_handle_widget_motionnotify(void *object, luaA_object_push(globalconf.L, *mouse_over); luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0); lua_pop(globalconf.L, 1); + + luaA_object_unref(globalconf.L, *mouse_over); + *mouse_over = NULL; } if(widget) { - /* emit mouse::enter signal on new widget and register it */ + /* Get a ref on this widget so that it can't be unref'd from + * underneath us (-> invalid pointer dereference). */ + luaA_object_push(globalconf.L, widget); + luaA_object_ref(globalconf.L, -1); *mouse_over = widget; + + /* emit mouse::enter signal on new widget */ luaA_object_push(globalconf.L, widget); luaA_object_emit_signal(globalconf.L, -1, "mouse::enter", 0); lua_pop(globalconf.L, 1); @@ -429,7 +437,7 @@ event_handle_leavenotify(void *data __attribute__ ((unused)), /* emit mouse::leave signal on widget the mouse was over */ luaA_object_emit_signal(globalconf.L, -1, "mouse::leave", 0); lua_pop(globalconf.L, 1); - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); } luaA_object_push(globalconf.L, wibox); diff --git a/objects/wibox.c b/objects/wibox.c index 88e8c46b..b3a06cbe 100644 --- a/objects/wibox.c +++ b/objects/wibox.c @@ -86,7 +86,7 @@ static void wibox_need_update(wibox_t *wibox) { wibox->need_update = true; - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); } static int @@ -631,6 +631,19 @@ wibox_refresh(void) } } +/** Clear the wibox' mouse_over pointer. + * \param wibox The wibox. + */ +void +wibox_clear_mouse_over(wibox_t *wibox) +{ + if (wibox->mouse_over) + { + luaA_object_unref(globalconf.L, wibox->mouse_over); + wibox->mouse_over = NULL; + } +} + /** Set a wibox visible or not. * \param L The Lua VM state. * \param udx The wibox. @@ -643,7 +656,7 @@ wibox_set_visible(lua_State *L, int udx, bool v) if(v != wibox->visible) { wibox->visible = v; - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); if(wibox->screen) { @@ -686,7 +699,7 @@ wibox_detach(lua_State *L, int udx) /* restore visibility */ wibox->visible = v; - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); wibox_wipe(wibox); diff --git a/objects/wibox.h b/objects/wibox.h index 37a80b38..6ebd2960 100644 --- a/objects/wibox.h +++ b/objects/wibox.h @@ -99,5 +99,7 @@ void wibox_class_setup(lua_State *); lua_class_t wibox_class; +void wibox_clear_mouse_over(wibox_t *); + #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80