diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 33 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 2 |
2 files changed, 27 insertions, 8 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 6a58b4b..59bd60c 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -4,8 +4,9 @@ #include "chrome/browser/gtk/browser_window_gtk.h" -#include "base/logging.h" #include "base/base_paths_linux.h" +#include "base/logging.h" +#include "base/message_loop.h" #include "base/path_service.h" #include "chrome/browser/browser.h" #include "chrome/browser/find_bar_controller.h" @@ -51,11 +52,6 @@ static GdkPixbuf* LoadThemeImage(int resource_id) { return pixbuf; } -gboolean MainWindowDestroyed(GtkWindow* window, BrowserWindowGtk* browser_win) { - delete browser_win; - return FALSE; // Don't stop this message. -} - gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event, BrowserWindowGtk* browser_win) { gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height); @@ -135,7 +131,7 @@ void BrowserWindowGtk::Init() { window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); gtk_window_set_default_size(window_, 640, 480); g_signal_connect(G_OBJECT(window_), "destroy", - G_CALLBACK(MainWindowDestroyed), this); + G_CALLBACK(OnWindowDestroyed), this); g_signal_connect(G_OBJECT(window_), "configure-event", G_CALLBACK(MainWindowConfigured), this); g_signal_connect(G_OBJECT(window_), "window-state-event", @@ -213,8 +209,11 @@ void BrowserWindowGtk::Close() { // we don't have a TabStripModel yet. find_bar_controller_->ChangeWebContents(NULL); - gtk_widget_destroy(GTK_WIDGET(window_)); + GtkWidget* window = GTK_WIDGET(window_); + // To help catch bugs in any event handlers that might get fired during the + // destruction, set window_ to NULL before any handlers will run. window_ = NULL; + gtk_widget_destroy(window); } void BrowserWindowGtk::Activate() { @@ -432,3 +431,21 @@ void BrowserWindowGtk::SetCustomFrame(bool custom_frame) { gtk_container_set_border_width(GTK_CONTAINER(vbox_), 0); } } + +// static +gboolean BrowserWindowGtk::OnWindowDestroyed(GtkWidget* window, + BrowserWindowGtk* browser_win) { + // BUG 8712. When we gtk_widget_destroy() in Close(), this will emit the + // signal right away, and we will be here (while Close() is still in the + // call stack). In order to not reenter Close(), and to also follow the + // expectations of BrowserList, we should run the BrowserWindowGtk destructor + // not now, but after the run loop goes back to process messages. Otherwise + // we will remove ourself from BrowserList while it's being iterated. + // Additionally, now that we know the window is gone, we need to make sure to + // set window_ to NULL, otherwise we will try to close the window again when + // we call Close() in the destructor. + browser_win->window_ = NULL; + MessageLoop::current()->DeleteSoon(FROM_HERE, browser_win); + return FALSE; // Don't stop this message. +} + diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 7d86175..abf2610 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -101,6 +101,8 @@ class BrowserWindowGtk : public BrowserWindow, static gboolean OnContentAreaExpose(GtkWidget* widget, GdkEventExpose* e, BrowserWindowGtk* window); + static gboolean OnWindowDestroyed(GtkWidget* window, + BrowserWindowGtk* browser_win); gfx::Rect bounds_; GdkWindowState state_; |