diff --git a/event.c b/event.c index 8ba4f04e4..1917f6535 100644 --- a/event.c +++ b/event.c @@ -359,11 +359,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); @@ -435,7 +443,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/wibox.c b/wibox.c index 88a2396a9..689c81f2f 100644 --- a/wibox.c +++ b/wibox.c @@ -59,7 +59,7 @@ static void wibox_need_update(wibox_t *wibox) { wibox->need_update = true; - wibox->mouse_over = NULL; + wibox_clear_mouse_over(wibox); } static int @@ -619,6 +619,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. @@ -631,7 +644,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) { @@ -704,7 +717,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/wibox.h b/wibox.h index fe7050a96..f642ac663 100644 --- a/wibox.h +++ b/wibox.h @@ -117,5 +117,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