From 44946a7752980e536f31beac8d80917aeefc4920 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Mon, 12 Sep 2011 19:49:38 +0000 Subject: [PATCH] Mac: Add context menu support (issue #293). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@286 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- libcef/browser_webview_delegate.cc | 74 ++++++++ libcef/browser_webview_delegate.h | 6 + libcef/browser_webview_delegate_mac.mm | 130 +++++++++++++- libcef/browser_webview_delegate_win.cc | 230 ++++++++++--------------- libcef/browser_webview_mac.h | 3 + libcef/browser_webview_mac.mm | 20 +++ 6 files changed, 320 insertions(+), 143 deletions(-) diff --git a/libcef/browser_webview_delegate.cc b/libcef/browser_webview_delegate.cc index cc402227c..54adf04e6 100644 --- a/libcef/browser_webview_delegate.cc +++ b/libcef/browser_webview_delegate.cc @@ -1145,3 +1145,77 @@ void BrowserWebViewDelegate::UpdateSessionHistory(WebFrame* frame) { 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 client = browser_->GetClient(); + CefRefPtr 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; +} diff --git a/libcef/browser_webview_delegate.h b/libcef/browser_webview_delegate.h index fb4a83244..a233ab2d7 100644 --- a/libcef/browser_webview_delegate.h +++ b/libcef/browser_webview_delegate.h @@ -288,6 +288,12 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient, void UpdateURL(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: // Causes navigation actions just printout the intended navigation instead // of taking you to the page. This is used for cases like mailto, where you diff --git a/libcef/browser_webview_delegate_mac.mm b/libcef/browser_webview_delegate_mac.mm index b5ac19179..052d88e65 100644 --- a/libcef/browser_webview_delegate_mac.mm +++ b/libcef/browser_webview_delegate_mac.mm @@ -13,6 +13,7 @@ #include "base/mac/mac_util.h" #include "base/sys_string_conversions.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/WebDragData.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h" @@ -26,6 +27,7 @@ #include "webkit/glue/webmenurunner_mac.h" using webkit::npapi::WebPluginDelegateImpl; +using WebKit::WebContextMenuData; using WebKit::WebCursorInfo; using WebKit::WebDragData; using WebKit::WebDragOperationsMask; @@ -38,6 +40,42 @@ using WebKit::WebPopupMenuInfo; using WebKit::WebRect; using WebKit::WebWidget; + +namespace { + +void AddMenuItem(CefRefPtr browser, + CefRefPtr 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 -------------------------------------------------------------- WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu( @@ -58,7 +96,97 @@ void BrowserWebViewDelegate::ClosePopupMenu() { void BrowserWebViewDelegate::showContextMenu( WebKit::WebFrame* frame, const WebKit::WebContextMenuData& data) { - NOTIMPLEMENTED(); + WebWidgetHost* host = GetWidgetHost(); + if (!host) + return; + + BrowserWebView *view = static_cast(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 client = browser_->GetClient(); + CefRefPtr 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 ------------------------------------------------------------ diff --git a/libcef/browser_webview_delegate_win.cc b/libcef/browser_webview_delegate_win.cc index 04af41d74..dcde5a2e9 100644 --- a/libcef/browser_webview_delegate_win.cc +++ b/libcef/browser_webview_delegate_win.cc @@ -56,8 +56,53 @@ using WebKit::WebPopupMenuInfo; using WebKit::WebRect; using WebKit::WebWidget; +namespace { + static const wchar_t kPluginWindowClassName[] = L"WebPluginHost"; +void AddMenuItem(CefRefPtr browser, + CefRefPtr handler, + HMENU menu, + cef_handler_menuid_t menuId, + const wchar_t* label, + bool enabled, + std::list& 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(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 -------------------------------------------------------------- WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu( @@ -371,47 +416,6 @@ void BrowserWebViewDelegate::DidMovePlugin( } } -static void AddMenuItem(CefRefPtr browser, HMENU menu, int index, - cef_handler_menuid_t id, const wchar_t* label, - bool enabled, std::list& label_list) -{ - CefString actual_label(label); - CefRefPtr client = browser->GetClient(); - if (client.get()) { - CefRefPtr 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(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( WebFrame* frame, const WebContextMenuData& data) { @@ -427,152 +431,94 @@ void BrowserWebViewDelegate::showContextMenu( screenY = mouse_pt.y; } + int edit_flags = 0; + int type_flags = 0; HMENU menu = NULL; std::list label_list; - // Enable recursive tasks on the message loop so we can get updates while - // the context menu is being displayed. - bool old_state = MessageLoop::current()->NestableTasksAllowed(); - MessageLoop::current()->SetNestableTasksAllowed(true); + // Make sure events can be pumped while the menu is up. + MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); - int edit_flags = data.editFlags; - if(browser_->UIT_CanGoBack()) - edit_flags |= MENU_CAN_GO_BACK; - 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; + // Give the client a chance to handle the menu. + if (OnBeforeMenu(data, mouse_pt.x, mouse_pt.y, edit_flags, type_flags)) + return; CefRefPtr client = browser_->GetClient(); CefRefPtr 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_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()) { + // Retrieve the screen coordinates. CefRefPtr render_handler = client->GetRenderHandler(); if (render_handler.get() && !render_handler->GetScreenPoint(browser_, mouse_pt.x, mouse_pt.y, screenX, screenY)) { - goto end; + return; } } // Build the correct default context menu if (type_flags & MENUTYPE_EDITABLE) { 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); - 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); - AddMenuSeparator(menu, -1); - AddMenuItem(browser_, menu, -1, MENU_ID_CUT, L"Cut", + AddMenuSeparator(menu); + AddMenuItem(browser_, handler, menu, MENU_ID_CUT, L"Cut", !!(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); - 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); - 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); - AddMenuSeparator(menu, -1); - AddMenuItem(browser_, menu, -1, MENU_ID_SELECTALL, L"Select All", + AddMenuSeparator(menu); + AddMenuItem(browser_, handler, menu, MENU_ID_SELECTALL, L"Select All", !!(edit_flags & MENU_CAN_SELECT_ALL), label_list); } else if(type_flags & MENUTYPE_SELECTION) { 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); } else if(type_flags & (MENUTYPE_PAGE | MENUTYPE_FRAME)) { 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); - 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); - AddMenuSeparator(menu, -1); - AddMenuItem(browser_, menu, -1, MENU_ID_PRINT, L"Print", + AddMenuSeparator(menu); + AddMenuItem(browser_, handler, menu, MENU_ID_PRINT, L"Print", 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); } - if (menu) { - // show the context menu - int selected_id = TrackPopupMenu(menu, - TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_RECURSE, - screenX, screenY, 0, browser_->UIT_GetMainWndHandle(), NULL); + if (!menu) + return; - if (selected_id != 0) { - // An action was chosen - cef_handler_menuid_t menuId = - static_cast(selected_id); - bool handled = false; - if (handler.get()) { - // Ask the handler if it wants to handle the action - handled = handler->OnMenuAction(browser_, menuId); - } + // Show the context menu + int selected_id = TrackPopupMenu(menu, + TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_RECURSE, + screenX, screenY, 0, browser_->UIT_GetMainWndHandle(), NULL); - if(!handled) { - // Execute the action - browser_->UIT_HandleAction(menuId, browser_->GetFocusedFrame()); - } + if (selected_id != 0) { + // An action was chosen + cef_handler_menuid_t menuId = + static_cast(selected_id); + bool handled = false; + 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()); } } DestroyMenu(menu); - -end: - MessageLoop::current()->SetNestableTasksAllowed(old_state); } // Private methods ------------------------------------------------------------ diff --git a/libcef/browser_webview_mac.h b/libcef/browser_webview_mac.h index eff4725fc..19920509a 100644 --- a/libcef/browser_webview_mac.h +++ b/libcef/browser_webview_mac.h @@ -40,6 +40,9 @@ struct WebDropData; - (BOOL)isOpaque; - (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. - (void)registerDragDrop; diff --git a/libcef/browser_webview_mac.mm b/libcef/browser_webview_mac.mm index b90282881..eb8a0ffe0 100644 --- a/libcef/browser_webview_mac.mm +++ b/libcef/browser_webview_mac.mm @@ -223,6 +223,26 @@ browser_->GetFocusedFrame()->SelectAll(); } +- (void)menuItemSelected:(id)sender { + cef_handler_menuid_t menuId = + static_cast([sender tag]); + bool handled = false; + + CefRefPtr client = browser_->GetClient(); + if (client.get()) { + CefRefPtr 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 { dropTarget_.reset([[WebDropTarget alloc] initWithWebView:self]);