Index: chrome/browser/ui/views/toolbar/browser_actions_container.cc |
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
index b86b08413c2a0ffa01566426b1bb203f4f2f0ad4..313026746f525c711a06c96b4adb941c1bab6bb1 100644 |
--- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc |
@@ -6,6 +6,7 @@ |
#include "base/compiler_specific.h" |
#include "base/stl_util.h" |
+#include "chrome/browser/extensions/extension_message_bubble_controller.h" |
#include "chrome/browser/extensions/tab_helper.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/ui/browser.h" |
@@ -14,6 +15,7 @@ |
#include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" |
#include "chrome/browser/ui/view_ids.h" |
#include "chrome/browser/ui/views/extensions/browser_action_drag_data.h" |
+#include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h" |
#include "chrome/browser/ui/views/extensions/extension_toolbar_icon_surfacing_bubble_views.h" |
#include "chrome/browser/ui/views/frame/browser_view.h" |
#include "chrome/browser/ui/views/toolbar/browser_actions_container_observer.h" |
@@ -33,6 +35,7 @@ |
#include "ui/gfx/canvas.h" |
#include "ui/gfx/geometry/rect.h" |
#include "ui/resources/grit/ui_resources.h" |
+#include "ui/views/bubble/bubble_delegate.h" |
#include "ui/views/controls/resize_area.h" |
#include "ui/views/painter.h" |
#include "ui/views/widget/widget.h" |
@@ -83,7 +86,8 @@ BrowserActionsContainer::BrowserActionsContainer( |
added_to_view_(false), |
shown_bubble_(false), |
resize_amount_(0), |
- animation_target_size_(0) { |
+ animation_target_size_(0), |
+ active_bubble_(nullptr) { |
set_id(VIEW_ID_BROWSER_ACTION_TOOLBAR); |
bool overflow_experiment = |
@@ -112,6 +116,12 @@ BrowserActionsContainer::BrowserActionsContainer( |
} |
BrowserActionsContainer::~BrowserActionsContainer() { |
+ if (active_bubble_) |
+ active_bubble_->GetWidget()->Close(); |
+ // We should synchronously receive the OnWidgetClosing() event, so we should |
+ // always have cleared the active bubble by now. |
+ DCHECK(!active_bubble_); |
+ |
FOR_EACH_OBSERVER(BrowserActionsContainerObserver, |
observers_, |
OnBrowserActionsContainerDestroyed()); |
@@ -339,6 +349,40 @@ void BrowserActionsContainer::OnOverflowedActionWantsToRunChanged( |
overflowed_action_wants_to_run); |
} |
+void BrowserActionsContainer::ShowExtensionMessageBubble( |
+ scoped_ptr<extensions::ExtensionMessageBubbleController> controller) { |
+ if (animating()) { |
+ // Similarly, if the container is animating, we can't effectively anchor the |
+ // bubble, so wait until animation stops. |
+ pending_extension_bubble_controller_ = controller.Pass(); |
+ return; |
+ } |
+ |
+ views::View* reference_view = VisibleBrowserActions() > 0 ? |
+ static_cast<views::View*>(toolbar_action_views_[0]) : |
+ BrowserView::GetBrowserViewForBrowser(browser_)->toolbar()->app_menu(); |
+ |
+ extensions::ExtensionMessageBubbleController* weak_controller = |
+ controller.get(); |
+ extensions::ExtensionMessageBubbleView* bubble = |
+ new extensions::ExtensionMessageBubbleView( |
+ reference_view, |
+ views::BubbleBorder::TOP_RIGHT, |
+ controller.Pass()); |
+ views::BubbleDelegateView::CreateBubble(bubble); |
+ active_bubble_ = bubble; |
+ active_bubble_->GetWidget()->AddObserver(this); |
+ weak_controller->Show(bubble); |
+} |
+ |
+void BrowserActionsContainer::OnWidgetClosing(views::Widget* widget) { |
+ ClearActiveBubble(widget); |
+} |
+ |
+void BrowserActionsContainer::OnWidgetDestroying(views::Widget* widget) { |
+ ClearActiveBubble(widget); |
+} |
+ |
void BrowserActionsContainer::AddObserver( |
BrowserActionsContainerObserver* observer) { |
observers_.AddObserver(observer); |
@@ -668,6 +712,9 @@ void BrowserActionsContainer::AnimationEnded(const gfx::Animation* animation) { |
FOR_EACH_OBSERVER(BrowserActionsContainerObserver, |
observers_, |
OnBrowserActionsContainerAnimationEnded()); |
+ |
+ if (pending_extension_bubble_controller_) |
+ ShowExtensionMessageBubble(pending_extension_bubble_controller_.Pass()); |
} |
content::WebContents* BrowserActionsContainer::GetCurrentWebContents() { |
@@ -780,3 +827,10 @@ void BrowserActionsContainer::LoadImages() { |
const int kImages[] = IMAGE_GRID(IDR_DEVELOPER_MODE_HIGHLIGHT); |
highlight_painter_.reset(views::Painter::CreateImageGridPainter(kImages)); |
} |
+ |
+void BrowserActionsContainer::ClearActiveBubble(views::Widget* widget) { |
+ DCHECK(active_bubble_); |
+ DCHECK_EQ(active_bubble_->GetWidget(), widget); |
+ widget->RemoveObserver(this); |
+ active_bubble_ = nullptr; |
+} |