Mac: Add context menu support (issue #293).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@286 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
588a69ed9b
commit
44946a7752
|
@ -1145,3 +1145,77 @@ void BrowserWebViewDelegate::UpdateSessionHistory(WebFrame* frame) {
|
||||||
|
|
||||||
entry->SetContentState(webkit_glue::HistoryItemToString(history_item));
|
entry->SetContentState(webkit_glue::HistoryItemToString(history_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BrowserWebViewDelegate::OnBeforeMenu(
|
||||||
|
const WebKit::WebContextMenuData& data, int mouse_x, int mouse_y,
|
||||||
|
int& edit_flags, int& type_flags) {
|
||||||
|
// Populate the edit flags values.
|
||||||
|
edit_flags = data.editFlags;
|
||||||
|
if(browser_->UIT_CanGoBack())
|
||||||
|
edit_flags |= MENU_CAN_GO_BACK;
|
||||||
|
if(browser_->UIT_CanGoForward())
|
||||||
|
edit_flags |= MENU_CAN_GO_FORWARD;
|
||||||
|
|
||||||
|
// Populate the type flags values.
|
||||||
|
type_flags = MENUTYPE_NONE;
|
||||||
|
if(!data.pageURL.isEmpty())
|
||||||
|
type_flags |= MENUTYPE_PAGE;
|
||||||
|
if(!data.frameURL.isEmpty())
|
||||||
|
type_flags |= MENUTYPE_FRAME;
|
||||||
|
if(!data.linkURL.isEmpty())
|
||||||
|
type_flags |= MENUTYPE_LINK;
|
||||||
|
if(data.mediaType == WebContextMenuData::MediaTypeImage)
|
||||||
|
type_flags |= MENUTYPE_IMAGE;
|
||||||
|
if(!data.selectedText.isEmpty())
|
||||||
|
type_flags |= MENUTYPE_SELECTION;
|
||||||
|
if(data.isEditable)
|
||||||
|
type_flags |= MENUTYPE_EDITABLE;
|
||||||
|
if(data.isSpellCheckingEnabled && !data.misspelledWord.isEmpty())
|
||||||
|
type_flags |= MENUTYPE_MISSPELLED_WORD;
|
||||||
|
if(data.mediaType == WebContextMenuData::MediaTypeVideo)
|
||||||
|
type_flags |= MENUTYPE_VIDEO;
|
||||||
|
if(data.mediaType == WebContextMenuData::MediaTypeAudio)
|
||||||
|
type_flags |= MENUTYPE_AUDIO;
|
||||||
|
|
||||||
|
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||||
|
CefRefPtr<CefMenuHandler> handler;
|
||||||
|
if (client.get())
|
||||||
|
handler = client->GetMenuHandler();
|
||||||
|
|
||||||
|
if (handler.get()) {
|
||||||
|
// Gather menu information.
|
||||||
|
cef_handler_menuinfo_t menuInfo;
|
||||||
|
memset(&menuInfo, 0, sizeof(menuInfo));
|
||||||
|
|
||||||
|
CefString linkStr(std::string(data.linkURL.spec()));
|
||||||
|
CefString imageStr(std::string(data.srcURL.spec()));
|
||||||
|
CefString pageStr(std::string(data.pageURL.spec()));
|
||||||
|
CefString frameStr(std::string(data.frameURL.spec()));
|
||||||
|
CefString selectedTextStr(string16(data.selectedText));
|
||||||
|
CefString misspelledWordStr(string16(data.misspelledWord));
|
||||||
|
CefString securityInfoStr(std::string(data.securityInfo));
|
||||||
|
|
||||||
|
menuInfo.typeFlags = type_flags;
|
||||||
|
menuInfo.x = mouse_x;
|
||||||
|
menuInfo.y = mouse_y;
|
||||||
|
cef_string_set(linkStr.c_str(), linkStr.length(), &menuInfo.linkUrl, false);
|
||||||
|
cef_string_set(imageStr.c_str(), imageStr.length(), &menuInfo.imageUrl,
|
||||||
|
false);
|
||||||
|
cef_string_set(pageStr.c_str(), pageStr.length(), &menuInfo.pageUrl, false);
|
||||||
|
cef_string_set(frameStr.c_str(), frameStr.length(), &menuInfo.frameUrl,
|
||||||
|
false);
|
||||||
|
cef_string_set(selectedTextStr.c_str(), selectedTextStr.length(),
|
||||||
|
&menuInfo.selectionText, false);
|
||||||
|
cef_string_set(misspelledWordStr.c_str(), misspelledWordStr.length(),
|
||||||
|
&menuInfo.misspelledWord, false);
|
||||||
|
menuInfo.editFlags = edit_flags;
|
||||||
|
cef_string_set(securityInfoStr.c_str(), securityInfoStr.length(),
|
||||||
|
&menuInfo.securityInfo, false);
|
||||||
|
|
||||||
|
// Notify the handler that a context menu is requested.
|
||||||
|
if (handler->OnBeforeMenu(browser_, menuInfo))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -288,6 +288,12 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
|
||||||
void UpdateURL(WebKit::WebFrame* frame);
|
void UpdateURL(WebKit::WebFrame* frame);
|
||||||
void UpdateSessionHistory(WebKit::WebFrame* frame);
|
void UpdateSessionHistory(WebKit::WebFrame* frame);
|
||||||
|
|
||||||
|
bool OnBeforeMenu(const WebKit::WebContextMenuData& data,
|
||||||
|
int mouse_x,
|
||||||
|
int mouse_y,
|
||||||
|
int& edit_flags,
|
||||||
|
int& type_flags);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Causes navigation actions just printout the intended navigation instead
|
// Causes navigation actions just printout the intended navigation instead
|
||||||
// of taking you to the page. This is used for cases like mailto, where you
|
// of taking you to the page. This is used for cases like mailto, where you
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "base/mac/mac_util.h"
|
#include "base/mac/mac_util.h"
|
||||||
#include "base/sys_string_conversions.h"
|
#include "base/sys_string_conversions.h"
|
||||||
#include "skia/ext/skia_utils_mac.h"
|
#include "skia/ext/skia_utils_mac.h"
|
||||||
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDragData.h"
|
||||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h"
|
#include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h"
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include "webkit/glue/webmenurunner_mac.h"
|
#include "webkit/glue/webmenurunner_mac.h"
|
||||||
|
|
||||||
using webkit::npapi::WebPluginDelegateImpl;
|
using webkit::npapi::WebPluginDelegateImpl;
|
||||||
|
using WebKit::WebContextMenuData;
|
||||||
using WebKit::WebCursorInfo;
|
using WebKit::WebCursorInfo;
|
||||||
using WebKit::WebDragData;
|
using WebKit::WebDragData;
|
||||||
using WebKit::WebDragOperationsMask;
|
using WebKit::WebDragOperationsMask;
|
||||||
|
@ -38,6 +40,42 @@ using WebKit::WebPopupMenuInfo;
|
||||||
using WebKit::WebRect;
|
using WebKit::WebRect;
|
||||||
using WebKit::WebWidget;
|
using WebKit::WebWidget;
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void AddMenuItem(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefMenuHandler> handler,
|
||||||
|
NSMenu* menu,
|
||||||
|
cef_handler_menuid_t menuId,
|
||||||
|
const std::string& label,
|
||||||
|
bool enabled) {
|
||||||
|
std::string disp_str;
|
||||||
|
if (handler.get()) {
|
||||||
|
// Let the handler change the label if desired.
|
||||||
|
CefString actual_label(label);
|
||||||
|
handler->GetMenuLabel(browser, menuId, actual_label);
|
||||||
|
disp_str = actual_label;
|
||||||
|
} else {
|
||||||
|
disp_str = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString* str = base::SysUTF8ToNSString(disp_str);
|
||||||
|
NSMenuItem* item =
|
||||||
|
[[[NSMenuItem alloc] initWithTitle:str
|
||||||
|
action:enabled?@selector(menuItemSelected:):nil
|
||||||
|
keyEquivalent:@""] autorelease];
|
||||||
|
[item setTag:menuId];
|
||||||
|
[menu addItem:item];
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddMenuSeparator(NSMenu* menu) {
|
||||||
|
NSMenuItem* item = [NSMenuItem separatorItem];
|
||||||
|
[menu addItem:item];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
// WebViewClient --------------------------------------------------------------
|
// WebViewClient --------------------------------------------------------------
|
||||||
|
|
||||||
WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu(
|
WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu(
|
||||||
|
@ -58,7 +96,97 @@ void BrowserWebViewDelegate::ClosePopupMenu() {
|
||||||
|
|
||||||
void BrowserWebViewDelegate::showContextMenu(
|
void BrowserWebViewDelegate::showContextMenu(
|
||||||
WebKit::WebFrame* frame, const WebKit::WebContextMenuData& data) {
|
WebKit::WebFrame* frame, const WebKit::WebContextMenuData& data) {
|
||||||
NOTIMPLEMENTED();
|
WebWidgetHost* host = GetWidgetHost();
|
||||||
|
if (!host)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BrowserWebView *view = static_cast<BrowserWebView*>(host->view_handle());
|
||||||
|
if (!view)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NSWindow* window = [view window];
|
||||||
|
NSPoint position = [window mouseLocationOutsideOfEventStream];
|
||||||
|
|
||||||
|
int edit_flags = 0;
|
||||||
|
int type_flags = 0;
|
||||||
|
NSMenu* menu = nil;
|
||||||
|
|
||||||
|
// Make sure events can be pumped while the menu is up.
|
||||||
|
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
|
||||||
|
|
||||||
|
// Give the client a chance to handle the menu.
|
||||||
|
if (OnBeforeMenu(data, position.x, position.y, edit_flags, type_flags))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||||
|
CefRefPtr<CefMenuHandler> handler;
|
||||||
|
if (client.get())
|
||||||
|
handler = client->GetMenuHandler();
|
||||||
|
|
||||||
|
// Build the correct default context menu
|
||||||
|
if (type_flags & MENUTYPE_EDITABLE) {
|
||||||
|
menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||||
|
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_UNDO, "Undo",
|
||||||
|
!!(edit_flags & MENU_CAN_UNDO));
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_REDO, "Redo",
|
||||||
|
!!(edit_flags & MENU_CAN_REDO));
|
||||||
|
AddMenuSeparator(menu);
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_CUT, "Cut",
|
||||||
|
!!(edit_flags & MENU_CAN_CUT));
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_COPY, "Copy",
|
||||||
|
!!(edit_flags & MENU_CAN_COPY));
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_PASTE, "Paste",
|
||||||
|
!!(edit_flags & MENU_CAN_PASTE));
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_DELETE, "Delete",
|
||||||
|
!!(edit_flags & MENU_CAN_DELETE));
|
||||||
|
AddMenuSeparator(menu);
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_SELECTALL, "Select All",
|
||||||
|
!!(edit_flags & MENU_CAN_SELECT_ALL));
|
||||||
|
} else if(type_flags & MENUTYPE_SELECTION) {
|
||||||
|
menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||||
|
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_COPY, "Copy",
|
||||||
|
!!(edit_flags & MENU_CAN_COPY));
|
||||||
|
} else if(type_flags & (MENUTYPE_PAGE | MENUTYPE_FRAME)) {
|
||||||
|
menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||||
|
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_NAV_BACK, "Back",
|
||||||
|
!!(edit_flags & MENU_CAN_GO_BACK));
|
||||||
|
AddMenuItem(browser_, handler, menu, MENU_ID_NAV_FORWARD, "Forward",
|
||||||
|
!!(edit_flags & MENU_CAN_GO_FORWARD));
|
||||||
|
// TODO(port): Enable the below menu items when supported.
|
||||||
|
//AddMenuSeparator(menu);
|
||||||
|
//AddMenuItem(browser_, handler, menu, MENU_ID_PRINT, "Print", true);
|
||||||
|
//AddMenuItem(browser_, handler, menu, MENU_ID_VIEWSOURCE, "View Source",
|
||||||
|
// true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Synthesize an event for the click, as there is no certainty that
|
||||||
|
// [NSApp currentEvent] will return a valid event.
|
||||||
|
NSEvent* currentEvent = [NSApp currentEvent];
|
||||||
|
NSTimeInterval eventTime = [currentEvent timestamp];
|
||||||
|
NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
|
||||||
|
location:position
|
||||||
|
modifierFlags:NSRightMouseDownMask
|
||||||
|
timestamp:eventTime
|
||||||
|
windowNumber:[window windowNumber]
|
||||||
|
context:nil
|
||||||
|
eventNumber:0
|
||||||
|
clickCount:1
|
||||||
|
pressure:1.0];
|
||||||
|
|
||||||
|
|
||||||
|
// Menu selection events go to the BrowserWebView.
|
||||||
|
[menu setDelegate:view];
|
||||||
|
|
||||||
|
// Show the menu.
|
||||||
|
[NSMenu popUpContextMenu:menu
|
||||||
|
withEvent:clickEvent
|
||||||
|
forView:view];
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebWidgetClient ------------------------------------------------------------
|
// WebWidgetClient ------------------------------------------------------------
|
||||||
|
|
|
@ -56,8 +56,53 @@ using WebKit::WebPopupMenuInfo;
|
||||||
using WebKit::WebRect;
|
using WebKit::WebRect;
|
||||||
using WebKit::WebWidget;
|
using WebKit::WebWidget;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
static const wchar_t kPluginWindowClassName[] = L"WebPluginHost";
|
static const wchar_t kPluginWindowClassName[] = L"WebPluginHost";
|
||||||
|
|
||||||
|
void AddMenuItem(CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefMenuHandler> handler,
|
||||||
|
HMENU menu,
|
||||||
|
cef_handler_menuid_t menuId,
|
||||||
|
const wchar_t* label,
|
||||||
|
bool enabled,
|
||||||
|
std::list<std::wstring>& label_list)
|
||||||
|
{
|
||||||
|
CefString actual_label(label);
|
||||||
|
if (handler.get()) {
|
||||||
|
// Let the handler change the label if desired,
|
||||||
|
handler->GetMenuLabel(browser, menuId, actual_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the label in a list to simplify memory management.
|
||||||
|
label_list.push_back(actual_label);
|
||||||
|
|
||||||
|
MENUITEMINFO mii;
|
||||||
|
mii.cbSize = sizeof(mii);
|
||||||
|
mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
|
||||||
|
mii.fType = MFT_STRING;
|
||||||
|
if (!enabled) {
|
||||||
|
mii.fMask |= MIIM_STATE;
|
||||||
|
mii.fState = MFS_GRAYED;
|
||||||
|
}
|
||||||
|
mii.wID = menuId;
|
||||||
|
mii.dwTypeData = const_cast<wchar_t*>(label_list.back().c_str());
|
||||||
|
|
||||||
|
InsertMenuItem(menu, -1, TRUE, &mii);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddMenuSeparator(HMENU menu)
|
||||||
|
{
|
||||||
|
MENUITEMINFO mii;
|
||||||
|
mii.cbSize = sizeof(mii);
|
||||||
|
mii.fMask = MIIM_FTYPE;
|
||||||
|
mii.fType = MFT_SEPARATOR;
|
||||||
|
|
||||||
|
InsertMenuItem(menu, -1, TRUE, &mii);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// WebViewClient --------------------------------------------------------------
|
// WebViewClient --------------------------------------------------------------
|
||||||
|
|
||||||
WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu(
|
WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu(
|
||||||
|
@ -371,47 +416,6 @@ void BrowserWebViewDelegate::DidMovePlugin(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddMenuItem(CefRefPtr<CefBrowser> browser, HMENU menu, int index,
|
|
||||||
cef_handler_menuid_t id, const wchar_t* label,
|
|
||||||
bool enabled, std::list<std::wstring>& label_list)
|
|
||||||
{
|
|
||||||
CefString actual_label(label);
|
|
||||||
CefRefPtr<CefClient> client = browser->GetClient();
|
|
||||||
if (client.get()) {
|
|
||||||
CefRefPtr<CefMenuHandler> handler = client->GetMenuHandler();
|
|
||||||
if(handler.get()) {
|
|
||||||
// Let the handler change the label if desired
|
|
||||||
handler->GetMenuLabel(browser, id, actual_label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the label in a list to simplify memory management
|
|
||||||
label_list.push_back(actual_label);
|
|
||||||
|
|
||||||
MENUITEMINFO mii;
|
|
||||||
mii.cbSize = sizeof(mii);
|
|
||||||
mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
|
|
||||||
mii.fType = MFT_STRING;
|
|
||||||
if(!enabled) {
|
|
||||||
mii.fMask |= MIIM_STATE;
|
|
||||||
mii.fState = MFS_GRAYED;
|
|
||||||
}
|
|
||||||
mii.wID = id;
|
|
||||||
mii.dwTypeData = const_cast<wchar_t*>(label_list.back().c_str());
|
|
||||||
|
|
||||||
InsertMenuItem(menu, index, TRUE, &mii);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AddMenuSeparator(HMENU menu, int index)
|
|
||||||
{
|
|
||||||
MENUITEMINFO mii;
|
|
||||||
mii.cbSize = sizeof(mii);
|
|
||||||
mii.fMask = MIIM_FTYPE;
|
|
||||||
mii.fType = MFT_SEPARATOR;
|
|
||||||
|
|
||||||
InsertMenuItem(menu, index, TRUE, &mii);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowserWebViewDelegate::showContextMenu(
|
void BrowserWebViewDelegate::showContextMenu(
|
||||||
WebFrame* frame, const WebContextMenuData& data)
|
WebFrame* frame, const WebContextMenuData& data)
|
||||||
{
|
{
|
||||||
|
@ -427,127 +431,73 @@ void BrowserWebViewDelegate::showContextMenu(
|
||||||
screenY = mouse_pt.y;
|
screenY = mouse_pt.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int edit_flags = 0;
|
||||||
|
int type_flags = 0;
|
||||||
HMENU menu = NULL;
|
HMENU menu = NULL;
|
||||||
std::list<std::wstring> label_list;
|
std::list<std::wstring> label_list;
|
||||||
|
|
||||||
// Enable recursive tasks on the message loop so we can get updates while
|
// Make sure events can be pumped while the menu is up.
|
||||||
// the context menu is being displayed.
|
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
|
||||||
bool old_state = MessageLoop::current()->NestableTasksAllowed();
|
|
||||||
MessageLoop::current()->SetNestableTasksAllowed(true);
|
|
||||||
|
|
||||||
int edit_flags = data.editFlags;
|
// Give the client a chance to handle the menu.
|
||||||
if(browser_->UIT_CanGoBack())
|
if (OnBeforeMenu(data, mouse_pt.x, mouse_pt.y, edit_flags, type_flags))
|
||||||
edit_flags |= MENU_CAN_GO_BACK;
|
return;
|
||||||
if(browser_->UIT_CanGoForward())
|
|
||||||
edit_flags |= MENU_CAN_GO_FORWARD;
|
|
||||||
|
|
||||||
int type_flags = MENUTYPE_NONE;
|
|
||||||
if(!data.pageURL.isEmpty())
|
|
||||||
type_flags |= MENUTYPE_PAGE;
|
|
||||||
if(!data.frameURL.isEmpty())
|
|
||||||
type_flags |= MENUTYPE_FRAME;
|
|
||||||
if(!data.linkURL.isEmpty())
|
|
||||||
type_flags |= MENUTYPE_LINK;
|
|
||||||
if(data.mediaType == WebContextMenuData::MediaTypeImage)
|
|
||||||
type_flags |= MENUTYPE_IMAGE;
|
|
||||||
if(!data.selectedText.isEmpty())
|
|
||||||
type_flags |= MENUTYPE_SELECTION;
|
|
||||||
if(data.isEditable)
|
|
||||||
type_flags |= MENUTYPE_EDITABLE;
|
|
||||||
if(data.isSpellCheckingEnabled && !data.misspelledWord.isEmpty())
|
|
||||||
type_flags |= MENUTYPE_MISSPELLED_WORD;
|
|
||||||
if(data.mediaType == WebContextMenuData::MediaTypeVideo)
|
|
||||||
type_flags |= MENUTYPE_VIDEO;
|
|
||||||
if(data.mediaType == WebContextMenuData::MediaTypeAudio)
|
|
||||||
type_flags |= MENUTYPE_AUDIO;
|
|
||||||
|
|
||||||
CefRefPtr<CefClient> client = browser_->GetClient();
|
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||||
CefRefPtr<CefMenuHandler> handler;
|
CefRefPtr<CefMenuHandler> handler;
|
||||||
if (client.get())
|
if (client.get())
|
||||||
handler = client->GetMenuHandler();
|
handler = client->GetMenuHandler();
|
||||||
|
|
||||||
if (handler.get()) {
|
|
||||||
// Gather menu information
|
|
||||||
cef_handler_menuinfo_t menuInfo;
|
|
||||||
memset(&menuInfo, 0, sizeof(menuInfo));
|
|
||||||
|
|
||||||
CefString linkStr(std::string(data.linkURL.spec()));
|
|
||||||
CefString imageStr(std::string(data.srcURL.spec()));
|
|
||||||
CefString pageStr(std::string(data.pageURL.spec()));
|
|
||||||
CefString frameStr(std::string(data.frameURL.spec()));
|
|
||||||
CefString selectedTextStr(string16(data.selectedText));
|
|
||||||
CefString misspelledWordStr(string16(data.misspelledWord));
|
|
||||||
CefString securityInfoStr(std::string(data.securityInfo));
|
|
||||||
|
|
||||||
menuInfo.typeFlags = type_flags;
|
|
||||||
menuInfo.x = mouse_pt.x;
|
|
||||||
menuInfo.y = mouse_pt.y;
|
|
||||||
cef_string_set(linkStr.c_str(), linkStr.length(), &menuInfo.linkUrl, false);
|
|
||||||
cef_string_set(imageStr.c_str(), imageStr.length(), &menuInfo.imageUrl,
|
|
||||||
false);
|
|
||||||
cef_string_set(pageStr.c_str(), pageStr.length(), &menuInfo.pageUrl, false);
|
|
||||||
cef_string_set(frameStr.c_str(), frameStr.length(), &menuInfo.frameUrl,
|
|
||||||
false);
|
|
||||||
cef_string_set(selectedTextStr.c_str(), selectedTextStr.length(),
|
|
||||||
&menuInfo.selectionText, false);
|
|
||||||
cef_string_set(misspelledWordStr.c_str(), misspelledWordStr.length(),
|
|
||||||
&menuInfo.misspelledWord, false);
|
|
||||||
menuInfo.editFlags = edit_flags;
|
|
||||||
cef_string_set(securityInfoStr.c_str(), securityInfoStr.length(),
|
|
||||||
&menuInfo.securityInfo, false);
|
|
||||||
|
|
||||||
// Notify the handler that a context menu is requested
|
|
||||||
if (handler->OnBeforeMenu(browser_, menuInfo))
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client.get() && browser_->IsWindowRenderingDisabled()) {
|
if (client.get() && browser_->IsWindowRenderingDisabled()) {
|
||||||
|
// Retrieve the screen coordinates.
|
||||||
CefRefPtr<CefRenderHandler> render_handler = client->GetRenderHandler();
|
CefRefPtr<CefRenderHandler> render_handler = client->GetRenderHandler();
|
||||||
if (render_handler.get() &&
|
if (render_handler.get() &&
|
||||||
!render_handler->GetScreenPoint(browser_, mouse_pt.x, mouse_pt.y,
|
!render_handler->GetScreenPoint(browser_, mouse_pt.x, mouse_pt.y,
|
||||||
screenX, screenY)) {
|
screenX, screenY)) {
|
||||||
goto end;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the correct default context menu
|
// Build the correct default context menu
|
||||||
if (type_flags & MENUTYPE_EDITABLE) {
|
if (type_flags & MENUTYPE_EDITABLE) {
|
||||||
menu = CreatePopupMenu();
|
menu = CreatePopupMenu();
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_UNDO, L"Undo",
|
AddMenuItem(browser_, handler, menu, MENU_ID_UNDO, L"Undo",
|
||||||
!!(edit_flags & MENU_CAN_UNDO), label_list);
|
!!(edit_flags & MENU_CAN_UNDO), label_list);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_REDO, L"Redo",
|
AddMenuItem(browser_, handler, menu, MENU_ID_REDO, L"Redo",
|
||||||
!!(edit_flags & MENU_CAN_REDO), label_list);
|
!!(edit_flags & MENU_CAN_REDO), label_list);
|
||||||
AddMenuSeparator(menu, -1);
|
AddMenuSeparator(menu);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_CUT, L"Cut",
|
AddMenuItem(browser_, handler, menu, MENU_ID_CUT, L"Cut",
|
||||||
!!(edit_flags & MENU_CAN_CUT), label_list);
|
!!(edit_flags & MENU_CAN_CUT), label_list);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_COPY, L"Copy",
|
AddMenuItem(browser_, handler, menu, MENU_ID_COPY, L"Copy",
|
||||||
!!(edit_flags & MENU_CAN_COPY), label_list);
|
!!(edit_flags & MENU_CAN_COPY), label_list);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_PASTE, L"Paste",
|
AddMenuItem(browser_, handler, menu, MENU_ID_PASTE, L"Paste",
|
||||||
!!(edit_flags & MENU_CAN_PASTE), label_list);
|
!!(edit_flags & MENU_CAN_PASTE), label_list);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_DELETE, L"Delete",
|
AddMenuItem(browser_, handler, menu, MENU_ID_DELETE, L"Delete",
|
||||||
!!(edit_flags & MENU_CAN_DELETE), label_list);
|
!!(edit_flags & MENU_CAN_DELETE), label_list);
|
||||||
AddMenuSeparator(menu, -1);
|
AddMenuSeparator(menu);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_SELECTALL, L"Select All",
|
AddMenuItem(browser_, handler, menu, MENU_ID_SELECTALL, L"Select All",
|
||||||
!!(edit_flags & MENU_CAN_SELECT_ALL), label_list);
|
!!(edit_flags & MENU_CAN_SELECT_ALL), label_list);
|
||||||
} else if(type_flags & MENUTYPE_SELECTION) {
|
} else if(type_flags & MENUTYPE_SELECTION) {
|
||||||
menu = CreatePopupMenu();
|
menu = CreatePopupMenu();
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_COPY, L"Copy",
|
AddMenuItem(browser_, handler, menu, MENU_ID_COPY, L"Copy",
|
||||||
!!(edit_flags & MENU_CAN_COPY), label_list);
|
!!(edit_flags & MENU_CAN_COPY), label_list);
|
||||||
} else if(type_flags & (MENUTYPE_PAGE | MENUTYPE_FRAME)) {
|
} else if(type_flags & (MENUTYPE_PAGE | MENUTYPE_FRAME)) {
|
||||||
menu = CreatePopupMenu();
|
menu = CreatePopupMenu();
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_NAV_BACK, L"Back",
|
AddMenuItem(browser_, handler, menu, MENU_ID_NAV_BACK, L"Back",
|
||||||
!!(edit_flags & MENU_CAN_GO_BACK), label_list);
|
!!(edit_flags & MENU_CAN_GO_BACK), label_list);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_NAV_FORWARD, L"Forward",
|
AddMenuItem(browser_, handler, menu, MENU_ID_NAV_FORWARD, L"Forward",
|
||||||
!!(edit_flags & MENU_CAN_GO_FORWARD), label_list);
|
!!(edit_flags & MENU_CAN_GO_FORWARD), label_list);
|
||||||
AddMenuSeparator(menu, -1);
|
AddMenuSeparator(menu);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_PRINT, L"Print",
|
AddMenuItem(browser_, handler, menu, MENU_ID_PRINT, L"Print",
|
||||||
true, label_list);
|
true, label_list);
|
||||||
AddMenuItem(browser_, menu, -1, MENU_ID_VIEWSOURCE, L"View Source",
|
AddMenuItem(browser_, handler, menu, MENU_ID_VIEWSOURCE, L"View Source",
|
||||||
true, label_list);
|
true, label_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menu) {
|
if (!menu)
|
||||||
// show the context menu
|
return;
|
||||||
|
|
||||||
|
// Show the context menu
|
||||||
int selected_id = TrackPopupMenu(menu,
|
int selected_id = TrackPopupMenu(menu,
|
||||||
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_RECURSE,
|
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_RECURSE,
|
||||||
screenX, screenY, 0, browser_->UIT_GetMainWndHandle(), NULL);
|
screenX, screenY, 0, browser_->UIT_GetMainWndHandle(), NULL);
|
||||||
|
@ -567,12 +517,8 @@ void BrowserWebViewDelegate::showContextMenu(
|
||||||
browser_->UIT_HandleAction(menuId, browser_->GetFocusedFrame());
|
browser_->UIT_HandleAction(menuId, browser_->GetFocusedFrame());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DestroyMenu(menu);
|
DestroyMenu(menu);
|
||||||
|
|
||||||
end:
|
|
||||||
MessageLoop::current()->SetNestableTasksAllowed(old_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private methods ------------------------------------------------------------
|
// Private methods ------------------------------------------------------------
|
||||||
|
|
|
@ -40,6 +40,9 @@ struct WebDropData;
|
||||||
- (BOOL)isOpaque;
|
- (BOOL)isOpaque;
|
||||||
- (void)setFrame:(NSRect)frameRect;
|
- (void)setFrame:(NSRect)frameRect;
|
||||||
|
|
||||||
|
// Called when a context menu item is selected by the user.
|
||||||
|
- (void)menuItemSelected:(id)sender;
|
||||||
|
|
||||||
// Register this WebView as a drag/drop target.
|
// Register this WebView as a drag/drop target.
|
||||||
- (void)registerDragDrop;
|
- (void)registerDragDrop;
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,26 @@
|
||||||
browser_->GetFocusedFrame()->SelectAll();
|
browser_->GetFocusedFrame()->SelectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)menuItemSelected:(id)sender {
|
||||||
|
cef_handler_menuid_t menuId =
|
||||||
|
static_cast<cef_handler_menuid_t>([sender tag]);
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||||
|
if (client.get()) {
|
||||||
|
CefRefPtr<CefMenuHandler> handler = client->GetMenuHandler();
|
||||||
|
if (handler.get()) {
|
||||||
|
// Ask the handler if it wants to handle the action.
|
||||||
|
handled = handler->OnMenuAction(browser_, menuId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!handled) {
|
||||||
|
// Execute the action.
|
||||||
|
browser_->UIT_HandleAction(menuId, browser_->GetFocusedFrame());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)registerDragDrop {
|
- (void)registerDragDrop {
|
||||||
dropTarget_.reset([[WebDropTarget alloc] initWithWebView:self]);
|
dropTarget_.reset([[WebDropTarget alloc] initWithWebView:self]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue