From 2f280f16eb7e6ed9317f4bdf7aa818c53925fd9b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 28 Jun 2013 12:13:02 +0100 Subject: completely rework scaffolding window destruction using gtkwidget destroy signals --- gtk/scaffolding.c | 127 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 65 insertions(+), 62 deletions(-) (limited to 'gtk/scaffolding.c') diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index 5a958447f..b10fb69ae 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -139,7 +139,6 @@ struct gtk_scaffolding { int throb_frame; struct gui_window *top_level; - int being_destroyed; bool fullscreen; @@ -147,9 +146,6 @@ struct gtk_scaffolding { struct gtk_scaffolding *next, *prev; }; -/** current number of open browser windows */ -static int open_windows = 0; - /** current window for model dialogue use */ static struct gtk_scaffolding *current_model; @@ -251,60 +247,57 @@ static void popup_menu_show(struct nsgtk_popup_submenu *menu, bool submenu, /* event handlers and support functions for them */ /** - * resource cleanup function for window closure. + * resource cleanup function for window destruction. */ -static void nsgtk_window_close(struct gtk_scaffolding *g) +static void scaffolding_window_destroy(GtkWidget *widget, gpointer data) { - /* close all tabs first */ - gint numbertabs = gtk_notebook_get_n_pages(g->notebook); - while (numbertabs-- > 1) { - nsgtk_tab_close_current(g->notebook); - } - LOG(("Being Destroyed = %d", g->being_destroyed)); + struct gtk_scaffolding *gs = data; - if ((g->history_window) && (g->history_window->window)) { - gtk_widget_destroy(GTK_WIDGET(g->history_window->window)); - } + LOG(("scaffold:%p", gs)); - if (--open_windows == 0) - netsurf_quit = true; + if ((gs->history_window) && (gs->history_window->window)) { + gtk_widget_destroy(GTK_WIDGET(gs->history_window->window)); + } - if (!g->being_destroyed) { - g->being_destroyed = 1; - nsgtk_window_destroy_browser(g->top_level); + if (gs->prev != NULL) { + gs->prev->next = gs->next; + } else { + scaf_list = gs->next; + } + if (gs->next != NULL) { + gs->next->prev = gs->prev; } - if (g->prev != NULL) - g->prev->next = g->next; - else - scaf_list = g->next; - if (g->next != NULL) - g->next->prev = g->prev; + LOG(("scaffold list head: %p", scaf_list)); + if (scaf_list == NULL) { + /* no more open windows */ + netsurf_quit = true; + } } -static gboolean nsgtk_window_delete_event(GtkWidget *widget, +/* signal delivered on window delete event, allowing to halt close if + * download is in progress + */ +static gboolean scaffolding_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { - struct gtk_scaffolding *g = (struct gtk_scaffolding *)data; - if ((open_windows != 1) || - nsgtk_check_for_downloads(GTK_WINDOW(widget)) == false) { - nsgtk_window_close(g); + struct gtk_scaffolding *g = data; + + if (nsgtk_check_for_downloads(GTK_WINDOW(widget)) == false) { gtk_widget_destroy(GTK_WIDGET(g->window)); } return TRUE; } /* exported interface documented in gtk_scaffold.h */ -void nsgtk_scaffolding_destroy(nsgtk_scaffolding *g) +void nsgtk_scaffolding_destroy(nsgtk_scaffolding *gs) { - /* Our top_level has asked us to die */ - LOG(("Being Destroyed = %d", g->being_destroyed)); - if (g->being_destroyed) return; - g->being_destroyed = 1; - nsgtk_window_close(g); - /* We're now unlinked, so let's finally destroy ourselves */ - nsgtk_window_destroy_browser(g->top_level); + LOG(("scaffold: %p", gs)); + + if (gtk_widget_in_destruction(GTK_WIDGET(gs->window)) != TRUE) { + gtk_widget_destroy(GTK_WIDGET(gs->window)); + } } /** @@ -522,21 +515,32 @@ static void nsgtk_window_tabs_add(GtkNotebook *notebook, /** * Update the menus when the number of tabs changes. */ -static void nsgtk_window_tabs_remove(GtkNotebook *notebook, - GtkWidget *page, guint page_num, struct gtk_scaffolding *g) -{ +static void +nsgtk_window_tabs_remove(GtkNotebook *notebook, + GtkWidget *page, + guint page_num, + struct gtk_scaffolding *gs) +{ + /* if the scaffold is being destroyed it is not useful to + * update the state, futher many of the widgets may have + * already been destroyed. + */ + if (gtk_widget_in_destruction(GTK_WIDGET(gs->window)) == TRUE) { + return; + } - if (gtk_notebook_get_n_pages(notebook) == 0) { - nsgtk_scaffolding_destroy(g); - } else { - gboolean visible = gtk_notebook_get_show_tabs(g->notebook); - g_object_set(g->menu_bar->view_submenu->tabs_menuitem, "visible", visible, NULL); - g_object_set(g->menu_popup->view_submenu->tabs_menuitem, "visible", visible, NULL); - g->buttons[NEXTTAB_BUTTON]->sensitivity = visible; - g->buttons[PREVTAB_BUTTON]->sensitivity = visible; - g->buttons[CLOSETAB_BUTTON]->sensitivity = visible; - nsgtk_scaffolding_set_sensitivity(g); + if (gtk_notebook_get_n_pages(notebook) == 1) { + nsgtk_scaffolding_destroy(gs); + return; } + + gboolean visible = gtk_notebook_get_show_tabs(gs->notebook); + g_object_set(gs->menu_bar->view_submenu->tabs_menuitem, "visible", visible, NULL); + g_object_set(gs->menu_popup->view_submenu->tabs_menuitem, "visible", visible, NULL); + gs->buttons[NEXTTAB_BUTTON]->sensitivity = visible; + gs->buttons[PREVTAB_BUTTON]->sensitivity = visible; + gs->buttons[CLOSETAB_BUTTON]->sensitivity = visible; + nsgtk_scaffolding_set_sensitivity(gs); } /** @@ -639,7 +643,8 @@ nserror nsgtk_scaffolding_new_tab(struct gui_window *gw) MULTIHANDLER(newtab) { nserror error; - nsgtk_scaffolding_new_tab(g->top_level); + + error = nsgtk_scaffolding_new_tab(g->top_level); if (error != NSERROR_OK) { warn_user(messages_get_errorcode(error), 0); } @@ -947,7 +952,6 @@ MULTIHANDLER(print) MULTIHANDLER(closewindow) { - nsgtk_window_close(g); gtk_widget_destroy(GTK_WIDGET(g->window)); return TRUE; } @@ -1842,12 +1846,13 @@ static bool nsgtk_new_scaffolding_popup(struct gtk_scaffolding *g, GtkAccelGroup nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) { - struct gtk_scaffolding *g = malloc(sizeof(*g)); + struct gtk_scaffolding *g; char *searchname; int i; GtkAccelGroup *group; GError* error = NULL; + g = malloc(sizeof(*g)); if (g == NULL) { warn_user("NoMemory", 0); return NULL; @@ -1857,8 +1862,6 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) g->top_level = toplevel; - open_windows++; - /* load the window template from the glade xml file, and extract * widget references from it for later use. */ @@ -2083,8 +2086,9 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) g_signal_connect_after(g->notebook, "page-removed", G_CALLBACK(nsgtk_window_tabs_remove), g); - /* connect signals to handlers. */ - CONNECT(g->window, "delete-event", nsgtk_window_delete_event, g); + /* connect main window signals to their handlers. */ + CONNECT(g->window, "delete-event", scaffolding_window_delete_event, g); + CONNECT(g->window, "destroy", scaffolding_window_destroy, g); /* toolbar URL bar menu bar search bar signal handlers */ CONNECT(g->menu_bar->edit_submenu->edit, "show", nsgtk_window_edit_menu_clicked, g); @@ -2132,8 +2136,6 @@ nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) nsgtk_scaffolding_initial_sensitivity(g); - g->being_destroyed = 0; - g->fullscreen = false; @@ -2469,8 +2471,10 @@ void nsgtk_scaffolding_set_top_level(struct gui_window *gw) } } +/* exported interface documented in scaffolding.h */ void nsgtk_scaffolding_set_sensitivity(struct gtk_scaffolding *g) { + int i; #define SENSITIVITY(q)\ i = q##_BUTTON;\ if (g->buttons[i]->main != NULL)\ @@ -2491,7 +2495,6 @@ void nsgtk_scaffolding_set_sensitivity(struct gtk_scaffolding *g) g->buttons[i]->popup),\ g->buttons[i]->sensitivity); - int i; SENSITIVITY(STOP) SENSITIVITY(RELOAD) SENSITIVITY(CUT) -- cgit v1.2.3