2012-05-16 18:56:38 +02:00
|
|
|
// Copyright (c) 2012 The Chromium Embedded Framework 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 <OpenGL/gl.h>
|
|
|
|
|
|
|
|
#include "cefclient/osrtest_mac.h"
|
|
|
|
#include "include/cef_browser.h"
|
2012-08-15 17:13:11 +02:00
|
|
|
#include "cefclient/cefclient.h"
|
2012-05-16 18:56:38 +02:00
|
|
|
#include "cefclient/client_popup_handler.h"
|
2012-08-15 17:13:11 +02:00
|
|
|
#include "cefclient/osrenderer.h"
|
2012-05-16 18:56:38 +02:00
|
|
|
#include "cefclient/resource_util.h"
|
|
|
|
#include "cefclient/util.h"
|
|
|
|
|
|
|
|
// The client OpenGL view.
|
|
|
|
@interface ClientOpenGLView : NSOpenGLView {
|
|
|
|
@public
|
|
|
|
NSTrackingArea* tracking_area_;
|
|
|
|
CefRefPtr<CefBrowser> browser_;
|
|
|
|
ClientOSRenderer* renderer_;
|
|
|
|
NSPoint last_mouse_pos_;
|
|
|
|
NSPoint cur_mouse_pos_;
|
|
|
|
bool rotating_;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency;
|
|
|
|
- (NSPoint)getClickPointForEvent:(NSEvent*)event;
|
|
|
|
- (void)getKeyInfo:(CefKeyInfo&)info forEvent:(NSEvent*)event;
|
|
|
|
- (int)getModifiersForEvent:(NSEvent*)event;
|
|
|
|
- (BOOL)isKeyUpEvent:(NSEvent*)event;
|
|
|
|
- (BOOL)isKeyPadEvent:(NSEvent*)event;
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Handler for off-screen rendering windows.
|
|
|
|
class ClientOSRHandler : public CefClient,
|
|
|
|
public CefLifeSpanHandler,
|
|
|
|
public CefLoadHandler,
|
|
|
|
public CefRequestHandler,
|
|
|
|
public CefDisplayHandler,
|
|
|
|
public CefRenderHandler {
|
|
|
|
public:
|
|
|
|
explicit ClientOSRHandler(ClientOpenGLView* view)
|
|
|
|
: view_(view) {
|
|
|
|
}
|
|
|
|
~ClientOSRHandler() {
|
|
|
|
}
|
|
|
|
|
|
|
|
void Disconnect() {
|
|
|
|
view_ = nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CefClient methods
|
|
|
|
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CefLifeSpanHandler methods
|
|
|
|
|
|
|
|
virtual bool OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser,
|
|
|
|
const CefPopupFeatures& popupFeatures,
|
|
|
|
CefWindowInfo& windowInfo,
|
|
|
|
const CefString& url,
|
|
|
|
CefRefPtr<CefClient>& client,
|
|
|
|
CefBrowserSettings& settings) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
windowInfo.m_bWindowRenderingDisabled = TRUE;
|
|
|
|
client = new ClientPopupHandler(view_->browser_);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
// Set the view size to match the window size.
|
|
|
|
const NSRect bounds = [view_ bounds];
|
|
|
|
browser->SetSize(PET_VIEW, bounds.size.width, bounds.size.height);
|
|
|
|
|
|
|
|
view_->browser_ = browser;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE {
|
|
|
|
if (view_)
|
|
|
|
view_->browser_ = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CefLoadHandler methods
|
|
|
|
|
|
|
|
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
|
|
|
CefRefPtr<CefFrame> frame) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!browser->IsPopup() && frame->IsMain()) {
|
|
|
|
// We've just started loading a page
|
|
|
|
SetLoading(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
|
|
|
CefRefPtr<CefFrame> frame,
|
|
|
|
int httpStatusCode) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!browser->IsPopup() && frame->IsMain()) {
|
|
|
|
// We've just finished loading a page
|
|
|
|
SetLoading(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// CefRequestHandler methods
|
|
|
|
|
|
|
|
virtual bool OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
|
|
|
|
CefRefPtr<CefRequest> request,
|
|
|
|
CefString& redirectUrl,
|
|
|
|
CefRefPtr<CefStreamReader>& resourceStream,
|
|
|
|
CefRefPtr<CefResponse> response,
|
|
|
|
int loadFlags) OVERRIDE {
|
|
|
|
REQUIRE_IO_THREAD();
|
|
|
|
|
|
|
|
std::string url = request->GetURL();
|
|
|
|
if (url == "http://tests/osrtest") {
|
|
|
|
// Show the osrtest HTML contents
|
|
|
|
resourceStream = GetBinaryResourceReader("osrtest.html");
|
|
|
|
response->SetMimeType("text/html");
|
|
|
|
response->SetStatus(200);
|
|
|
|
} else if (url == "http://tests/transparency") {
|
|
|
|
// Show the osrtest HTML contents
|
|
|
|
resourceStream = GetBinaryResourceReader("transparency.html");
|
|
|
|
response->SetMimeType("text/html");
|
|
|
|
response->SetStatus(200);
|
|
|
|
} else if (strstr(url.c_str(), "/logoball.png") != NULL) {
|
|
|
|
// Load the "logoball.png" image resource.
|
|
|
|
resourceStream = GetBinaryResourceReader("logoball.png");
|
|
|
|
response->SetMimeType("image/png");
|
|
|
|
response->SetStatus(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CefDisplayHandler methods
|
|
|
|
|
|
|
|
virtual void OnNavStateChange(CefRefPtr<CefBrowser> browser,
|
|
|
|
bool canGoBack,
|
|
|
|
bool canGoForward) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnAddressChange(CefRefPtr<CefBrowser> browser,
|
|
|
|
CefRefPtr<CefFrame> frame,
|
|
|
|
const CefString& url) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnTitleChange(CefRefPtr<CefBrowser> browser,
|
|
|
|
const CefString& title) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!view_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Set the frame window title bar
|
|
|
|
NSWindow* window = [view_ window];
|
|
|
|
std::string titleStr(title);
|
|
|
|
NSString* str = [NSString stringWithUTF8String:titleStr.c_str()];
|
|
|
|
[window setTitle:str];
|
|
|
|
}
|
|
|
|
|
|
|
|
// CefRenderHandler methods
|
|
|
|
|
|
|
|
virtual bool GetViewRect(CefRefPtr<CefBrowser> browser,
|
|
|
|
CefRect& rect) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!view_)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// The simulated screen and view rectangle are the same. This is necessary
|
|
|
|
// for popup menus to be located and sized inside the view.
|
|
|
|
const NSRect bounds = [view_ bounds];
|
|
|
|
rect.x = rect.y = 0;
|
|
|
|
rect.width = bounds.size.width;
|
|
|
|
rect.height = bounds.size.height;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool GetScreenRect(CefRefPtr<CefBrowser> browser,
|
|
|
|
CefRect& rect) OVERRIDE {
|
|
|
|
return GetViewRect(browser, rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
|
|
|
int viewX,
|
|
|
|
int viewY,
|
|
|
|
int& screenX,
|
|
|
|
int& screenY) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!view_)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Convert the point from view coordinates to actual screen coordinates.
|
|
|
|
NSRect bounds = [view_ bounds];
|
|
|
|
NSPoint view_pt = {viewX, bounds.size.height - viewY};
|
|
|
|
NSPoint window_pt = [view_ convertPoint:view_pt toView:nil];
|
|
|
|
NSPoint screen_pt = [[view_ window] convertBaseToScreen:window_pt];
|
|
|
|
screenX = screen_pt.x;
|
|
|
|
screenY = screen_pt.y;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnPopupShow(CefRefPtr<CefBrowser> browser,
|
|
|
|
bool show) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!view_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
view_->renderer_->OnPopupShow(browser, show);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnPopupSize(CefRefPtr<CefBrowser> browser,
|
|
|
|
const CefRect& rect) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!view_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
view_->renderer_->OnPopupSize(browser, rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
|
|
|
|
PaintElementType type,
|
|
|
|
const RectList& dirtyRects,
|
|
|
|
const void* buffer) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
|
|
|
|
if (!view_)
|
|
|
|
return;
|
|
|
|
|
2012-08-16 21:21:47 +02:00
|
|
|
NSOpenGLContext* context = [view_ openGLContext];
|
|
|
|
[context makeCurrentContext];
|
2012-05-16 18:56:38 +02:00
|
|
|
|
|
|
|
view_->renderer_->OnPaint(browser, type, dirtyRects, buffer);
|
2012-08-16 21:21:47 +02:00
|
|
|
view_->renderer_->Render();
|
2012-05-16 18:56:38 +02:00
|
|
|
|
2012-08-16 21:21:47 +02:00
|
|
|
[context flushBuffer];
|
2012-05-16 18:56:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void OnCursorChange(CefRefPtr<CefBrowser> browser,
|
|
|
|
CefCursorHandle cursor) OVERRIDE {
|
|
|
|
REQUIRE_UI_THREAD();
|
|
|
|
[cursor set];
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void SetLoading(bool isLoading) {
|
|
|
|
}
|
|
|
|
|
|
|
|
ClientOpenGLView* view_;
|
|
|
|
|
|
|
|
// Include the default reference counting implementation.
|
|
|
|
IMPLEMENT_REFCOUNTING(ClientOSRPlugin);
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
|
|
@implementation ClientOpenGLView
|
|
|
|
|
|
|
|
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency {
|
|
|
|
NSOpenGLPixelFormat * pixelFormat =
|
|
|
|
[[NSOpenGLPixelFormat alloc]
|
|
|
|
initWithAttributes:(NSOpenGLPixelFormatAttribute[]) {
|
|
|
|
NSOpenGLPFAWindow,
|
|
|
|
NSOpenGLPFADoubleBuffer,
|
|
|
|
NSOpenGLPFADepthSize,
|
|
|
|
32,
|
|
|
|
0}];
|
|
|
|
[pixelFormat autorelease];
|
|
|
|
|
|
|
|
self = [super initWithFrame:frame pixelFormat:pixelFormat];
|
|
|
|
if (self) {
|
|
|
|
renderer_ = new ClientOSRenderer(transparency);
|
|
|
|
rotating_ = false;
|
|
|
|
|
|
|
|
tracking_area_ =
|
|
|
|
[[NSTrackingArea alloc] initWithRect:frame
|
|
|
|
options:NSTrackingMouseMoved |
|
|
|
|
NSTrackingActiveInActiveApp |
|
|
|
|
NSTrackingInVisibleRect
|
|
|
|
owner:self
|
|
|
|
userInfo:nil];
|
|
|
|
[self addTrackingArea:tracking_area_];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc {
|
|
|
|
if (browser_) {
|
|
|
|
static_cast<ClientOSRHandler*>(browser_->GetClient().get())->Disconnect();
|
|
|
|
browser_->CloseBrowser();
|
|
|
|
browser_ = NULL;
|
|
|
|
}
|
|
|
|
if (renderer_)
|
|
|
|
delete renderer_;
|
|
|
|
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setFrame:(NSRect)frameRect {
|
|
|
|
[super setFrame:frameRect];
|
|
|
|
|
|
|
|
int width = frameRect.size.width;
|
|
|
|
int height = frameRect.size.height;
|
|
|
|
|
|
|
|
if (browser_)
|
|
|
|
browser_->SetSize(PET_VIEW, width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseDown:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
int clickCount = [event clickCount];
|
|
|
|
|
|
|
|
browser_->SendMouseClickEvent(point.x, point.y, MBT_LEFT, false, clickCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)rightMouseDown:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
|
|
|
|
if ([event modifierFlags] & NSShiftKeyMask) {
|
|
|
|
// Start rotation effect.
|
|
|
|
last_mouse_pos_ = cur_mouse_pos_ = point;
|
|
|
|
rotating_ = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int clickCount = [event clickCount];
|
|
|
|
|
|
|
|
browser_->SendMouseClickEvent(point.x, point.y, MBT_RIGHT, false, clickCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)otherMouseDown:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
int clickCount = [event clickCount];
|
|
|
|
|
|
|
|
browser_->SendMouseClickEvent(point.x, point.y, MBT_MIDDLE, false,
|
|
|
|
clickCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseUp:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
int clickCount = [event clickCount];
|
|
|
|
|
|
|
|
browser_->SendMouseClickEvent(point.x, point.y, MBT_LEFT, true, clickCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)rightMouseUp:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (rotating_) {
|
|
|
|
// End rotation effect.
|
|
|
|
renderer_->SetSpin(0, 0);
|
|
|
|
rotating_ = false;
|
|
|
|
[self setNeedsDisplay:YES];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
int clickCount = [event clickCount];
|
|
|
|
|
|
|
|
browser_->SendMouseClickEvent(point.x, point.y, MBT_RIGHT, true, clickCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)otherMouseUp:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
int clickCount = [event clickCount];
|
|
|
|
|
|
|
|
browser_->SendMouseClickEvent(point.x, point.y, MBT_MIDDLE, true, clickCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseMoved:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
|
|
|
|
if (rotating_) {
|
|
|
|
// Apply rotation effect.
|
|
|
|
cur_mouse_pos_ = point;
|
|
|
|
renderer_->IncrementSpin((cur_mouse_pos_.x - last_mouse_pos_.x),
|
|
|
|
(cur_mouse_pos_.y - last_mouse_pos_.y));
|
|
|
|
last_mouse_pos_ = cur_mouse_pos_;
|
|
|
|
[self setNeedsDisplay:YES];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
browser_->SendMouseMoveEvent(point.x, point.y, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseDragged:(NSEvent *)event {
|
|
|
|
[self mouseMoved:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)rightMouseDragged:(NSEvent *)event {
|
|
|
|
[self mouseMoved:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)otherMouseDragged:(NSEvent *)event {
|
|
|
|
[self mouseMoved:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseEntered:(NSEvent *)event {
|
|
|
|
[self mouseMoved:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseExited:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
|
|
|
|
browser_->SendMouseMoveEvent(point.x, point.y, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)keyDown:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CefKeyInfo keyInfo;
|
|
|
|
[self getKeyInfo:keyInfo forEvent:event];
|
|
|
|
int modifiers = [self getModifiersForEvent:event];
|
|
|
|
|
|
|
|
browser_->SendKeyEvent(KT_KEYDOWN, keyInfo, modifiers);
|
|
|
|
|
|
|
|
if ([event modifierFlags] & (NSNumericPadKeyMask | NSFunctionKeyMask)) {
|
|
|
|
// Don't send a Char event for non-char keys like arrows, function keys and
|
|
|
|
// clear.
|
|
|
|
switch (keyInfo.keyCode) {
|
|
|
|
case 81: // =
|
|
|
|
case 75: // /
|
|
|
|
case 67: // *
|
|
|
|
case 78: // -
|
|
|
|
case 69: // +
|
|
|
|
case 76: // Enter
|
|
|
|
case 65: // .
|
|
|
|
case 82: // 0
|
|
|
|
case 83: // 1
|
|
|
|
case 84: // 2
|
|
|
|
case 85: // 3
|
|
|
|
case 86: // 4
|
|
|
|
case 87: // 5
|
|
|
|
case 88: // 6
|
|
|
|
case 89: // 7
|
|
|
|
case 91: // 8
|
|
|
|
case 92: // 9
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
browser_->SendKeyEvent(KT_CHAR, keyInfo, modifiers);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)keyUp:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CefKeyInfo keyInfo;
|
|
|
|
[self getKeyInfo:keyInfo forEvent:event];
|
|
|
|
int modifiers = [self getModifiersForEvent:event];
|
|
|
|
|
|
|
|
browser_->SendKeyEvent(KT_KEYUP, keyInfo, modifiers);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)flagsChanged:(NSEvent *)event {
|
|
|
|
if ([self isKeyUpEvent:event])
|
|
|
|
[self keyUp:event];
|
|
|
|
else
|
|
|
|
[self keyDown:event];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)scrollWheel:(NSEvent *)event {
|
|
|
|
if (!browser_)
|
|
|
|
return;
|
|
|
|
|
|
|
|
CGEventRef cgEvent = [event CGEvent];
|
|
|
|
ASSERT(cgEvent);
|
|
|
|
|
|
|
|
NSPoint point = [self getClickPointForEvent:event];
|
|
|
|
int deltaX =
|
|
|
|
CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2);
|
|
|
|
int deltaY =
|
|
|
|
CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
|
|
|
|
|
|
|
|
browser_->SendMouseWheelEvent(point.x, point.y, deltaX, deltaY);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)canBecomeKeyView {
|
|
|
|
return (browser_ != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)acceptsFirstResponder {
|
|
|
|
return (browser_ != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)becomeFirstResponder {
|
|
|
|
if (browser_) {
|
|
|
|
browser_->SendFocusEvent(true);
|
|
|
|
return [super becomeFirstResponder];
|
|
|
|
}
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)resignFirstResponder {
|
|
|
|
if (browser_) {
|
|
|
|
browser_->SendFocusEvent(false);
|
|
|
|
return [super resignFirstResponder];
|
|
|
|
}
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)undo:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Undo();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)redo:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Redo();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)cut:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Cut();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)copy:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Copy();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)paste:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Paste();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)delete:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectAll:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->SelectAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPoint)getClickPointForEvent:(NSEvent*)event {
|
|
|
|
NSPoint windowLocal = [event locationInWindow];
|
|
|
|
NSPoint contentLocal = [self convertPoint:windowLocal fromView:nil];
|
|
|
|
|
2012-10-02 20:29:11 +02:00
|
|
|
NSPoint point;
|
|
|
|
point.x = contentLocal.x;
|
|
|
|
point.y = [self frame].size.height - contentLocal.y; // Flip y.
|
|
|
|
return point;
|
2012-05-16 18:56:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)getKeyInfo:(CefKeyInfo&)info forEvent:(NSEvent*)event {
|
|
|
|
if ([event type] == NSKeyDown || [event type] == NSKeyUp) {
|
|
|
|
NSString* s = [event characters];
|
|
|
|
if ([s length] > 0)
|
|
|
|
info.character = [s characterAtIndex:0];
|
|
|
|
|
|
|
|
s = [event charactersIgnoringModifiers];
|
|
|
|
if ([s length] > 0)
|
|
|
|
info.characterNoModifiers = [s characterAtIndex:0];
|
|
|
|
}
|
|
|
|
|
|
|
|
info.keyCode = [event keyCode];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (int)getModifiersForEvent:(NSEvent*)event {
|
|
|
|
int modifiers = 0;
|
|
|
|
|
|
|
|
if ([event modifierFlags] & NSControlKeyMask)
|
|
|
|
modifiers |= KEY_CTRL;
|
|
|
|
if ([event modifierFlags] & NSShiftKeyMask)
|
|
|
|
modifiers |= KEY_SHIFT;
|
|
|
|
if ([event modifierFlags] & NSAlternateKeyMask)
|
|
|
|
modifiers |= KEY_ALT;
|
|
|
|
if ([event modifierFlags] & NSCommandKeyMask)
|
|
|
|
modifiers |= KEY_META;
|
|
|
|
if ([self isKeyPadEvent:event])
|
|
|
|
modifiers |= KEY_KEYPAD;
|
|
|
|
|
|
|
|
return modifiers;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isKeyUpEvent:(NSEvent*)event {
|
|
|
|
if ([event type] != NSFlagsChanged)
|
|
|
|
return [event type] == NSKeyUp;
|
|
|
|
|
|
|
|
// FIXME: This logic fails if the user presses both Shift keys at once, for
|
|
|
|
// example: we treat releasing one of them as keyDown.
|
|
|
|
switch ([event keyCode]) {
|
|
|
|
case 54: // Right Command
|
|
|
|
case 55: // Left Command
|
|
|
|
return ([event modifierFlags] & NSCommandKeyMask) == 0;
|
|
|
|
|
|
|
|
case 57: // Capslock
|
|
|
|
return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0;
|
|
|
|
|
|
|
|
case 56: // Left Shift
|
|
|
|
case 60: // Right Shift
|
|
|
|
return ([event modifierFlags] & NSShiftKeyMask) == 0;
|
|
|
|
|
|
|
|
case 58: // Left Alt
|
|
|
|
case 61: // Right Alt
|
|
|
|
return ([event modifierFlags] & NSAlternateKeyMask) == 0;
|
|
|
|
|
|
|
|
case 59: // Left Ctrl
|
|
|
|
case 62: // Right Ctrl
|
|
|
|
return ([event modifierFlags] & NSControlKeyMask) == 0;
|
|
|
|
|
|
|
|
case 63: // Function
|
|
|
|
return ([event modifierFlags] & NSFunctionKeyMask) == 0;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isKeyPadEvent:(NSEvent*)event {
|
|
|
|
if ([event modifierFlags] & NSNumericPadKeyMask)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
switch ([event keyCode]) {
|
|
|
|
case 71: // Clear
|
|
|
|
case 81: // =
|
|
|
|
case 75: // /
|
|
|
|
case 67: // *
|
|
|
|
case 78: // -
|
|
|
|
case 69: // +
|
|
|
|
case 76: // Enter
|
|
|
|
case 65: // .
|
|
|
|
case 82: // 0
|
|
|
|
case 83: // 1
|
|
|
|
case 84: // 2
|
|
|
|
case 85: // 3
|
|
|
|
case 86: // 4
|
|
|
|
case 87: // 5
|
|
|
|
case 88: // 6
|
|
|
|
case 89: // 7
|
|
|
|
case 91: // 8
|
|
|
|
case 92: // 9
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
namespace osrtest {
|
|
|
|
|
|
|
|
void RunTest(bool transparent) {
|
|
|
|
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
|
|
|
|
NSRect window_rect = {{0, screen_rect.size.height}, {700, 700}};
|
|
|
|
NSWindow* newWnd = [[NSWindow alloc]
|
|
|
|
initWithContentRect:window_rect
|
|
|
|
styleMask:(NSTitledWindowMask |
|
|
|
|
NSClosableWindowMask |
|
|
|
|
NSMiniaturizableWindowMask |
|
|
|
|
NSResizableWindowMask |
|
|
|
|
NSUnifiedTitleAndToolbarWindowMask)
|
|
|
|
backing:NSBackingStoreBuffered
|
|
|
|
defer:NO];
|
|
|
|
ASSERT(newWnd);
|
|
|
|
|
|
|
|
ClientOpenGLView* view = [[ClientOpenGLView alloc] initWithFrame:window_rect
|
|
|
|
andTransparency:transparent];
|
|
|
|
[view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
|
|
|
|
|
|
|
|
[newWnd setContentView:view];
|
|
|
|
[view release];
|
|
|
|
|
|
|
|
CefWindowInfo info;
|
|
|
|
|
|
|
|
// Initialize the window info as off-screen.
|
|
|
|
info.SetAsOffScreen(view);
|
|
|
|
info.SetTransparentPainting(transparent);
|
|
|
|
|
2012-08-15 17:13:11 +02:00
|
|
|
CefBrowserSettings settings;
|
|
|
|
AppGetBrowserSettings(settings);
|
|
|
|
|
2012-05-16 18:56:38 +02:00
|
|
|
// Creat the browser window.
|
|
|
|
CefBrowser::CreateBrowser(info, new ClientOSRHandler(view),
|
|
|
|
"http://tests/osrtest", settings);
|
|
|
|
|
|
|
|
[newWnd makeKeyAndOrderFront: nil];
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace osrtest
|
|
|
|
|