# HG changeset patch # User Olaf Wintermann # Date 1731703820 -3600 # Node ID 8e7c57c231331d79675db920db3f1756cd2bcb4f # Parent 44ebbb4c8a13d0d65f56778fbc823ec9f282f45e add reference counting to download window diff -r 44ebbb4c8a13 -r 8e7c57c23133 application/davcontroller.c --- a/application/davcontroller.c Thu Nov 14 23:22:35 2024 +0100 +++ b/application/davcontroller.c Fri Nov 15 21:50:20 2024 +0100 @@ -935,7 +935,7 @@ free(sz_total); free(label1.ptr); - + return 1; } @@ -998,6 +998,16 @@ return 0; } +static int qthr_download_finished(void *data) { + return 0; +} + +static void uithr_download_finished(UiEvent *event, void *data) { + DavFileDownload *download = data; + printf("download finished\n"); + ui_object_unref(download->dialog); +} + typedef struct DlStackElm { DavResource *resource; @@ -1083,6 +1093,8 @@ ui_threadpool_job(download->queue, download->ui, qthr_download_resource, file, NULL, NULL); } } + + ui_threadpool_job(download->queue, download->ui, qthr_download_finished, download, uithr_download_finished, download); cxListDestroy(stack); @@ -1145,6 +1157,8 @@ ui_set(download->progress, 0); ui_show(dialog); + + ui_object_ref(dialog); // start upload and stat threads ui_job(ui, jobthr_download_scan, download, uithr_download_scan_finished, download); diff -r 44ebbb4c8a13 -r 8e7c57c23133 ui/common/object.c --- a/ui/common/object.c Thu Nov 14 23:22:35 2024 +0100 +++ b/ui/common/object.c Fri Nov 15 21:50:20 2024 +0100 @@ -49,6 +49,34 @@ } } +void ui_object_ref(UiObject *obj) { + obj->ref++; +} + +void ui_object_unref(UiObject *obj) { + // it is possible to have 0 references, in case + // a window was created but ui_show was never called + if(obj->ref == 0 || --obj->ref == 0) { + if(obj->destroy) { + obj->destroy(obj); + } else { + uic_object_destroy(obj); + } + } +} + +void uic_object_destroy(UiObject *obj) { + if(obj->ctx->close_callback) { + UiEvent ev; + ev.window = obj->window; + ev.document = obj->ctx->document; + ev.obj = obj; + ev.eventdata = NULL; + ev.intval = 0; + obj->ctx->close_callback(&ev, obj->ctx->close_data); + } + cxMempoolDestroy(obj->ctx->mp); +} UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget) { return uic_ctx_object_new(toplevel->ctx, widget); diff -r 44ebbb4c8a13 -r 8e7c57c23133 ui/common/object.h --- a/ui/common/object.h Thu Nov 14 23:22:35 2024 +0100 +++ b/ui/common/object.h Fri Nov 15 21:50:20 2024 +0100 @@ -35,6 +35,8 @@ extern "C" { #endif +void uic_object_destroy(UiObject *obj); + UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget); UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget); void uic_obj_add(UiObject *toplevel, UiObject *ctobj); diff -r 44ebbb4c8a13 -r 8e7c57c23133 ui/gtk/toolkit.c --- a/ui/gtk/toolkit.c Thu Nov 14 23:22:35 2024 +0100 +++ b/ui/gtk/toolkit.c Fri Nov 15 21:50:20 2024 +0100 @@ -163,6 +163,7 @@ #elif GTK_MAJOR_VERSION <= 3 gtk_widget_show_all(obj->widget); #endif + obj->ref++; } void ui_close(UiObject *obj) { diff -r 44ebbb4c8a13 -r 8e7c57c23133 ui/gtk/window.c --- a/ui/gtk/window.c Thu Nov 14 23:22:35 2024 +0100 +++ b/ui/gtk/window.c Fri Nov 15 21:50:20 2024 +0100 @@ -51,18 +51,7 @@ static gboolean ui_window_destroy(void *data) { UiObject *obj = data; - UiEvent ev; - ev.window = obj->window; - ev.document = obj->ctx->document; - ev.obj = obj; - ev.eventdata = NULL; - ev.intval = 0; - - if(obj->ctx->close_callback) { - obj->ctx->close_callback(&ev, obj->ctx->close_data); - } - - cxMempoolDestroy(obj->ctx->mp); + uic_object_destroy(obj); nwindows--; #ifdef UI_GTK2 @@ -74,27 +63,48 @@ return FALSE; } +void ui_window_widget_destroy(UiObject *obj) { +#if GTK_MAJOR_VERSION >= 4 + gtk_window_destroy(GTK_WINDOW(obj->widget)); +#else + gtk_widget_destroy(obj->widget); +#endif +} + void ui_exit_event(GtkWidget *widget, gpointer data) { // delay exit handler - UiObject *obj = data; g_idle_add(ui_window_destroy, data); } +static gboolean ui_window_close_request(UiObject *obj) { + uic_context_prepare_close(obj->ctx); + obj->ref--; + if(obj->ref > 0) { +#if GTK_CHECK_VERSION(2, 18, 0) + gtk_widget_set_visible(obj->widget, FALSE); +#else + gtk_widget_hide(obj->widget); +#endif + return TRUE; + } else { + return FALSE; + } +} + #if GTK_MAJOR_VERSION >= 4 -static gboolean close_request(GtkWindow* self, UiContext *ctx) { - uic_context_prepare_close(ctx); - return FALSE; +static gboolean close_request(GtkWindow* self, UiObject *obj) { + return ui_window_close_request(obj); } #else -static gboolean close_request(GtkWidget* self, GdkEvent* event, UiContext *ctx) { - uic_context_prepare_close(ctx); - return FALSE; +static gboolean close_request(GtkWidget* self, GdkEvent* event, UiObject *obj) { + return ui_window_close_request(obj); } #endif static UiObject* create_window(const char *title, void *window_data, UiBool simple) { CxMempool *mp = cxBasicMempoolCreate(256); - UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); + UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); + obj->ref = 0; #ifdef UI_LIBADWAITA obj->widget = adw_application_window_new(ui_get_application()); @@ -130,6 +140,7 @@ window_default_height); } + obj->destroy = ui_window_widget_destroy; g_signal_connect( obj->widget, "destroy", @@ -140,13 +151,13 @@ obj->widget, "close-request", G_CALLBACK(close_request), - obj->ctx); + obj); #else g_signal_connect( obj->widget, "delete-event", G_CALLBACK(close_request), - obj->ctx); + obj); #endif GtkWidget *vbox = ui_gtk_vbox_new(0); @@ -683,6 +694,8 @@ UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); obj->ctx = uic_context(obj, mp); obj->widget = dialog; + obj->ref = 0; + obj->destroy = ui_window_widget_destroy; nwindows++; if(args.title != NULL) { @@ -710,6 +723,19 @@ "destroy", G_CALLBACK(ui_exit_event), obj); +#if GTK_MAJOR_VERSION >= 4 + g_signal_connect( + obj->widget, + "close-request", + G_CALLBACK(close_request), + obj); +#else + g_signal_connect( + obj->widget, + "delete-event", + G_CALLBACK(close_request), + obj); +#endif #if GTK_MAJOR_VERSION < 4 GtkWidget *c = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); diff -r 44ebbb4c8a13 -r 8e7c57c23133 ui/ui/toolkit.h --- a/ui/ui/toolkit.h Thu Nov 14 23:22:35 2024 +0100 +++ b/ui/ui/toolkit.h Fri Nov 15 21:50:20 2024 +0100 @@ -238,6 +238,16 @@ * next container object */ UiObject *next; + + /* + * obj destroy func + */ + void (*destroy)(UiObject *obj); + + /* + * reference counter + */ + unsigned int ref; }; struct UiTabbedPane { @@ -420,6 +430,9 @@ UIEXPORT void ui_context_destroy(UiContext *ctx); +UIEXPORT void ui_object_ref(UiObject *obj); +UIEXPORT void ui_object_unref(UiObject *obj); + UIEXPORT void ui_onstartup(ui_callback f, void *userdata); UIEXPORT void ui_onopen(ui_callback f, void *userdata); UIEXPORT void ui_onexit(ui_callback f, void *userdata);