Add initial Mac implementation files.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@123 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2010-10-23 17:00:47 +00:00
parent d4004fc57e
commit c6be988e89
17 changed files with 1139 additions and 27 deletions

View File

@ -388,7 +388,6 @@
'libcef/browser_file_writer.h',
'libcef/browser_impl.cc',
'libcef/browser_impl.h',
'libcef/browser_impl_win.cc',
'libcef/browser_navigation_controller.cc',
'libcef/browser_navigation_controller.h',
'libcef/browser_request_context.cc',
@ -447,6 +446,7 @@
'libcef/browser_drag_delegate.h',
'libcef/browser_drop_delegate.cc',
'libcef/browser_drop_delegate.h',
'libcef/browser_impl_win.cc',
'libcef/browser_webkit_glue_win.cc',
'libcef/browser_webview_delegate_win.cc',
'libcef/printing/print_settings.cc',
@ -461,8 +461,11 @@
'sources': [
'include/cef_types_mac.h',
'include/cef_mac.h',
'libcef/browser_impl_mac.mm',
'libcef/browser_webkit_glue_mac.mm',
'libcef/browser_webview_delegate_mac.mm',
'libcef/browser_webview_mac.h',
'libcef/browser_webview_mac.mm',
'libcef/webview_host_mac.mm',
'libcef/webwidget_host_mac.mm',
],
@ -471,6 +474,7 @@
'sources': [
'include/cef_types_linux.h',
'include/cef_linux.h',
'libcef/browser_impl_gtk.cc',
'libcef/browser_webkit_glue_gtk.cc',
'libcef/browser_webview_delegate_gtk.cc',
'libcef/webview_host_gtk.cc',

View File

@ -38,6 +38,9 @@ extern "C" {
#if defined(__linux__)
#include "cef_string.h"
// Window handle.
#define cef_window_handle_t void*
// Class representing window information.
typedef struct _cef_window_info_t
{
@ -55,8 +58,6 @@ typedef struct _cef_print_info_t
double m_Scale;
} cef_print_info_t;
// Window handle.
#define cef_window_handle_t void*
#endif // defined(__linux__)
#ifdef __cplusplus

View File

@ -38,6 +38,9 @@ extern "C" {
#if defined(__APPLE__)
#include "cef_string.h"
// Window handle.
#define cef_window_handle_t void*
// Class representing window information.
typedef struct _cef_window_info_t
{
@ -47,6 +50,12 @@ typedef struct _cef_window_info_t
int m_y;
int m_nWidth;
int m_nHeight;
// NSWindow pointer for the parent window.
cef_window_handle_t m_ParentWindow;
// NSWindow pointer for the new browser window.
cef_window_handle_t m_Window;
} cef_window_info_t;
// Class representing print context information.
@ -55,8 +64,6 @@ typedef struct _cef_print_info_t
double m_Scale;
} cef_print_info_t;
// Window handle.
#define cef_window_handle_t void*
#endif // defined(__APPLE__)
#ifdef __cplusplus

View File

@ -39,6 +39,9 @@ extern "C" {
#include <windows.h>
#include "cef_string.h"
// Window handle.
#define cef_window_handle_t HWND
// Class representing window information.
typedef struct _cef_window_info_t
{
@ -50,11 +53,11 @@ typedef struct _cef_window_info_t
int m_y;
int m_nWidth;
int m_nHeight;
HWND m_hWndParent;
cef_window_handle_t m_hWndParent;
HMENU m_hMenu;
// Handle for the new browser window.
HWND m_hWnd;
cef_window_handle_t m_hWnd;
} cef_window_info_t;
// Class representing print context information.
@ -65,8 +68,6 @@ typedef struct _cef_print_info_t
double m_Scale;
} cef_print_info_t;
// Window handle.
#define cef_window_handle_t HWND
#endif // _WIN32
#ifdef __cplusplus

View File

@ -112,7 +112,7 @@ public:
BrowserWebViewDelegate* GetWebViewDelegate() const {
return delegate_.get();
}
CefWindowHandle GetWebViewWndHandle() const {
gfx::NativeView GetWebViewWndHandle() const {
return webviewhost_->view_handle();
}
WebKit::WebWidget* GetPopup() const {
@ -124,17 +124,10 @@ public:
BrowserWebViewDelegate* GetPopupDelegate() const {
return popup_delegate_.get();
}
CefWindowHandle GetPopupWndHandle() const {
gfx::NativeView GetPopupWndHandle() const {
return popuphost_->view_handle();
}
CefWindowHandle GetMainWndHandle() const {
#if defined(OS_WIN)
return window_info_.m_hWnd;
#else
return 0;
#endif
}
gfx::NativeWindow GetMainWndHandle() const;
////////////////////////////////////////////////////////////
// ALL UIT_* METHODS MUST ONLY BE CALLED ON THE UI THREAD //

127
libcef/browser_impl_mac.mm Normal file
View File

@ -0,0 +1,127 @@
// Copyright (c) 2010 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2008 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 "cef_context.h"
#include "browser_impl.h"
#import <Cocoa/Cocoa.h>
#include "base/utf_string_conversions.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
using WebKit::WebRect;
using WebKit::WebSize;
CefWindowHandle CefBrowserImpl::GetWindowHandle()
{
Lock();
CefWindowHandle handle = window_info_.m_Window;
Unlock();
return handle;
}
gfx::NativeWindow CefBrowserImpl::GetMainWndHandle() const {
return (NSWindow*)window_info_.m_Window;
}
void CefBrowserImpl::UIT_CreateBrowser(const std::wstring& url)
{
REQUIRE_UIT();
// Create the new browser window
// TODO(port): Add implementation.
// Add a reference that will be released on WM_DESTROY.
AddRef();
// Add the new browser to the list maintained by the context
_Context->AddBrowser(this);
// Create the webview host object
webviewhost_.reset(
WebViewHost::Create([GetMainWndHandle() contentView], delegate_.get(),
NULL, *_Context->web_preferences()));
delegate_->RegisterDragDrop();
// Size the web view window to the browser window
// TODO(port): Add implementation.
if(handler_.get()) {
// Notify the handler that we're done creating the new window
handler_->HandleAfterCreated(this);
}
if(url.size() > 0) {
CefRefPtr<CefFrame> frame = GetMainFrame();
frame->AddRef();
UIT_LoadURL(frame, url.c_str());
}
}
void CefBrowserImpl::UIT_SetFocus(WebWidgetHost* host, bool enable)
{
REQUIRE_UIT();
if (!host)
return;
// TODO(port): Add implementation.
}
WebKit::WebWidget* CefBrowserImpl::UIT_CreatePopupWidget()
{
REQUIRE_UIT();
DCHECK(!popuphost_);
popuphost_ = WebWidgetHost::Create(NULL, popup_delegate_.get());
// TODO(port): Show window.
return popuphost_->webwidget();
}
void CefBrowserImpl::UIT_ClosePopupWidget()
{
REQUIRE_UIT();
// TODO(port): Close window.
popuphost_ = NULL;
}
bool CefBrowserImpl::UIT_ViewDocumentString(WebKit::WebFrame *frame)
{
REQUIRE_UIT();
// TODO(port): Add implementation.
NOTIMPLEMENTED();
return false;
}
void CefBrowserImpl::UIT_PrintPage(int page_number, int total_pages,
const gfx::Size& canvas_size,
WebKit::WebFrame* frame) {
REQUIRE_UIT();
// TODO(port): Add implementation.
NOTIMPLEMENTED();
}
void CefBrowserImpl::UIT_PrintPages(WebKit::WebFrame* frame) {
REQUIRE_UIT();
// TODO(port): Add implementation.
NOTIMPLEMENTED();
}
int CefBrowserImpl::UIT_GetPagesCount(WebKit::WebFrame* frame)
{
REQUIRE_UIT();
// TODO(port): Add implementation.
NOTIMPLEMENTED();
return 0;
}

View File

@ -104,6 +104,10 @@ CefWindowHandle CefBrowserImpl::GetWindowHandle()
return handle;
}
gfx::NativeWindow CefBrowserImpl::GetMainWndHandle() const {
return window_info_.m_hWnd;
}
void CefBrowserImpl::UIT_CreateBrowser(const std::wstring& url)
{
REQUIRE_UIT();

View File

@ -43,10 +43,6 @@ void AppendToLog(const char* file, int line, const char* msg) {
logging::LogMessage(file, line).stream() << msg;
}
base::StringPiece GetDataResource(int resource_id) {
return NetResourceProvider(resource_id);
}
bool GetApplicationDirectory(FilePath* path) {
return PathService::Get(base::DIR_EXE, path);
}
@ -154,8 +150,8 @@ bool IsContentDispositionAttachment(const std::string& cd_header,
WTF::String name_str =
WebCore::filenameFromHTTPContentDisposition(cd_str);
if (!name_str.isEmpty()) {
file_name = WideToUTF8(
std::wstring(name_str.characters(), name_str.length()));
WTF::CString cstr(name_str.utf8());
file_name = std::string(cstr.data(), cstr.length());
}
return true;
}

View File

@ -0,0 +1,126 @@
// Copyright (c) 2010 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2006-2008 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 "base/compiler_specific.h"
#include "third_party/webkit/webcore/config.h"
#include "browser_webkit_glue.h"
#undef LOG
#include "base/data_pack.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/mac_util.h"
#include "base/path_service.h"
#include "grit/webkit_resources.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/plugins/plugin_list.h"
namespace webkit_glue {
// Data pack resource. This is a pointer to the mmapped resources file.
static base::DataPack* g_resource_data_pack = NULL;
// Helper method for getting the path to the CEF resources directory.
FilePath GetResourcesFilePath() {
FilePath path;
// We need to know if we're bundled or not to know which path to use.
if (mac_util::AmIBundled()) {
PathService::Get(base::DIR_EXE, &path);
path = path.Append(FilePath::kParentDirectory);
return path.AppendASCII("Resources");
} else {
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("src");
path = path.AppendASCII("cef");
return path.AppendASCII("resources");
}
}
string16 GetLocalizedString(int message_id) {
base::StringPiece res;
if (!g_resource_data_pack->GetStringPiece(message_id, &res)) {
LOG(FATAL) << "failed to load webkit string with id " << message_id;
}
return string16(reinterpret_cast<const char16*>(res.data()),
res.length() / 2);
}
base::StringPiece NetResourceProvider(int key) {
base::StringPiece res;
g_resource_data_pack->GetStringPiece(key, &res);
return res;
}
base::StringPiece GetDataResource(int resource_id) {
switch (resource_id) {
case IDR_BROKENIMAGE: {
// Use webkit's broken image icon (16x16)
static std::string broken_image_data;
if (broken_image_data.empty()) {
FilePath path = GetResourcesFilePath();
// In order to match WebKit's colors for the missing image, we have to
// use a PNG. The GIF doesn't have the color range needed to correctly
// match the TIFF they use in Safari.
path = path.AppendASCII("missingImage.png");
bool success = file_util::ReadFileToString(path, &broken_image_data);
if (!success) {
LOG(FATAL) << "Failed reading: " << path.value();
}
}
return broken_image_data;
}
case IDR_TEXTAREA_RESIZER: {
// Use webkit's text area resizer image.
static std::string resize_corner_data;
if (resize_corner_data.empty()) {
FilePath path = GetResourcesFilePath();
path = path.AppendASCII("textAreaResizeCorner.png");
bool success = file_util::ReadFileToString(path, &resize_corner_data);
if (!success) {
LOG(FATAL) << "Failed reading: " << path.value();
}
}
return resize_corner_data;
}
case IDR_SEARCH_CANCEL:
case IDR_SEARCH_CANCEL_PRESSED:
case IDR_SEARCH_MAGNIFIER:
case IDR_SEARCH_MAGNIFIER_RESULTS:
case IDR_MEDIA_PAUSE_BUTTON:
case IDR_MEDIA_PLAY_BUTTON:
case IDR_MEDIA_PLAY_BUTTON_DISABLED:
case IDR_MEDIA_SOUND_FULL_BUTTON:
case IDR_MEDIA_SOUND_NONE_BUTTON:
case IDR_MEDIA_SOUND_DISABLED:
case IDR_MEDIA_SLIDER_THUMB:
case IDR_MEDIA_VOLUME_SLIDER_THUMB:
case IDR_INPUT_SPEECH:
case IDR_INPUT_SPEECH_RECORDING:
case IDR_INPUT_SPEECH_WAITING:
return NetResourceProvider(resource_id);
default:
break;
}
return base::StringPiece();
}
void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins);
}
void DidLoadPlugin(const std::string& filename) {
}
void DidUnloadPlugin(const std::string& filename) {
}
} // namespace webkit_glue

View File

@ -66,6 +66,10 @@ base::StringPiece NetResourceProvider(int key) {
return GetRawDataResource(hModule, key);
}
base::StringPiece GetDataResource(int resource_id) {
return NetResourceProvider(resource_id);
}
void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
NPAPI::PluginList::Singleton()->GetPlugins(refresh, plugins);
}
@ -303,4 +307,4 @@ BOOL SaveBitmapToFile(HBITMAP hBmp, HDC hDC, LPCTSTR file, LPBYTE lpBits)
return ret;
}
} // namespace webkit_glue
} // namespace webkit_glue

