Chromium Code Reviews| Index: chrome/browser/ui/views/toolbar/browser_action_view.cc |
| diff --git a/chrome/browser/ui/views/toolbar/browser_action_view.cc b/chrome/browser/ui/views/toolbar/browser_action_view.cc |
| index 149148aef0d0a9d3d01b2a1d6c1c38028d6df924..f5390cbf20f248ea162eca67040158a88a67b6af 100644 |
| --- a/chrome/browser/ui/views/toolbar/browser_action_view.cc |
| +++ b/chrome/browser/ui/views/toolbar/browser_action_view.cc |
| @@ -4,13 +4,14 @@ |
| #include "chrome/browser/ui/views/toolbar/browser_action_view.h" |
| +#include <string> |
| + |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| #include "chrome/browser/extensions/api/commands/command_service.h" |
| #include "chrome/browser/extensions/extension_action.h" |
| #include "chrome/browser/extensions/extension_action_manager.h" |
| #include "chrome/browser/extensions/extension_context_menu_model.h" |
| -#include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/themes/theme_service.h" |
| #include "chrome/browser/themes/theme_service_factory.h" |
| @@ -138,7 +139,7 @@ BrowserActionButton::BrowserActionButton(const Extension* extension, |
| void BrowserActionButton::Destroy() { |
| MaybeUnregisterExtensionCommand(false); |
| - |
| + HidePopup(); |
| if (menu_runner_) { |
| menu_runner_->Cancel(); |
| base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| @@ -176,7 +177,7 @@ void BrowserActionButton::GetAccessibleState(ui::AXViewState* state) { |
| void BrowserActionButton::ButtonPressed(views::Button* sender, |
| const ui::Event& event) { |
| - delegate_->OnBrowserActionExecuted(this); |
| + ExecuteBrowserAction(); |
| } |
| void BrowserActionButton::ShowContextMenuForView( |
| @@ -190,7 +191,7 @@ void BrowserActionButton::ShowContextMenuForView( |
| // Reconstructs the menu every time because the menu's contents are dynamic. |
| scoped_refptr<ExtensionContextMenuModel> context_menu_contents( |
| - new ExtensionContextMenuModel(extension(), browser_, delegate_)); |
| + new ExtensionContextMenuModel(extension(), browser_, this)); |
| gfx::Point screen_loc; |
| views::View::ConvertPointToScreen(this, &screen_loc); |
| @@ -271,6 +272,58 @@ GURL BrowserActionButton::GetPopupUrl() { |
| return (tab_id < 0) ? GURL() : browser_action_->GetPopupUrl(tab_id); |
| } |
| +bool BrowserActionButton::ShowPopup( |
| + ExtensionPopup::ShowAction show_action, |
| + bool grant_tab_permissions) { |
| + GURL popup_url; |
| + if (delegate_->GetModel()->ExecuteBrowserAction( |
| + extension_, browser_, &popup_url, grant_tab_permissions) == |
| + extensions::ExtensionToolbarModel::ACTION_NONE) { |
| + return false; |
| + } |
| + |
| + // If we're showing the same popup, just hide it and return. |
|
Peter Kasting
2014/07/26 02:33:20
Nit: The word "same" in this sentence is slightly
Devlin
2014/07/29 19:07:14
Yeah - same means "the popup for this browser acti
|
| + bool already_showing = popup_ != NULL; |
| + |
| + // Always hide the current popup, even if it's not the same. |
| + // Only one popup should be visible at a time. |
| + delegate_->HideActivePopup(); |
| + if (already_showing) |
| + return false; |
| + |
| + // Browser actions in the overflow menu can still show popups, so we may need |
| + // a reference view other than this view. If so, use the overflow view. |
| + views::View* reference_view = |
| + parent()->visible() ? this : delegate_->GetOverflowReferenceView(); |
| + |
| + popup_ = ExtensionPopup::ShowPopup(popup_url, |
| + browser_, |
| + reference_view, |
| + views::BubbleBorder::TOP_RIGHT, |
| + show_action); |
| + popup_->GetWidget()->AddObserver(this); |
| + delegate_->SetPopupOwner(this); |
| + |
| + // Only set button as pushed if it was triggered by a user click. |
| + if (grant_tab_permissions) |
| + SetButtonPushed(); |
| + return true; |
| +} |
| + |
| +void BrowserActionButton::HidePopup() { |
| + if (popup_) { |
| + popup_->GetWidget()->RemoveObserver(this); |
| + popup_->GetWidget()->Close(); |
| + popup_ = NULL; |
| + SetButtonNotPushed(); |
| + delegate_->SetPopupOwner(NULL); |
| + } |
| +} |
| + |
| +void BrowserActionButton::ExecuteBrowserAction() { |
| + ShowPopup(ExtensionPopup::SHOW, true); |
| +} |
| + |
| void BrowserActionButton::Observe(int type, |
| const content::NotificationSource& source, |
| const content::NotificationDetails& details) { |
| @@ -315,7 +368,7 @@ bool BrowserActionButton::Activate() { |
| if (!IsPopup()) |
| return true; |
| - delegate_->OnBrowserActionExecuted(this); |
| + ExecuteBrowserAction(); |
| // TODO(erikkay): Run a nested modal loop while the mouse is down to |
| // enable menu-like drag-select behavior. |
| @@ -386,7 +439,7 @@ bool BrowserActionButton::AcceleratorPressed( |
| ui::AcceleratorManager::kNormalPriority) |
| return false; |
| - delegate_->OnBrowserActionExecuted(this); |
| + ExecuteBrowserAction(); |
| return true; |
| } |
| @@ -420,6 +473,20 @@ gfx::ImageSkia BrowserActionButton::GetIconForTest() { |
| BrowserActionButton::~BrowserActionButton() { |
| } |
| +void BrowserActionButton::InspectPopup(ExtensionAction* action) { |
| + DCHECK_EQ(browser_action_, action); |
| + ShowPopup(ExtensionPopup::SHOW_AND_INSPECT, true); // grant active tab |
| +} |
| + |
| +void BrowserActionButton::OnWidgetDestroying(views::Widget* widget) { |
|
Peter Kasting
2014/07/26 02:33:20
This code sure looks a lot like HidePopup(). Can
Devlin
2014/07/29 19:07:14
I'm not 100% sure. The problem being the call to
Peter Kasting
2014/07/29 19:18:01
Widget::Close()'s definition checks whether the wi
Devlin
2014/07/29 19:51:46
That may still be problematic. In particular, wid
Peter Kasting
2014/07/29 19:56:05
There isn't from the user's perspective, but there
Devlin
2014/07/29 19:59:48
In theory, if we have a popup showing, and then we
Peter Kasting
2014/07/29 20:03:02
The async close should happen with the next messag
Devlin
2014/07/29 21:25:43
- PatchSet 2 (just calling HidePopup() from OnWidg
Devlin
2014/07/29 21:45:04
Done!
|
| + DCHECK(popup_); |
| + DCHECK_EQ(popup_->GetWidget(), widget); |
| + popup_->GetWidget()->RemoveObserver(this); |
| + popup_ = NULL; |
| + SetButtonNotPushed(); |
| + delegate_->SetPopupOwner(NULL); |
| +} |
| + |
| void BrowserActionButton::MaybeRegisterExtensionCommand() { |
| extensions::CommandService* command_service = |
| extensions::CommandService::Get(browser_->profile()); |