From 94a2904ab606ace64db968c95cd0d9d34cf26164 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 26 Nov 2017 11:50:49 +0000 Subject: [PATCH] GTK: add a delete_inst() function to clean up a gui_data. This has been logically necessary in principle for ages, but we got away without it because we just exited the program. But in the multi- window GtkApplication front ends, we can't get away with that for ever; we need to be able to free _one_ of our 'struct gui_data' instances and everything dangling off it (or, at least, everything that GTK's reference counting system doesn't clean up for us), without also doing anything global to the process in which that gui_data is contained. --- unix/gtkwin.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 1038e756..e5345349 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -1993,9 +1993,6 @@ static void exit_callback(void *vinst) (exitcode = inst->back->exitcode(inst->backhandle)) >= 0) { inst->exited = TRUE; close_on_exit = conf_get_int(inst->conf, CONF_close_on_exit); - if (close_on_exit == FORCE_ON || - (close_on_exit == AUTO && exitcode == 0)) - gtk_main_quit(); /* just go */ if (inst->ldisc) { ldisc_free(inst->ldisc); inst->ldisc = NULL; @@ -2006,6 +2003,12 @@ static void exit_callback(void *vinst) term_provide_resize_fn(inst->term, NULL, NULL); update_specials_menu(inst); gtk_widget_set_sensitive(inst->restartitem, TRUE); + + if (close_on_exit == FORCE_ON || + (close_on_exit == AUTO && exitcode == 0)) { + gtk_widget_destroy(inst->window); + gtk_main_quit(); + } } } @@ -2016,8 +2019,46 @@ void notify_remote_exit(void *frontend) queue_toplevel_callback(exit_callback, inst); } +static void delete_inst(struct gui_data *inst) +{ + delete_callbacks_for_context(inst); + if (inst->window) { + gtk_widget_destroy(inst->window); + inst->window = NULL; + } + if (inst->menu) { + gtk_widget_destroy(inst->menu); + inst->menu = NULL; + } + if (inst->backhandle) { + inst->back->free(inst->backhandle); + inst->backhandle = NULL; + inst->back = NULL; + } + if (inst->term) { + term_free(inst->term); + inst->term = NULL; + } + if (inst->ldisc) { + ldisc_free(inst->ldisc); + inst->ldisc = NULL; + } + if (inst->conf) { + conf_free(inst->conf); + inst->conf = NULL; + } + if (inst->logctx) { + log_free(inst->logctx); + inst->logctx = NULL; + } + sfree(inst); +} + void destroy(GtkWidget *widget, gpointer data) { + struct gui_data *inst = (struct gui_data *)data; + inst->window = NULL; + delete_inst(inst); gtk_main_quit(); }