Attempt to exit cleanly, without crash (#51)
This commit is contained in:
parent
ed1ff87494
commit
53684f0e79
13 changed files with 71 additions and 26 deletions
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
wlr_output_layout_remove(
|
if (output->desktop->output_layout) {
|
||||||
output->desktop->output_layout, output->wlr_output);
|
wlr_output_layout_remove(
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
decoration->view->decoration = NULL;
|
if (decoration->view) {
|
||||||
|
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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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,10 +130,12 @@ 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_signal_init(&obj->events.destroy);
|
wl_list_init(&obj->destroy.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_signal_init(&obj->events.destroy);
|
||||||
|
|
||||||
wl_list_init(&obj->callbacks);
|
wl_list_init(&obj->callbacks);
|
||||||
|
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lua->objects);
|
lua_rawgeti(L, LUA_REGISTRYINDEX, lua->objects);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue