diff options
12 files changed, 38 insertions, 22 deletions
diff --git a/chrome/browser/chromeos/notifications/balloon_view.cc b/chrome/browser/chromeos/notifications/balloon_view.cc index b4fe5aa..756de0b 100644 --- a/chrome/browser/chromeos/notifications/balloon_view.cc +++ b/chrome/browser/chromeos/notifications/balloon_view.cc @@ -121,12 +121,11 @@ class NotificationControlView : public views::View, CreateOptionsMenu(); views::MenuModelAdapter menu_model_adapter(options_menu_contents_.get()); - views::MenuRunner menu_runner(menu_model_adapter.CreateMenu()); + menu_runner_.reset(new views::MenuRunner(menu_model_adapter.CreateMenu())); gfx::Point screen_location; - views::View::ConvertPointToScreen(options_menu_button_, - &screen_location); - if (menu_runner.RunMenuAt( + views::View::ConvertPointToScreen(options_menu_button_, &screen_location); + if (menu_runner_->RunMenuAt( source->GetWidget()->GetTopLevelWidget(), options_menu_button_, gfx::Rect(screen_location, options_menu_button_->size()), views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) == @@ -189,6 +188,7 @@ class NotificationControlView : public views::View, // The options menu. scoped_ptr<ui::SimpleMenuModel> options_menu_contents_; + scoped_ptr<views::MenuRunner> menu_runner_; views::MenuButton* options_menu_button_; DISALLOW_COPY_AND_ASSIGN(NotificationControlView); diff --git a/chrome/browser/chromeos/status/memory_menu_button.cc b/chrome/browser/chromeos/status/memory_menu_button.cc index 291fa67..fe4c33c 100644 --- a/chrome/browser/chromeos/status/memory_menu_button.cc +++ b/chrome/browser/chromeos/status/memory_menu_button.cc @@ -212,11 +212,11 @@ void MemoryMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { // View passed in must be a views::MenuButton, i.e. the MemoryMenuButton. DCHECK_EQ(source, this); - views::MenuRunner menu_runner(CreateMenu()); + menu_runner_.reset(new views::MenuRunner(CreateMenu())); gfx::Point screen_location; views::View::ConvertPointToScreen(source, &screen_location); gfx::Rect bounds(screen_location, source->size()); - if (menu_runner.RunMenuAt( + if (menu_runner_->RunMenuAt( source->GetWidget()->GetTopLevelWidget(), this, bounds, views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED) diff --git a/chrome/browser/chromeos/status/memory_menu_button.h b/chrome/browser/chromeos/status/memory_menu_button.h index 2802c26..c86db2a 100644 --- a/chrome/browser/chromeos/status/memory_menu_button.h +++ b/chrome/browser/chromeos/status/memory_menu_button.h @@ -75,6 +75,8 @@ class MemoryMenuButton : public StatusAreaButton, // Number of renderer kills we have observed. int renderer_kills_; + scoped_ptr<views::MenuRunner> menu_runner_; + DISALLOW_COPY_AND_ASSIGN(MemoryMenuButton); }; diff --git a/chrome/browser/chromeos/status/power_menu_button.cc b/chrome/browser/chromeos/status/power_menu_button.cc index 05578636..555f67d 100644 --- a/chrome/browser/chromeos/status/power_menu_button.cc +++ b/chrome/browser/chromeos/status/power_menu_button.cc @@ -222,7 +222,7 @@ class PowerMenuButton::StatusView : public View { void OnMouseReleased(const views::MouseEvent& event) { if (event.IsLeftMouseButton()) { - DCHECK(menu_button_->menu_runner_); + DCHECK(menu_button_->menu_runner_.get()); menu_button_->menu_runner_->Cancel(); } } @@ -244,8 +244,7 @@ PowerMenuButton::PowerMenuButton(StatusAreaHost* host) battery_index_(-1), battery_time_to_full_(TimeDelta::FromMicroseconds(kInitialMS)), battery_time_to_empty_(TimeDelta::FromMicroseconds(kInitialMS)), - status_(NULL), - menu_runner_(NULL) { + status_(NULL) { UpdateIconAndLabelInfo(); CrosLibrary::Get()->GetPowerLibrary()->AddObserver(this); } @@ -319,7 +318,7 @@ void PowerMenuButton::OnLocaleChanged() { void PowerMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { views::MenuItemView* menu = new views::MenuItemView(this); // MenuRunner takes ownership of |menu|. - views::MenuRunner menu_runner(menu); + menu_runner_.reset(new views::MenuRunner(menu)); views::MenuItemView* submenu = menu->AppendMenuItem( POWER_BATTERY_PERCENTAGE_ITEM, std::wstring(), @@ -334,14 +333,13 @@ void PowerMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { gfx::Point screen_location; views::View::ConvertPointToScreen(source, &screen_location); gfx::Rect bounds(screen_location, source->size()); - AutoReset<views::MenuRunner*> menu_runner_reseter(&menu_runner_, - &menu_runner); - if (menu_runner.RunMenuAt( + if (menu_runner_->RunMenuAt( source->GetWidget()->GetTopLevelWidget(), this, bounds, views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED) return; status_ = NULL; + menu_runner_.reset(NULL); } //////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/browser/chromeos/status/power_menu_button.h b/chrome/browser/chromeos/status/power_menu_button.h index aef5aec7..14e157e 100644 --- a/chrome/browser/chromeos/status/power_menu_button.h +++ b/chrome/browser/chromeos/status/power_menu_button.h @@ -80,7 +80,7 @@ class PowerMenuButton : public StatusAreaButton, StatusView* status_; // If non-null the menu is showing. - views::MenuRunner* menu_runner_; + scoped_ptr<views::MenuRunner> menu_runner_; DISALLOW_COPY_AND_ASSIGN(PowerMenuButton); }; diff --git a/chrome/browser/ui/views/infobars/after_translate_infobar.cc b/chrome/browser/ui/views/infobars/after_translate_infobar.cc index 6100958..43803af 100644 --- a/chrome/browser/ui/views/infobars/after_translate_infobar.cc +++ b/chrome/browser/ui/views/infobars/after_translate_infobar.cc @@ -177,8 +177,8 @@ void AfterTranslateInfoBar::RunMenu(View* source, const gfx::Point& pt) { } views::MenuModelAdapter menu_model_adapter(menu_model); - views::MenuRunner menu_runner(menu_model_adapter.CreateMenu()); - if (menu_runner.RunMenuAt( + menu_runner_.reset(new views::MenuRunner(menu_model_adapter.CreateMenu())); + if (menu_runner_->RunMenuAt( source->GetWidget(), NULL, gfx::Rect(pt, gfx::Size()), views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED) diff --git a/chrome/browser/ui/views/infobars/after_translate_infobar.h b/chrome/browser/ui/views/infobars/after_translate_infobar.h index ade2d2b..443e60e 100644 --- a/chrome/browser/ui/views/infobars/after_translate_infobar.h +++ b/chrome/browser/ui/views/infobars/after_translate_infobar.h @@ -14,6 +14,7 @@ class TranslateInfoBarDelegate; namespace views { class MenuButton; +class MenuRunner; } class AfterTranslateInfoBar : public TranslateInfoBarBase, @@ -53,6 +54,8 @@ class AfterTranslateInfoBar : public TranslateInfoBarBase, LanguagesMenuModel target_language_menu_model_; OptionsMenuModel options_menu_model_; + scoped_ptr<views::MenuRunner> menu_runner_; + // True if the target language comes before the original one. bool swapped_language_buttons_; diff --git a/chrome/browser/ui/views/infobars/extension_infobar.cc b/chrome/browser/ui/views/infobars/extension_infobar.cc index ad83e0f..49f02ab 100644 --- a/chrome/browser/ui/views/infobars/extension_infobar.cc +++ b/chrome/browser/ui/views/infobars/extension_infobar.cc @@ -149,11 +149,10 @@ void ExtensionInfoBar::RunMenu(View* source, const gfx::Point& pt) { scoped_refptr<ExtensionContextMenuModel> options_menu_contents = new ExtensionContextMenuModel(extension, browser, NULL); views::MenuModelAdapter options_menu_delegate(options_menu_contents.get()); - views::MenuRunner options_menu_runner(options_menu_delegate.CreateMenu()); - + menu_runner_.reset(new views::MenuRunner(options_menu_delegate.CreateMenu())); gfx::Point screen_point; views::View::ConvertPointToScreen(menu_, &screen_point); - if (options_menu_runner.RunMenuAt(GetWidget(), menu_, + if (menu_runner_->RunMenuAt(GetWidget(), menu_, gfx::Rect(screen_point, menu_->size()), views::MenuItemView::TOPLEFT, views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED) return; diff --git a/chrome/browser/ui/views/infobars/extension_infobar.h b/chrome/browser/ui/views/infobars/extension_infobar.h index 8739c347..2d42e98 100644 --- a/chrome/browser/ui/views/infobars/extension_infobar.h +++ b/chrome/browser/ui/views/infobars/extension_infobar.h @@ -14,6 +14,7 @@ class TabContentsWrapper; namespace views { class MenuButton; +class MenuRunner; } class ExtensionInfoBar : public InfoBarView, @@ -56,6 +57,8 @@ class ExtensionInfoBar : public InfoBarView, // Keeps track of images being loaded on the File thread. ImageLoadingTracker tracker_; + scoped_ptr<views::MenuRunner> menu_runner_; + DISALLOW_COPY_AND_ASSIGN(ExtensionInfoBar); }; diff --git a/chrome/browser/ui/views/location_bar/page_action_image_view.cc b/chrome/browser/ui/views/location_bar/page_action_image_view.cc index dc7086c..0638fa6 100644 --- a/chrome/browser/ui/views/location_bar/page_action_image_view.cc +++ b/chrome/browser/ui/views/location_bar/page_action_image_view.cc @@ -144,11 +144,10 @@ void PageActionImageView::ShowContextMenu(const gfx::Point& p, scoped_refptr<ExtensionContextMenuModel> context_menu_model( new ExtensionContextMenuModel(extension, owner_->browser(), this)); views::MenuModelAdapter menu_model_adapter(context_menu_model.get()); - views::MenuRunner menu_runner(menu_model_adapter.CreateMenu()); - + menu_runner_.reset(new views::MenuRunner(menu_model_adapter.CreateMenu())); gfx::Point screen_loc; views::View::ConvertPointToScreen(this, &screen_loc); - if (menu_runner.RunMenuAt(GetWidget(), NULL, gfx::Rect(screen_loc, size()), + if (menu_runner_->RunMenuAt(GetWidget(), NULL, gfx::Rect(screen_loc, size()), views::MenuItemView::TOPLEFT, views::MenuRunner::HAS_MNEMONICS) == views::MenuRunner::MENU_DELETED) return; diff --git a/chrome/browser/ui/views/location_bar/page_action_image_view.h b/chrome/browser/ui/views/location_bar/page_action_image_view.h index 5b045b2..8e00aff 100644 --- a/chrome/browser/ui/views/location_bar/page_action_image_view.h +++ b/chrome/browser/ui/views/location_bar/page_action_image_view.h @@ -16,6 +16,9 @@ #include "views/controls/image_view.h" class LocationBarView; +namespace views { +class MenuRunner; +} // PageActionImageView is used by the LocationBarView to display the icon for a // given PageAction and notify the extension when the icon is clicked. @@ -98,6 +101,8 @@ class PageActionImageView : public views::ImageView, // The current popup and the button it came from. NULL if no popup. ExtensionPopup* popup_; + scoped_ptr<views::MenuRunner> menu_runner_; + DISALLOW_IMPLICIT_CONSTRUCTORS(PageActionImageView); }; diff --git a/views/controls/menu/menu_runner.h b/views/controls/menu/menu_runner.h index 5cdb845..37b8440 100644 --- a/views/controls/menu/menu_runner.h +++ b/views/controls/menu/menu_runner.h @@ -32,6 +32,13 @@ class MenuRunnerImpl; // the MenuRunner while the menu is running, your object is effectively still // on the stack. A return value of MENU_DELETED indicated this. In most cases // if RunMenuAt() returns MENU_DELETED, you should return immediately. +// +// Similarly you should avoid creating MenuRunner on the stack. Doing so means +// MenuRunner may not be immediately destroyed if your object is destroyed, +// resulting in possible callbacks to your now deleted object. Instead you +// should define MenuRunner as a scoped_ptr in your class so that when your +// object is destroyed MenuRunner initiates the proper cleanup and ensures your +// object isn't accessed again. class VIEWS_EXPORT MenuRunner { public: enum RunTypes { |