View File

@ -26,6 +26,9 @@
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#if defined(OS_MACOSX)
#include "third_party/WebKit/WebKit/chromium/public/WebPopupMenuInfo.h"
#endif
#include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h"
#include "webkit/glue/webcursor.h"
#include "webkit/glue/plugins/webplugin_page_delegate.h"
@ -314,7 +317,12 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
// cursor.
GdkCursorType cursor_type_;
#endif
#if defined(OS_MACOSX)
scoped_ptr<WebKit::WebPopupMenuInfo> popup_menu_info_;
WebKit::WebRect popup_bounds_;
#endif
// true if we want to enable smart insert/delete.
bool smart_insert_delete_enabled_;

View File

@ -0,0 +1,244 @@
// Copyright (c) 2008 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 "browser_webview_delegate.h"
#include "browser_impl.h"
#import <Cocoa/Cocoa.h>
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPopupMenu.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "webkit/glue/webcursor.h"
#include "webkit/glue/plugins/plugin_list.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/glue/webmenurunner_mac.h"
using WebKit::WebCursorInfo;
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();
popup_menu_info_.reset(new WebPopupMenuInfo(info));
return webwidget;
}
void BrowserWebViewDelegate::showContextMenu(
WebKit::WebFrame* frame, const WebKit::WebContextMenuData& data) {
NOTIMPLEMENTED();
}
// WebWidgetClient ------------------------------------------------------------
void BrowserWebViewDelegate::show(WebNavigationPolicy policy) {
if (!popup_menu_info_.get())
return;
if (this != browser_->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_->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_->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_->GetPopupHost();
int window_num = [browser_->GetMainWndHandle() 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);
}
}
void BrowserWebViewDelegate::closeWidgetSoon() {
if (this == browser_->GetWebViewDelegate()) {
NSWindow *win = browser_->GetMainWndHandle();
[win performSelector:@selector(performClose:) withObject:nil afterDelay:0];
} else if (this == browser_->GetPopupDelegate()) {
browser_->UIT_ClosePopupWidget();
}
}
void BrowserWebViewDelegate::didChangeCursor(const WebCursorInfo& cursor_info) {
NSCursor* ns_cursor = WebCursor(cursor_info).GetCursor();
[ns_cursor set];
}
WebRect BrowserWebViewDelegate::windowRect() {
if (WebWidgetHost* host = GetWidgetHost()) {
NSView *view = host->view_handle();
NSRect rect = [view frame];
return gfx::Rect(NSRectToCGRect(rect));
}
return WebRect();
}
void BrowserWebViewDelegate::setWindowRect(const WebRect& rect) {
if (this == browser_->GetWebViewDelegate()) {
// TODO(port): Set the window rectangle.
} else if (this == browser_->GetPopupDelegate()) {
popup_bounds_ = rect; // The initial position of the popup.
}
}
WebRect BrowserWebViewDelegate::rootWindowRect() {
if (WebWidgetHost* host = GetWidgetHost()) {
NSView *view = host->view_handle();
NSRect rect = [[[view window] contentView] frame];
return gfx::Rect(NSRectToCGRect(rect));
}
return WebRect();
}
@interface NSWindow(OSInternals)
- (NSRect)_growBoxRect;
@end
WebRect BrowserWebViewDelegate::windowResizerRect() {
NSRect resize_rect = NSMakeRect(0, 0, 0, 0);
WebWidgetHost* host = GetWidgetHost();
if (host) {
NSView *view = host->view_handle();
NSWindow* window = [view window];
resize_rect = [window _growBoxRect];
// The scrollbar assumes that the resizer goes all the way down to the
// bottom corner, so we ignore any y offset to the rect itself and use the
// entire bottom corner.
resize_rect.origin.y = 0;
// Convert to view coordinates from window coordinates.
resize_rect = [view convertRect:resize_rect fromView:nil];
// Flip the rect in view coordinates
resize_rect.origin.y =
[view frame].size.height - resize_rect.origin.y -
resize_rect.size.height;
}
return gfx::Rect(NSRectToCGRect(resize_rect));
}
void BrowserWebViewDelegate::runModal() {
NOTIMPLEMENTED();
}
// WebPluginPageDelegate ------------------------------------------------------
webkit_glue::WebPluginDelegate* BrowserWebViewDelegate::CreatePluginDelegate(
const FilePath& path,
const std::string& mime_type) {
WebWidgetHost *host = GetWidgetHost();
if (!host)
return NULL;
gfx::PluginWindowHandle containing_view = NULL;
return WebPluginDelegateImpl::Create(path, mime_type, containing_view);
}
void BrowserWebViewDelegate::CreatedPluginWindow(
gfx::PluginWindowHandle handle) {
}
void BrowserWebViewDelegate::WillDestroyPluginWindow(
gfx::PluginWindowHandle handle) {
}
void BrowserWebViewDelegate::DidMovePlugin(
const webkit_glue::WebPluginGeometry& move) {
// TODO(port): add me once plugins work.
}
// Protected methods ----------------------------------------------------------
void BrowserWebViewDelegate::ShowJavaScriptAlert(
WebKit::WebFrame* webframe, const std::wstring& message) {
NSString *text =
[NSString stringWithUTF8String:WideToUTF8(message).c_str()];
NSAlert *alert = [NSAlert alertWithMessageText:@"JavaScript Alert"
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:text];
[alert runModal];
}
bool BrowserWebViewDelegate::ShowJavaScriptConfirm(
WebKit::WebFrame* webframe, const std::wstring& message) {
NOTIMPLEMENTED();
return false;
}
bool BrowserWebViewDelegate::ShowJavaScriptPrompt(
WebKit::WebFrame* webframe, const std::wstring& message,
const std::wstring& default_value, std::wstring* result) {
NOTIMPLEMENTED();
return false;
}
// Called to show the file chooser dialog.
bool BrowserWebViewDelegate::ShowFileChooser(std::vector<FilePath>& file_names,
const bool multi_select,
const WebKit::WebString& title,
const FilePath& default_file) {
NOTIMPLEMENTED();
return false;
}
// Private methods ------------------------------------------------------------
/*
void BrowserWebViewDelegate::SetPageTitle(const std::wstring& title) {
[[browser_->GetWebViewHost()->view_handle() window]
setTitle:[NSString stringWithUTF8String:WideToUTF8(title).c_str()]];
}
void BrowserWebViewDelegate::SetAddressBarURL(const GURL& url) {
const char* frameURL = url.spec().c_str();
NSString *address = [NSString stringWithUTF8String:frameURL];
[browser_->GetEditWnd() setStringValue:address];
}
*/

