diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 20:46:01 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 20:46:01 +0000 |
commit | 6d9a36f8262936f7ef730bfdac7a1058aa1d99d6 (patch) | |
tree | 808b265651401303b3da57f930ccd7dba465f9a7 /chrome | |
parent | 3b5f702430290ecaba83c83d5e617b22acf2b517 (diff) | |
download | chromium_src-6d9a36f8262936f7ef730bfdac7a1058aa1d99d6.zip chromium_src-6d9a36f8262936f7ef730bfdac7a1058aa1d99d6.tar.gz chromium_src-6d9a36f8262936f7ef730bfdac7a1058aa1d99d6.tar.bz2 |
GTK: Notifications shouldn't crash when gtk notification is destroyed.
(Use callbacks, while I'm at it.)
BUG=34515
TEST=none
Review URL: http://codereview.chromium.org/1372001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42664 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/notifications/balloon_view_gtk.cc | 43 | ||||
-rw-r--r-- | chrome/browser/gtk/notifications/balloon_view_gtk.h | 20 |
2 files changed, 32 insertions, 31 deletions
diff --git a/chrome/browser/gtk/notifications/balloon_view_gtk.cc b/chrome/browser/gtk/notifications/balloon_view_gtk.cc index 40de463..3775b5b 100644 --- a/chrome/browser/gtk/notifications/balloon_view_gtk.cc +++ b/chrome/browser/gtk/notifications/balloon_view_gtk.cc @@ -125,7 +125,11 @@ gfx::Size BalloonViewImpl::GetSize() const { void BalloonViewImpl::DelayedClose(bool by_user) { html_contents_->Shutdown(); - gtk_widget_hide(frame_container_); + if (frame_container_) { + // It's possible that |frame_container_| was destroyed before the + // BalloonViewImpl if our related browser window was closed first. + gtk_widget_hide(frame_container_); + } balloon_->OnClose(by_user); } @@ -182,7 +186,6 @@ void PrepareButtonWithIcon(GtkWidget* button, ResourceBundle& rb = ResourceBundle::GetSharedInstance(); GdkPixbuf* pixbuf = rb.GetPixbufNamed(icon_id); GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); - g_object_unref(pixbuf); GtkWidget* box = gtk_hbox_new(FALSE, kButtonIconSpacing); @@ -251,7 +254,9 @@ void BalloonViewImpl::Show(Balloon* balloon) { gtk_widget_show_all(vbox); g_signal_connect(frame_container_, "expose-event", - G_CALLBACK(HandleExposeThunk), this); + G_CALLBACK(OnExposeThunk), this); + g_signal_connect(frame_container_, "destroy", + G_CALLBACK(OnDestroyThunk), this); // Create a label for the source of the notification and add it to the // toolbar. @@ -268,7 +273,7 @@ void BalloonViewImpl::Show(Balloon* balloon) { // Create a button for showing the options menu, and add it to the toolbar. options_menu_button_ = theme_provider->BuildChromeButton(); g_signal_connect(options_menu_button_, "clicked", - G_CALLBACK(HandleOptionsMenuButtonThunk), this); + G_CALLBACK(OnOptionsMenuButtonThunk), this); PrepareButtonWithIcon(options_menu_button_, options_text, IDR_BALLOON_OPTIONS_ARROW_HOVER); gtk_box_pack_start(GTK_BOX(hbox_), options_menu_button_, FALSE, FALSE, 0); @@ -276,7 +281,7 @@ void BalloonViewImpl::Show(Balloon* balloon) { // Create a button to dismiss the balloon and add it to the toolbar. close_button_ = theme_provider->BuildChromeButton(); g_signal_connect(close_button_, "clicked", - G_CALLBACK(HandleCloseButtonThunk), this); + G_CALLBACK(OnCloseButtonThunk), this); PrepareButtonWithIcon(close_button_, dismiss_text, IDR_BALLOON_CLOSE_HOVER); gtk_box_pack_start(GTK_BOX(hbox_), close_button_, FALSE, FALSE, 0); @@ -293,10 +298,6 @@ void BalloonViewImpl::Show(Balloon* balloon) { NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon)); } -void BalloonViewImpl::RunOptionsMenu() { - options_menu_->PopupAsContext(gtk_get_current_event_time()); -} - gfx::Point BalloonViewImpl::GetContentsOffset() const { return gfx::Point(kTopShadowWidth + kTopMargin, kLeftShadowWidth + kLeftMargin); @@ -334,13 +335,6 @@ gfx::Rect BalloonViewImpl::GetContentsRectangle() const { content_size.width(), content_size.height()); } -gboolean BalloonViewImpl::HandleExpose() { - // Draw the background images. - balloon_background_->RenderToWidget(frame_container_); - shelf_background_->RenderToWidget(shelf_); - return FALSE; -} - void BalloonViewImpl::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { @@ -355,3 +349,20 @@ void BalloonViewImpl::Observe(NotificationType type, NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon_)); Close(false); } + +gboolean BalloonViewImpl::OnExpose(GtkWidget* sender, GdkEventExpose* e) { + // Draw the background images. + balloon_background_->RenderToWidget(frame_container_); + shelf_background_->RenderToWidget(shelf_); + return FALSE; +} + +void BalloonViewImpl::OnOptionsMenuButton(GtkWidget* widget) { + options_menu_->PopupAsContext(gtk_get_current_event_time()); +} + +gboolean BalloonViewImpl::OnDestroy(GtkWidget* widget) { + frame_container_ = NULL; + Close(false); + return FALSE; // Propagate. +} diff --git a/chrome/browser/gtk/notifications/balloon_view_gtk.h b/chrome/browser/gtk/notifications/balloon_view_gtk.h index 22660c9..9412cad 100644 --- a/chrome/browser/gtk/notifications/balloon_view_gtk.h +++ b/chrome/browser/gtk/notifications/balloon_view_gtk.h @@ -8,6 +8,7 @@ #define CHROME_BROWSER_GTK_NOTIFICATIONS_BALLOON_VIEW_GTK_H_ #include "app/animation.h" +#include "app/gtk_signal.h" #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "chrome/browser/gtk/menu_gtk.h" @@ -63,9 +64,6 @@ class BalloonViewImpl : public BalloonView, // AnimationDelegate interface. virtual void AnimationProgressed(const Animation* animation); - // Launches the options menu. - void RunOptionsMenu(); - // Adjust the contents window size to be appropriate for the frame. void SizeContentsWindow(); @@ -92,21 +90,13 @@ class BalloonViewImpl : public BalloonView, // Where the balloon contents should be in screen coordinates. gfx::Rect GetContentsRectangle() const; - static gboolean HandleExposeThunk(GtkWidget* widget, - GdkEventExpose* event, - gpointer user_data) { - return reinterpret_cast<BalloonViewImpl*>(user_data)->HandleExpose(); - } - gboolean HandleExpose(); - - static void HandleCloseButtonThunk(GtkWidget* widget, gpointer user_data) { + static void OnCloseButtonThunk(GtkWidget* widget, gpointer user_data) { reinterpret_cast<BalloonViewImpl*>(user_data)->Close(true); } - static void HandleOptionsMenuButtonThunk(GtkWidget* widget, - gpointer user_data) { - reinterpret_cast<BalloonViewImpl*>(user_data)->RunOptionsMenu(); - } + CHROMEGTK_CALLBACK_1(BalloonViewImpl, gboolean, OnExpose, GdkEventExpose*); + CHROMEGTK_CALLBACK_0(BalloonViewImpl, void, OnOptionsMenuButton); + CHROMEGTK_CALLBACK_0(BalloonViewImpl, gboolean, OnDestroy); // Non-owned pointer to the balloon which owns this object. Balloon* balloon_; |