summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-12 03:50:39 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-12 03:50:39 +0000
commite943d666020b7275d7fb70db625b47f69712d3b3 (patch)
treed56f0d56bb766103e8c51566f46197966a689cb1
parentd66688b2a167882dad56fcb6d963d918ed413052 (diff)
downloadchromium_src-e943d666020b7275d7fb70db625b47f69712d3b3.zip
chromium_src-e943d666020b7275d7fb70db625b47f69712d3b3.tar.gz
chromium_src-e943d666020b7275d7fb70db625b47f69712d3b3.tar.bz2
Allow external hosts to handle the context menu and thus be able to customize it.
Changes include 1. A HandleContextMenu function which can be implemented by a TabContentsDelegate. Currently only ExternalTabContainer implements this. 2. Removed InitMenu calls from the RenderViewContextMenu subclass constructors, We need the subclasses to be able to override individual AddMenuItem calls. The newly added RenderViewContextMenuExternalWin class derives from RenderViewContextMenuWin whose constructor calls InitMenu. This happens at a time when the vtable is not yet setup. To fix this we added an Init function to the RenderViewContextMenu base class which then calls a virtual function DoInit, which derived classes can override to perform specific initializations. 3. Added automation messages to send over context menu events to external hosts and back amit, please review everything. estade please review changes to tab_contents_view_gtk.cc and render_view_context_menu_gtk.cc. pinkerton please review changes to tab_contents_view_mac.mm and render_view_context_menu_mac.mm Review URL: http://codereview.chromium.org/119429 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18250 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-xchrome/browser/automation/automation_provider.cc24
-rw-r--r--chrome/browser/automation/automation_provider.h1
-rw-r--r--chrome/browser/external_tab_container.cc40
-rw-r--r--chrome/browser/external_tab_container.h17
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc5
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.h6
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_external_win.cc25
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_external_win.h32
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_gtk.cc8
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_gtk.h1
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_mac.h2
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_mac.mm16
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_win.cc6
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_win.h9
-rw-r--r--chrome/browser/tab_contents/tab_contents_delegate.h11
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc1
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_mac.mm1
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_win.cc7
-rw-r--r--chrome/chrome.gyp2
-rwxr-xr-xchrome/test/automation/automation_messages_internal.h12
-rw-r--r--chrome/test/automation/tab_proxy.cc5
-rw-r--r--chrome/test/automation/tab_proxy.h4
-rw-r--r--views/controls/menu/menu.h5
-rw-r--r--views/controls/menu/menu_win.h10
24 files changed, 233 insertions, 17 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 5b692b8..3a58327 100755
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -1028,6 +1028,8 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(AutomationMsg_SetInitialFocus, SetInitialFocus)
#if defined(OS_WIN)
IPC_MESSAGE_HANDLER(AutomationMsg_TabReposition, OnTabReposition)
+ IPC_MESSAGE_HANDLER(AutomationMsg_ForwardContextMenuCommandToChrome,
+ OnForwardContextMenuCommandToChrome)
#endif
IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
@@ -3003,7 +3005,27 @@ void AutomationProvider::OnTabReposition(
}
}
}
-#endif
+
+void AutomationProvider::OnForwardContextMenuCommandToChrome(int tab_handle,
+ int command) {
+ if (tab_tracker_->ContainsHandle(tab_handle)) {
+ NavigationController* tab = tab_tracker_->GetResource(tab_handle);
+ if (!tab) {
+ NOTREACHED();
+ return;
+ }
+
+ TabContents* tab_contents = tab->tab_contents();
+ if (!tab_contents || !tab_contents->delegate()) {
+ NOTREACHED();
+ return;
+ }
+
+ tab_contents->delegate()->ExecuteContextMenuCommand(command);
+ }
+}
+
+#endif // defined(OS_WIN)
void AutomationProvider::GetWindowTitle(int handle, string16* text) {
gfx::NativeWindow window = window_tracker_->GetResource(handle);
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 3dedd65..59935f5 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -334,6 +334,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
void OnTabReposition(int tab_handle,
const IPC::Reposition_Params& params);
+ void OnForwardContextMenuCommandToChrome(int tab_handle, int command);
#endif // defined(OS_WIN)
// Gets the security state for the tab associated to the specified |handle|.
diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc
index 14ee79e..2dbf706 100644
--- a/chrome/browser/external_tab_container.cc
+++ b/chrome/browser/external_tab_container.cc
@@ -13,12 +13,15 @@
#include "chrome/browser/load_notification_details.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/provisional_load_details.h"
+#include "chrome/browser/tab_contents/render_view_context_menu_external_win.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/automation/automation_messages.h"
+#include "grit/generated_resources.h"
+
static const wchar_t kWindowObjectKey[] = L"ChromeWindowObject";
// TODO(sanjeevr): The external_accel_table_ and external_accel_entry_count_
@@ -96,6 +99,9 @@ bool ExternalTabContainer::Init(Profile* profile,
SetParent(GetNativeView(), parent);
::ShowWindow(tab_contents_->GetNativeView(), SW_SHOWNA);
+
+ disabled_context_menu_ids_.push_back(
+ IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD);
return true;
}
@@ -253,6 +259,40 @@ bool ExternalTabContainer::TakeFocus(bool reverse) {
return true;
}
+bool ExternalTabContainer::HandleContextMenu(const ContextMenuParams& params) {
+ if (!automation_) {
+ NOTREACHED();
+ return false;
+ }
+
+ external_context_menu_.reset(
+ new RenderViewContextMenuExternalWin(tab_contents(),
+ params,
+ GetNativeView(),
+ disabled_context_menu_ids_));
+ external_context_menu_->Init();
+
+ POINT screen_pt = { params.x, params.y };
+ MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1);
+
+ automation_->Send(
+ new AutomationMsg_ForwardContextMenuToExternalHost(0, tab_handle_,
+ external_context_menu_->GetMenuHandle(), screen_pt.x, screen_pt.y,
+ external_context_menu_->GetTPMAlignFlags()));
+
+ return true;
+}
+
+bool ExternalTabContainer::ExecuteContextMenuCommand(int command) {
+ if (!external_context_menu_.get()) {
+ NOTREACHED();
+ return false;
+ }
+
+ external_context_menu_->ExecuteCommand(command);
+ return true;
+}
+
////////////////////////////////////////////////////////////////////////////////
// ExternalTabContainer, NotificationObserver implementation:
diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h
index 3d65321..1f98891 100644
--- a/chrome/browser/external_tab_container.h
+++ b/chrome/browser/external_tab_container.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_H_
#define CHROME_BROWSER_EXTERNAL_TAB_CONTAINER_H_
+#include <vector>
+
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
@@ -13,6 +15,7 @@
class AutomationProvider;
class Profile;
class TabContentsContainer;
+class RenderViewContextMenuExternalWin;
// This class serves as the container window for an external tab.
// An external tab is a Chrome tab that is meant to displayed in an
@@ -83,6 +86,7 @@ class ExternalTabContainer : public TabContentsDelegate,
virtual bool IsExternalTabContainer() const {
return true;
};
+
virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher(
RenderViewHost* render_view_host,
const std::string& extension_id);
@@ -97,6 +101,14 @@ class ExternalTabContainer : public TabContentsDelegate,
virtual bool ProcessKeyStroke(HWND window, UINT message, WPARAM wparam,
LPARAM lparam);
+ // Handles the context menu display operation. This allows external
+ // hosts to customize the menu.
+ virtual bool HandleContextMenu(const ContextMenuParams& params);
+
+ // Executes the context menu command identified by the command
+ // parameter.
+ virtual bool ExecuteContextMenuCommand(int command);
+
protected:
// Overridden from views::WidgetWin:
virtual void OnDestroy();
@@ -126,6 +138,11 @@ class ExternalTabContainer : public TabContentsDelegate,
// is set when we need to ignore the next load notification.
bool ignore_next_load_notification_;
+ // Contains the list of disabled context menu identifiers.
+ std::vector<int> disabled_context_menu_ids_;
+
+ scoped_ptr<RenderViewContextMenuExternalWin> external_context_menu_;
+
DISALLOW_COPY_AND_ASSIGN(ExternalTabContainer);
};
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index fc387d9..bb33e78 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -43,6 +43,11 @@ RenderViewContextMenu::~RenderViewContextMenu() {
// Menu construction functions -------------------------------------------------
+void RenderViewContextMenu::Init() {
+ InitMenu(params_.node);
+ DoInit();
+}
+
void RenderViewContextMenu::InitMenu(ContextNode node) {
if (node.type & ContextNode::PAGE)
AppendPageItems();
diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h
index 0fc13cd..cc779bd 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.h
+++ b/chrome/browser/tab_contents/render_view_context_menu.h
@@ -21,11 +21,17 @@ class RenderViewContextMenu {
virtual ~RenderViewContextMenu();
+ // Initializes the context menu.
+ void Init();
+
protected:
void InitMenu(ContextNode node);
// Functions to be implemented by platform-specific subclasses ---------------
+ // Platform specific initialization goes here.
+ virtual void DoInit() {}
+
// Append a normal menu item, taking the name from the id.
virtual void AppendMenuItem(int id) = 0;
diff --git a/chrome/browser/tab_contents/render_view_context_menu_external_win.cc b/chrome/browser/tab_contents/render_view_context_menu_external_win.cc
new file mode 100644
index 0000000..0c19f94
--- /dev/null
+++ b/chrome/browser/tab_contents/render_view_context_menu_external_win.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/tab_contents/render_view_context_menu_external_win.h"
+
+#include <algorithm>
+
+RenderViewContextMenuExternalWin::RenderViewContextMenuExternalWin(
+ TabContents* tab_contents,
+ const ContextMenuParams& params,
+ HWND owner,
+ const std::vector<int> disabled_ids)
+ : RenderViewContextMenuWin(tab_contents, params, owner),
+ disabled_menu_ids_(disabled_ids) {
+}
+
+void RenderViewContextMenuExternalWin::AppendMenuItem(int id) {
+ std::vector<int>::iterator found =
+ std::find(disabled_menu_ids_.begin(), disabled_menu_ids_.end(), id);
+
+ if (found == disabled_menu_ids_.end()) {
+ RenderViewContextMenuWin::AppendMenuItem(id);
+ }
+}
diff --git a/chrome/browser/tab_contents/render_view_context_menu_external_win.h b/chrome/browser/tab_contents/render_view_context_menu_external_win.h
new file mode 100644
index 0000000..3c31e44
--- /dev/null
+++ b/chrome/browser/tab_contents/render_view_context_menu_external_win.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_EXTERNAL_WIN_H_
+#define CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_EXTERNAL_WIN_H_
+
+#include <vector>
+
+#include "chrome/browser/tab_contents/render_view_context_menu_win.h"
+
+// This class provides a facility for an external host to customize the context
+// menu displayed in Chrome.
+class RenderViewContextMenuExternalWin : public RenderViewContextMenuWin {
+ public:
+ RenderViewContextMenuExternalWin(TabContents* tab_contents,
+ const ContextMenuParams& params,
+ HWND window,
+ const std::vector<int> disabled_menu_ids);
+
+ ~RenderViewContextMenuExternalWin() {}
+
+ protected:
+ // RenderViewContextMenuWin overrides --------------------------------------
+ virtual void AppendMenuItem(int id);
+
+ private:
+ // Contains the list of context menu ids to be disabled.
+ std::vector<int> disabled_menu_ids_;
+};
+
+#endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_EXTERNAL_WIN_H_
diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc
index c58a7f3..80e90db 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc
@@ -20,14 +20,16 @@ RenderViewContextMenuGtk::RenderViewContextMenuGtk(
making_submenu_(false),
triggering_event_time_(triggering_event_time),
host_view_(rwhv) {
- InitMenu(params.node);
- DoneMakingMenu(&menu_);
- gtk_menu_.reset(new MenuGtk(this, menu_.data(), NULL));
}
RenderViewContextMenuGtk::~RenderViewContextMenuGtk() {
}
+void RenderViewContextMenuGtk::DoInit() {
+ DoneMakingMenu(&menu_);
+ gtk_menu_.reset(new MenuGtk(this, menu_.data(), NULL));
+}
+
void RenderViewContextMenuGtk::Popup() {
host_view_->ShowingContextMenu(true);
gtk_menu_->PopupAsContext(triggering_event_time_);
diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.h b/chrome/browser/tab_contents/render_view_context_menu_gtk.h
index 8b6ebb6..51f5cf35 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_gtk.h
+++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.h
@@ -39,6 +39,7 @@ class RenderViewContextMenuGtk : public RenderViewContextMenu,
protected:
// RenderViewContextMenu implementation --------------------------------------
+ virtual void DoInit();
virtual void AppendMenuItem(int id);
virtual void AppendMenuItem(int id, const std::wstring& label);
virtual void AppendRadioMenuItem(int id, const std::wstring& label);
diff --git a/chrome/browser/tab_contents/render_view_context_menu_mac.h b/chrome/browser/tab_contents/render_view_context_menu_mac.h
index 4b39b56..8ca5e3c 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_mac.h
+++ b/chrome/browser/tab_contents/render_view_context_menu_mac.h
@@ -27,6 +27,7 @@ class RenderViewContextMenuMac : public RenderViewContextMenu {
protected:
// RenderViewContextMenu implementation-
+ virtual void DoInit();
virtual void AppendMenuItem(int id);
virtual void AppendMenuItem(int id, const std::wstring& label);
virtual void AppendRadioMenuItem(int id, const std::wstring& label);
@@ -43,6 +44,7 @@ class RenderViewContextMenuMac : public RenderViewContextMenu {
NSMenu* insert_menu_; // weak, where new items are inserted (usually
// |menu_| unless there's a submenu in progress).
ContextMenuTarget* target_; // obj-c target for menu actions
+ NSView* parent_view_; // parent view
};
#endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_MAC_H_
diff --git a/chrome/browser/tab_contents/render_view_context_menu_mac.mm b/chrome/browser/tab_contents/render_view_context_menu_mac.mm
index ba55aa2..4c0537f 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_mac.mm
+++ b/chrome/browser/tab_contents/render_view_context_menu_mac.mm
@@ -46,15 +46,10 @@ RenderViewContextMenuMac::RenderViewContextMenuMac(
: RenderViewContextMenu(web_contents, params),
menu_([[NSMenu alloc] init]),
insert_menu_(menu_),
- target_(nil) {
+ target_(nil),
+ parent_view_(parent_view) {
[menu_ setAutoenablesItems:NO];
target_ = [[ContextMenuTarget alloc] initWithContext:this];
- InitMenu(params.node);
-
- // show the menu
- [NSMenu popUpContextMenu:menu_
- withEvent:[NSApp currentEvent]
- forView:parent_view];
}
RenderViewContextMenuMac::~RenderViewContextMenuMac() {
@@ -62,6 +57,13 @@ RenderViewContextMenuMac::~RenderViewContextMenuMac() {
[menu_ release];
}
+void RenderViewContextMenuMac::DoInit() {
+ // show the menu
+ [NSMenu popUpContextMenu:menu_
+ withEvent:[NSApp currentEvent]
+ forView:parent_view_];
+}
+
// Do things like remove the windows accelerators.
// TODO(pinkerton): Do we want to do anything like make a maximum string width
// and middle-truncate?
diff --git a/chrome/browser/tab_contents/render_view_context_menu_win.cc b/chrome/browser/tab_contents/render_view_context_menu_win.cc
index 90b0345..952993f 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_win.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu_win.cc
@@ -14,13 +14,13 @@ RenderViewContextMenuWin::RenderViewContextMenuWin(
const ContextMenuParams& params,
HWND owner)
: RenderViewContextMenu(tab_contents, params),
- sub_menu_(NULL) {
+ sub_menu_(NULL),
+ owner_(owner) {
// anchor_position set per http://crbug.com/10827.
views::Menu::AnchorPoint anchor_position = views::Menu::TOPLEFT;
if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
anchor_position = views::Menu::TOPRIGHT;
- menu_.reset(new views::MenuWin(this, anchor_position, owner));
- InitMenu(params.node);
+ menu_.reset(new views::MenuWin(this, anchor_position, owner_));
}
RenderViewContextMenuWin::~RenderViewContextMenuWin() {
diff --git a/chrome/browser/tab_contents/render_view_context_menu_win.h b/chrome/browser/tab_contents/render_view_context_menu_win.h
index 94aec65..3488d59 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_win.h
+++ b/chrome/browser/tab_contents/render_view_context_menu_win.h
@@ -28,6 +28,14 @@ class RenderViewContextMenuWin : public RenderViewContextMenu,
// TODO(port): move the logic in this function to RenderViewContextMenu.
virtual bool GetAcceleratorInfo(int id, views::Accelerator* accel);
+ HMENU GetMenuHandle() const {
+ return (menu_.get() ? menu_->GetMenuHandle() : NULL);
+ }
+
+ unsigned int GetTPMAlignFlags() const {
+ return (menu_.get() ? menu_->GetTPMAlignFlags() : 0);
+ }
+
protected:
// RenderViewContextMenu implementation --------------------------------------
virtual void AppendMenuItem(int id);
@@ -46,6 +54,7 @@ class RenderViewContextMenuWin : public RenderViewContextMenu,
scoped_ptr<views::MenuWin> menu_;
views::Menu* sub_menu_;
+ HWND owner_;
};
#endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_WIN_H_
diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h
index 496172a..d7820e2 100644
--- a/chrome/browser/tab_contents/tab_contents_delegate.h
+++ b/chrome/browser/tab_contents/tab_contents_delegate.h
@@ -10,6 +10,7 @@
#include "base/gfx/rect.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/common/renderer_preferences.h"
+#include "webkit/glue/context_menu.h"
#include "webkit/glue/window_open_disposition.h"
class DownloadItem;
@@ -180,6 +181,16 @@ class TabContentsDelegate {
virtual void OnStartDownload(DownloadItem* download) {
}
+ // Returns true if the context menu operation was handled by the delegate.
+ virtual bool HandleContextMenu(const ContextMenuParams& params) {
+ return false;
+ }
+
+ // Returns true if the context menu command was handled
+ virtual bool ExecuteContextMenuCommand(int command) {
+ return false;
+ }
+
// Returns the renderer's current preferences settings.
RendererPreferences GetRendererPrefs() const { return renderer_preferences_; }
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index 30cef96..8496b03 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -312,6 +312,7 @@ void TabContentsViewGtk::Observe(NotificationType type,
void TabContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) {
context_menu_.reset(new RenderViewContextMenuGtk(tab_contents(), params,
last_mouse_down_time_, tab_contents()->render_widget_host_view()));
+ context_menu_->Init();
context_menu_->Popup();
}
diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm
index fd32310..9bf8e1e 100644
--- a/chrome/browser/tab_contents/tab_contents_view_mac.mm
+++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm
@@ -180,6 +180,7 @@ void TabContentsViewMac::ShowContextMenu(const ContextMenuParams& params) {
RenderViewContextMenuMac menu(tab_contents(),
params,
GetNativeView());
+ menu.Init();
}
RenderWidgetHostView* TabContentsViewMac::CreateNewWidgetInternal(
diff --git a/chrome/browser/tab_contents/tab_contents_view_win.cc b/chrome/browser/tab_contents/tab_contents_view_win.cc
index ed72402..966c41e 100644
--- a/chrome/browser/tab_contents/tab_contents_view_win.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_win.cc
@@ -380,10 +380,17 @@ void TabContentsViewWin::HandleKeyboardEvent(
}
void TabContentsViewWin::ShowContextMenu(const ContextMenuParams& params) {
+ // Allow delegates to handle the context menu operation first.
+ if (tab_contents()->delegate()->HandleContextMenu(params)) {
+ return;
+ }
+
RenderViewContextMenuWin menu(tab_contents(),
params,
GetNativeView());
+ menu.Init();
+
POINT screen_pt = { params.x, params.y };
MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1);
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 583cafa..735ee10 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1355,6 +1355,8 @@
'browser/tab_contents/render_view_context_menu_mac.h',
'browser/tab_contents/render_view_context_menu_win.cc',
'browser/tab_contents/render_view_context_menu_win.h',
+ 'browser/tab_contents/render_view_context_menu_external_win.cc',
+ 'browser/tab_contents/render_view_context_menu_external_win.h',
'browser/tab_contents/render_view_host_delegate_helper.cc',
'browser/tab_contents/render_view_host_delegate_helper.h',
'browser/tab_contents/render_view_host_manager.cc',
diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h
index d746202..7e20454 100755
--- a/chrome/test/automation/automation_messages_internal.h
+++ b/chrome/test/automation/automation_messages_internal.h
@@ -939,5 +939,17 @@ IPC_BEGIN_MESSAGES(Automation)
IPC_SYNC_MESSAGE_ROUTED1_1(AutomationMsg_BlockedPopupCount,
int /* tab_handle */,
int /* blocked_popup_count */)
+#if defined(OS_WIN)
+ IPC_MESSAGE_ROUTED5(AutomationMsg_ForwardContextMenuToExternalHost,
+ int /* tab_handle */,
+ HANDLE /* source menu handle */,
+ int /* the x coordinate for displaying the menu */,
+ int /* the y coordinate for displaying the menu */,
+ int /* align flags */)
+
+ IPC_MESSAGE_ROUTED2(AutomationMsg_ForwardContextMenuCommandToChrome,
+ int /* tab_handle */,
+ int /* selected_command */)
+#endif // OS_WIN
IPC_END_MESSAGES(Automation)
diff --git a/chrome/test/automation/tab_proxy.cc b/chrome/test/automation/tab_proxy.cc
index 1a2d1144..f81e23b 100644
--- a/chrome/test/automation/tab_proxy.cc
+++ b/chrome/test/automation/tab_proxy.cc
@@ -662,6 +662,11 @@ void TabProxy::Reposition(HWND window, HWND window_insert_after, int left,
sender_->Send(new AutomationMsg_TabReposition(0, handle_, params));
}
+void TabProxy::SendContextMenuCommand(int selected_command) {
+ sender_->Send(new AutomationMsg_ForwardContextMenuCommandToChrome(
+ 0, handle_, selected_command));
+}
+
#endif // defined(OS_WIN)
void TabProxy::AddObserver(TabProxyDelegate* observer) {
diff --git a/chrome/test/automation/tab_proxy.h b/chrome/test/automation/tab_proxy.h
index 2b142b1..5366119 100644
--- a/chrome/test/automation/tab_proxy.h
+++ b/chrome/test/automation/tab_proxy.h
@@ -303,6 +303,10 @@ class TabProxy : public AutomationResourceProxy {
// passed in.
void Reposition(HWND window, HWND window_insert_after, int left, int top,
int width, int height, int flags, HWND parent_window);
+
+ // Sends the selected context menu command to the chrome instance
+ void SendContextMenuCommand(int selected_command);
+
#endif // defined(OS_WIN)
// Calls delegates
diff --git a/views/controls/menu/menu.h b/views/controls/menu/menu.h
index faf4a7b..b93ef98 100644
--- a/views/controls/menu/menu.h
+++ b/views/controls/menu/menu.h
@@ -271,6 +271,11 @@ class Menu {
// Returns the number of menu items.
virtual int ItemCount() = 0;
+#if defined(OS_WIN)
+ // Returns the underlying menu handle
+ virtual HMENU GetMenuHandle() const = 0;
+#endif // defined(OS_WIN)
+
protected:
explicit Menu(Menu* parent);
diff --git a/views/controls/menu/menu_win.h b/views/controls/menu/menu_win.h
index 5022db7..0469c12 100644
--- a/views/controls/menu/menu_win.h
+++ b/views/controls/menu/menu_win.h
@@ -63,6 +63,13 @@ class MenuWin : public Menu {
virtual void Cancel();
virtual int ItemCount();
+ virtual HMENU GetMenuHandle() const {
+ return menu_;
+ }
+
+ // Gets the Win32 TPM alignment flags for the specified AnchorPoint.
+ DWORD GetTPMAlignFlags() const;
+
protected:
virtual void AddMenuItemInternal(int index,
int item_id,
@@ -91,9 +98,6 @@ class MenuWin : public Menu {
// the state of the item in preference to |controller_|.
UINT GetStateFlagsForItemID(int item_id) const;
- // Gets the Win32 TPM alignment flags for the specified AnchorPoint.
- DWORD GetTPMAlignFlags() const;
-
// The Win32 Menu Handle we wrap
HMENU menu_;