View File

@ -0,0 +1,45 @@
// Copyright (c) 2008 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.
#import <Cocoa/Cocoa.h>
class CefBrowserImpl;
// A view to wrap the WebCore view and help it live in a Cocoa world. The
// (rough) equivalent of Apple's WebView.
@interface BrowserWebView : NSView {
@private
CefBrowserImpl *browser_; // weak
NSTrackingArea *trackingArea_;
}
- (IBAction)goBack:(id)sender;
- (IBAction)goForward:(id)sender;
- (IBAction)reload:(id)sender;
- (IBAction)stopLoading:(id)sender;
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender;
- (void)mouseDown:(NSEvent *)theEvent;
- (void)rightMouseDown:(NSEvent *)theEvent;
- (void)otherMouseDown:(NSEvent *)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
- (void)rightMouseUp:(NSEvent *)theEvent;
- (void)otherMouseUp:(NSEvent *)theEvent;
- (void)mouseMoved:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent *)theEvent;
- (void)scrollWheel:(NSEvent *)theEvent;
- (void)rightMouseDragged:(NSEvent *)theEvent;
- (void)otherMouseDragged:(NSEvent *)theEvent;
- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;
- (void)keyDown:(NSEvent *)theEvent;
- (void)keyUp:(NSEvent *)theEvent;
- (BOOL)isOpaque;
- (void)setFrame:(NSRect)frameRect;
- (void)setIsActive:(BOOL)active;
@property (nonatomic, assign) CefBrowserImpl *browser;
@end

