Tue, 19 May 2026 18:10:13 +0200
rework window closing behavior and reference counting (GTK)
| application/main.c | file | annotate | diff | comparison | revisions | |
| ui/common/object.c | file | annotate | diff | comparison | revisions | |
| ui/gtk/toolkit.c | file | annotate | diff | comparison | revisions | |
| ui/gtk/window.c | file | annotate | diff | comparison | revisions | |
| ui/qt/window.cpp | file | annotate | diff | comparison | revisions | |
| ui/ui/toolkit.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Mon May 18 21:29:56 2026 +0200 +++ b/application/main.c Tue May 19 18:10:13 2026 +0200 @@ -643,6 +643,10 @@ } void application_startup(UiEvent *event, void *data) { + // test window destruction + UiObject *testobj = ui_window("testwindow"); + ui_object_unref(testobj); + // global list UiContext *global = ui_global_context(); ui_add_action(global, "save", global_action_save, NULL);
--- a/ui/common/object.c Mon May 18 21:29:56 2026 +0200 +++ b/ui/common/object.c Tue May 19 18:10:13 2026 +0200 @@ -114,6 +114,7 @@ } void uic_object_destroy(UiObject *obj) { + uic_context_prepare_close(obj->ctx); uic_object_destroyed(obj); uic_context_destroy(obj->ctx, obj->ctx->document); }
--- a/ui/gtk/toolkit.c Mon May 18 21:29:56 2026 +0200 +++ b/ui/gtk/toolkit.c Tue May 19 18:10:13 2026 +0200 @@ -165,7 +165,6 @@ void ui_show(UiObject *obj) { gboolean visible = FALSE; - uic_check_state_widgets(obj->ctx); if(obj->widget) { visible = gtk_widget_is_visible(obj->widget); #if GTK_MAJOR_VERSION >= 4 @@ -174,6 +173,7 @@ gtk_widget_show_all(obj->widget); #endif } + uic_check_state_widgets(obj->ctx); if(!visible) { obj->ref++; @@ -181,18 +181,6 @@ } void ui_close(UiObject *obj) { - uic_context_prepare_close(obj->ctx); // TODO: should this be moved to the close event handler? Yes! - /* - if(obj->widget) { -#if GTK_CHECK_VERSION(4, 0, 0) - gtk_window_close(GTK_WINDOW(obj->widget)); -#else - gtk_widget_destroy(obj->widget); -#endif - } else { - ui_window_close_request(obj); - } - */ ui_window_close_request(obj); }
--- a/ui/gtk/window.c Mon May 18 21:29:56 2026 +0200 +++ b/ui/gtk/window.c Tue May 19 18:10:13 2026 +0200 @@ -112,7 +112,12 @@ } } - obj->ref--; + if(obj->ref > 0) { + obj->ref--; + } else { + // warn about invalid reference counting + fprintf(stderr, "Error: UiObject %p ref == 0\n", obj); + } if(obj->ref > 0) { #if GTK_CHECK_VERSION(2, 18, 0) gtk_widget_set_visible(obj->widget, FALSE); @@ -138,12 +143,25 @@ } } +static void window_onclose_callback(UiObject *obj) { + if(obj->onclose) { + UiEvent event; + memset(&event, 0, sizeof(UiEvent)); + event.obj = obj; + event.window = obj->window; + event.document = obj->ctx->document; + obj->onclose(&event, obj->onclosedata); + } +} + #if GTK_MAJOR_VERSION >= 4 static gboolean close_request(GtkWindow* self, UiObject *obj) { + window_onclose_callback(obj); return ui_window_close_request(obj); } #else static gboolean close_request(GtkWidget* self, GdkEvent* event, UiObject *obj) { + window_onclose_callback(obj); return ui_window_close_request(obj); } #endif @@ -305,17 +323,23 @@ adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE); } else if(!strcmp(show_title, "sidebar")) { adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE); - adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE); + if(headerbar_sidebar) { + adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE); + } } else if(!strcmp(show_title, "false")) { - adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE); + if(headerbar_sidebar) { + adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE); + } adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE); } else { fprintf(stderr, "Unknown value '%s' for property ui.gtk.window.showtitle\n", show_title); - adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE); + if(headerbar_sidebar) { + adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE); + } } } else { adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE); - if(sidebar) { + if(headerbar_sidebar) { adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE); } }
--- a/ui/qt/window.cpp Mon May 18 21:29:56 2026 +0200 +++ b/ui/qt/window.cpp Tue May 19 18:10:13 2026 +0200 @@ -43,7 +43,6 @@ static UiObject* create_window(const char *title, bool simple, bool sidebar = false) { UiObject *obj = uic_object_new_toplevel(); - obj->next = NULL; QMainWindow *window = new QMainWindow(); window->setWindowTitle(title);
--- a/ui/ui/toolkit.h Mon May 18 21:29:56 2026 +0200 +++ b/ui/ui/toolkit.h Tue May 19 18:10:13 2026 +0200 @@ -295,9 +295,10 @@ UiContainer *container_end; /* - * next container object + * called when someone requests to close the window */ - UiObject *next; + void (*onclose)(UiEvent *event, void *userdata); + void *onclosedata; /* * obj destroy func