diff --git a/include/input/keyboard.h b/include/input/keyboard.h index b5febe6..fd15673 100644 --- a/include/input/keyboard.h +++ b/include/input/keyboard.h @@ -40,5 +40,6 @@ struct kiwmi_keyboard_key_event { struct kiwmi_keyboard * keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device); +void keyboard_destroy(struct kiwmi_keyboard *keyboard); #endif /* KIWMI_INPUT_KEYBOARD_H */ diff --git a/kiwmi/desktop/desktop.c b/kiwmi/desktop/desktop.c index d6dee0b..31ae835 100644 --- a/kiwmi/desktop/desktop.c +++ b/kiwmi/desktop/desktop.c @@ -85,6 +85,7 @@ void desktop_fini(struct kiwmi_desktop *desktop) { wlr_output_layout_destroy(desktop->output_layout); + desktop->output_layout = NULL; } struct kiwmi_output * diff --git a/kiwmi/desktop/output.c b/kiwmi/desktop/output.c index 2464c00..fd60452 100644 --- a/kiwmi/desktop/output.c +++ b/kiwmi/desktop/output.c @@ -264,14 +264,20 @@ output_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) { struct kiwmi_output *output = wl_container_of(listener, output, destroy); - wlr_output_layout_remove( - output->desktop->output_layout, output->wlr_output); + if (output->desktop->output_layout) { + wlr_output_layout_remove( + output->desktop->output_layout, output->wlr_output); + } wl_signal_emit(&output->events.destroy, output); wl_list_remove(&output->link); wl_list_remove(&output->frame.link); + wl_list_remove(&output->commit.link); wl_list_remove(&output->destroy.link); + wl_list_remove(&output->mode.link); + + wl_list_remove(&output->events.destroy.listener_list); free(output); } diff --git a/kiwmi/desktop/xdg_shell.c b/kiwmi/desktop/xdg_shell.c index 7d87785..62bc41d 100644 --- a/kiwmi/desktop/xdg_shell.c +++ b/kiwmi/desktop/xdg_shell.c @@ -250,6 +250,8 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) wl_list_remove(&view->request_move.link); wl_list_remove(&view->request_resize.link); + wl_list_remove(&view->events.unmap.listener_list); + free(view); } diff --git a/kiwmi/input/cursor.c b/kiwmi/input/cursor.c index 6fff8ec..0b9f770 100644 --- a/kiwmi/input/cursor.c +++ b/kiwmi/input/cursor.c @@ -266,11 +266,7 @@ cursor_destroy(struct kiwmi_cursor *cursor) wlr_cursor_destroy(cursor->cursor); wlr_xcursor_manager_destroy(cursor->xcursor_manager); - wl_list_remove(&cursor->cursor_motion.link); - wl_list_remove(&cursor->cursor_motion_absolute.link); - wl_list_remove(&cursor->cursor_button.link); - wl_list_remove(&cursor->cursor_axis.link); - wl_list_remove(&cursor->cursor_frame.link); + // The wlr_cursor is already destroyed, don't unregister listeners free(cursor); } diff --git a/kiwmi/input/input.c b/kiwmi/input/input.c index b3cd3f9..e70159f 100644 --- a/kiwmi/input/input.c +++ b/kiwmi/input/input.c @@ -101,7 +101,7 @@ input_fini(struct kiwmi_input *input) struct kiwmi_keyboard *keyboard; struct kiwmi_keyboard *tmp; wl_list_for_each_safe (keyboard, tmp, &input->keyboards, link) { - free(keyboard); + keyboard_destroy(keyboard); } seat_destroy(input->seat); diff --git a/kiwmi/input/keyboard.c b/kiwmi/input/keyboard.c index e41cfcb..9746b4e 100644 --- a/kiwmi/input/keyboard.c +++ b/kiwmi/input/keyboard.c @@ -116,14 +116,7 @@ keyboard_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) struct kiwmi_keyboard *keyboard = wl_container_of(listener, keyboard, device_destroy); - wl_list_remove(&keyboard->link); - wl_list_remove(&keyboard->modifiers.link); - wl_list_remove(&keyboard->key.link); - wl_list_remove(&keyboard->device_destroy.link); - - wl_signal_emit(&keyboard->events.destroy, keyboard); - - free(keyboard); + keyboard_destroy(keyboard); } struct kiwmi_keyboard * @@ -167,3 +160,19 @@ keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device) return keyboard; } + +void +keyboard_destroy(struct kiwmi_keyboard *keyboard) +{ + wl_list_remove(&keyboard->modifiers.link); + wl_list_remove(&keyboard->key.link); + wl_list_remove(&keyboard->device_destroy.link); + + wl_signal_emit(&keyboard->events.destroy, keyboard); + + wl_list_remove(&keyboard->link); + + wl_list_remove(&keyboard->events.destroy.listener_list); + + free(keyboard); +} diff --git a/kiwmi/luak/luak.c b/kiwmi/luak/luak.c index 3d4945c..f00a407 100644 --- a/kiwmi/luak/luak.c +++ b/kiwmi/luak/luak.c @@ -39,6 +39,15 @@ luaK_toudata(lua_State *L, int ud, const char *tname) return NULL; } +static void +kiwmi_object_destroy(struct kiwmi_object *obj) +{ + wl_list_remove(&obj->destroy.link); + wl_list_remove(&obj->events.destroy.listener_list); + + free(obj); +} + int luaK_kiwmi_object_gc(lua_State *L) { @@ -47,7 +56,7 @@ luaK_kiwmi_object_gc(lua_State *L) --obj->refcount; if (obj->refcount == 0 && wl_list_empty(&obj->callbacks)) { - free(obj); + kiwmi_object_destroy(obj); } return 0; @@ -71,8 +80,6 @@ kiwmi_object_destroy_notify(struct wl_listener *listener, void *data) free(lc); } - wl_list_remove(&obj->destroy.link); - lua_State *L = obj->lua->L; lua_rawgeti(L, LUA_REGISTRYINDEX, obj->lua->objects); @@ -84,7 +91,7 @@ kiwmi_object_destroy_notify(struct wl_listener *listener, void *data) obj->valid = false; if (obj->refcount == 0) { - free(obj); + kiwmi_object_destroy(obj); } } @@ -123,10 +130,12 @@ luaK_get_kiwmi_object( if (destroy) { obj->destroy.notify = kiwmi_object_destroy_notify; wl_signal_add(destroy, &obj->destroy); - - wl_signal_init(&obj->events.destroy); + } else { + wl_list_init(&obj->destroy.link); } + wl_signal_init(&obj->events.destroy); + wl_list_init(&obj->callbacks); lua_rawgeti(L, LUA_REGISTRYINDEX, lua->objects); diff --git a/kiwmi/server.c b/kiwmi/server.c index a361013..924017a 100644 --- a/kiwmi/server.c +++ b/kiwmi/server.c @@ -133,11 +133,12 @@ server_fini(struct kiwmi_server *server) wlr_log(WLR_DEBUG, "Shutting down Wayland server"); wl_display_destroy_clients(server->wl_display); - wl_display_destroy(server->wl_display); desktop_fini(&server->desktop); input_fini(&server->input); + wl_display_destroy(server->wl_display); + luaK_destroy(server->lua); free(server->config_path);