View File

@ -0,0 +1,212 @@
// Copyright (c) 2008 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.
#import "browser_webview_mac.h"
#import <Cocoa/Cocoa.h>
#include "browser_impl.h"
#include "webwidget_host.h"
#include "base/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "gfx/rect.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
@implementation BrowserWebView
@synthesize browser = browser_;
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
trackingArea_ =
[[NSTrackingArea alloc] initWithRect:frame
options:NSTrackingMouseMoved |
NSTrackingActiveInActiveApp |
NSTrackingInVisibleRect
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea_];
}
return self;
}
- (void) dealloc {
[self removeTrackingArea:trackingArea_];
[trackingArea_ release];
[super dealloc];
}
- (void)drawRect:(NSRect)rect {
CGContextRef context =
reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext]
graphicsPort]);
// start by filling the rect with magenta, so that we can see what's drawn
CGContextSetRGBFillColor (context, 1, 0, 1, 1);
CGContextFillRect(context, NSRectToCGRect(rect));
if (browser_ && browser_->GetWebView()) {
gfx::Rect client_rect(NSRectToCGRect(rect));
// flip from cocoa coordinates
client_rect.set_y([self frame].size.height -
client_rect.height() - client_rect.y());
browser_->GetWebViewHost()->UpdatePaintRect(client_rect);
browser_->GetWebViewHost()->Paint();
}
}
- (IBAction)goBack:(id)sender {
if (browser_)
browser_->UIT_GoBackOrForward(-1);
}
- (IBAction)goForward:(id)sender {
if (browser_)
browser_->UIT_GoBackOrForward(1);
}
- (IBAction)reload:(id)sender {
if (browser_)
browser_->UIT_Reload(false);
}
- (IBAction)stopLoading:(id)sender {
if (browser_ && browser_->GetWebView())
browser_->GetWebView()->mainFrame()->stopLoading();
}
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender {
NSString *url = [sender stringValue];
// if it doesn't already have a prefix, add http. If we can't parse it,
// just don't bother rather than making things worse.
NSURL* tempUrl = [NSURL URLWithString:url];
if (tempUrl && ![tempUrl scheme])
url = [@"http://" stringByAppendingString:url];
browser_->LoadURL(browser_->GetMainFrame(), UTF8ToWide([url UTF8String]));
}
- (void)mouseDown:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)rightMouseDown:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)otherMouseDown:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)mouseUp:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)rightMouseUp:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)otherMouseUp:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)mouseMoved:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)mouseDragged:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)scrollWheel:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->WheelEvent(theEvent);
}
- (void)rightMouseDragged:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)otherMouseDragged:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)mouseEntered:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)mouseExited:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->MouseEvent(theEvent);
}
- (void)keyDown:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->KeyEvent(theEvent);
}
- (void)keyUp:(NSEvent *)theEvent {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->KeyEvent(theEvent);
}
- (BOOL)isOpaque {
return YES;
}
- (BOOL)canBecomeKeyView {
return browser_ && browser_->GetWebView();
}
- (BOOL)acceptsFirstResponder {
return browser_ && browser_->GetWebView();
}
- (BOOL)becomeFirstResponder {
if (browser_ && browser_->GetWebView()) {
browser_->GetWebViewHost()->SetFocus(YES);
return YES;
}
return NO;
}
- (BOOL)resignFirstResponder {
if (browser_ && browser_->GetWebView()) {
browser_->GetWebViewHost()->SetFocus(NO);
return YES;
}
return NO;
}
- (void)setIsActive:(BOOL)active {
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->SetIsActive(active ? true : false);
}
- (void)setFrame:(NSRect)frameRect {
[super setFrame:frameRect];
if (browser_ && browser_->GetWebView())
browser_->GetWebViewHost()->Resize(gfx::Rect(NSRectToCGRect(frameRect)));
[self setNeedsDisplay:YES];
}
@end

