summaryrefslogtreecommitdiffstats
path: root/chrome_frame
diff options
context:
space:
mode:
authorrhashimoto@chromium.org <rhashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-12 16:54:12 +0000
committerrhashimoto@chromium.org <rhashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-12 16:54:12 +0000
commitb516e2d2ff5ad3d2a7c754b081566137fd7ed089 (patch)
tree75d5a32b65ce6b417eba6ff42fe0dbe3d1d8c5b1 /chrome_frame
parent471072f9fd132a46b24ddd159922f6a4d099707d (diff)
downloadchromium_src-b516e2d2ff5ad3d2a7c754b081566137fd7ed089.zip
chromium_src-b516e2d2ff5ad3d2a7c754b081566137fd7ed089.tar.gz
chromium_src-b516e2d2ff5ad3d2a7c754b081566137fd7ed089.tar.bz2
Convert RenderViewContextMenu to MenuItemView.
This CL is part of general GTK removal for ChromiumOS. Menu2 uses GTK on linux so we are replacing it with MenuItemView. Chrome Frame currently passes the context menu between processes by using the HMENU. Because MenuItemView does not use HMENU, we need to use another mechanism. This CL creates a ContextMenuModel struct that is serialized into an automation message for Chrome Frame. ContextMenuModel contains the context menu definition in-band replacing the out-of-band HMENU. BUG=chromium-os:13887 TEST=none Review URL: http://codereview.chromium.org/7167002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92182 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r--chrome_frame/cfproxy.h1
-rw-r--r--chrome_frame/chrome_frame_activex_base.h4
-rw-r--r--chrome_frame/chrome_frame_delegate.h4
-rw-r--r--chrome_frame/chrome_frame_plugin.h17
-rw-r--r--chrome_frame/external_tab.cc5
-rw-r--r--chrome_frame/external_tab.h6
-rw-r--r--chrome_frame/external_tab_test.cc4
-rw-r--r--chrome_frame/utils.cc97
-rw-r--r--chrome_frame/utils.h6
9 files changed, 76 insertions, 68 deletions
diff --git a/chrome_frame/cfproxy.h b/chrome_frame/cfproxy.h
index 7e4c0fb..6bc8abd 100644
--- a/chrome_frame/cfproxy.h
+++ b/chrome_frame/cfproxy.h
@@ -22,6 +22,7 @@ class ChromeProxyFactory;
class GURL;
struct AttachExternalTabParams;
struct AutomationURLRequest;
+struct ContextMenuModel;
struct ExternalTabSettings;
struct MiniContextMenuParams;
struct NavigationInfo;
diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h
index fce6164..46287fd7 100644
--- a/chrome_frame/chrome_frame_activex_base.h
+++ b/chrome_frame/chrome_frame_activex_base.h
@@ -504,11 +504,11 @@ END_MSG_MAP()
HostNavigate(GURL(url), GURL(), chrome_frame::GetDisposition(params));
}
- virtual void OnHandleContextMenu(HANDLE menu_handle,
+ virtual void OnHandleContextMenu(const ContextMenuModel& menu_model,
int align_flags,
const MiniContextMenuParams& params) {
scoped_refptr<BasePlugin> ref(this);
- ChromeFramePlugin<T>::OnHandleContextMenu(menu_handle, align_flags, params);
+ ChromeFramePlugin<T>::OnHandleContextMenu(menu_model, align_flags, params);
}
LRESULT OnCreate(UINT message, WPARAM wparam, LPARAM lparam,
diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h
index 3af3bd4..582365b 100644
--- a/chrome_frame/chrome_frame_delegate.h
+++ b/chrome_frame/chrome_frame_delegate.h
@@ -21,6 +21,7 @@
class GURL;
struct AttachExternalTabParams;
struct AutomationURLRequest;
+struct ContextMenuModel;
struct MiniContextMenuParams;
struct NavigationInfo;
@@ -105,7 +106,8 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate {
virtual void OnMessageFromChromeFrame(const std::string& message,
const std::string& origin,
const std::string& target) {}
- virtual void OnHandleContextMenu(HANDLE menu_handle, int align_flags,
+ virtual void OnHandleContextMenu(const ContextMenuModel& context_menu_model,
+ int align_flags,
const MiniContextMenuParams& params) {}
virtual void OnRequestStart(
int request_id, const AutomationURLRequest& request) {}
diff --git a/chrome_frame/chrome_frame_plugin.h b/chrome_frame/chrome_frame_plugin.h
index af4242a..51106ab 100644
--- a/chrome_frame/chrome_frame_plugin.h
+++ b/chrome_frame/chrome_frame_plugin.h
@@ -120,23 +120,20 @@ END_MSG_MAP()
OnLoadFailed(error_code, gurl.spec());
}
- virtual void OnHandleContextMenu(HANDLE menu_handle,
+ virtual void OnHandleContextMenu(const ContextMenuModel& menu_model,
int align_flags,
const MiniContextMenuParams& params) {
- if (!menu_handle || !automation_client_.get()) {
+ if (!automation_client_.get()) {
NOTREACHED();
return;
}
- // TrackPopupMenuEx call will fail on IE on Vista running
- // in low integrity mode. We DO seem to be able to enumerate the menu
- // though, so just clone it and show the copy:
- HMENU copy = UtilCloneContextMenu(static_cast<HMENU>(menu_handle));
- if (!copy)
+ HMENU menu = BuildContextMenu(menu_model);
+ if (!menu)
return;
T* self = static_cast<T*>(this);
- if (self->PreProcessContextMenu(copy)) {
+ if (self->PreProcessContextMenu(menu)) {
// In order for the context menu to handle keyboard input, give the
// ActiveX window focus.
ignore_setfocus_ = true;
@@ -145,7 +142,7 @@ END_MSG_MAP()
UINT flags = align_flags | TPM_LEFTBUTTON | TPM_RETURNCMD | TPM_RECURSE;
int x, y;
ChromeFramePluginGetParamsCoordinates(params, &x, &y);
- UINT selected = TrackPopupMenuEx(copy, flags, x, y, GetWindow(), NULL);
+ UINT selected = TrackPopupMenuEx(menu, flags, x, y, GetWindow(), NULL);
// Menu is over now give focus back to chrome
GiveFocusToChrome(false);
if (IsValid() && selected != 0 &&
@@ -154,7 +151,7 @@ END_MSG_MAP()
}
}
- DestroyMenu(copy);
+ DestroyMenu(menu);
}
LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam,
diff --git a/chrome_frame/external_tab.cc b/chrome_frame/external_tab.cc
index c9eb204..6be47a7 100644
--- a/chrome_frame/external_tab.cc
+++ b/chrome_frame/external_tab.cc
@@ -282,11 +282,12 @@ void ExternalTabProxy::OnHandleAccelerator(const MSG& accel_message) {
}
void ExternalTabProxy::OnHandleContextMenu(
- HANDLE menu_handle,
+ const ContextMenuModel& context_menu_model,
int align_flags,
const MiniContextMenuParams& params) {
ui_.PostTask(FROM_HERE, NewRunnableMethod(ui_delegate_,
- &UIDelegate::OnHandleContextMenu, menu_handle, align_flags, params));
+ &UIDelegate::OnHandleContextMenu, context_menu_model, align_flags,
+ params));
}
void ExternalTabProxy::OnTabbedOut(bool reverse) {
diff --git a/chrome_frame/external_tab.h b/chrome_frame/external_tab.h
index 66844df07..26abf8f 100644
--- a/chrome_frame/external_tab.h
+++ b/chrome_frame/external_tab.h
@@ -32,7 +32,6 @@ class WaitableEvent;
namespace IPC {
struct NavigationInfo;
-struct MiniContextMenuParams;
}
namespace gfx {
@@ -54,7 +53,7 @@ class UIDelegate {
const std::string& message, const std::string& origin,
const std::string& target) = 0;
virtual void OnHandleContextMenu(
- HANDLE menu_handle, int align_flags,
+ const ContextMenuModel& context_menu_model, int align_flags,
const MiniContextMenuParams& params) = 0;
virtual void OnHandleAccelerator(const MSG& accel_message) = 0;
virtual void OnTabbedOut(bool reverse) = 0;
@@ -168,7 +167,8 @@ class ExternalTabProxy : public CWindowImpl<ExternalTabProxy>,
// Misc. UI.
virtual void OnHandleAccelerator(const MSG& accel_message);
- virtual void OnHandleContextMenu(HANDLE menu_handle, int align_flags,
+ virtual void OnHandleContextMenu(const ContextMenuModel& context_menu_model,
+ int align_flags,
const MiniContextMenuParams& params);
virtual void OnTabbedOut(bool reverse);
diff --git a/chrome_frame/external_tab_test.cc b/chrome_frame/external_tab_test.cc
index 46da607..63834a0 100644
--- a/chrome_frame/external_tab_test.cc
+++ b/chrome_frame/external_tab_test.cc
@@ -40,8 +40,8 @@ struct MockUIDelegate : public UIDelegate {
MOCK_METHOD1(OnMoveWindow, void(const gfx::Rect& pos));
MOCK_METHOD3(OnMessageFromChromeFrame, void(const std::string& message,
const std::string& origin, const std::string& target));
- MOCK_METHOD3(OnHandleContextMenu, void(HANDLE menu_handle, int align_flags,
- const MiniContextMenuParams& params));
+ MOCK_METHOD3(OnHandleContextMenu, void(const ContextMenuModel& menu_model,
+ int align_flags, const MiniContextMenuParams& params));
MOCK_METHOD1(OnHandleAccelerator, void(const MSG& accel_message));
MOCK_METHOD1(OnTabbedOut, void(bool reverse));
MOCK_METHOD1(OnGoToHistoryOffset, void(int offset));
diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc
index a55d858..b80511e 100644
--- a/chrome_frame/utils.cc
+++ b/chrome_frame/utils.cc
@@ -25,6 +25,7 @@
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
+#include "chrome/common/automation_messages.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/url_constants.h"
#include "chrome/installer/util/chrome_frame_distribution.h"
@@ -38,6 +39,7 @@
#include "grit/chromium_strings.h"
#include "net/base/escape.h"
#include "net/http/http_util.h"
+#include "ui/base/models/menu_model.h"
#include "chrome_tab.h" // NOLINT
@@ -542,61 +544,66 @@ namespace {
const int kMaxSubmenuDepth = 10;
-// Copies original_menu and returns the copy. The caller is responsible for
-// closing the returned HMENU. This does not currently copy over bitmaps
-// (e.g. hbmpChecked, hbmpUnchecked or hbmpItem), so checkmarks, radio buttons,
-// and custom icons won't work.
+// Builds a Windows menu from the menu model sent from Chrome. The
+// caller is responsible for closing the returned HMENU. This does
+// not currently handle bitmaps (e.g. hbmpChecked, hbmpUnchecked or
+// hbmpItem), so checkmarks, radio buttons, and custom icons won't work.
// It also copies over submenus up to a maximum depth of kMaxSubMenuDepth.
-//
-// TODO(robertshield): Add support for the bitmap fields if need be.
-HMENU UtilCloneContextMenuImpl(HMENU original_menu, int depth) {
- DCHECK(IsMenu(original_menu));
-
+HMENU BuildContextMenuImpl(const ContextMenuModel* menu_model, int depth) {
if (depth >= kMaxSubmenuDepth)
return NULL;
- HMENU new_menu = CreatePopupMenu();
- int item_count = GetMenuItemCount(original_menu);
- if (item_count <= 0) {
- NOTREACHED();
- } else {
- for (int i = 0; i < item_count; i++) {
- MENUITEMINFO item_info = { 0 };
- item_info.cbSize = sizeof(MENUITEMINFO);
- item_info.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE |
- MIIM_STATE | MIIM_DATA | MIIM_SUBMENU |
- MIIM_CHECKMARKS | MIIM_BITMAP;
-
- // Call GetMenuItemInfo a first time to obtain the buffer size for
- // the label.
- if (GetMenuItemInfo(original_menu, i, TRUE, &item_info)) {
- item_info.cch++; // Increment this as per MSDN
- std::vector<wchar_t> buffer(item_info.cch, 0);
- item_info.dwTypeData = &buffer[0];
-
- // Call GetMenuItemInfo a second time with dwTypeData set to a buffer
- // of a correct size to get the label.
- GetMenuItemInfo(original_menu, i, TRUE, &item_info);
-
- // Clone any submenus. Within reason.
- if (item_info.hSubMenu) {
- HMENU new_submenu = UtilCloneContextMenuImpl(item_info.hSubMenu,
- depth + 1);
- item_info.hSubMenu = new_submenu;
- }
-
- // Now insert the item into the new menu.
- InsertMenuItem(new_menu, i, TRUE, &item_info);
- }
+ HMENU menu = CreatePopupMenu();
+ for (size_t i = 0; i < menu_model->items.size(); i++) {
+ const ContextMenuModel::Item& item = menu_model->items[i];
+
+ MENUITEMINFO item_info = { 0 };
+ item_info.cbSize = sizeof(MENUITEMINFO);
+ switch (item.type) {
+ case ui::MenuModel::TYPE_COMMAND:
+ case ui::MenuModel::TYPE_CHECK:
+ item_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
+ item_info.fType = MFT_STRING;
+ item_info.wID = item.item_id;
+ item_info.dwTypeData = const_cast<LPWSTR>(item.label.c_str());
+ break;
+ case ui::MenuModel::TYPE_RADIO:
+ item_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
+ item_info.fType = MFT_STRING | MFT_RADIOCHECK;
+ item_info.wID = item.item_id;
+ item_info.dwTypeData = const_cast<LPWSTR>(item.label.c_str());
+ break;
+ case ui::MenuModel::TYPE_SEPARATOR:
+ item_info.fMask = MIIM_FTYPE;
+ item_info.fType = MFT_SEPARATOR;
+ break;
+ case ui::MenuModel::TYPE_SUBMENU:
+ item_info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_SUBMENU;
+ item_info.fType = MFT_STRING;
+ item_info.wID = item.item_id;
+ item_info.dwTypeData = const_cast<LPWSTR>(item.label.c_str());
+ item_info.hSubMenu = BuildContextMenuImpl(item.submenu, depth + 1);
+ break;
+ default:
+ NOTREACHED() << "Unsupported MenuModel::ItemType " << item.type;
+ break;
}
+
+ item_info.fMask |= MIIM_STATE;
+ item_info.fState =
+ (item.checked ? MFS_CHECKED : MFS_UNCHECKED) |
+ (item.enabled ? MFS_ENABLED : (MFS_DISABLED | MFS_GRAYED));
+
+ InsertMenuItem(menu, i, TRUE, &item_info);
}
- return new_menu;
+
+ return menu;
}
} // namespace
-HMENU UtilCloneContextMenu(HMENU original_menu) {
- return UtilCloneContextMenuImpl(original_menu, 0);
+HMENU BuildContextMenu(const ContextMenuModel& menu_model) {
+ return BuildContextMenuImpl(&menu_model, 0);
}
std::string ResolveURL(const std::string& document,
diff --git a/chrome_frame/utils.h b/chrome_frame/utils.h
index 7c24e9e..a41978e 100644
--- a/chrome_frame/utils.h
+++ b/chrome_frame/utils.h
@@ -23,6 +23,7 @@
class FilePath;
interface IBrowserService;
interface IWebBrowser2;
+struct ContextMenuModel;
// utils.h : Various utility functions and classes
@@ -225,9 +226,8 @@ bool IsIEInPrivate();
// Calls [ieframe|shdocvw]!DoFileDownload to initiate a download.
HRESULT DoFileDownloadInIE(const wchar_t* url);
-// Creates a copy of a menu. We need this when original menu comes from
-// a process with higher integrity.
-HMENU UtilCloneContextMenu(HMENU original_menu);
+// Construct a menu from the model sent from Chrome.
+HMENU BuildContextMenu(const ContextMenuModel& menu_model);
// Uses GURL internally to append 'relative' to 'document'
std::string ResolveURL(const std::string& document,