summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/notifications
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 20:46:01 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-25 20:46:01 +0000
commit6d9a36f8262936f7ef730bfdac7a1058aa1d99d6 (patch)
tree808b265651401303b3da57f930ccd7dba465f9a7 /chrome/browser/gtk/notifications
parent3b5f702430290ecaba83c83d5e617b22acf2b517 (diff)
downloadchromium_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/browser/gtk/notifications')
-rw-r--r--chrome/browser/gtk/notifications/balloon_view_gtk.cc43
-rw-r--r--chrome/browser/gtk/notifications/balloon_view_gtk.h20
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_;