Commit e934d06d authored by lazyboy's avatar lazyboy Committed by Commit bot

Remove Downcasting RVContextMenuBase in ContextMenuDeleagate implementations.

ContextMenuDelegate talks in RVCMBase. This is fine for
ContextMenuDelegate::BuildMenu, but while showing it through
ContextMenuDelegate::ShowMenu, each platform downcasts the
RVCMBase to its own variant (RVCMViews, RVCMMac, RVCMImpl),
this seems unnecessary since the showing functionality can be
moved to RVContextMenuBase.
This CL does that and adds a virtual Show() function on
RVCMBase.

BUG=397364
Test=No visible change should occur.
For reference, this CL is related to brining up right-click context menus
in chrome.

Review URL: https://codereview.chromium.org/678653003

Cr-Commit-Position: refs/heads/master@{#301564}
parent 4a2dcc48
......@@ -8,9 +8,13 @@
#include "components/renderer_context_menu/context_menu_content_type.h"
#include "components/renderer_context_menu/views/toolkit_delegate_views.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "third_party/WebKit/public/web/WebContextMenuData.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/widget/widget.h"
namespace athena {
using blink::WebContextMenuData;
......@@ -110,6 +114,34 @@ void RenderViewContextMenuImpl::RunMenuAt(views::Widget* parent,
->RunMenuAt(parent, point, type);
}
void RenderViewContextMenuImpl::Show() {
// Menus need a Widget to work. If we're not the active tab we won't
// necessarily be in a widget.
views::Widget* top_level_widget = GetTopLevelWidget();
if (!top_level_widget)
return;
// Don't show empty menus.
if (menu_model().GetItemCount() == 0)
return;
gfx::Point screen_point(params().x, params().y);
// Convert from target window coordinates to root window coordinates.
aura::Window* target_window = GetActiveNativeView();
aura::Window* root_window = target_window->GetRootWindow();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root_window);
if (screen_position_client)
screen_position_client->ConvertPointToScreen(target_window, &screen_point);
// Enable recursive tasks on the message loop so we can get updates while
// the context menu is being displayed.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
RunMenuAt(top_level_widget, screen_point, params().source_type);
}
void RenderViewContextMenuImpl::InitMenu() {
RenderViewContextMenuBase::InitMenu();
bool needs_separator = false;
......@@ -279,4 +311,22 @@ void RenderViewContextMenuImpl::ExecuteCommand(int command_id,
}
}
views::Widget* RenderViewContextMenuImpl::GetTopLevelWidget() {
return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView());
}
aura::Window* RenderViewContextMenuImpl::GetActiveNativeView() {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(GetRenderFrameHost());
if (!web_contents) {
LOG(ERROR) << "RenderViewContextMenuImpl::Show, couldn't find WebContents";
return NULL;
}
return web_contents->GetFullscreenRenderWidgetHostView()
? web_contents->GetFullscreenRenderWidgetHostView()
->GetNativeView()
: web_contents->GetNativeView();
}
} // namespace athena
......@@ -7,14 +7,18 @@
#include "components/renderer_context_menu/render_view_context_menu_base.h"
namespace views {
class Widget;
namespace aura {
class Window;
}
namespace gfx {
class Point;
}
namespace views {
class Widget;
}
namespace athena {
class RenderViewContextMenuImpl : public RenderViewContextMenuBase {
......@@ -27,6 +31,9 @@ class RenderViewContextMenuImpl : public RenderViewContextMenuBase {
const gfx::Point& point,
ui::MenuSourceType type);
// RenderViewContextMenuBase:
void Show() override;
private:
// RenderViewContextMenuBase:
void InitMenu() override;
......@@ -46,6 +53,9 @@ class RenderViewContextMenuImpl : public RenderViewContextMenuBase {
bool IsCommandIdEnabled(int command_id) const override;
void ExecuteCommand(int command_id, int event_flags) override;
aura::Window* GetActiveNativeView();
views::Widget* GetTopLevelWidget();
DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenuImpl);
};
......
......@@ -81,37 +81,10 @@ class WebContentsViewDelegateImpl : public content::WebContentsViewDelegate {
void ShowMenu(scoped_ptr<RenderViewContextMenuImpl> menu) {
context_menu_.reset(menu.release());
if (!context_menu_.get())
if (!context_menu_)
return;
// Menus need a Widget to work. If we're not the active tab we won't
// necessarily be in a widget.
views::Widget* top_level_widget = GetTopLevelWidget();
if (!top_level_widget)
return;
const content::ContextMenuParams& params = context_menu_->params();
// Don't show empty menus.
if (context_menu_->menu_model().GetItemCount() == 0)
return;
gfx::Point screen_point(params.x, params.y);
// Convert from target window coordinates to root window coordinates.
aura::Window* target_window = GetActiveNativeView();
aura::Window* root_window = target_window->GetRootWindow();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root_window);
if (screen_position_client) {
screen_position_client->ConvertPointToScreen(target_window,
&screen_point);
}
// Enable recursive tasks on the message loop so we can get updates while
// the context menu is being displayed.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
context_menu_->RunMenuAt(
top_level_widget, screen_point, params.source_type);
context_menu_->Show();
}
aura::Window* GetActiveNativeView() {
......
......@@ -75,6 +75,8 @@ class PlatformAppContextMenu : public RenderViewContextMenu {
return menu_model_.GetIndexOfCommandId(command_id) != -1;
}
void Show() override {}
protected:
// RenderViewContextMenu implementation.
bool GetAcceleratorForCommandId(int command_id,
......
......@@ -21,7 +21,7 @@ bool ChromeAppViewGuestDelegate::HandleContextMenu(
ContextMenuDelegate::FromWebContents(web_contents);
DCHECK(menu_delegate);
scoped_ptr<RenderViewContextMenu> menu =
scoped_ptr<RenderViewContextMenuBase> menu =
menu_delegate->BuildMenu(web_contents, params);
menu_delegate->ShowMenu(menu.Pass());
return true;
......
......@@ -32,7 +32,7 @@ bool ChromeExtensionOptionsGuestDelegate::HandleContextMenu(
extension_options_guest()->web_contents());
DCHECK(menu_delegate);
scoped_ptr<RenderViewContextMenu> menu = menu_delegate->BuildMenu(
scoped_ptr<RenderViewContextMenuBase> menu = menu_delegate->BuildMenu(
extension_options_guest()->web_contents(), params);
menu_delegate->ShowMenu(menu.Pass());
return true;
......
......@@ -62,7 +62,7 @@ bool ChromeMimeHandlerViewGuestDelegate::HandleContextMenu(
ContextMenuDelegate::FromWebContents(web_contents);
DCHECK(menu_delegate);
scoped_ptr<RenderViewContextMenu> menu =
scoped_ptr<RenderViewContextMenuBase> menu =
menu_delegate->BuildMenu(web_contents, params);
menu_delegate->ShowMenu(menu.Pass());
return true;
......
......@@ -14,7 +14,7 @@
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#endif
class RenderViewContextMenu;
class RenderViewContextMenuBase;
namespace ui {
class SimpleMenuModel;
......@@ -75,9 +75,9 @@ class ChromeWebViewGuestDelegate : public WebViewGuestDelegate,
// Stores the current zoom factor.
double current_zoom_factor_;
// Holds the RenderViewContextMenu that has been built but yet to be
// shown. This is .Reset() after ShowContextMenu().
scoped_ptr<RenderViewContextMenu> pending_menu_;
// Holds the RenderViewContextMenuBase that has been built but yet to be
// shown. This is .reset() after ShowContextMenu().
scoped_ptr<RenderViewContextMenuBase> pending_menu_;
#if defined(OS_CHROMEOS)
// Subscription to receive notifications on changes to a11y settings.
......
......@@ -65,3 +65,6 @@ bool TestRenderViewContextMenu::GetMenuModelAndItemIndex(
return false;
}
void TestRenderViewContextMenu::Show() {
}
......@@ -57,6 +57,8 @@ class TestRenderViewContextMenu : public RenderViewContextMenu {
extensions::ContextMenuMatcher& extension_items() { return extension_items_; }
#endif
void Show() override;
private:
DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu);
};
......
......@@ -27,7 +27,8 @@ class RenderViewContextMenuMac : public RenderViewContextMenu {
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
void Show();
// RenderViewContextMenuBase implementation.
void Show() override;
protected:
// RenderViewContextMenu implementation.
......
......@@ -12,8 +12,7 @@
#include "components/renderer_context_menu/context_menu_delegate.h"
#include "content/public/browser/web_contents_view_delegate.h"
class RenderViewContextMenu;
class RenderViewContextMenuMac;
class RenderViewContextMenuBase;
class WebDragBookmarkHandlerMac;
namespace content {
......@@ -38,16 +37,16 @@ class ChromeWebContentsViewDelegateMac
const content::ContextMenuParams& params) override;
// Overridden from ContextMenuDelegate.
scoped_ptr<RenderViewContextMenu> BuildMenu(
scoped_ptr<RenderViewContextMenuBase> BuildMenu(
content::WebContents* web_contents,
const content::ContextMenuParams& params) override;
void ShowMenu(scoped_ptr<RenderViewContextMenu> menu) override;
void ShowMenu(scoped_ptr<RenderViewContextMenuBase> menu) override;
private:
content::RenderWidgetHostView* GetActiveRenderWidgetHostView();
// The context menu. Callbacks are asynchronous so we need to keep it around.
scoped_ptr<RenderViewContextMenuMac> context_menu_;
scoped_ptr<RenderViewContextMenuBase> context_menu_;
// The chrome specific delegate that receives events from WebDragDestMac.
scoped_ptr<WebDragBookmarkHandlerMac> bookmark_handler_;
......
......@@ -42,8 +42,8 @@ void ChromeWebContentsViewDelegateMac::ShowContextMenu(
}
void ChromeWebContentsViewDelegateMac::ShowMenu(
scoped_ptr<RenderViewContextMenu> menu) {
context_menu_.reset(static_cast<RenderViewContextMenuMac*>(menu.release()));
scoped_ptr<RenderViewContextMenuBase> menu) {
context_menu_ = menu.Pass();
if (!context_menu_.get())
return;
......@@ -61,10 +61,11 @@ void ChromeWebContentsViewDelegateMac::ShowMenu(
context_menu_->Show();
}
scoped_ptr<RenderViewContextMenu> ChromeWebContentsViewDelegateMac::BuildMenu(
scoped_ptr<RenderViewContextMenuBase>
ChromeWebContentsViewDelegateMac::BuildMenu(
content::WebContents* web_contents,
const content::ContextMenuParams& params) {
scoped_ptr<RenderViewContextMenuMac> menu;
scoped_ptr<RenderViewContextMenuBase> menu;
content::RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
// If the frame tree does not have a focused frame at this point, do not
// bother creating RenderViewContextMenuMac.
......
......@@ -123,6 +123,8 @@ class PanelContextMenu : public RenderViewContextMenu {
return menu_model_.GetIndexOfCommandId(command_id) != -1;
}
void Show() override {}
protected:
// RenderViewContextMenu implementation.
bool GetAcceleratorForCommandId(int command_id,
......
......@@ -10,10 +10,14 @@
#include "chrome/grit/generated_resources.h"
#include "components/renderer_context_menu/views/toolkit_delegate_views.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/views/widget/widget.h"
using content::WebContents;
......@@ -167,3 +171,48 @@ void RenderViewContextMenuViews::AppendPlatformEditableItems() {
l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU),
&bidi_submenu_model_);
}
void RenderViewContextMenuViews::Show() {
// Menus need a Widget to work. If we're not the active tab we won't
// necessarily be in a widget.
views::Widget* top_level_widget = GetTopLevelWidget();
if (!top_level_widget)
return;
// Don't show empty menus.
if (menu_model().GetItemCount() == 0)
return;
gfx::Point screen_point(params().x, params().y);
// Convert from target window coordinates to root window coordinates.
aura::Window* target_window = GetActiveNativeView();
aura::Window* root_window = target_window->GetRootWindow();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root_window);
if (screen_position_client) {
screen_position_client->ConvertPointToScreen(target_window, &screen_point);
}
// Enable recursive tasks on the message loop so we can get updates while
// the context menu is being displayed.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
RunMenuAt(top_level_widget, screen_point, params().source_type);
}
views::Widget* RenderViewContextMenuViews::GetTopLevelWidget() {
return views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView());
}
aura::Window* RenderViewContextMenuViews::GetActiveNativeView() {
WebContents* web_contents =
WebContents::FromRenderFrameHost(GetRenderFrameHost());
if (!web_contents) {
LOG(ERROR) << "RenderViewContextMenuViews::Show, couldn't find WebContents";
return NULL;
}
return web_contents->GetFullscreenRenderWidgetHostView()
? web_contents->GetFullscreenRenderWidgetHostView()
->GetNativeView()
: web_contents->GetNativeView();
}
......@@ -8,6 +8,10 @@
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "ui/base/ui_base_types.h"
namespace aura {
class Window;
}
namespace gfx {
class Point;
}
......@@ -31,6 +35,9 @@ class RenderViewContextMenuViews : public RenderViewContextMenu {
void ExecuteCommand(int command_id, int event_flags) override;
// RenderViewContextMenuBase implementation.
void Show() override;
protected:
RenderViewContextMenuViews(content::RenderFrameHost* render_frame_host,
const content::ContextMenuParams& params);
......@@ -44,6 +51,9 @@ class RenderViewContextMenuViews : public RenderViewContextMenu {
bool IsCommandIdChecked(int command_id) const override;
bool IsCommandIdEnabled(int command_id) const override;
aura::Window* GetActiveNativeView();
views::Widget* GetTopLevelWidget();
// Model for the BiDi input submenu.
ui::SimpleMenuModel bidi_submenu_model_;
DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenuViews);
......
......@@ -112,10 +112,11 @@ void ChromeWebContentsViewDelegateViews::RestoreFocus() {
}
}
scoped_ptr<RenderViewContextMenu> ChromeWebContentsViewDelegateViews::BuildMenu(
scoped_ptr<RenderViewContextMenuBase>
ChromeWebContentsViewDelegateViews::BuildMenu(
content::WebContents* web_contents,
const content::ContextMenuParams& params) {
scoped_ptr<RenderViewContextMenu> menu;
scoped_ptr<RenderViewContextMenuBase> menu;
content::RenderFrameHost* focused_frame = web_contents->GetFocusedFrame();
// If the frame tree does not have a focused frame at this point, do not
// bother creating RenderViewContextMenuViews.
......@@ -129,38 +130,12 @@ scoped_ptr<RenderViewContextMenu> ChromeWebContentsViewDelegateViews::BuildMenu(
}
void ChromeWebContentsViewDelegateViews::ShowMenu(
scoped_ptr<RenderViewContextMenu> menu) {
context_menu_.reset(static_cast<RenderViewContextMenuViews*>(menu.release()));
if (!context_menu_.get())
scoped_ptr<RenderViewContextMenuBase> menu) {
context_menu_ = menu.Pass();
if (!context_menu_)
return;
// Menus need a Widget to work. If we're not the active tab we won't
// necessarily be in a widget.
views::Widget* top_level_widget = GetTopLevelWidget();
if (!top_level_widget)
return;
const content::ContextMenuParams& params = context_menu_->params();
// Don't show empty menus.
if (context_menu_->menu_model().GetItemCount() == 0)
return;
gfx::Point screen_point(params.x, params.y);
// Convert from target window coordinates to root window coordinates.
aura::Window* target_window = GetActiveNativeView();
aura::Window* root_window = target_window->GetRootWindow();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root_window);
if (screen_position_client) {
screen_position_client->ConvertPointToScreen(target_window,
&screen_point);
}
// Enable recursive tasks on the message loop so we can get updates while
// the context menu is being displayed.
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
context_menu_->RunMenuAt(top_level_widget, screen_point, params.source_type);
context_menu_->Show();
}
void ChromeWebContentsViewDelegateViews::ShowContextMenu(
......
......@@ -12,8 +12,7 @@
#include "content/public/browser/web_contents_view_delegate.h"
class LinkDisambiguationPopup;
class RenderViewContextMenu;
class RenderViewContextMenuViews;
class RenderViewContextMenuBase;
namespace aura {
class Window;
......@@ -58,10 +57,10 @@ class ChromeWebContentsViewDelegateViews
void HideDisambiguationPopup() override;
// Overridden from ContextMenuDelegate.
scoped_ptr<RenderViewContextMenu> BuildMenu(
scoped_ptr<RenderViewContextMenuBase> BuildMenu(
content::WebContents* web_contents,
const content::ContextMenuParams& params) override;
void ShowMenu(scoped_ptr<RenderViewContextMenu> menu) override;
void ShowMenu(scoped_ptr<RenderViewContextMenuBase> menu) override;
private:
aura::Window* GetActiveNativeView();
......@@ -74,7 +73,7 @@ class ChromeWebContentsViewDelegateViews
// The context menu is reset every time we show it, but we keep a pointer to
// between uses so that it won't go out of scope before we're done with it.
scoped_ptr<RenderViewContextMenuViews> context_menu_;
scoped_ptr<RenderViewContextMenuBase> context_menu_;
// The chrome specific delegate that receives events from WebDragDest.
scoped_ptr<content::WebDragDestDelegate> bookmark_handler_;
......
......@@ -7,7 +7,7 @@
#include "base/memory/scoped_ptr.h"
class RenderViewContextMenu;
class RenderViewContextMenuBase;
namespace content {
class WebContents;
......@@ -25,12 +25,12 @@ class ContextMenuDelegate {
// Builds and returns a context menu for a context specified by |params|.
// The returned value can be used to display the context menu.
virtual scoped_ptr<RenderViewContextMenu> BuildMenu(
virtual scoped_ptr<RenderViewContextMenuBase> BuildMenu(
content::WebContents* web_contents,
const content::ContextMenuParams& params) = 0;
// Displays the context menu.
virtual void ShowMenu(scoped_ptr<RenderViewContextMenu> menu) = 0;
virtual void ShowMenu(scoped_ptr<RenderViewContextMenuBase> menu) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ContextMenuDelegate);
......
......@@ -69,6 +69,10 @@ class RenderViewContextMenuBase : public ui::SimpleMenuModel::Delegate,
~RenderViewContextMenuBase() override;
// Displays the menu.
// Different platform will have their own implementation.
virtual void Show() = 0;
// Initializes the context menu.
void Init();
......
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