fix memleaks under wayland

This commit is contained in:
IoI_xD 2026-04-23 14:02:33 -07:00
commit 7cdd2bcc79
3 changed files with 25 additions and 22 deletions

View file

@ -60,6 +60,7 @@ typedef struct wayland_call_table {
struct wl_display* (*wl_display_connect)(const char* name); struct wl_display* (*wl_display_connect)(const char* name);
uint32_t (*wl_proxy_get_version)(struct wl_proxy* proxy); uint32_t (*wl_proxy_get_version)(struct wl_proxy* proxy);
struct wl_display* (*wl_display_connect_to_fd)(int fd); struct wl_display* (*wl_display_connect_to_fd)(int fd);
int (*wl_display_get_error)(struct wl_display* display);
struct xkb_context* (*xkb_context_new)(enum xkb_context_flags flags); struct xkb_context* (*xkb_context_new)(enum xkb_context_flags flags);
void (*xkb_context_unref)(struct xkb_context* context); void (*xkb_context_unref)(struct xkb_context* context);
@ -176,6 +177,7 @@ MwInline int wayland_load_funcs() {
WAYLAND_FUNC(wl_display_connect) WAYLAND_FUNC(wl_display_connect)
WAYLAND_FUNC(wl_proxy_get_version) WAYLAND_FUNC(wl_proxy_get_version)
WAYLAND_FUNC(wl_display_connect_to_fd) WAYLAND_FUNC(wl_display_connect_to_fd)
WAYLAND_FUNC(wl_display_get_error)
#undef WAYLAND_FUNC #undef WAYLAND_FUNC
@ -259,6 +261,7 @@ MwInline int wayland_load_funcs() {
#define wl_display_connect wl_call_tbl.wl_display_connect #define wl_display_connect wl_call_tbl.wl_display_connect
#define wl_proxy_get_version wl_call_tbl.wl_proxy_get_version #define wl_proxy_get_version wl_call_tbl.wl_proxy_get_version
#define wl_display_connect_to_fd wl_call_tbl.wl_display_connect_to_fd #define wl_display_connect_to_fd wl_call_tbl.wl_display_connect_to_fd
#define wl_display_get_error wl_call_tbl.wl_display_get_error
#define xkb_state_unref wl_call_tbl.xkb_state_unref #define xkb_state_unref wl_call_tbl.xkb_state_unref
#define xkb_context_new wl_call_tbl.xkb_context_new #define xkb_context_new wl_call_tbl.xkb_context_new
@ -423,13 +426,13 @@ struct _MwLLWayland {
/* Map of Wayland interfaces to their relevant setup functions. */ /* Map of Wayland interfaces to their relevant setup functions. */
struct { struct {
char key[255]; char* key;
wayland_protocol_callback_table_t* value; wayland_protocol_callback_table_t* value;
}* wl_protocol_setup_map; }* wl_protocol_setup_map;
/* Map of Wayland interfaces to any information we keep about them once we've registered them. */ /* Map of Wayland interfaces to any information we keep about them once we've registered them. */
struct { struct {
char key[255]; char* key;
wayland_protocol_t* value; wayland_protocol_t* value;
}* wl_protocol_map; }* wl_protocol_map;

View file

@ -91,9 +91,7 @@ static void new_protocol(void* data, struct wl_registry* registry,
wayland_protocol_callback_table_t* cb = shget(self->wayland.wl_protocol_setup_map, interface); wayland_protocol_callback_table_t* cb = shget(self->wayland.wl_protocol_setup_map, interface);
if(cb != NULL) { if(cb != NULL) {
char* inter = malloc(strlen(interface) + 1); shput(self->wayland.wl_protocol_map, interface, cb->setup(name, data));
strcpy(inter, interface);
shput(self->wayland.wl_protocol_map, inter, cb->setup(name, data));
/* we don't care for adding this protocol, we just use it to know if the compositor will let us have transparent surfaces */ /* we don't care for adding this protocol, we just use it to know if the compositor will let us have transparent surfaces */
} else if(strcmp(interface, "wp_alpha_modifier_v1") == 0) { } else if(strcmp(interface, "wp_alpha_modifier_v1") == 0) {
self->common.supports_transparency = MwTRUE; self->common.supports_transparency = MwTRUE;
@ -1174,7 +1172,7 @@ static int event_loop(MwLL handle) {
static void hang_until_configured(MwLL handle) { static void hang_until_configured(MwLL handle) {
while(!handle->wayland.configured) { while(!handle->wayland.configured) {
if(wl_display_roundtrip(handle->wayland.display) == -1) { if(wl_display_roundtrip(handle->wayland.display) == -1) {
printf("roundtrip failed\n"); printf("roundtrip failed: %d\n", wl_display_get_error(handle->wayland.display));
raise(SIGTRAP); raise(SIGTRAP);
return; return;
} }
@ -1334,6 +1332,8 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) {
if(!buffer->setup) { if(!buffer->setup) {
return; return;
} }
if(buffer->buf) munmap(buffer->buf, buffer->buf_size);
if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_size);
if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer); if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer);
if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back); if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back);
if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool); if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool);
@ -1465,6 +1465,9 @@ static void setup_callbacks(struct _MwLLWayland* wayland) {
wayland->wl_protocol_setup_map = NULL; wayland->wl_protocol_setup_map = NULL;
wayland->wl_protocol_map = NULL; wayland->wl_protocol_map = NULL;
sh_new_arena(wayland->wl_protocol_map);
sh_new_arena(wayland->wl_protocol_setup_map);
WL_INTERFACE(wl_shm); WL_INTERFACE(wl_shm);
WL_INTERFACE(wl_compositor); WL_INTERFACE(wl_compositor);
WL_INTERFACE(wl_seat); WL_INTERFACE(wl_seat);
@ -1618,7 +1621,7 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
if(wl_display_roundtrip(r->wayland.display) == -1) { if(wl_display_roundtrip(r->wayland.display) == -1) {
printf("roundtrip failed\n"); printf("roundtrip failed: %d\n", wl_display_get_error(r->wayland.display));
raise(SIGTRAP); raise(SIGTRAP);
return; return;
} }
@ -1705,7 +1708,7 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
r->wayland.registry = wl_display_get_registry(r->wayland.display); r->wayland.registry = wl_display_get_registry(r->wayland.display);
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
if(wl_display_roundtrip(r->wayland.display) == -1) { if(wl_display_roundtrip(r->wayland.display) == -1) {
printf("roundtrip failed\n"); printf("roundtrip failed: %d\n", wl_display_get_error(r->wayland.display));
raise(SIGTRAP); raise(SIGTRAP);
return; return;
} }

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#define WIDGET_AMOUNT 1 #define WIDGET_AMOUNT 16
int main() { int main() {
MwWidget window, widget; MwWidget window, widget;
@ -9,7 +9,7 @@ int main() {
window = MwCreateWidget(MwWindowClass, "window", NULL, 0, 0, 400, 400); window = MwCreateWidget(MwWindowClass, "window", NULL, 0, 0, 400, 400);
while(true) { while(MwPending(window)) {
int r = rand() % WIDGET_AMOUNT; int r = rand() % WIDGET_AMOUNT;
MwClass cls; MwClass cls;
switch(r) { switch(r) {
@ -46,38 +46,35 @@ int main() {
case 10: case 10:
cls = MwNumberEntryClass; cls = MwNumberEntryClass;
break; break;
case 12: case 11:
cls = MwProgressBarClass; cls = MwProgressBarClass;
break; break;
case 13: case 12:
cls = MwRadioBoxClass; cls = MwRadioBoxClass;
break; break;
case 14: case 13:
cls = MwScrollBarClass; cls = MwScrollBarClass;
break; break;
case 15: case 14:
cls = MwSeparatorClass; cls = MwSeparatorClass;
break; break;
// case 16:
// cls = MwSubMenuClass; case 15:
// break;
case 17:
cls = MwTreeViewClass; cls = MwTreeViewClass;
break; break;
case 18: case 16:
cls = MwViewportClass; cls = MwViewportClass;
break; break;
default: default:
cls = NULL; cls = NULL;
break; break;
} }
printf("%d\n", r);
if(cls) { if(cls) {
widget = MwCreateWidget(cls, "Cls", window, 0, 0, 100, 100); widget = MwCreateWidget(cls, "Cls", window, 0, 0, 100, 100);
} }
if(MwPending(window)) { MwStep(window);
MwStep(window);
}
if(cls) { if(cls) {
MwDestroyWidget(widget); MwDestroyWidget(widget);
} }