mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-02 12:17:15 +01:00
Mac:
- Implement the WebExternalPopupMenu interface to fix select popup menu display. - Remove the kCFRunLoopBeforeTimers option from CFRunLoopObserverCreate to reduce CPU usage (issue #211). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@218 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
a66c733ab6
commit
1f7a4b4566
2
cef.gyp
2
cef.gyp
@ -686,6 +686,8 @@
|
||||
'libcef/browser_webview_mac.h',
|
||||
'libcef/browser_webview_mac.mm',
|
||||
'libcef/cef_process_ui_thread_mac.mm',
|
||||
'libcef/external_popup_menu_mac.h',
|
||||
'libcef/external_popup_menu_mac.mm',
|
||||
'libcef/external_protocol_handler_mac.mm',
|
||||
'libcef/webview_host_mac.mm',
|
||||
'libcef/webwidget_host_mac.mm',
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h"
|
||||
#include "external_popup_menu_mac.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@ -55,8 +56,9 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
|
||||
WebKit::WebFrame* creator, const WebKit::WebURLRequest& request,
|
||||
const WebKit::WebWindowFeatures& features, const WebKit::WebString& name);
|
||||
virtual WebKit::WebWidget* createPopupMenu(WebKit::WebPopupType popup_type);
|
||||
virtual WebKit::WebWidget* createPopupMenu(
|
||||
const WebKit::WebPopupMenuInfo& info);
|
||||
virtual WebKit::WebExternalPopupMenu* createExternalPopupMenu(
|
||||
const WebKit::WebPopupMenuInfo& info,
|
||||
WebKit::WebExternalPopupMenuClient* client);
|
||||
virtual WebKit::WebStorageNamespace* createSessionStorageNamespace(
|
||||
unsigned quota);
|
||||
virtual void didAddMessageToConsole(
|
||||
@ -247,7 +249,8 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
|
||||
CefBrowserImpl* GetBrowser() { return browser_; }
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
void SetPopupMenuInfo(const WebKit::WebPopupMenuInfo& info);
|
||||
// Called after the external popup menu has been dismissed.
|
||||
void ClosePopupMenu();
|
||||
#endif
|
||||
|
||||
// Called after dragging has finished.
|
||||
@ -322,8 +325,8 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
scoped_ptr<WebKit::WebPopupMenuInfo> popup_menu_info_;
|
||||
WebKit::WebRect popup_bounds_;
|
||||
// The external popup menu for the currently showing select popup.
|
||||
scoped_ptr<ExternalPopupMenu> external_popup_menu_;
|
||||
#endif
|
||||
|
||||
// true if we want to enable smart insert/delete.
|
||||
|
@ -17,19 +17,29 @@
|
||||
#include "webkit/glue/webmenurunner_mac.h"
|
||||
|
||||
using WebKit::WebCursorInfo;
|
||||
using WebKit::WebExternalPopupMenu;
|
||||
using WebKit::WebExternalPopupMenuClient;
|
||||
using WebKit::WebNavigationPolicy;
|
||||
using WebKit::WebPopupMenu;
|
||||
using WebKit::WebPopupMenuInfo;
|
||||
using WebKit::WebRect;
|
||||
using WebKit::WebWidget;
|
||||
|
||||
// WebViewClient --------------------------------------------------------------
|
||||
|
||||
WebWidget* BrowserWebViewDelegate::createPopupMenu(
|
||||
const WebPopupMenuInfo& info) {
|
||||
WebWidget* webwidget = browser_->UIT_CreatePopupWidget();
|
||||
browser_->UIT_GetPopupDelegate()->SetPopupMenuInfo(info);
|
||||
return webwidget;
|
||||
WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu(
|
||||
const WebPopupMenuInfo& info,
|
||||
WebExternalPopupMenuClient* client) {
|
||||
DCHECK(!external_popup_menu_.get());
|
||||
external_popup_menu_.reset(new ExternalPopupMenu(this, info, client));
|
||||
return external_popup_menu_.get();
|
||||
}
|
||||
|
||||
void BrowserWebViewDelegate::ClosePopupMenu() {
|
||||
if (external_popup_menu_ == NULL) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
external_popup_menu_.reset();
|
||||
}
|
||||
|
||||
void BrowserWebViewDelegate::showContextMenu(
|
||||
@ -40,64 +50,6 @@ void BrowserWebViewDelegate::showContextMenu(
|
||||
// WebWidgetClient ------------------------------------------------------------
|
||||
|
||||
void BrowserWebViewDelegate::show(WebNavigationPolicy policy) {
|
||||
if (!popup_menu_info_.get())
|
||||
return;
|
||||
if (this != browser_->UIT_GetPopupDelegate())
|
||||
return;
|
||||
// Display a HTML select menu.
|
||||
|
||||
std::vector<WebMenuItem> items;
|
||||
for (size_t i = 0; i < popup_menu_info_->items.size(); ++i)
|
||||
items.push_back(popup_menu_info_->items[i]);
|
||||
|
||||
int item_height = popup_menu_info_->itemHeight;
|
||||
double font_size = popup_menu_info_->itemFontSize;
|
||||
int selected_index = popup_menu_info_->selectedIndex;
|
||||
bool right_aligned = popup_menu_info_->rightAligned;
|
||||
popup_menu_info_.reset(); // No longer needed.
|
||||
|
||||
const WebRect& bounds = popup_bounds_;
|
||||
|
||||
// Set up the menu position.
|
||||
NSView* web_view = browser_->UIT_GetWebViewWndHandle();
|
||||
NSRect view_rect = [web_view bounds];
|
||||
int y_offset = bounds.y + bounds.height;
|
||||
NSRect position = NSMakeRect(bounds.x, view_rect.size.height - y_offset,
|
||||
bounds.width, bounds.height);
|
||||
|
||||
// Display the menu.
|
||||
scoped_nsobject<WebMenuRunner> menu_runner;
|
||||
menu_runner.reset([[WebMenuRunner alloc] initWithItems:items
|
||||
fontSize:font_size
|
||||
rightAligned:right_aligned]);
|
||||
|
||||
[menu_runner runMenuInView:browser_->UIT_GetWebViewWndHandle()
|
||||
withBounds:position
|
||||
initialIndex:selected_index];
|
||||
|
||||
// Get the selected item and forward to WebKit. WebKit expects an input event
|
||||
// (mouse down, keyboard activity) for this, so we calculate the proper
|
||||
// position based on the selected index and provided bounds.
|
||||
WebWidgetHost* popup = browser_->UIT_GetPopupHost();
|
||||
NSWindow* window = [browser_->UIT_GetMainWndHandle() window];
|
||||
int window_num = [window windowNumber];
|
||||
NSEvent* event =
|
||||
webkit_glue::EventWithMenuAction([menu_runner menuItemWasChosen],
|
||||
window_num, item_height,
|
||||
[menu_runner indexOfSelectedItem],
|
||||
position, view_rect);
|
||||
|
||||
if ([menu_runner menuItemWasChosen]) {
|
||||
// Construct a mouse up event to simulate the selection of an appropriate
|
||||
// menu item.
|
||||
popup->MouseEvent(event);
|
||||
} else {
|
||||
// Fake an ESC key event (keyCode = 0x1B, from webinputevent_mac.mm) and
|
||||
// forward that to WebKit.
|
||||
popup->KeyEvent(event);
|
||||
}
|
||||
|
||||
browser_->UIT_ClosePopupWidget();
|
||||
}
|
||||
|
||||
void BrowserWebViewDelegate::didChangeCursor(const WebCursorInfo& cursor_info) {
|
||||
@ -117,8 +69,6 @@ WebRect BrowserWebViewDelegate::windowRect() {
|
||||
void BrowserWebViewDelegate::setWindowRect(const WebRect& rect) {
|
||||
if (this == browser_->UIT_GetWebViewDelegate()) {
|
||||
// TODO(port): Set the window rectangle.
|
||||
} else if (this == browser_->UIT_GetPopupDelegate()) {
|
||||
popup_bounds_ = rect; // The initial position of the popup.
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,10 +139,6 @@ void BrowserWebViewDelegate::DidMovePlugin(
|
||||
|
||||
// Protected methods ----------------------------------------------------------
|
||||
|
||||
void BrowserWebViewDelegate::SetPopupMenuInfo(const WebPopupMenuInfo& info) {
|
||||
popup_menu_info_.reset(new WebPopupMenuInfo(info));
|
||||
}
|
||||
|
||||
void BrowserWebViewDelegate::ShowJavaScriptAlert(
|
||||
WebKit::WebFrame* webframe, const CefString& message) {
|
||||
std::string messageStr(message);
|
||||
|
@ -38,6 +38,8 @@
|
||||
using webkit::npapi::WebPluginDelegateImpl;
|
||||
using WebKit::WebContextMenuData;
|
||||
using WebKit::WebCursorInfo;
|
||||
using WebKit::WebExternalPopupMenu;
|
||||
using WebKit::WebExternalPopupMenuClient;
|
||||
using WebKit::WebFrame;
|
||||
using WebKit::WebNavigationPolicy;
|
||||
using WebKit::WebPopupMenuInfo;
|
||||
@ -48,8 +50,9 @@ static const wchar_t kPluginWindowClassName[] = L"WebPluginHost";
|
||||
|
||||
// WebViewClient --------------------------------------------------------------
|
||||
|
||||
WebWidget* BrowserWebViewDelegate::createPopupMenu(
|
||||
const WebPopupMenuInfo& info) {
|
||||
WebExternalPopupMenu* BrowserWebViewDelegate::createExternalPopupMenu(
|
||||
const WebPopupMenuInfo& info,
|
||||
WebExternalPopupMenuClient* client) {
|
||||
NOTREACHED();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "cef_process_ui_thread.h"
|
||||
#include "browser_webkit_glue.h"
|
||||
#include "base/message_pump_mac.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
||||
#include "third_party/WebKit/Source/WebKit/mac/WebCoreSupport/WebSystemInterface.h"
|
||||
|
||||
// CrAppProtocol implementation.
|
||||
@ -53,7 +54,7 @@ void CefProcessUIThread::PlatformInit() {
|
||||
// Register the run loop observer.
|
||||
CFRunLoopObserverRef observer =
|
||||
CFRunLoopObserverCreate(NULL,
|
||||
kCFRunLoopBeforeTimers | kCFRunLoopBeforeWaiting,
|
||||
kCFRunLoopBeforeWaiting,
|
||||
YES, /* repeat */
|
||||
0,
|
||||
&RunLoopObserver,
|
||||
@ -64,6 +65,9 @@ void CefProcessUIThread::PlatformInit() {
|
||||
}
|
||||
|
||||
webkit_glue::InitializeDataPak();
|
||||
|
||||
// On Mac, the select popup menus are rendered by the browser.
|
||||
WebKit::WebView::setUseExternalPopupMenus(true);
|
||||
}
|
||||
|
||||
void CefProcessUIThread::PlatformCleanUp() {
|
||||
|
36
libcef/external_popup_menu_mac.h
Normal file
36
libcef/external_popup_menu_mac.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2011 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright (c) 2010 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 _EXTERNAL_POPUP_MENU_MAC_H
|
||||
#define _EXTERNAL_POPUP_MENU_MAC_H
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebExternalPopupMenu.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h"
|
||||
|
||||
class BrowserWebViewDelegate;
|
||||
namespace WebKit {
|
||||
class WebExternalPopupMenuClient;
|
||||
}
|
||||
|
||||
class ExternalPopupMenu : public WebKit::WebExternalPopupMenu {
|
||||
public:
|
||||
ExternalPopupMenu(BrowserWebViewDelegate* delegate,
|
||||
const WebKit::WebPopupMenuInfo& popup_menu_info,
|
||||
WebKit::WebExternalPopupMenuClient* popup_menu_client);
|
||||
|
||||
// WebKit::WebExternalPopupMenu implementation:
|
||||
virtual void show(const WebKit::WebRect& bounds);
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
BrowserWebViewDelegate* delegate_;
|
||||
WebKit::WebPopupMenuInfo popup_menu_info_;
|
||||
WebKit::WebExternalPopupMenuClient* popup_menu_client_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ExternalPopupMenu);
|
||||
};
|
||||
|
||||
#endif // _EXTERNAL_POPUP_MENU_MAC_H
|
66
libcef/external_popup_menu_mac.mm
Normal file
66
libcef/external_popup_menu_mac.mm
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2011 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright (c) 2010 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 "external_popup_menu_mac.h"
|
||||
#include "browser_impl.h"
|
||||
|
||||
#include "content/common/view_messages.h"
|
||||
#include "content/renderer/render_view.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebExternalPopupMenuClient.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
|
||||
#include "webkit/glue/webmenurunner_mac.h"
|
||||
|
||||
ExternalPopupMenu::ExternalPopupMenu(
|
||||
BrowserWebViewDelegate* delegate,
|
||||
const WebKit::WebPopupMenuInfo& popup_menu_info,
|
||||
WebKit::WebExternalPopupMenuClient* popup_menu_client)
|
||||
: delegate_(delegate),
|
||||
popup_menu_info_(popup_menu_info),
|
||||
popup_menu_client_(popup_menu_client) {
|
||||
}
|
||||
|
||||
void ExternalPopupMenu::show(const WebKit::WebRect& bounds) {
|
||||
// Display a HTML select menu.
|
||||
|
||||
std::vector<WebMenuItem> items;
|
||||
for (size_t i = 0; i < popup_menu_info_.items.size(); ++i)
|
||||
items.push_back(popup_menu_info_.items[i]);
|
||||
|
||||
double font_size = popup_menu_info_.itemFontSize;
|
||||
int selected_index = popup_menu_info_.selectedIndex;
|
||||
bool right_aligned = popup_menu_info_.rightAligned;
|
||||
|
||||
CefBrowserImpl* browser = delegate_->GetBrowser();
|
||||
|
||||
// Set up the menu position.
|
||||
NSView* web_view = browser->UIT_GetWebViewWndHandle();
|
||||
NSRect view_rect = [web_view bounds];
|
||||
int y_offset = bounds.y + bounds.height;
|
||||
NSRect position = NSMakeRect(bounds.x, view_rect.size.height - y_offset,
|
||||
bounds.width, bounds.height);
|
||||
|
||||
// Display the menu.
|
||||
scoped_nsobject<WebMenuRunner> menu_runner;
|
||||
menu_runner.reset([[WebMenuRunner alloc] initWithItems:items
|
||||
fontSize:font_size
|
||||
rightAligned:right_aligned]);
|
||||
|
||||
[menu_runner runMenuInView:browser->UIT_GetWebViewWndHandle()
|
||||
withBounds:position
|
||||
initialIndex:selected_index];
|
||||
|
||||
if ([menu_runner menuItemWasChosen])
|
||||
popup_menu_client_->didAcceptIndex([menu_runner indexOfSelectedItem]);
|
||||
else
|
||||
popup_menu_client_->didCancel();
|
||||
|
||||
delegate_->ClosePopupMenu();
|
||||
}
|
||||
|
||||
void ExternalPopupMenu::close() {
|
||||
popup_menu_client_ = NULL;
|
||||
delegate_ = NULL;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user