Attempt to exit cleanly, without crash (#51)

This commit is contained in:
tiosgz 2021-12-04 17:25:31 +00:00 committed by GitHub
parent ed1ff87494
commit 53684f0e79
13 changed files with 71 additions and 26 deletions

View file

@ -43,6 +43,7 @@ struct kiwmi_cursor {
struct { struct {
struct wl_signal button_down; struct wl_signal button_down;
struct wl_signal button_up; struct wl_signal button_up;
struct wl_signal destroy;
struct wl_signal motion; struct wl_signal motion;
struct wl_signal scroll; struct wl_signal scroll;
} events; } events;

View file

@ -40,5 +40,6 @@ struct kiwmi_keyboard_key_event {
struct kiwmi_keyboard * struct kiwmi_keyboard *
keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device); keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device);
void keyboard_destroy(struct kiwmi_keyboard *keyboard);
#endif /* KIWMI_INPUT_KEYBOARD_H */ #endif /* KIWMI_INPUT_KEYBOARD_H */

View file

@ -22,6 +22,10 @@ struct kiwmi_server {
struct kiwmi_lua *lua; struct kiwmi_lua *lua;
struct kiwmi_desktop desktop; struct kiwmi_desktop desktop;
struct kiwmi_input input; struct kiwmi_input input;
struct {
struct wl_signal destroy;
} events;
}; };
bool server_init(struct kiwmi_server *server, char *config_path); bool server_init(struct kiwmi_server *server, char *config_path);

View file

@ -85,6 +85,7 @@ void
desktop_fini(struct kiwmi_desktop *desktop) desktop_fini(struct kiwmi_desktop *desktop)
{ {
wlr_output_layout_destroy(desktop->output_layout); wlr_output_layout_destroy(desktop->output_layout);
desktop->output_layout = NULL;
} }
struct kiwmi_output * struct kiwmi_output *

View file

@ -264,14 +264,20 @@ output_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
{ {
struct kiwmi_output *output = wl_container_of(listener, output, destroy); struct kiwmi_output *output = wl_container_of(listener, output, destroy);
if (output->desktop->output_layout) {
wlr_output_layout_remove( wlr_output_layout_remove(
output->desktop->output_layout, output->wlr_output); output->desktop->output_layout, output->wlr_output);
}
wl_signal_emit(&output->events.destroy, output); wl_signal_emit(&output->events.destroy, output);
wl_list_remove(&output->link); wl_list_remove(&output->link);
wl_list_remove(&output->frame.link); wl_list_remove(&output->frame.link);
wl_list_remove(&output->commit.link);
wl_list_remove(&output->destroy.link); wl_list_remove(&output->destroy.link);
wl_list_remove(&output->mode.link);
wl_list_remove(&output->events.destroy.listener_list);
free(output); free(output);
} }

View file

@ -239,6 +239,10 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
view_child_destroy(child); view_child_destroy(child);
} }
if (view->decoration) {
view->decoration->view = NULL;
}
wl_list_remove(&view->link); wl_list_remove(&view->link);
wl_list_remove(&view->children); wl_list_remove(&view->children);
wl_list_remove(&view->map.link); wl_list_remove(&view->map.link);
@ -250,6 +254,8 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
wl_list_remove(&view->request_move.link); wl_list_remove(&view->request_move.link);
wl_list_remove(&view->request_resize.link); wl_list_remove(&view->request_resize.link);
wl_list_remove(&view->events.unmap.listener_list);
free(view); free(view);
} }
@ -509,7 +515,9 @@ xdg_decoration_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
struct kiwmi_xdg_decoration *decoration = struct kiwmi_xdg_decoration *decoration =
wl_container_of(listener, decoration, destroy); wl_container_of(listener, decoration, destroy);
if (decoration->view) {
decoration->view->decoration = NULL; decoration->view->decoration = NULL;
}
wl_list_remove(&decoration->destroy.link); wl_list_remove(&decoration->destroy.link);
wl_list_remove(&decoration->request_mode.link); wl_list_remove(&decoration->request_mode.link);

View file

@ -254,6 +254,7 @@ cursor_create(
wl_signal_init(&cursor->events.button_down); wl_signal_init(&cursor->events.button_down);
wl_signal_init(&cursor->events.button_up); wl_signal_init(&cursor->events.button_up);
wl_signal_init(&cursor->events.destroy);
wl_signal_init(&cursor->events.motion); wl_signal_init(&cursor->events.motion);
wl_signal_init(&cursor->events.scroll); wl_signal_init(&cursor->events.scroll);
@ -263,14 +264,12 @@ cursor_create(
void void
cursor_destroy(struct kiwmi_cursor *cursor) cursor_destroy(struct kiwmi_cursor *cursor)
{ {
wl_signal_emit(&cursor->events.destroy, cursor);
wlr_cursor_destroy(cursor->cursor); wlr_cursor_destroy(cursor->cursor);
wlr_xcursor_manager_destroy(cursor->xcursor_manager); wlr_xcursor_manager_destroy(cursor->xcursor_manager);
wl_list_remove(&cursor->cursor_motion.link); // The wlr_cursor is already destroyed, don't unregister listeners
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);
free(cursor); free(cursor);
} }

View file

@ -101,7 +101,7 @@ input_fini(struct kiwmi_input *input)
struct kiwmi_keyboard *keyboard; struct kiwmi_keyboard *keyboard;
struct kiwmi_keyboard *tmp; struct kiwmi_keyboard *tmp;
wl_list_for_each_safe (keyboard, tmp, &input->keyboards, link) { wl_list_for_each_safe (keyboard, tmp, &input->keyboards, link) {
free(keyboard); keyboard_destroy(keyboard);
} }
seat_destroy(input->seat); seat_destroy(input->seat);

View file

@ -116,14 +116,7 @@ keyboard_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
struct kiwmi_keyboard *keyboard = struct kiwmi_keyboard *keyboard =
wl_container_of(listener, keyboard, device_destroy); wl_container_of(listener, keyboard, device_destroy);
wl_list_remove(&keyboard->link); keyboard_destroy(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);
free(keyboard);
} }
struct kiwmi_keyboard * struct kiwmi_keyboard *
@ -167,3 +160,19 @@ keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device)
return keyboard; 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);
}