View File

@ -0,0 +1,56 @@
// Copyright (c) 2008 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.
#import <Cocoa/Cocoa.h>
#include "webview_host.h"
#include "browser_webview_delegate.h"
#include "browser_webview_mac.h"
#include "gfx/rect.h"
#include "gfx/size.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "webkit/glue/webpreferences.h"
using WebKit::WebDevToolsAgentClient;
using WebKit::WebSize;
using WebKit::WebView;
// static
WebViewHost* WebViewHost::Create(NSView* parent_view,
BrowserWebViewDelegate* delegate,
WebDevToolsAgentClient* dev_tools_client,
const WebPreferences& prefs) {
WebViewHost* host = new WebViewHost();
NSRect content_rect = [parent_view frame];
// bump down the top of the view so that it doesn't overlap the buttons
// and URL field. 32 is an ad hoc constant.
// TODO(awalker): replace explicit view layout with a little nib file
// and use that for view geometry.
content_rect.size.height -= 32;
host->view_ = [[BrowserWebView alloc] initWithFrame:content_rect];
// make the height and width track the window size.
[host->view_ setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[parent_view addSubview:host->view_];
[host->view_ release];
host->webwidget_ = WebView::create(delegate, dev_tools_client);
prefs.Apply(host->webview());
host->webview()->initializeMainFrame(delegate);
host->webwidget_->resize(WebSize(content_rect.size.width,
content_rect.size.height));
return host;
}
WebView* WebViewHost::webview() const {
return static_cast<WebView*>(webwidget_);
}
void WebViewHost::SetIsActive(bool active) {
webview()->setIsActive(active);
}

View File

@ -11,6 +11,7 @@
#include "gfx/rect.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include <string>
namespace gfx {
class Size;

View File

@ -0,0 +1,283 @@
// Copyright (c) 2008-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.
#import <Cocoa/Cocoa.h>
#include "webwidget_host.h"
#include "base/logging.h"
#include "gfx/rect.h"
#include "gfx/size.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/mac/WebInputEventFactory.h"
#include "third_party/WebKit/WebKit/chromium/public/mac/WebScreenInfoFactory.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPopupMenu.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "webkit/glue/webkit_glue.h"
using WebKit::WebInputEvent;
using WebKit::WebInputEventFactory;
using WebKit::WebKeyboardEvent;
using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent;
using WebKit::WebPopupMenu;
using WebKit::WebScreenInfo;
using WebKit::WebScreenInfoFactory;
using WebKit::WebSize;
using WebKit::WebWidgetClient;
/*static*/
WebWidgetHost* WebWidgetHost::Create(NSView* parent_view,
WebWidgetClient* client) {
WebWidgetHost* host = new WebWidgetHost();
NSRect content_rect = [parent_view frame];
content_rect.origin.y += 64;
content_rect.size.height -= 64;
host->view_ = [[NSView alloc] initWithFrame:content_rect];
[parent_view addSubview:host->view_];
// win_util::SetWindowUserData(host->hwnd_, host);
host->webwidget_ = WebPopupMenu::create(client);
host->webwidget_->resize(WebSize(content_rect.size.width,
content_rect.size.height));
return host;
}
/*static*/
void WebWidgetHost::HandleEvent(NSView* view, NSEvent* event) {
/* TODO(port): rig up a way to get to the host */
WebWidgetHost* host = NULL;
if (host) {
switch ([event type]) {
case NSLeftMouseDown:
case NSLeftMouseUp:
case NSRightMouseDown:
case NSRightMouseUp:
case NSOtherMouseDown:
case NSOtherMouseUp:
case NSMouseEntered:
case NSMouseExited:
host->MouseEvent(event);
break;
case NSScrollWheel:
host->WheelEvent(event);
break;
case NSKeyDown:
case NSKeyUp:
host->KeyEvent(event);
break;
case NSAppKitDefined:
switch ([event subtype]) {
case NSApplicationActivatedEventType:
host->SetFocus(true);
break;
case NSApplicationDeactivatedEventType:
host->SetFocus(false);
break;
}
break;
}
}
}
void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
#ifndef NDEBUG
DLOG_IF(WARNING, painting_) << "unexpected invalidation while painting";
#endif
// If this invalidate overlaps with a pending scroll, then we have to
// downgrade to invalidating the scroll rect.
if (damaged_rect.Intersects(scroll_rect_)) {
paint_rect_ = paint_rect_.Union(scroll_rect_);
ResetScrollRect();
}
paint_rect_ = paint_rect_.Union(damaged_rect);
NSRect r = NSRectFromCGRect(damaged_rect.ToCGRect());
// flip to cocoa coordinates
r.origin.y = [view_ frame].size.height - r.size.height - r.origin.y;
[view_ setNeedsDisplayInRect:r];
}
void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
DCHECK(dx || dy);
// If we already have a pending scroll operation or if this scroll operation
// intersects the existing paint region, then just failover to invalidating.
if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) {
paint_rect_ = paint_rect_.Union(scroll_rect_);
ResetScrollRect();
paint_rect_ = paint_rect_.Union(clip_rect);
}
// We will perform scrolling lazily, when requested to actually paint.
scroll_rect_ = clip_rect;
scroll_dx_ = dx;
scroll_dy_ = dy;
NSRect r = NSRectFromCGRect(clip_rect.ToCGRect());
// flip to cocoa coordinates
r.origin.y = [view_ frame].size.height - r.size.height - r.origin.y;
[view_ setNeedsDisplayInRect:r];
}
void WebWidgetHost::ScheduleComposite() {
if (!webwidget_)
return;
WebSize size = webwidget_->size();
NSRect r = NSMakeRect(0, 0, size.width, size.height);
[view_ setNeedsDisplayInRect:r];
}
// void WebWidgetHost::SetCursor(HCURSOR cursor) {
// }
void WebWidgetHost::DiscardBackingStore() {
canvas_.reset();
}
WebWidgetHost::WebWidgetHost()
: view_(NULL),
webwidget_(NULL),
scroll_dx_(0),
scroll_dy_(0) {
set_painting(false);
}
WebWidgetHost::~WebWidgetHost() {
// win_util::SetWindowUserData(hwnd_, 0);
webwidget_->close();
}
void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
paint_rect_ = paint_rect_.Union(rect);
}
void WebWidgetHost::Paint() {
gfx::Rect client_rect(NSRectToCGRect([view_ frame]));
NSGraphicsContext* view_context = [NSGraphicsContext currentContext];
CGContextRef context = static_cast<CGContextRef>([view_context graphicsPort]);
// Allocate a canvas if necessary
if (!canvas_.get()) {
ResetScrollRect();
paint_rect_ = client_rect;
canvas_.reset(new skia::PlatformCanvas(
paint_rect_.width(), paint_rect_.height(), true));
}
// make sure webkit draws into our bitmap, not the window
CGContextRef bitmap_context =
canvas_->getTopPlatformDevice().GetBitmapContext();
[NSGraphicsContext setCurrentContext:
[NSGraphicsContext graphicsContextWithGraphicsPort:bitmap_context
flipped:YES]];
// This may result in more invalidation
webwidget_->layout();
// Scroll the canvas if necessary
scroll_rect_ = client_rect.Intersect(scroll_rect_);
if (!scroll_rect_.IsEmpty()) {
// add to invalidate rect, since there's no equivalent of ScrollDC.
paint_rect_ = paint_rect_.Union(scroll_rect_);
}
ResetScrollRect();
// Paint the canvas if necessary. Allow painting to generate extra rects the
// first time we call it. This is necessary because some WebCore rendering
// objects update their layout only when painted.
for (int i = 0; i < 2; ++i) {
paint_rect_ = client_rect.Intersect(paint_rect_);
if (!paint_rect_.IsEmpty()) {
gfx::Rect rect(paint_rect_);
paint_rect_ = gfx::Rect();
// DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations";
PaintRect(rect);
}
}
DCHECK(paint_rect_.IsEmpty());
// set the context back to our window
[NSGraphicsContext setCurrentContext: view_context];
// Paint to the screen
if ([view_ lockFocusIfCanDraw]) {
int bitmap_height = CGBitmapContextGetHeight(bitmap_context);
int bitmap_width = CGBitmapContextGetWidth(bitmap_context);
CGRect bitmap_rect = { { 0, 0 },
{ bitmap_width, bitmap_height } };
canvas_->getTopPlatformDevice().DrawToContext(
context, 0, client_rect.height() - bitmap_height, &bitmap_rect);
[view_ unlockFocus];
}
}
void WebWidgetHost::SetTooltipText(const std::wstring& tooltip_text) {
NOTIMPLEMENTED();
}
WebScreenInfo WebWidgetHost::GetScreenInfo() {
return WebScreenInfoFactory::screenInfo(view_);
}
void WebWidgetHost::Resize(const gfx::Rect& rect) {
// Force an entire re-paint. TODO(darin): Maybe reuse this memory buffer.
DiscardBackingStore();
webwidget_->resize(WebSize(rect.width(), rect.height()));
}
void WebWidgetHost::MouseEvent(NSEvent *event) {
const WebMouseEvent& web_event = WebInputEventFactory::mouseEvent(
event, view_);
webwidget_->handleInputEvent(web_event);
}
void WebWidgetHost::WheelEvent(NSEvent *event) {
webwidget_->handleInputEvent(
WebInputEventFactory::mouseWheelEvent(event, view_));
}
void WebWidgetHost::KeyEvent(NSEvent *event) {
WebKeyboardEvent keyboard_event(WebInputEventFactory::keyboardEvent(event));
webwidget_->handleInputEvent(keyboard_event);
if ([event type] == NSKeyDown) {
// Send a Char event here to emulate the keyboard events.
// TODO(hbono): Bug 20852 <http://crbug.com/20852> implement the
// NSTextInput protocol and remove this code.
keyboard_event.type = WebInputEvent::Char;
webwidget_->handleInputEvent(keyboard_event);
}
}
void WebWidgetHost::SetFocus(bool enable) {
webwidget_->setFocus(enable);
}
void WebWidgetHost::ResetScrollRect() {
scroll_rect_ = gfx::Rect();
scroll_dx_ = 0;
scroll_dy_ = 0;
}
void WebWidgetHost::PaintRect(const gfx::Rect& rect) {
#ifndef NDEBUG
DCHECK(!painting_);
#endif
DCHECK(canvas_.get());
set_painting(true);
webwidget_->paint(webkit_glue::ToWebCanvas(canvas_.get()), rect);
set_painting(false);
}