diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-29 17:52:58 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-29 17:52:58 +0000 |
commit | ebdc76943e8909d261b6d776ed973a16c0086341 (patch) | |
tree | 385381b00f4ce3f1974d21b7a295924bc395dcf0 | |
parent | c8173315b15ccf58d8062900fd25eebfd56eb327 (diff) | |
download | chromium_src-ebdc76943e8909d261b6d776ed973a16c0086341.zip chromium_src-ebdc76943e8909d261b6d776ed973a16c0086341.tar.gz chromium_src-ebdc76943e8909d261b6d776ed973a16c0086341.tar.bz2 |
Put TabGtk's Observer inside a scoped_ptr.
BUG=24679
TEST=Mouse down on a tab, then press ctrl+w. This should not result in a dangling pointer in the MessagePump's ObserverList.
Review URL: http://codereview.chromium.org/340028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30472 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/tabs/tab_gtk.cc | 25 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_gtk.h | 4 |
2 files changed, 25 insertions, 4 deletions
diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc index 4713063..299c2be 100644 --- a/chrome/browser/gtk/tabs/tab_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_gtk.cc @@ -108,6 +108,23 @@ class TabGtk::ContextMenuController : public MenuGtk::Delegate { DISALLOW_COPY_AND_ASSIGN(ContextMenuController); }; +class TabGtk::TabGtkObserverHelper { + public: + explicit TabGtkObserverHelper(TabGtk* tab) + : tab_(tab) { + MessageLoopForUI::current()->AddObserver(tab_); + } + + ~TabGtkObserverHelper() { + MessageLoopForUI::current()->RemoveObserver(tab_); + } + + private: + TabGtk* tab_; + + DISALLOW_COPY_AND_ASSIGN(TabGtkObserverHelper); +}; + /////////////////////////////////////////////////////////////////////////////// // TabGtk, public: @@ -162,7 +179,7 @@ gboolean TabGtk::OnButtonPressEvent(GtkWidget* widget, GdkEventButton* event, } // Hook into the message loop to handle dragging. - MessageLoopForUI::current()->AddObserver(tab); + tab->observer_.reset(new TabGtkObserverHelper(tab)); // Store the button press event, used to initiate a drag. tab->last_mouse_down_ = gdk_event_copy(reinterpret_cast<GdkEvent*>(event)); @@ -180,7 +197,7 @@ gboolean TabGtk::OnButtonPressEvent(GtkWidget* widget, GdkEventButton* event, gboolean TabGtk::OnButtonReleaseEvent(GtkWidget* widget, GdkEventButton* event, TabGtk* tab) { if (event->button == 1) { - MessageLoopForUI::current()->RemoveObserver(tab); + tab->observer_.reset(); if (tab->last_mouse_down_) { gdk_event_free(tab->last_mouse_down_); @@ -200,7 +217,7 @@ gboolean TabGtk::OnButtonReleaseEvent(GtkWidget* widget, GdkEventButton* event, // started, we don't get the middle mouse click here. if (tab->last_mouse_down_) { DCHECK(!tab->drag_widget_); - MessageLoopForUI::current()->RemoveObserver(tab); + tab->observer_.reset(); gdk_event_free(tab->last_mouse_down_); tab->last_mouse_down_ = NULL; } @@ -382,5 +399,5 @@ void TabGtk::EndDrag(bool canceled) { // Clean up the drag helper, which is re-created on the next mouse press. delegate_->EndDrag(canceled); - MessageLoopForUI::current()->RemoveObserver(this); + observer_.reset(); } diff --git a/chrome/browser/gtk/tabs/tab_gtk.h b/chrome/browser/gtk/tabs/tab_gtk.h index c5a91d2..75a7945 100644 --- a/chrome/browser/gtk/tabs/tab_gtk.h +++ b/chrome/browser/gtk/tabs/tab_gtk.h @@ -97,6 +97,7 @@ class TabGtk : public TabRendererGtk, private: class ContextMenuController; + class TabGtkObserverHelper; friend class ContextMenuController; // MessageLoop::Observer implementation: @@ -184,6 +185,9 @@ class TabGtk : public TabRendererGtk, // changes. int title_width_; + // Keep track of whether or not we have an observer. + scoped_ptr<TabGtkObserverHelper> observer_; + // Used to destroy the drag widget after a return to the message loop. ScopedRunnableMethodFactory<TabGtk> destroy_factory_; |