diff --git a/src/backend/wayland/buffer.c b/src/backend/wayland/buffer.c index ce5659938..df1de797c 100644 --- a/src/backend/wayland/buffer.c +++ b/src/backend/wayland/buffer.c @@ -15,6 +15,7 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) { MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer); }; void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* wayland) { + wl_surface_attach(wayland->framebuffer.surface, NULL, 0, 0); MwLLWaylandBufferDestroy(&wayland->framebuffer); MwLLCairoFrontDestroy(&wayland->cairo); }; @@ -41,6 +42,7 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) { MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer); }; void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* wayland) { + // wl_surface_attach(wayland->backbuffer.surface, NULL, 0, 0); MwLLWaylandBufferDestroy(&wayland->backbuffer); MwLLCairoBackDestroy(&wayland->cairo); }; diff --git a/src/backend/wayland/interfaces.c b/src/backend/wayland/interfaces.c index 57c30e388..84ed4923d 100644 --- a/src/backend/wayland/interfaces.c +++ b/src/backend/wayland/interfaces.c @@ -16,6 +16,9 @@ static void setup_clipboard(MwLL self, struct wl_seat* wl_seat); static void setup_zwp_clipboard(MwLL self, struct wl_seat* wl_seat); +static void destroy_clipboard(MwLL self, struct wl_seat* wl_seat); +static void destroy_zwp_clipboard(MwLL self, struct wl_seat* wl_seat); + /* Recursively dispatch a move event to a widget and its children */ static void recursive_dispatch_move(MwLL handle, MwMouse* p) { MwWidget h = (MwWidget)handle->common.user; @@ -1017,6 +1020,7 @@ static wayland_protocol_t* wl_seat_setup(MwU32 name, MwLL ll, MwU32 version) { static void wl_seat_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { (void)wayland; free(data->listener); + free(data); } /* wl_output setup function */ @@ -1060,7 +1064,11 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { (void)data; - wl_subcompositor_destroy(wayland->sublevel->subcompositor); + if(wayland->type == MwLL_WAYLAND_TOPLEVEL) { + wl_subcompositor_destroy(wayland->toplevel->scompositor); + } else { + wl_subcompositor_destroy(wayland->sublevel->subcompositor); + } } /* xdg_wm_base setup function */ @@ -1080,6 +1088,7 @@ static wayland_protocol_t* xdg_wm_base_setup(MwU32 name, struct _MwLLWayland* wa static void xdg_wm_base_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { (void)wayland; free(data->listener); + free(data); } /* xdg_wm_base setup function */ @@ -1145,6 +1154,7 @@ static wayland_protocol_t* xdg_toplevel_icon_manager_v1_setup(MwU32 name, struct static void xdg_toplevel_icon_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { (void)wayland; free(data->listener); + free(data); } static wayland_protocol_t* zwlr_layer_shell_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { @@ -1175,8 +1185,16 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) { wayland->registry_listener.global = new_protocol; wayland->registry_listener.global_remove = protocol_removed; - wayland->wl_protocol_setup_map = NULL; - wayland->wl_protocol_map = NULL; + + if(wayland->wl_protocol_map) { + shfree(wayland->wl_protocol_map); + } + if(wayland->wl_protocol_setup_map) { + shfree(wayland->wl_protocol_setup_map); + } + + wayland->wl_protocol_setup_map = NULL; + wayland->wl_protocol_map = NULL; sh_new_arena(wayland->wl_protocol_map); sh_new_arena(wayland->wl_protocol_setup_map); diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c index c156e04d9..278b453b0 100644 --- a/src/backend/wayland/wayland.c +++ b/src/backend/wayland/wayland.c @@ -573,16 +573,22 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) { /* Popup destroy function */ static void destroy_popup(MwLL r) { - xdg_popup_destroy(r->wayland.popup->xdg_popup); + + MwLLWaylandBackbufferDestroy(&r->wayland); + MwLLWaylandFramebufferDestroy(&r->wayland); xdg_surface_destroy(r->wayland.popup->xdg_surface); + xdg_popup_destroy(r->wayland.popup->xdg_popup); + xdg_positioner_destroy(r->wayland.popup->xdg_positioner); wl_surface_destroy(r->wayland.framebuffer.surface); wl_registry_destroy(r->wayland.registry); + free(r->wayland.popup); + r->wayland.configured = MwFALSE; } @@ -702,6 +708,51 @@ static void destroy_layer_surface(MwLL r) { r->wayland.configured = MwFALSE; } +static void destroy_widget(MwLL handle) { + int i; + + MwLLShow(handle, MwFALSE); + + switch(handle->wayland.type) { + case MwLL_WAYLAND_TOPLEVEL: + destroy_toplevel(handle); + break; + case MwLL_WAYLAND_SUBLEVEL: + destroy_sublevel(handle); + break; + case MwLL_WAYLAND_POPUP: + destroy_popup(handle); + break; + case MwLL_WAYLAND_LAYER_SURFACE: + destroy_layer_surface(handle); + break; + default: + printf("Handle with unknown type(%d) tried to be destroyed (%p)\n", handle->wayland.type, handle); + break; + } + + if(wl_display_roundtrip(handle->wayland.display) == -1) { + printf("roundtrip failed\n"); + raise(SIGTRAP); + return; + } + + for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) { + void* ctx = shget(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].key); + + if(ctx != NULL) { + handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, ctx); + } + shdel(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].value); + free(handle->wayland.wl_protocol_setup_map[i].value); + } + + shfree(handle->wayland.wl_protocol_map); + shfree(handle->wayland.wl_protocol_setup_map); + + MwLLWaylandFlush(handle); +} + static void clip(MwLL handle) { int i; int x, y, cx, cy, mx, my; @@ -955,28 +1006,11 @@ static void MwLLDestroyImpl(MwLL handle) { wl_surface_destroy(handle->wayland.icon->surface); } - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { - destroy_toplevel(handle); - } else if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) { - destroy_sublevel(handle); - } else if(handle->wayland.type == MwLL_WAYLAND_POPUP) { - destroy_popup(handle); - } + destroy_widget(handle); + } else { + printf("widget invalid\n"); } - for(i = 0; i < shlen(handle->wayland.wl_protocol_setup_map); i++) { - void* ctx = shget(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].key); - - if(ctx != NULL) { - handle->wayland.wl_protocol_setup_map[i].value->destroy(&handle->wayland, ctx); - } - shdel(handle->wayland.wl_protocol_map, handle->wayland.wl_protocol_setup_map[i].value); - } - shfree(handle->wayland.wl_protocol_map); - shfree(handle->wayland.wl_protocol_setup_map); - - MwLLWaylandFlush(handle); - pthread_mutex_lock(&destroyedWidgetsTableMutex); arrput(destroyedWidgetsTable, handle); pthread_mutex_unlock(&destroyedWidgetsTableMutex); @@ -1049,7 +1083,7 @@ static void actually_set_wh(MwLL handle) { } if(handle->wayland.type == MwLL_WAYLAND_POPUP) { - destroy_popup(handle); + destroy_widget(handle); MwLLWaylandFlush(handle); setup_popup(handle, handle->wayland.x, handle->wayland.y, handle->wayland.parent); } @@ -1751,22 +1785,7 @@ static void MwLLEndStateChangeImpl(MwLL handle) { } } - switch(handle->wayland.type) { - case MwLL_WAYLAND_UNKNOWN: - break; - case MwLL_WAYLAND_TOPLEVEL: - destroy_toplevel(handle); - break; - case MwLL_WAYLAND_SUBLEVEL: - destroy_sublevel(handle); - break; - case MwLL_WAYLAND_POPUP: - destroy_popup(handle); - break; - case MwLL_WAYLAND_LAYER_SURFACE: - destroy_layer_surface(handle); - break; - } + destroy_widget(handle); if(wl_display_roundtrip(handle->wayland.display) == -1) { printf("roundtrip failed\n");