Commit 9999a61c authored by Caroline Rising's avatar Caroline Rising Committed by Commit Bot

Make popped out extensions stay popped out if they have a context menu shown...

Make popped out extensions stay popped out if they have a context menu shown in the new extensions toolbar container.

Previously we would only check if a context menu was running when trying to hide a popped out extension. In the case where the context menu was not yet running when this happened then the popped out extension would be hidden when it shouldn't be. This change lets the ExtensionsToolbarContainer keep track of an extension with an open context menu and adjust visibility accordingly.

Bug: 943702
Change-Id: I547b16eb324852c9559238c646d189c39892fb55
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2065009
Commit-Queue: Caroline Rising <corising@chromium.org>
Reviewed-by: default avatarPeter Boström <pbos@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744119}
parent 493d2a83
...@@ -219,9 +219,19 @@ ui::MenuModel* ExtensionActionViewController::GetContextMenu() { ...@@ -219,9 +219,19 @@ ui::MenuModel* ExtensionActionViewController::GetContextMenu() {
return context_menu_model_.get(); return context_menu_model_.get();
} }
void ExtensionActionViewController::OnContextMenuShown() {
extensions_container_->OnContextMenuShown(this);
}
void ExtensionActionViewController::OnContextMenuClosed() { void ExtensionActionViewController::OnContextMenuClosed() {
if (extensions_container_->GetPoppedOutAction() == this && !IsShowingPopup()) if (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) {
extensions_container_->OnContextMenuClosed(this);
return;
}
if (extensions_container_->GetPoppedOutAction() == this &&
!view_delegate_->IsMenuRunning()) {
extensions_container_->UndoPopOut(); extensions_container_->UndoPopOut();
}
} }
bool ExtensionActionViewController::ExecuteAction(bool by_user) { bool ExtensionActionViewController::ExecuteAction(bool by_user) {
...@@ -439,7 +449,8 @@ void ExtensionActionViewController::OnPopupClosed() { ...@@ -439,7 +449,8 @@ void ExtensionActionViewController::OnPopupClosed() {
popup_host_ = nullptr; popup_host_ = nullptr;
extensions_container_->SetPopupOwner(nullptr); extensions_container_->SetPopupOwner(nullptr);
if (extensions_container_->GetPoppedOutAction() == this && if (extensions_container_->GetPoppedOutAction() == this &&
!view_delegate_->IsMenuRunning()) { (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu) ||
!view_delegate_->IsMenuRunning())) {
extensions_container_->UndoPopOut(); extensions_container_->UndoPopOut();
} }
view_delegate_->OnPopupClosed(); view_delegate_->OnPopupClosed();
......
...@@ -68,6 +68,7 @@ class ExtensionActionViewController ...@@ -68,6 +68,7 @@ class ExtensionActionViewController
void HidePopup() override; void HidePopup() override;
gfx::NativeView GetPopupNativeView() override; gfx::NativeView GetPopupNativeView() override;
ui::MenuModel* GetContextMenu() override; ui::MenuModel* GetContextMenu() override;
void OnContextMenuShown() override;
void OnContextMenuClosed() override; void OnContextMenuClosed() override;
bool ExecuteAction(bool by_user) override; bool ExecuteAction(bool by_user) override;
void UpdateState() override; void UpdateState() override;
......
...@@ -24,6 +24,14 @@ class ExtensionsContainer { ...@@ -24,6 +24,14 @@ class ExtensionsContainer {
// that relate to more than one extension. // that relate to more than one extension.
virtual ToolbarActionViewController* GetPoppedOutAction() const = 0; virtual ToolbarActionViewController* GetPoppedOutAction() const = 0;
// Called when a context menu is shown so the container can perform any
// necessary setup.
virtual void OnContextMenuShown(ToolbarActionViewController* extension) {}
// Called when a context menu is closed so the container can perform any
// necessary cleanup.
virtual void OnContextMenuClosed(ToolbarActionViewController* extension) {}
// Returns true if the given |action| is visible on the toolbar. // Returns true if the given |action| is visible on the toolbar.
virtual bool IsActionVisibleOnToolbar( virtual bool IsActionVisibleOnToolbar(
const ToolbarActionViewController* action) const = 0; const ToolbarActionViewController* action) const = 0;
......
...@@ -88,6 +88,10 @@ class ToolbarActionViewController { ...@@ -88,6 +88,10 @@ class ToolbarActionViewController {
// Returns the context menu model, or null if no context menu should be shown. // Returns the context menu model, or null if no context menu should be shown.
virtual ui::MenuModel* GetContextMenu() = 0; virtual ui::MenuModel* GetContextMenu() = 0;
// Called when a context menu is shown so the controller can perform any
// necessary setup.
virtual void OnContextMenuShown() {}
// Called when a context menu has closed so the controller can perform any // Called when a context menu has closed so the controller can perform any
// necessary cleanup. // necessary cleanup.
virtual void OnContextMenuClosed() {} virtual void OnContextMenuClosed() {}
......
...@@ -56,6 +56,7 @@ void ExtensionContextMenuController::ShowContextMenuForViewImpl( ...@@ -56,6 +56,7 @@ void ExtensionContextMenuController::ShowContextMenuForViewImpl(
menu_runner_ = std::make_unique<views::MenuRunner>(menu_, run_types); menu_runner_ = std::make_unique<views::MenuRunner>(menu_, run_types);
controller_->OnContextMenuShown();
menu_runner_->RunMenuAt( menu_runner_->RunMenuAt(
parent, parent,
static_cast<views::MenuButtonController*>( static_cast<views::MenuButtonController*>(
......
...@@ -215,6 +215,17 @@ class ExtensionsMenuViewBrowserTest : public ExtensionsToolbarBrowserTest { ...@@ -215,6 +215,17 @@ class ExtensionsMenuViewBrowserTest : public ExtensionsToolbarBrowserTest {
views::test::WaitForAnimatingLayoutManager(GetExtensionsToolbarContainer()); views::test::WaitForAnimatingLayoutManager(GetExtensionsToolbarContainer());
} }
void RightClickExtensionInToolbar(ToolbarActionView* extension) {
ui::MouseEvent click_down_event(ui::ET_MOUSE_PRESSED, gfx::Point(),
gfx::Point(), base::TimeTicks(),
ui::EF_RIGHT_MOUSE_BUTTON, 0);
ui::MouseEvent click_up_event(ui::ET_MOUSE_RELEASED, gfx::Point(),
gfx::Point(), base::TimeTicks(),
ui::EF_RIGHT_MOUSE_BUTTON, 0);
extension->OnMouseEvent(&click_down_event);
extension->OnMouseEvent(&click_up_event);
}
void ClickExtensionsMenuButton(Browser* browser) { void ClickExtensionsMenuButton(Browser* browser) {
ui::MouseEvent click_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), ui::MouseEvent click_event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, 0); base::TimeTicks(), ui::EF_LEFT_MOUSE_BUTTON, 0);
...@@ -388,6 +399,46 @@ IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewBrowserTest, TriggerPopup) { ...@@ -388,6 +399,46 @@ IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewBrowserTest, TriggerPopup) {
EXPECT_TRUE(GetVisibleToolbarActionViews().empty()); EXPECT_TRUE(GetVisibleToolbarActionViews().empty());
} }
IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewBrowserTest,
ContextMenuKeepsExtensionPoppedOut) {
LoadTestExtension("extensions/simple_with_popup");
ShowUi("");
VerifyUi();
ExtensionsToolbarContainer* const extensions_container =
GetExtensionsToolbarContainer();
EXPECT_EQ(nullptr, extensions_container->GetPoppedOutAction());
EXPECT_TRUE(GetVisibleToolbarActionViews().empty());
TriggerSingleExtensionButton();
// After triggering an extension with a popup, there should a popped-out
// action and show the view.
auto visible_icons = GetVisibleToolbarActionViews();
EXPECT_NE(nullptr, extensions_container->GetPoppedOutAction());
EXPECT_EQ(base::nullopt,
extensions_container->GetExtensionWithOpenContextMenuForTesting());
ASSERT_EQ(1u, visible_icons.size());
EXPECT_EQ(extensions_container->GetPoppedOutAction(),
visible_icons[0]->view_controller());
RightClickExtensionInToolbar(extensions_container->GetViewForId(
extensions_container->GetPoppedOutAction()->GetId()));
extensions_container->HideActivePopup();
// Wait for animations to finish.
views::test::WaitForAnimatingLayoutManager(extensions_container);
visible_icons = GetVisibleToolbarActionViews();
ASSERT_EQ(1u, visible_icons.size());
EXPECT_EQ(nullptr, extensions_container->GetPoppedOutAction());
EXPECT_NE(base::nullopt,
extensions_container->GetExtensionWithOpenContextMenuForTesting());
EXPECT_EQ(extensions_container->GetExtensionWithOpenContextMenuForTesting(),
visible_icons[0]->view_controller()->GetId());
}
IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewBrowserTest, IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewBrowserTest,
RemoveExtensionShowingPopup) { RemoveExtensionShowingPopup) {
LoadTestExtension("extensions/simple_with_popup"); LoadTestExtension("extensions/simple_with_popup");
......
...@@ -137,6 +137,11 @@ bool ExtensionsToolbarContainer::ShouldForceVisibility( ...@@ -137,6 +137,11 @@ bool ExtensionsToolbarContainer::ShouldForceVisibility(
if (popped_out_action_ && popped_out_action_->GetId() == extension_id) if (popped_out_action_ && popped_out_action_->GetId() == extension_id)
return true; return true;
if (extension_with_open_context_menu_id_.has_value() &&
extension_with_open_context_menu_id_.value() == extension_id) {
return true;
}
for (const auto& anchored_widget : anchored_widgets_) { for (const auto& anchored_widget : anchored_widgets_) {
if (anchored_widget.extension_id == extension_id) if (anchored_widget.extension_id == extension_id)
return true; return true;
...@@ -227,6 +232,21 @@ ToolbarActionViewController* ExtensionsToolbarContainer::GetPoppedOutAction() ...@@ -227,6 +232,21 @@ ToolbarActionViewController* ExtensionsToolbarContainer::GetPoppedOutAction()
return popped_out_action_; return popped_out_action_;
} }
void ExtensionsToolbarContainer::OnContextMenuShown(
ToolbarActionViewController* extension) {
extension_with_open_context_menu_id_ = extension->GetId();
UpdateIconVisibility(extension_with_open_context_menu_id_.value());
}
void ExtensionsToolbarContainer::OnContextMenuClosed(
ToolbarActionViewController* extension) {
DCHECK(extension_with_open_context_menu_id_.has_value());
base::Optional<extensions::ExtensionId> const
extension_with_open_context_menu = extension_with_open_context_menu_id_;
extension_with_open_context_menu_id_.reset();
UpdateIconVisibility(extension_with_open_context_menu.value());
}
bool ExtensionsToolbarContainer::IsActionVisibleOnToolbar( bool ExtensionsToolbarContainer::IsActionVisibleOnToolbar(
const ToolbarActionViewController* action) const { const ToolbarActionViewController* action) const {
const std::string& extension_id = action->GetId(); const std::string& extension_id = action->GetId();
......
...@@ -78,6 +78,11 @@ class ExtensionsToolbarContainer : public ToolbarIconContainerView, ...@@ -78,6 +78,11 @@ class ExtensionsToolbarContainer : public ToolbarIconContainerView,
views::Widget* GetAnchoredWidgetForExtensionForTesting( views::Widget* GetAnchoredWidgetForExtensionForTesting(
const std::string& extension_id); const std::string& extension_id);
base::Optional<extensions::ExtensionId>
GetExtensionWithOpenContextMenuForTesting() {
return extension_with_open_context_menu_id_;
}
// ToolbarIconContainerView: // ToolbarIconContainerView:
void UpdateAllIcons() override; void UpdateAllIcons() override;
bool GetDropFormats(int* formats, bool GetDropFormats(int* formats,
...@@ -92,6 +97,8 @@ class ExtensionsToolbarContainer : public ToolbarIconContainerView, ...@@ -92,6 +97,8 @@ class ExtensionsToolbarContainer : public ToolbarIconContainerView,
ToolbarActionViewController* GetActionForId( ToolbarActionViewController* GetActionForId(
const std::string& action_id) override; const std::string& action_id) override;
ToolbarActionViewController* GetPoppedOutAction() const override; ToolbarActionViewController* GetPoppedOutAction() const override;
void OnContextMenuShown(ToolbarActionViewController* extension) override;
void OnContextMenuClosed(ToolbarActionViewController* extension) override;
bool IsActionVisibleOnToolbar( bool IsActionVisibleOnToolbar(
const ToolbarActionViewController* action) const override; const ToolbarActionViewController* action) const override;
void UndoPopOut() override; void UndoPopOut() override;
...@@ -217,6 +224,8 @@ class ExtensionsToolbarContainer : public ToolbarIconContainerView, ...@@ -217,6 +224,8 @@ class ExtensionsToolbarContainer : public ToolbarIconContainerView,
ToolbarActionViewController* popped_out_action_ = nullptr; ToolbarActionViewController* popped_out_action_ = nullptr;
// The action that triggered the current popup, if any. // The action that triggered the current popup, if any.
ToolbarActionViewController* popup_owner_ = nullptr; ToolbarActionViewController* popup_owner_ = nullptr;
// Extension with an open context menu, if any.
base::Optional<extensions::ExtensionId> extension_with_open_context_menu_id_;
// The widgets currently popped out and, for each, the extension it is // The widgets currently popped out and, for each, the extension it is
// associated with. See AnchoredWidget. // associated with. See AnchoredWidget.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment