summaryrefslogtreecommitdiff
path: root/gtk/scaffolding.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@netsurf-browser.org>2013-06-28 12:13:02 +0100
committerVincent Sanders <vince@netsurf-browser.org>2013-06-28 12:13:02 +0100
commit2f280f16eb7e6ed9317f4bdf7aa818c53925fd9b (patch)
tree5d670f2bb8f8c9a9618968d643710b8631bdffc8 /gtk/scaffolding.c
parent3d7f79683c770a197e9d67aee840b76dde422e11 (diff)
downloadnetsurf-2f280f16eb7e6ed9317f4bdf7aa818c53925fd9b.tar.gz
netsurf-2f280f16eb7e6ed9317f4bdf7aa818c53925fd9b.tar.bz2
completely rework scaffolding window destruction using gtkwidget destroy signals
Diffstat (limited to 'gtk/scaffolding.c')
-rw-r--r--gtk/scaffolding.c127
1 files changed, 65 insertions, 62 deletions
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)