View file

@ -309,7 +309,8 @@ luaK_kiwmi_cursor_new(lua_State *L)
struct kiwmi_lua *lua = lua_touserdata(L, 1); struct kiwmi_lua *lua = lua_touserdata(L, 1);
struct kiwmi_cursor *cursor = lua_touserdata(L, 2); struct kiwmi_cursor *cursor = lua_touserdata(L, 2);
struct kiwmi_object *obj = luaK_get_kiwmi_object(lua, cursor, NULL); struct kiwmi_object *obj =
luaK_get_kiwmi_object(lua, cursor, &cursor->events.destroy);
struct kiwmi_object **cursor_ud = lua_newuserdata(L, sizeof(*cursor_ud)); struct kiwmi_object **cursor_ud = lua_newuserdata(L, sizeof(*cursor_ud));
luaL_getmetatable(L, "kiwmi_cursor"); luaL_getmetatable(L, "kiwmi_cursor");

View file

@ -574,7 +574,8 @@ luaK_kiwmi_server_new(lua_State *L)
struct kiwmi_lua *lua = lua_touserdata(L, 1); struct kiwmi_lua *lua = lua_touserdata(L, 1);
struct kiwmi_server *server = lua_touserdata(L, 2); struct kiwmi_server *server = lua_touserdata(L, 2);
struct kiwmi_object *obj = luaK_get_kiwmi_object(lua, server, NULL); struct kiwmi_object *obj =
luaK_get_kiwmi_object(lua, server, &server->events.destroy);
struct kiwmi_object **server_ud = lua_newuserdata(L, sizeof(*server_ud)); struct kiwmi_object **server_ud = lua_newuserdata(L, sizeof(*server_ud));
luaL_getmetatable(L, "kiwmi_server"); luaL_getmetatable(L, "kiwmi_server");

View file

@ -39,6 +39,15 @@ luaK_toudata(lua_State *L, int ud, const char *tname)
return NULL; 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 int
luaK_kiwmi_object_gc(lua_State *L) luaK_kiwmi_object_gc(lua_State *L)
{ {
@ -47,7 +56,7 @@ luaK_kiwmi_object_gc(lua_State *L)
--obj->refcount; --obj->refcount;
if (obj->refcount == 0 && wl_list_empty(&obj->callbacks)) { if (obj->refcount == 0 && wl_list_empty(&obj->callbacks)) {
free(obj); kiwmi_object_destroy(obj);
} }
return 0; return 0;
@ -71,8 +80,6 @@ kiwmi_object_destroy_notify(struct wl_listener *listener, void *data)
free(lc); free(lc);
} }
wl_list_remove(&obj->destroy.link);
lua_State *L = obj->lua->L; lua_State *L = obj->lua->L;
lua_rawgeti(L, LUA_REGISTRYINDEX, obj->lua->objects); 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; obj->valid = false;
if (obj->refcount == 0) { if (obj->refcount == 0) {
free(obj); kiwmi_object_destroy(obj);
} }
} }
@ -123,9 +130,11 @@ luaK_get_kiwmi_object(
if (destroy) { if (destroy) {
obj->destroy.notify = kiwmi_object_destroy_notify; obj->destroy.notify = kiwmi_object_destroy_notify;
wl_signal_add(destroy, &obj->destroy); wl_signal_add(destroy, &obj->destroy);
} else {
wl_list_init(&obj->destroy.link);
}
wl_signal_init(&obj->events.destroy); wl_signal_init(&obj->events.destroy);
}
wl_list_init(&obj->callbacks); wl_list_init(&obj->callbacks);

View file

@ -46,6 +46,8 @@ server_init(struct kiwmi_server *server, char *config_path)
struct wlr_renderer *renderer = wlr_backend_get_renderer(server->backend); struct wlr_renderer *renderer = wlr_backend_get_renderer(server->backend);
wlr_renderer_init_wl_display(renderer, server->wl_display); wlr_renderer_init_wl_display(renderer, server->wl_display);
wl_signal_init(&server->events.destroy);
if (!desktop_init(&server->desktop, renderer)) { if (!desktop_init(&server->desktop, renderer)) {
wlr_log(WLR_ERROR, "Failed to initialize desktop"); wlr_log(WLR_ERROR, "Failed to initialize desktop");
wl_display_destroy(server->wl_display); wl_display_destroy(server->wl_display);
@ -132,12 +134,15 @@ server_fini(struct kiwmi_server *server)
{ {
wlr_log(WLR_DEBUG, "Shutting down Wayland server"); wlr_log(WLR_DEBUG, "Shutting down Wayland server");
wl_signal_emit(&server->events.destroy, server);
wl_display_destroy_clients(server->wl_display); wl_display_destroy_clients(server->wl_display);
wl_display_destroy(server->wl_display);
desktop_fini(&server->desktop); desktop_fini(&server->desktop);
input_fini(&server->input); input_fini(&server->input);
wl_display_destroy(server->wl_display);
luaK_destroy(server->lua); luaK_destroy(server->lua);
free(server->config_path); free(server->config_path);