cefclient: Mac: Introduce RootWindow concept and associated window/client object hierarchy (issue #1500).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@2006 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2015-01-30 18:07:13 +00:00
parent 0031e7c603
commit c44f6f7efb
36 changed files with 1676 additions and 1424 deletions

View File

@ -149,6 +149,8 @@
'cefclient_sources_common': [
'tests/cefclient/binding_test.cc',
'tests/cefclient/binding_test.h',
'tests/cefclient/browser_window.cc',
'tests/cefclient/browser_window.h',
'tests/cefclient/bytes_write_handler.cc',
'tests/cefclient/bytes_write_handler.h',
'tests/cefclient/client_app.cc',
@ -156,6 +158,12 @@
'tests/cefclient/client_app_delegates.cc',
'tests/cefclient/client_handler.cc',
'tests/cefclient/client_handler.h',
'tests/cefclient/client_handler_osr.cc',
'tests/cefclient/client_handler_osr.h',
'tests/cefclient/client_handler_single.cc',
'tests/cefclient/client_handler_single.h',
'tests/cefclient/client_handler_std.cc',
'tests/cefclient/client_handler_std.h',
'tests/cefclient/client_renderer.cc',
'tests/cefclient/client_renderer.h',
'tests/cefclient/client_switches.cc',
@ -179,6 +187,10 @@
'tests/cefclient/performance_test_setup.h',
'tests/cefclient/performance_test_tests.cc',
'tests/cefclient/resource_util.h',
'tests/cefclient/root_window.cc',
'tests/cefclient/root_window.h',
'tests/cefclient/root_window_manager.cc',
'tests/cefclient/root_window_manager.h',
'tests/cefclient/scheme_test.cc',
'tests/cefclient/scheme_test.h',
'tests/cefclient/test_runner.cc',
@ -188,8 +200,6 @@
'<@(cefclient_bundle_resources_common)',
],
'cefclient_sources_win': [
'tests/cefclient/browser_window.cc',
'tests/cefclient/browser_window.h',
'tests/cefclient/browser_window_osr_win.cc',
'tests/cefclient/browser_window_osr_win.h',
'tests/cefclient/browser_window_std_win.cc',
@ -197,12 +207,6 @@
'tests/cefclient/cefclient.exe.manifest',
'tests/cefclient/cefclient.rc',
'tests/cefclient/cefclient_win.cc',
'tests/cefclient/client_handler_osr.cc',
'tests/cefclient/client_handler_osr.h',
'tests/cefclient/client_handler_single.cc',
'tests/cefclient/client_handler_single.h',
'tests/cefclient/client_handler_std.cc',
'tests/cefclient/client_handler_std.h',
'tests/cefclient/main_context_impl_win.cc',
'tests/cefclient/main_message_loop_multithreaded_win.cc',
'tests/cefclient/main_message_loop_multithreaded_win.h',
@ -214,9 +218,6 @@
'tests/cefclient/res/cefclient.ico',
'tests/cefclient/res/small.ico',
'tests/cefclient/resource_util_win.cc',
'tests/cefclient/root_window.h',
'tests/cefclient/root_window_manager.cc',
'tests/cefclient/root_window_manager.h',
'tests/cefclient/root_window_win.cc',
'tests/cefclient/root_window_win.h',
'tests/cefclient/temp_window_win.cc',
@ -226,15 +227,18 @@
'tests/cefclient/window_test_win.cc',
],
'cefclient_sources_mac': [
'tests/cefclient/browser_window_osr_mac.h',
'tests/cefclient/browser_window_osr_mac.mm',
'tests/cefclient/browser_window_std_mac.h',
'tests/cefclient/browser_window_std_mac.mm',
'tests/cefclient/cefclient_mac.mm',
'tests/cefclient/client_handler_shared.cc',
'tests/cefclient/client_handler_shared.h',
'tests/cefclient/client_handler_shared_mac.mm',
'tests/cefclient/main_context_impl_posix.cc',
'tests/cefclient/osr_widget_mac.h',
'tests/cefclient/osr_widget_mac.mm',
'tests/cefclient/resource_util_mac.mm',
'tests/cefclient/resource_util_posix.cc',
'tests/cefclient/root_window_mac.h',
'tests/cefclient/root_window_mac.mm',
'tests/cefclient/temp_window_mac.h',
'tests/cefclient/temp_window_mac.mm',
'tests/cefclient/window_test_mac.mm',
],
'cefclient_sources_mac_helper': [
@ -280,18 +284,10 @@
],
'cefclient_sources_linux': [
'tests/cefclient/cefclient_gtk.cc',
'tests/cefclient/browser_window.cc',
'tests/cefclient/browser_window.h',
'tests/cefclient/browser_window_osr_gtk.cc',
'tests/cefclient/browser_window_osr_gtk.h',
'tests/cefclient/browser_window_std_gtk.cc',
'tests/cefclient/browser_window_std_gtk.h',
'tests/cefclient/client_handler_osr.cc',
'tests/cefclient/client_handler_osr.h',
'tests/cefclient/client_handler_single.cc',
'tests/cefclient/client_handler_single.h',
'tests/cefclient/client_handler_std.cc',
'tests/cefclient/client_handler_std.h',
'tests/cefclient/dialog_handler_gtk.cc',
'tests/cefclient/dialog_handler_gtk.h',
'tests/cefclient/main_context_impl_posix.cc',
@ -299,9 +295,6 @@
'tests/cefclient/print_handler_gtk.h',
'tests/cefclient/resource_util_linux.cc',
'tests/cefclient/resource_util_posix.cc',
'tests/cefclient/root_window.h',
'tests/cefclient/root_window_manager.cc',
'tests/cefclient/root_window_manager.h',
'tests/cefclient/root_window_gtk.cc',
'tests/cefclient/root_window_gtk.h',
'tests/cefclient/temp_window_x11.cc',

View File

@ -71,7 +71,7 @@ class BrowserWindow : public ClientHandlerSingle::Delegate {
virtual void SetBounds(int x, int y, size_t width, size_t height) = 0;
// Set focus to the window.
virtual void SetFocus() = 0;
virtual void SetFocus(bool focus) = 0;
// Returns the window handle.
virtual ClientWindowHandle GetWindowHandle() const = 0;

View File

@ -1011,9 +1011,9 @@ void BrowserWindowOsrGtk::SetBounds(int x, int y, size_t width, size_t height) {
// Nothing to do here. GTK will take care of positioning in the container.
}
void BrowserWindowOsrGtk::SetFocus() {
void BrowserWindowOsrGtk::SetFocus(bool focus) {
REQUIRE_MAIN_THREAD();
if (glarea_)
if (glarea_ && focus)
gtk_widget_grab_focus(glarea_);
}

View File

@ -37,7 +37,7 @@ class BrowserWindowOsrGtk : public BrowserWindow,
void Show() OVERRIDE;
void Hide() OVERRIDE;
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
void SetFocus() OVERRIDE;
void SetFocus(bool focus) OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;
// ClientHandlerOsr::OsrDelegate methods.

View File

@ -0,0 +1,94 @@
// Copyright (c) 2015 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.
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_MAC_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_MAC_H_
#include "cefclient/browser_window.h"
#include "cefclient/client_handler_osr.h"
#include "cefclient/osr_renderer.h"
namespace client {
// Represents a native child window hosting a single off-screen browser
// instance. The methods of this class must be called on the main thread unless
// otherwise indicated.
class BrowserWindowOsrMac : public BrowserWindow,
public ClientHandlerOsr::OsrDelegate {
public:
// Constructor may be called on any thread.
// |delegate| must outlive this object.
BrowserWindowOsrMac(BrowserWindow::Delegate* delegate,
const std::string& startup_url,
bool transparent,
bool show_update_rect);
~BrowserWindowOsrMac();
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
void ShowPopup(ClientWindowHandle parent_handle,
int x, int y, size_t width, size_t height) OVERRIDE;
void Show() OVERRIDE;
void Hide() OVERRIDE;
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
void SetFocus(bool focus) OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;
// ClientHandlerOsr::OsrDelegate methods.
void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
bool GetRootScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) OVERRIDE;
void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE;
void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
void OnPaint(CefRefPtr<CefBrowser> browser,
CefRenderHandler::PaintElementType type,
const CefRenderHandler::RectList& dirtyRects,
const void* buffer,
int width,
int height) OVERRIDE;
void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor,
CefRenderHandler::CursorType type,
const CefCursorInfo& custom_cursor_info) OVERRIDE;
bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) OVERRIDE;
void UpdateDragCursor(CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) OVERRIDE;
private:
// Create the NSView.
void Create(ClientWindowHandle parent_handle, const CefRect& rect);
// The below members will only be accessed on the main thread which should be
// the same as the CEF UI thread.
OsrRenderer renderer_;
ClientWindowHandle nsview_;
bool hidden_;
bool painting_popup_;
DISALLOW_COPY_AND_ASSIGN(BrowserWindowOsrMac);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_OSR_MAC_H_

View File

@ -64,9 +64,9 @@ void BrowserWindowOsrWin::SetBounds(int x, int y, size_t width, size_t height) {
osr_window_->SetBounds(x, y, width, height);
}
void BrowserWindowOsrWin::SetFocus() {
void BrowserWindowOsrWin::SetFocus(bool focus) {
REQUIRE_MAIN_THREAD();
if (osr_window_)
if (osr_window_ && focus)
osr_window_->SetFocus();
}

View File

@ -36,7 +36,7 @@ class BrowserWindowOsrWin : public BrowserWindow,
void Show() OVERRIDE;
void Hide() OVERRIDE;
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
void SetFocus() OVERRIDE;
void SetFocus(bool focus) OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;
private:

View File

@ -165,13 +165,11 @@ void BrowserWindowStdGtk::SetBounds(int x, int y, size_t width, size_t height) {
}
}
void BrowserWindowStdGtk::SetFocus() {
void BrowserWindowStdGtk::SetFocus(bool focus) {
REQUIRE_MAIN_THREAD();
if (browser_) {
// Give focus to the browser window.
browser_->GetHost()->SetFocus(true);
}
if (browser_)
browser_->GetHost()->SetFocus(focus);
}
ClientWindowHandle BrowserWindowStdGtk::GetWindowHandle() const {

View File

@ -32,7 +32,7 @@ class BrowserWindowStdGtk : public BrowserWindow {
void Show() OVERRIDE;
void Hide() OVERRIDE;
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
void SetFocus() OVERRIDE;
void SetFocus(bool focus) OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;
private:

View File

@ -0,0 +1,44 @@
// Copyright (c) 2015 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.
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_MAC_H_
#define CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_MAC_H_
#include "cefclient/browser_window.h"
namespace client {
// Represents a native child window hosting a single windowed browser instance.
// The methods of this class must be called on the main thread unless otherwise
// indicated.
class BrowserWindowStdMac : public BrowserWindow {
public:
// Constructor may be called on any thread.
// |delegate| must outlive this object.
BrowserWindowStdMac(Delegate* delegate,
const std::string& startup_url);
// BrowserWindow methods.
void CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) OVERRIDE;
void GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
void ShowPopup(ClientWindowHandle parent_handle,
int x, int y, size_t width, size_t height) OVERRIDE;
void Show() OVERRIDE;
void Hide() OVERRIDE;
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
void SetFocus(bool focus) OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStdMac);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_BROWSER_WINDOW_STD_MAC_H_

View File

@ -0,0 +1,94 @@
// Copyright (c) 2015 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.
#include "cefclient/browser_window_std_mac.h"
#include <Cocoa/Cocoa.h>
#include "include/base/cef_logging.h"
#include "include/cef_app.h"
#include "cefclient/client_handler_std.h"
#include "cefclient/main_message_loop.h"
namespace client {
BrowserWindowStdMac::BrowserWindowStdMac(Delegate* delegate,
const std::string& startup_url)
: BrowserWindow(delegate) {
client_handler_ = new ClientHandlerStd(this, startup_url);
}
void BrowserWindowStdMac::CreateBrowser(ClientWindowHandle parent_handle,
const CefRect& rect,
const CefBrowserSettings& settings) {
REQUIRE_MAIN_THREAD();
CefWindowInfo window_info;
window_info.SetAsChild(parent_handle,
rect.x, rect.y, rect.width, rect.height);
CefBrowserHost::CreateBrowser(window_info, client_handler_,
client_handler_->startup_url(),
settings, NULL);
}
void BrowserWindowStdMac::GetPopupConfig(CefWindowHandle temp_handle,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) {
// Note: This method may be called on any thread.
// The window will be properly sized after the browser is created.
windowInfo.SetAsChild(temp_handle, 0, 0, 0, 0);
client = client_handler_;
}
void BrowserWindowStdMac::ShowPopup(ClientWindowHandle parent_handle,
int x, int y, size_t width, size_t height) {
REQUIRE_MAIN_THREAD();
NSView* browser_view = GetWindowHandle();
// Re-parent |browser_view| to |parent_handle|.
[browser_view removeFromSuperview];
[parent_handle addSubview:browser_view];
NSSize size = NSMakeSize(static_cast<int>(width), static_cast<int>(height));
[browser_view setFrameSize:size];
}
void BrowserWindowStdMac::Show() {
REQUIRE_MAIN_THREAD();
if (browser_)
browser_->GetHost()->SetWindowVisibility(true);
}
void BrowserWindowStdMac::Hide() {
REQUIRE_MAIN_THREAD();
if (browser_)
browser_->GetHost()->SetWindowVisibility(false);
}
void BrowserWindowStdMac::SetBounds(int x, int y, size_t width, size_t height) {
REQUIRE_MAIN_THREAD();
// Nothing to do here. Cocoa will size the browser for us.
}
void BrowserWindowStdMac::SetFocus(bool focus) {
REQUIRE_MAIN_THREAD();
if (browser_)
browser_->GetHost()->SetFocus(focus);
}
ClientWindowHandle BrowserWindowStdMac::GetWindowHandle() const {
REQUIRE_MAIN_THREAD();
if (browser_)
return browser_->GetHost()->GetWindowHandle();
return NULL;
}
} // namespace client

View File

@ -85,13 +85,11 @@ void BrowserWindowStdWin::SetBounds(int x, int y, size_t width, size_t height) {
}
}
void BrowserWindowStdWin::SetFocus() {
void BrowserWindowStdWin::SetFocus(bool focus) {
REQUIRE_MAIN_THREAD();
if (browser_) {
// Give focus to the browser window.
browser_->GetHost()->SetFocus(true);
}
if (browser_)
browser_->GetHost()->SetFocus(focus);
}
ClientWindowHandle BrowserWindowStdWin::GetWindowHandle() const {

View File

@ -32,7 +32,7 @@ class BrowserWindowStdWin : public BrowserWindow {
void Show() OVERRIDE;
void Hide() OVERRIDE;
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
void SetFocus() OVERRIDE;
void SetFocus(bool focus) OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;
private:

View File

@ -4,58 +4,18 @@
// found in the LICENSE file.
#import <Cocoa/Cocoa.h>
#include <sstream>
#include "include/cef_app.h"
#import "include/cef_application_mac.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "cefclient/client_app.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_switches.h"
#include "cefclient/main_context_impl.h"
#include "cefclient/main_message_loop_std.h"
#include "cefclient/osr_widget_mac.h"
#include "cefclient/resource.h"
#include "cefclient/resource_util.h"
#include "cefclient/root_window.h"
#include "cefclient/test_runner.h"
namespace {
// The global ClientHandlerShared reference.
CefRefPtr<client::ClientHandlerShared> g_handler;
// Used by off-screen rendering to find the associated CefBrowser.
class MainBrowserProvider : public client::OSRBrowserProvider {
virtual CefRefPtr<CefBrowser> GetBrowser() {
if (g_handler.get())
return g_handler->GetBrowser();
return NULL;
}
} g_main_browser_provider;
// Sizes for URL bar layout
#define BUTTON_HEIGHT 22
#define BUTTON_WIDTH 72
#define BUTTON_MARGIN 8
#define URLBAR_HEIGHT 32
// Content area size for newly created windows.
const int kWindowWidth = 800;
const int kWindowHeight = 600;
NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
NSButton* button = [[[NSButton alloc] initWithFrame:*rect] autorelease];
[button setTitle:title];
[button setBezelStyle:NSSmallSquareBezelStyle];
[button setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)];
[parent addSubview:button];
rect->origin.x += BUTTON_WIDTH;
return button;
}
void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
NSMenuItem* item = [menu addItemWithTitle:label
action:@selector(menuItemSelected:)
@ -66,7 +26,13 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
} // namespace
// Receives notifications from the application. Will delete itself when done.
@interface ClientAppDelegate : NSObject
@interface ClientAppDelegate : NSObject<NSApplicationDelegate> {
@private
bool with_osr_;
}
@property (nonatomic, readwrite) bool with_osr;
- (void)createApplication:(id)object;
- (void)tryToTerminateApplication:(NSApplication*)app;
- (IBAction)menuItemSelected:(id)sender;
@ -74,12 +40,15 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
// Provide the CefAppProtocol implementation required by CEF.
@interface ClientApplication : NSApplication<CefAppProtocol> {
@private
@private
BOOL handlingSendEvent_;
}
@end
@implementation ClientApplication
@synthesize with_osr = with_osr_;
- (BOOL)isHandlingSendEvent {
return handlingSendEvent_;
}
@ -131,222 +100,25 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
// The standard |-applicationShouldTerminate:| is not supported, and code paths
// leading to it must be redirected.
- (void)terminate:(id)sender {
ClientAppDelegate* delegate =
static_cast<ClientAppDelegate*>([NSApp delegate]);
ClientAppDelegate* delegate = static_cast<ClientAppDelegate*>(
[[NSApplication sharedApplication] delegate]);
[delegate tryToTerminateApplication:self];
// Return, don't exit. The application is responsible for exiting on its own.
}
@end
// Receives notifications from controls and the browser window. Will delete
// itself when done.
@interface ClientWindowDelegate : NSObject <NSWindowDelegate> {
@private
NSWindow* window_;
}
- (id)initWithWindow:(NSWindow*)window;
- (IBAction)goBack:(id)sender;
- (IBAction)goForward:(id)sender;
- (IBAction)reload:(id)sender;
- (IBAction)stopLoading:(id)sender;
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender;
- (void)alert:(NSString*)title withMessage:(NSString*)message;
@end
@implementation ClientWindowDelegate
- (id)initWithWindow:(NSWindow*)window {
if (self = [super init]) {
window_ = window;
[window_ setDelegate:self];
// Register for application hide/unhide notifications.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationDidHide:)
name:NSApplicationDidHideNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationDidUnhide:)
name:NSApplicationDidUnhideNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (IBAction)goBack:(id)sender {
if (g_handler.get() && g_handler->GetBrowserId())
g_handler->GetBrowser()->GoBack();
}
- (IBAction)goForward:(id)sender {
if (g_handler.get() && g_handler->GetBrowserId())
g_handler->GetBrowser()->GoForward();
}
- (IBAction)reload:(id)sender {
if (g_handler.get() && g_handler->GetBrowserId())
g_handler->GetBrowser()->Reload();
}
- (IBAction)stopLoading:(id)sender {
if (g_handler.get() && g_handler->GetBrowserId())
g_handler->GetBrowser()->StopLoad();
}
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender {
if (!g_handler.get() || !g_handler->GetBrowserId())
return;
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];
std::string urlStr = [url UTF8String];
g_handler->GetBrowser()->GetMainFrame()->LoadURL(urlStr);
}
- (void)alert:(NSString*)title withMessage:(NSString*)message {
NSAlert *alert = [NSAlert alertWithMessageText:title
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:@"%@", message];
[alert runModal];
}
// Called when we are activated (when we gain focus).
- (void)windowDidBecomeKey:(NSNotification*)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get()) {
if (g_handler->is_osr()) {
browser->GetHost()->SendFocusEvent(true);
} else {
browser->GetHost()->SetFocus(true);
}
}
}
}
// Called when we are deactivated (when we lose focus).
- (void)windowDidResignKey:(NSNotification*)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get()) {
if (g_handler->is_osr()) {
browser->GetHost()->SendFocusEvent(false);
} else {
browser->GetHost()->SetFocus(false);
}
}
}
}
// Called when we have been minimized.
- (void)windowDidMiniaturize:(NSNotification *)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(false);
}
}
// Called when we have been unminimized.
- (void)windowDidDeminiaturize:(NSNotification *)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(true);
}
}
// Called when the application has been hidden.
- (void)applicationDidHide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![window_ isMiniaturized]) {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(false);
}
}
}
// Called when the application has been unhidden.
- (void)applicationDidUnhide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![window_ isMiniaturized]) {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(true);
}
}
}
// Called when the window is about to close. Perform the self-destruction
// sequence by getting rid of the window. By returning YES, we allow the window
// to be removed from the screen.
- (BOOL)windowShouldClose:(id)window {
if (g_handler.get() && !g_handler->IsClosing()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get()) {
// Notify the browser window that we would like to close it. This
// will result in a call to ClientHandler::DoClose() if the
// JavaScript 'onbeforeunload' event handler allows it.
browser->GetHost()->CloseBrowser(false);
// Cancel the close.
return NO;
}
}
// Try to make the window go away.
[window autorelease];
// Clean ourselves up after clearing the stack of anything that might have the
// window on it.
[self performSelectorOnMainThread:@selector(cleanup:)
withObject:window
waitUntilDone:NO];
// Allow the close.
return YES;
}
// Deletes itself.
- (void)cleanup:(id)window {
[self release];
}
@end
@implementation ClientAppDelegate
// Create the application on the UI thread.
- (void)createApplication:(id)object {
[NSApplication sharedApplication];
NSApplication* application = [NSApplication sharedApplication];
[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
// Set the delegate for application events.
[NSApp setDelegate:self];
[application setDelegate:self];
// Add the Tests menu.
NSMenu* menubar = [NSApp mainMenu];
NSMenu* menubar = [application mainMenu];
NSMenuItem *testItem = [[[NSMenuItem alloc] initWithTitle:@"Tests"
action:nil
keyEquivalent:@""] autorelease];
@ -366,127 +138,32 @@ void AddMenuItem(NSMenu *menu, NSString* label, int idval) {
[testItem setSubmenu:testMenu];
[menubar addItem:testItem];
// Create the main application window.
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
NSRect window_rect = { {0, screen_rect.size.height - kWindowHeight},
{kWindowWidth, kWindowHeight} };
NSWindow* mainWnd = [[UnderlayOpenGLHostingWindow alloc]
initWithContentRect:window_rect
styleMask:(NSTitledWindowMask |
NSClosableWindowMask |
NSMiniaturizableWindowMask |
NSResizableWindowMask )
backing:NSBackingStoreBuffered
defer:NO];
[mainWnd setTitle:@"cefclient"];
// Create the delegate for control and browser window events.
ClientWindowDelegate* delegate =
[[ClientWindowDelegate alloc] initWithWindow:mainWnd];
// Rely on the window delegate to clean us up rather than immediately
// releasing when the window gets closed. We use the delegate to do
// everything from the autorelease pool so the window isn't on the stack
// during cleanup (ie, a window close from javascript).
[mainWnd setReleasedWhenClosed:NO];
NSView* contentView = [mainWnd contentView];
// Create the buttons.
NSRect button_rect = [contentView bounds];
button_rect.origin.y = window_rect.size.height - URLBAR_HEIGHT +
(URLBAR_HEIGHT - BUTTON_HEIGHT) / 2;
button_rect.size.height = BUTTON_HEIGHT;
button_rect.origin.x += BUTTON_MARGIN;
button_rect.size.width = BUTTON_WIDTH;
NSButton* backButton = MakeButton(&button_rect, @"Back", contentView);
[backButton setTarget:delegate];
[backButton setAction:@selector(goBack:)];
[backButton setEnabled:NO];
NSButton* forwardButton = MakeButton(&button_rect, @"Forward", contentView);
[forwardButton setTarget:delegate];
[forwardButton setAction:@selector(goForward:)];
[forwardButton setEnabled:NO];
NSButton* reloadButton = MakeButton(&button_rect, @"Reload", contentView);
[reloadButton setTarget:delegate];
[reloadButton setAction:@selector(reload:)];
[reloadButton setEnabled:NO];
NSButton* stopButton = MakeButton(&button_rect, @"Stop", contentView);
[stopButton setTarget:delegate];
[stopButton setAction:@selector(stopLoading:)];
[stopButton setEnabled:NO];
// Create the URL text field.
button_rect.origin.x += BUTTON_MARGIN;
button_rect.size.width = [contentView bounds].size.width -
button_rect.origin.x - BUTTON_MARGIN;
NSTextField* editWnd = [[NSTextField alloc] initWithFrame:button_rect];
[contentView addSubview:editWnd];
[editWnd setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
[editWnd setTarget:delegate];
[editWnd setAction:@selector(takeURLStringValueFrom:)];
[editWnd setEnabled:NO];
[[editWnd cell] setWraps:NO];
[[editWnd cell] setScrollable:YES];
// Create the handler.
g_handler = new client::ClientHandlerShared();
g_handler->SetMainWindowHandle(contentView);
g_handler->SetUXWindowHandles(editWnd, backButton, forwardButton,
reloadButton, stopButton);
// Create the browser view.
CefWindowInfo window_info;
CefBrowserSettings settings;
// Populate the browser settings based on command line arguments.
client::MainContext::Get()->PopulateBrowserSettings(&settings);
if (g_handler->is_osr()) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const bool transparent =
command_line->HasSwitch(client::switches::kTransparentPaintingEnabled);
const bool show_update_rect =
command_line->HasSwitch(client::switches::kShowUpdateRect);
CefRefPtr<client::OSRWindow> osr_window =
client::OSRWindow::Create(&g_main_browser_provider, transparent,
show_update_rect, contentView,
CefRect(0, 0, kWindowWidth, kWindowHeight));
window_info.SetAsWindowless(osr_window->GetWindowHandle(), transparent);
g_handler->SetOSRHandler(osr_window->GetRenderHandler().get());
} else {
// Initialize window info to the defaults for a child window.
window_info.SetAsChild(contentView, 0, 0, kWindowWidth, kWindowHeight);
}
CefBrowserHost::CreateBrowser(window_info, g_handler.get(),
g_handler->startup_url(), settings, NULL);
// Show the window.
[mainWnd makeKeyAndOrderFront: nil];
// Size the window.
NSRect r = [mainWnd contentRectForFrameRect:[mainWnd frame]];
r.size.width = kWindowWidth;
r.size.height = kWindowHeight + URLBAR_HEIGHT;
[mainWnd setFrame:[mainWnd frameRectForContentRect:r] display:YES];
// Create the first window.
client::MainContext::Get()->GetRootWindowManager()->CreateRootWindow(
true, // Show controls.
with_osr_, // Use off-screen rendering.
CefRect(), // Use default system size.
std::string()); // Use default URL.
}
- (void)tryToTerminateApplication:(NSApplication*)app {
if (g_handler.get() && !g_handler->IsClosing())
g_handler->CloseAllBrowsers(false);
client::MainContext::Get()->GetRootWindowManager()->CloseAllWindows(false);
}
- (IBAction)menuItemSelected:(id)sender {
NSMenuItem *item = (NSMenuItem*)sender;
if (g_handler.get() && g_handler->GetBrowserId())
client::test_runner::RunTest(g_handler->GetBrowser(), [item tag]);
// Retrieve the active RootWindow.
NSWindow* key_window = [[NSApplication sharedApplication] keyWindow];
if (!key_window)
return;
scoped_refptr<client::RootWindow> root_window =
client::RootWindow::GetForNSWindow(key_window);
CefRefPtr<CefBrowser> browser = root_window->GetBrowser();
if (browser.get()) {
NSMenuItem *item = (NSMenuItem*)sender;
client::test_runner::RunTest(browser, [item tag]);
}
}
- (NSApplicationTerminateReply)applicationShouldTerminate:
@ -528,7 +205,8 @@ int RunMain(int argc, char* argv[]) {
test_runner::RegisterSchemeHandlers();
// Create the application delegate and window.
NSObject* delegate = [[ClientAppDelegate alloc] init];
ClientAppDelegate* delegate = [[ClientAppDelegate alloc] init];
delegate->with_osr = settings.windowless_rendering_enabled ? true : false;
[delegate performSelectorOnMainThread:@selector(createApplication:)
withObject:nil
waitUntilDone:NO];
@ -540,7 +218,6 @@ int RunMain(int argc, char* argv[]) {
context->Shutdown();
// Release objects in reverse order of creation.
g_handler = NULL;
[delegate release];
message_loop.reset();
context.reset();

View File

@ -1,188 +0,0 @@
// Copyright (c) 2015 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.
#include "cefclient/client_handler_shared.h"
#include <stdio.h>
#include <algorithm>
#include <string>
#include "include/base/cef_bind.h"
#include "include/cef_command_line.h"
#include "include/wrapper/cef_closure_task.h"
#include "cefclient/client_switches.h"
#include "cefclient/main_context.h"
#include "cefclient/main_message_loop.h"
#include "cefclient/test_runner.h"
namespace client {
ClientHandlerShared::ClientHandlerShared()
: ClientHandler(MainContext::Get()->GetMainURL(),
CefCommandLine::GetGlobalCommandLine()->HasSwitch(
switches::kOffScreenRenderingEnabled)),
is_closing_(false),
browser_id_(0),
edit_handle_(NULL),
back_handle_(NULL),
forward_handle_(NULL),
stop_handle_(NULL),
reload_handle_(NULL) {
}
ClientHandlerShared::~ClientHandlerShared() {
}
void ClientHandlerShared::BrowserCreated(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == 0) {
// Keep references to the browser hosted in the main window.
browser_id_ = browser->GetIdentifier();
browser_ = browser;
} else if (browser->IsPopup()) {
// Add to the list of popup browsers.
popup_browsers_.push_back(browser);
// Give focus to the popup browser. Perform asynchronously because the
// parent window may attempt to keep focus after launching the popup.
CefPostTask(TID_UI,
base::Bind(&CefBrowserHost::SetFocus, browser->GetHost().get(), true));
}
}
void ClientHandlerShared::BrowserClosing(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
// Closing the main window requires special handling. See the DoClose()
// documentation in the CEF header for a detailed destription of this
// process.
if (browser_id_ == browser->GetIdentifier()) {
// Set a flag to indicate that the window close should be allowed.
is_closing_ = true;
}
}
void ClientHandlerShared::BrowserClosed(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Free the browser pointer so that the browser can be destroyed.
browser_ = NULL;
if (osr_handler_.get()) {
osr_handler_->OnBeforeClose(browser);
osr_handler_ = NULL;
}
browser_id_ = 0;
} else if (browser->IsPopup()) {
// Remove from the browser popup list.
BrowserList::iterator bit = popup_browsers_.begin();
for (; bit != popup_browsers_.end(); ++bit) {
if ((*bit)->IsSame(browser)) {
popup_browsers_.erase(bit);
break;
}
}
}
if (GetBrowserCount() == 0) {
// Quit the main message loop.
MainMessageLoop::Get()->Quit();
}
}
bool ClientHandlerShared::CreatePopupWindow(
CefRefPtr<CefBrowser> browser,
bool is_devtools,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) {
// Note: This method will be called on multiple threads.
if (is_devtools) {
CEF_REQUIRE_UI_THREAD();
// Create DevTools as a windowed popup browser using the same client.
#if defined(OS_WIN)
windowInfo.SetAsPopup(GetMainWindowHandle(), "DevTools");
#endif
client = this;
} else if (is_osr()) {
CefPostTask(TID_UI,
base::Bind(test_runner::Alert, browser,
"Popup windows are disabled with off-screen rendering."));
// Cancel popups in off-screen rendering mode.
return false;
}
return true;
}
void ClientHandlerShared::SetUXWindowHandles(
ClientWindowHandle editHandle,
ClientWindowHandle backHandle,
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle) {
CEF_REQUIRE_UI_THREAD();
edit_handle_ = editHandle;
back_handle_ = backHandle;
forward_handle_ = forwardHandle;
reload_handle_ = reloadHandle;
stop_handle_ = stopHandle;
}
CefRefPtr<ClientHandlerShared::RenderHandler>
ClientHandlerShared::GetOSRHandler() const {
CEF_REQUIRE_UI_THREAD();
return osr_handler_;
}
void ClientHandlerShared::SetOSRHandler(CefRefPtr<RenderHandler> handler) {
CEF_REQUIRE_UI_THREAD();
osr_handler_ = handler;
}
CefRefPtr<CefBrowser> ClientHandlerShared::GetBrowser() const {
CEF_REQUIRE_UI_THREAD();
return browser_;
}
int ClientHandlerShared::GetBrowserId() const {
CEF_REQUIRE_UI_THREAD();
return browser_id_;
}
void ClientHandlerShared::CloseAllBrowsers(bool force_close) {
CEF_REQUIRE_UI_THREAD();
if (!popup_browsers_.empty()) {
// Request that any popup browsers close.
BrowserList::const_iterator it = popup_browsers_.begin();
for (; it != popup_browsers_.end(); ++it)
(*it)->GetHost()->CloseBrowser(force_close);
}
if (browser_.get()) {
// Request that the main browser close.
browser_->GetHost()->CloseBrowser(force_close);
}
}
bool ClientHandlerShared::IsClosing() const {
CEF_REQUIRE_UI_THREAD();
return is_closing_;
}
} // namespace client

View File

@ -1,113 +0,0 @@
// Copyright (c) 2015 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.
#ifndef CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SHARED_H_
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SHARED_H_
#pragma once
#include <list>
#include <string>
#include "cefclient/client_handler.h"
namespace client {
// Client handler implementation that is shared by all existing browsers. All
// methods must be called on the CEF UI thread unless otherwise indicated.
class ClientHandlerShared : public ClientHandler {
public:
// Interface implemented to handle off-screen rendering.
class RenderHandler : public CefRenderHandler {
public:
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) =0;
};
ClientHandlerShared();
~ClientHandlerShared();
// CefClient methods
CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE {
return osr_handler_;
}
// ClientHandler methods
void BrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
void BrowserClosing(CefRefPtr<CefBrowser> browser) OVERRIDE;
void BrowserClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
void SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) OVERRIDE;
void SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) OVERRIDE;
void SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) OVERRIDE;
bool CreatePopupWindow(
CefRefPtr<CefBrowser> browser,
bool is_devtools,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
void SetUXWindowHandles(ClientWindowHandle editHandle,
ClientWindowHandle backHandle,
ClientWindowHandle forwardHandle,
ClientWindowHandle reloadHandle,
ClientWindowHandle stopHandle);
CefRefPtr<RenderHandler> GetOSRHandler() const;
void SetOSRHandler(CefRefPtr<RenderHandler> handler);
// Get the main (non-popup) browser associated with this client.
CefRefPtr<CefBrowser> GetBrowser() const;
// Get the main (non-popup) browser ID. Will return non-0 if the main browser
// currently exists.
int GetBrowserId() const;
// Request that all existing browser windows close.
void CloseAllBrowsers(bool force_close);
// Returns true if the main browser window is currently closing. Used in
// combination with DoClose() and the OS close notification to properly handle
// 'onbeforeunload' JavaScript events during window close.
bool IsClosing() const;
private:
// The following members will only be accessed on the CEF UI thread.
// The handler for off-screen rendering, if any.
CefRefPtr<RenderHandler> osr_handler_;
// The child browser window.
CefRefPtr<CefBrowser> browser_;
// True if the main browser window is currently closing.
bool is_closing_;
// The child browser id.
int browser_id_;
// List of any popup browser windows.
typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
BrowserList popup_browsers_;
// The edit window handle.
ClientWindowHandle edit_handle_;
// The button window handles.
ClientWindowHandle back_handle_;
ClientWindowHandle forward_handle_;
ClientWindowHandle stop_handle_;
ClientWindowHandle reload_handle_;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientHandlerShared);
DISALLOW_COPY_AND_ASSIGN(ClientHandlerShared);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_SHARED_H_

View File

@ -1,105 +0,0 @@
// Copyright (c) 2014 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.
#include <gtk/gtk.h>
#include <libgen.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#undef Success // Definition conflicts with cef_message_router.h
#include <string>
#include "cefclient/client_handler_shared.h"
#include "include/cef_browser.h"
namespace client {
void ClientHandlerShared::SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Set the edit window text.
std::string urlStr(url);
gtk_entry_set_text(GTK_ENTRY(edit_handle_), urlStr.c_str());
}
}
void ClientHandlerShared::SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
std::string titleStr(title);
if (!browser->IsPopup()) {
// Set the GTK parent window title.
GtkWidget* window = gtk_widget_get_ancestor(GetMainWindowHandle(),
GTK_TYPE_WINDOW);
gtk_window_set_title(GTK_WINDOW(window), titleStr.c_str());
} else {
// Retrieve the X11 display shared with Chromium.
::Display* display = cef_get_xdisplay();
DCHECK(display);
// Retrieve the X11 window handle for the browser.
::Window window = browser->GetHost()->GetWindowHandle();
DCHECK(window != kNullWindowHandle);
// Retrieve the atoms required by the below XChangeProperty call.
const char* kAtoms[] = {
"_NET_WM_NAME",
"UTF8_STRING"
};
Atom atoms[2];
int result = XInternAtoms(display, const_cast<char**>(kAtoms), 2, false,
atoms);
if (!result)
NOTREACHED();
// Set the window title.
XChangeProperty(display,
window,
atoms[0],
atoms[1],
8,
PropModeReplace,
reinterpret_cast<const unsigned char*>(titleStr.c_str()),
titleStr.size());
// TODO(erg): This is technically wrong. So XStoreName and friends expect
// this in Host Portable Character Encoding instead of UTF-8, which I
// believe is Compound Text. This shouldn't matter 90% of the time since
// this is the fallback to the UTF8 property above.
XStoreName(display, browser->GetHost()->GetWindowHandle(),
titleStr.c_str());
}
}
void ClientHandlerShared::SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) {
CEF_REQUIRE_UI_THREAD();
// Nothing to do for popup windows.
if (browser_id_ != browser->GetIdentifier())
return;
if (isLoading)
gtk_widget_set_sensitive(GTK_WIDGET(stop_handle_), true);
else
gtk_widget_set_sensitive(GTK_WIDGET(stop_handle_), false);
if (canGoBack)
gtk_widget_set_sensitive(GTK_WIDGET(back_handle_), true);
else
gtk_widget_set_sensitive(GTK_WIDGET(back_handle_), false);
if (canGoForward)
gtk_widget_set_sensitive(GTK_WIDGET(forward_handle_), true);
else
gtk_widget_set_sensitive(GTK_WIDGET(forward_handle_), false);
}
} // namespace client

View File

@ -1,53 +0,0 @@
// Copyright (c) 2011 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 "cefclient/client_handler_shared.h"
#include "include/cef_browser.h"
namespace client {
void ClientHandlerShared::SetAddress(CefRefPtr<CefBrowser> browser,
const CefString& url) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Set edit window text for the main window.
NSTextField* textField = (NSTextField*)edit_handle_;
std::string urlStr(url);
NSString* str = [NSString stringWithUTF8String:urlStr.c_str()];
[textField setStringValue:str];
}
}
void ClientHandlerShared::SetTitle(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
// Set the frame window title bar.
NSView* view = (NSView*)browser->GetHost()->GetWindowHandle();
NSWindow* window = [view window];
std::string titleStr(title);
NSString* str = [NSString stringWithUTF8String:titleStr.c_str()];
[window setTitle:str];
}
void ClientHandlerShared::SetLoadingState(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) {
CEF_REQUIRE_UI_THREAD();
if (browser_id_ == browser->GetIdentifier()) {
// Set UX control state for the main window.
[(NSTextField*)edit_handle_ setEnabled:YES];
[(NSButton*)reload_handle_ setEnabled:!isLoading];
[(NSButton*)stop_handle_ setEnabled:isLoading];
[(NSButton*)back_handle_ setEnabled:canGoBack];
[(NSButton*)forward_handle_ setEnabled:canGoForward];
}
}
} // namespace client

View File

@ -16,5 +16,17 @@
#define ClientWindowHandle CefWindowHandle
#endif
#if defined(OS_MACOSX)
// Forward declaration of ObjC types used by cefclient and not provided by
// include/internal/cef_types_mac.h.
#ifdef __cplusplus
#ifdef __OBJC__
@class NSWindow;
#else
class NSWindow;
#endif
#endif
#endif // defined OS_MACOSX
#endif // CEF_TESTS_CEFCLIENT_CLIENT_TYPES_H_

View File

@ -12,9 +12,7 @@
namespace client {
#if defined(OS_WIN) || defined(OS_LINUX)
class RootWindowManager;
#endif
// Used to store global context in the browser process. The methods of this
// class are thread-safe unless otherwise indicated.
@ -39,10 +37,8 @@ class MainContext {
virtual void PopulateSettings(CefSettings* settings) = 0;
virtual void PopulateBrowserSettings(CefBrowserSettings* settings) = 0;
#if defined(OS_WIN) || defined(OS_LINUX)
// Returns the object used to create/manage RootWindow instances.
virtual RootWindowManager* GetRootWindowManager() = 0;
#endif
protected:
MainContext();

View File

@ -70,12 +70,10 @@ void MainContextImpl::PopulateBrowserSettings(CefBrowserSettings* settings) {
}
}
#if defined(OS_WIN) || defined(OS_LINUX)
RootWindowManager* MainContextImpl::GetRootWindowManager() {
DCHECK(InValidState());
return root_window_manager_.get();
}
#endif
bool MainContextImpl::Initialize(const CefMainArgs& args,
const CefSettings& settings,
@ -88,12 +86,10 @@ bool MainContextImpl::Initialize(const CefMainArgs& args,
if (!CefInitialize(args, settings, application, windows_sandbox_info))
return false;
#if defined(OS_WIN) || defined(OS_LINUX)
// Need to create the RootWindowManager after calling CefInitialize because
// TempWindowX11 uses cef_get_xdisplay().
root_window_manager_.reset(
new RootWindowManager(terminate_when_all_windows_closed_));
#endif
initialized_ = true;
@ -105,9 +101,7 @@ void MainContextImpl::Shutdown() {
DCHECK(initialized_);
DCHECK(!shutdown_);
#if defined(OS_WIN) || defined(OS_LINUX)
root_window_manager_.reset();
#endif
CefShutdown();

View File

@ -10,10 +10,7 @@
#include "include/cef_app.h"
#include "include/cef_command_line.h"
#include "cefclient/main_context.h"
#if defined(OS_WIN) || defined(OS_LINUX)
#include "cefclient/root_window_manager.h"
#endif
namespace client {
@ -31,9 +28,7 @@ class MainContextImpl : public MainContext {
std::string GetMainURL() OVERRIDE;
void PopulateSettings(CefSettings* settings) OVERRIDE;
void PopulateBrowserSettings(CefBrowserSettings* settings) OVERRIDE;
#if defined(OS_WIN) || defined(OS_LINUX)
RootWindowManager* GetRootWindowManager() OVERRIDE;
#endif
// Initialize CEF and associated main context state. This method must be
// called on the same thread that created this object.
@ -69,9 +64,7 @@ class MainContextImpl : public MainContext {
CefRefPtr<CefCommandLine> command_line_;
std::string main_url_;
#if defined(OS_WIN) || defined(OS_LINUX)
scoped_ptr<RootWindowManager> root_window_manager_;
#endif
// Used to verify that methods are called on the correct thread.
base::ThreadChecker thread_checker_;

View File

@ -283,6 +283,8 @@ void OsrRenderer::OnPaint(CefRefPtr<CefBrowser> browser,
CefRenderHandler::RectList::const_iterator i = dirtyRects.begin();
for (; i != dirtyRects.end(); ++i) {
const CefRect& rect = *i;
DCHECK(rect.x + rect.width <= view_width_);
DCHECK(rect.y + rect.height <= view_height_);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x); VERIFY_NO_ERROR;
glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y); VERIFY_NO_ERROR;
glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x, rect.y, rect.width,

View File

@ -1,151 +0,0 @@
// Copyright (c) 2013 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.
#ifndef CEF_TESTS_CEFCLIENT_OSR_WIDGET_MAC_H_
#define CEF_TESTS_CEFCLIENT_OSR_WIDGET_MAC_H_
#include "include/cef_client.h"
#include "cefclient/client_handler_shared.h"
namespace client {
class OSRBrowserProvider;
class OsrRenderer;
}
// The client OpenGL view.
@interface ClientOpenGLView
: NSOpenGLView <NSDraggingSource, NSDraggingDestination> {
@public
NSTrackingArea* tracking_area_;
client::OSRBrowserProvider* browser_provider_;
client::OsrRenderer* renderer_;
NSPoint last_mouse_pos_;
NSPoint cur_mouse_pos_;
bool rotating_;
bool was_last_mouse_down_on_view_;
// Drag and drop
CefRefPtr<CefDragData> current_drag_data_;
NSDragOperation current_drag_op_;
NSDragOperation current_allowed_ops_;
NSPasteboard* pasteboard_;
CFStringRef fileUTI_;
// Event monitor for scroll wheel end event.
id endWheelMonitor_;
}
- (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency
andShowUpdateRect:(bool)show_update_rect;
- (NSPoint)getClickPointForEvent:(NSEvent*)event;
- (void)getKeyEvent:(CefKeyEvent&)keyEvent forEvent:(NSEvent*)event;
- (void)getMouseEvent:(CefMouseEvent&)mouseEvent forEvent:(NSEvent*)event;
- (int)getModifiersForEvent:(NSEvent*)event;
- (BOOL)isKeyUpEvent:(NSEvent*)event;
- (BOOL)isKeyPadEvent:(NSEvent*)event;
- (CefRefPtr<CefBrowser>)getBrowser;
- (BOOL)startDragging:(CefRefPtr<CefDragData>)drag_data
allowed_ops:(NSDragOperation)ops point:(NSPoint)p;
@end
namespace client {
class OSRBrowserProvider {
public:
virtual CefRefPtr<CefBrowser> GetBrowser() =0;
protected:
virtual ~OSRBrowserProvider() {}
};
// Handler for off-screen rendering windows.
class ClientOSRHandler : public ClientHandlerShared::RenderHandler {
public:
explicit ClientOSRHandler(ClientOpenGLView* view,
OSRBrowserProvider* browser_provider);
~ClientOSRHandler();
void Disconnect();
// ClientHandlerShared::RenderHandler methods
void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefRenderHandler methods
bool GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) OVERRIDE;
bool GetScreenPoint(CefRefPtr<CefBrowser> browser,
int viewX,
int viewY,
int& screenX,
int& screenY) OVERRIDE;
bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) OVERRIDE;
void OnPopupShow(CefRefPtr<CefBrowser> browser,
bool show) OVERRIDE;
void OnPopupSize(CefRefPtr<CefBrowser> browser,
const CefRect& rect) OVERRIDE;
void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width, int height) OVERRIDE;
void OnCursorChange(CefRefPtr<CefBrowser> browser,
CefCursorHandle cursor,
CursorType type,
const CefCursorInfo& custom_cursor_info) OVERRIDE;
bool StartDragging(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> drag_data,
CefRenderHandler::DragOperationsMask allowed_ops,
int x, int y) OVERRIDE;
void UpdateDragCursor(
CefRefPtr<CefBrowser> browser,
CefRenderHandler::DragOperation operation) OVERRIDE;
CefWindowHandle view() { return view_; }
private:
void SetLoading(bool isLoading);
ClientOpenGLView* view_;
bool painting_popup_;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientOSRHandler);
};
class OSRWindow {
public:
static CefRefPtr<OSRWindow> Create(OSRBrowserProvider* browser_provider,
bool transparent,
bool show_update_rect,
CefWindowHandle parentView,
const CefRect& frame);
CefRefPtr<ClientHandlerShared::RenderHandler> GetRenderHandler() {
return render_client.get();
}
CefWindowHandle GetWindowHandle() { return view_; }
private:
OSRWindow(OSRBrowserProvider* browser_provider,
bool transparent,
bool show_update_rect,
CefWindowHandle parentView,
const CefRect& frame);
~OSRWindow();
CefRefPtr<ClientOSRHandler> render_client;
CefWindowHandle view_;
IMPLEMENT_REFCOUNTING(OSRWindow);
DISALLOW_COPY_AND_ASSIGN(OSRWindow);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_OSR_WIDGET_MAC_H_

View File

@ -0,0 +1,18 @@
// Copyright (c) 2015 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.
#include "cefclient/root_window.h"
#include "cefclient/main_context.h"
#include "cefclient/root_window_manager.h"
namespace client {
// static
scoped_refptr<RootWindow> GetForBrowser(int browser_id) {
return MainContext::Get()->GetRootWindowManager()->GetWindowForBrowser(
browser_id);
}
} // namespace client

View File

@ -42,6 +42,16 @@ class RootWindow :
// instead of calling this method directly.
static scoped_refptr<RootWindow> Create();
// Returns the RootWindow associated with the specified |browser_id|. Must be
// called on the main thread.
static scoped_refptr<RootWindow> GetForBrowser(int browser_id);
#if defined(OS_MACOSX)
// Returns the RootWindow associated with the specified |window|. Must be
// called on the main thread.
static scoped_refptr<RootWindow> GetForNSWindow(NSWindow* window);
#endif
// Initialize as a normal window. This will create and show a browser window.
// This method may be called on any thread.
// |delegate| must be non-NULL and outlive this object.

View File

@ -345,8 +345,8 @@ void RootWindowGtk::OnBrowserWindowDestroyed() {
if (!window_destroyed_) {
// The browser was destroyed first. This could be due to the use of
// off-screen rendering or execution of JavaScript window.close().
// Close the RootWindow asynchronously.
Close(false);
// Close the RootWindow.
Close(true);
}
browser_destroyed_ = true;
@ -395,7 +395,7 @@ gboolean RootWindowGtk::WindowFocusIn(GtkWidget* widget,
GdkEventFocus* event,
RootWindowGtk* self) {
if (event->in && self->browser_window_.get()) {
self->browser_window_->SetFocus();
self->browser_window_->SetFocus(true);
// Return true for a windowed browser so that focus is not passed to GTK.
return self->with_osr_ ? FALSE : TRUE;
}

View File

@ -0,0 +1,99 @@
// Copyright (c) 2015 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.
#ifndef CEF_TESTS_CEFCLIENT_ROOT_WINDOW_MAC_H_
#define CEF_TESTS_CEFCLIENT_ROOT_WINDOW_MAC_H_
#include <Cocoa/Cocoa.h>
#include <string>
#include "include/base/cef_scoped_ptr.h"
#include "cefclient/browser_window.h"
#include "cefclient/root_window.h"
namespace client {
// OS X implementation of a top-level native window in the browser process.
// The methods of this class must be called on the main thread unless otherwise
// indicated.
class RootWindowMac : public RootWindow,
public BrowserWindow::Delegate {
public:
// Constructor may be called on any thread.
RootWindowMac();
~RootWindowMac();
// RootWindow methods.
void Init(RootWindow::Delegate* delegate,
bool with_controls,
bool with_osr,
const CefRect& rect,
const CefBrowserSettings& settings,
const std::string& url) OVERRIDE;
void InitAsPopup(RootWindow::Delegate* delegate,
bool with_controls,
bool with_osr,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE;
void Show(ShowMode mode) OVERRIDE;
void Hide() OVERRIDE;
void SetBounds(int x, int y, size_t width, size_t height) OVERRIDE;
void Close(bool force) OVERRIDE;
CefRefPtr<CefBrowser> GetBrowser() const OVERRIDE;
ClientWindowHandle GetWindowHandle() const OVERRIDE;
// Called by RootWindowDelegate after the associated NSWindow has been
// destroyed.
void WindowDestroyed();
BrowserWindow* browser_window() const { return browser_window_.get(); }
private:
void CreateBrowserWindow(const std::string& startup_url);
void CreateRootWindow(const CefBrowserSettings& settings);
// BrowserWindow::Delegate methods.
void OnBrowserCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
void OnBrowserWindowDestroyed() OVERRIDE;
void OnSetAddress(const std::string& url) OVERRIDE;
void OnSetTitle(const std::string& title) OVERRIDE;
void OnSetLoadingState(bool isLoading,
bool canGoBack,
bool canGoForward) OVERRIDE;
void NotifyDestroyedIfDone();
// After initialization all members are only accessed on the main thread.
// Members set during initialization.
RootWindow::Delegate* delegate_;
bool with_controls_;
bool with_osr_;
bool is_popup_;
CefRect start_rect_;
scoped_ptr<BrowserWindow> browser_window_;
bool initialized_;
// Main window.
NSWindow* window_;
// Buttons.
NSButton* back_button_;
NSButton* forward_button_;
NSButton* reload_button_;
NSButton* stop_button_;
// URL text field.
NSTextField* url_textfield_;
bool window_destroyed_;
bool browser_destroyed_;
DISALLOW_COPY_AND_ASSIGN(RootWindowMac);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_ROOT_WINDOW_MAC_H_

View File

@ -0,0 +1,617 @@
// Copyright (c) 2015 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.
#include "cefclient/root_window_mac.h"
#include "include/base/cef_bind.h"
#include "include/cef_app.h"
#include "include/cef_application_mac.h"
#include "cefclient/browser_window_osr_mac.h"
#include "cefclient/browser_window_std_mac.h"
#include "cefclient/client_switches.h"
#include "cefclient/main_message_loop.h"
#include "cefclient/temp_window_mac.h"
// Receives notifications from controls and the browser window. Will delete
// itself when done.
@interface RootWindowDelegate : NSObject <NSWindowDelegate> {
@private
NSWindow* window_;
client::RootWindowMac* root_window_;
bool force_close_;
}
@property (nonatomic, readonly) client::RootWindowMac* root_window;
@property (nonatomic, readwrite) bool force_close;
- (id)initWithWindow:(NSWindow*)window
andRootWindow:(client::RootWindowMac*)root_window;
- (IBAction)goBack:(id)sender;
- (IBAction)goForward:(id)sender;
- (IBAction)reload:(id)sender;
- (IBAction)stopLoading:(id)sender;
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender;
@end
@implementation RootWindowDelegate
@synthesize root_window = root_window_;
@synthesize force_close = force_close_;
- (id)initWithWindow:(NSWindow*)window
andRootWindow:(client::RootWindowMac*)root_window {
if (self = [super init]) {
window_ = window;
[window_ setDelegate:self];
root_window_ = root_window;
force_close_ = false;
// Register for application hide/unhide notifications.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationDidHide:)
name:NSApplicationDidHideNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationDidUnhide:)
name:NSApplicationDidUnhideNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (IBAction)goBack:(id)sender {
CefRefPtr<CefBrowser> browser = root_window_->GetBrowser();
if (browser.get())
browser->GoBack();
}
- (IBAction)goForward:(id)sender {
CefRefPtr<CefBrowser> browser = root_window_->GetBrowser();
if (browser.get())
browser->GoForward();
}
- (IBAction)reload:(id)sender {
CefRefPtr<CefBrowser> browser = root_window_->GetBrowser();
if (browser.get())
browser->Reload();
}
- (IBAction)stopLoading:(id)sender {
CefRefPtr<CefBrowser> browser = root_window_->GetBrowser();
if (browser.get())
browser->StopLoad();
}
- (IBAction)takeURLStringValueFrom:(NSTextField *)sender {
CefRefPtr<CefBrowser> browser = root_window_->GetBrowser();
if (!browser.get())
return;
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];
std::string urlStr = [url UTF8String];
browser->GetMainFrame()->LoadURL(urlStr);
}
// Called when we are activated (when we gain focus).
- (void)windowDidBecomeKey:(NSNotification*)notification {
client::BrowserWindow* browser_window = root_window_->browser_window();
if (browser_window)
browser_window->SetFocus(true);
}
// Called when we are deactivated (when we lose focus).
- (void)windowDidResignKey:(NSNotification*)notification {
client::BrowserWindow* browser_window = root_window_->browser_window();
if (browser_window)
browser_window->SetFocus(false);
}
// Called when we have been minimized.
- (void)windowDidMiniaturize:(NSNotification *)notification {
client::BrowserWindow* browser_window = root_window_->browser_window();
if (browser_window)
browser_window->Hide();
}
// Called when we have been unminimized.
- (void)windowDidDeminiaturize:(NSNotification *)notification {
client::BrowserWindow* browser_window = root_window_->browser_window();
if (browser_window)
browser_window->Show();
}
// Called when the application has been hidden.
- (void)applicationDidHide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![window_ isMiniaturized]) {
client::BrowserWindow* browser_window = root_window_->browser_window();
if (browser_window)
browser_window->Hide();
}
}
// Called when the application has been unhidden.
- (void)applicationDidUnhide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![window_ isMiniaturized]) {
client::BrowserWindow* browser_window = root_window_->browser_window();
if (browser_window)
browser_window->Show();
}
}
// Called when the window is about to close. Perform the self-destruction
// sequence by getting rid of the window. By returning YES, we allow the window
// to be removed from the screen.
- (BOOL)windowShouldClose:(id)window {
if (!force_close_) {
client::BrowserWindow* browser_window = root_window_->browser_window();
if (browser_window && !browser_window->IsClosing()) {
CefRefPtr<CefBrowser> browser = browser_window->GetBrowser();
if (browser.get()) {
// Notify the browser window that we would like to close it. This
// will result in a call to ClientHandler::DoClose() if the
// JavaScript 'onbeforeunload' event handler allows it.
browser->GetHost()->CloseBrowser(false);
// Cancel the close.
return NO;
}
}
}
// Try to make the window go away.
[window autorelease];
// Clean ourselves up after clearing the stack of anything that might have the
// window on it.
[self performSelectorOnMainThread:@selector(cleanup:)
withObject:window
waitUntilDone:NO];
// Allow the close.
return YES;
}
// Deletes itself.
- (void)cleanup:(id)window {
root_window_->WindowDestroyed();
[self release];
}
@end
namespace client {
namespace {
// Sizes for URL bar layout.
#define BUTTON_HEIGHT 22
#define BUTTON_WIDTH 72
#define BUTTON_MARGIN 8
#define URLBAR_HEIGHT 32
NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
NSButton* button = [[[NSButton alloc] initWithFrame:*rect] autorelease];
[button setTitle:title];
[button setBezelStyle:NSSmallSquareBezelStyle];
[button setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)];
[parent addSubview:button];
rect->origin.x += BUTTON_WIDTH;
return button;
}
NSRect GetScreenRectForWindow(NSWindow* window) {
NSScreen* screen = [window screen];
if (screen == nil)
screen = [NSScreen mainScreen];
return [screen visibleFrame];
}
} // namespace
RootWindowMac::RootWindowMac()
: delegate_(NULL),
with_controls_(false),
with_osr_(false),
is_popup_(false),
initialized_(false),
window_(nil),
back_button_(nil),
forward_button_(nil),
reload_button_(nil),
stop_button_(nil),
url_textfield_(nil),
window_destroyed_(false),
browser_destroyed_(false) {
}
RootWindowMac::~RootWindowMac() {
REQUIRE_MAIN_THREAD();
// The window and browser should already have been destroyed.
DCHECK(window_destroyed_);
DCHECK(browser_destroyed_);
}
void RootWindowMac::Init(RootWindow::Delegate* delegate,
bool with_controls,
bool with_osr,
const CefRect& bounds,
const CefBrowserSettings& settings,
const std::string& url) {
DCHECK(delegate);
DCHECK(!initialized_);
delegate_ = delegate;
with_controls_ = with_controls;
with_osr_ = with_osr;
start_rect_ = bounds;
CreateBrowserWindow(url);
initialized_ = true;
// Create the native root window on the main thread.
if (CURRENTLY_ON_MAIN_THREAD()) {
CreateRootWindow(settings);
} else {
MAIN_POST_CLOSURE(
base::Bind(&RootWindowMac::CreateRootWindow, this, settings));
}
}
void RootWindowMac::InitAsPopup(RootWindow::Delegate* delegate,
bool with_controls,
bool with_osr,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) {
DCHECK(delegate);
DCHECK(!initialized_);
delegate_ = delegate;
with_controls_ = with_controls;
with_osr_ = with_osr;
is_popup_ = true;
if (popupFeatures.xSet)
start_rect_.x = popupFeatures.x;
if (popupFeatures.ySet)
start_rect_.y = popupFeatures.y;
if (popupFeatures.widthSet)
start_rect_.width = popupFeatures.width;
if (popupFeatures.heightSet)
start_rect_.height = popupFeatures.height;
CreateBrowserWindow(std::string());
initialized_ = true;
// The new popup is initially parented to a temporary window. The native root
// window will be created after the browser is created and the popup window
// will be re-parented to it at that time.
browser_window_->GetPopupConfig(TempWindowMac::GetWindowHandle(),
windowInfo, client, settings);
}
void RootWindowMac::Show(ShowMode mode) {
REQUIRE_MAIN_THREAD();
if (!window_)
return;
const bool is_visible = [window_ isVisible];
const bool is_minimized = [window_ isMiniaturized];
const bool is_maximized = [window_ isZoomed];
if ((mode == ShowMinimized && is_minimized) ||
(mode == ShowMaximized && is_maximized) ||
(mode == ShowNormal && is_visible)) {
// The window is already in the desired state.
return;
}
// Undo the previous state since it's not the desired state.
if (is_minimized)
[window_ deminiaturize:nil];
else if (is_maximized)
[window_ performZoom:nil];
// Window visibility may change after (for example) deminiaturizing the
// window.
if (![window_ isVisible])
[window_ makeKeyAndOrderFront: nil];
if (mode == ShowMinimized)
[window_ performMiniaturize:nil];
else if (mode == ShowMaximized)
[window_ performZoom:nil];
}
void RootWindowMac::Hide() {
REQUIRE_MAIN_THREAD();
if (!window_)
return;
// Undo miniaturization, if any, so the window will actually be hidden.
if ([window_ isMiniaturized])
[window_ deminiaturize:nil];
// Hide the window.
[window_ orderOut:nil];
}
void RootWindowMac::SetBounds(int x, int y, size_t width, size_t height) {
REQUIRE_MAIN_THREAD();
if (!window_)
return;
NSRect screen_rect = GetScreenRectForWindow(window_);
// Desired content rectangle.
NSRect content_rect;
content_rect.size.width = static_cast<int>(width);
content_rect.size.height = static_cast<int>(height) +
(with_controls_ ? URLBAR_HEIGHT : 0);
// Convert to a frame rectangle.
NSRect frame_rect = [window_ frameRectForContentRect:content_rect];
frame_rect.origin.x = x;
frame_rect.origin.y = screen_rect.size.height - y;
[window_ setFrame:frame_rect display:YES];
}
void RootWindowMac::Close(bool force) {
REQUIRE_MAIN_THREAD();
if (window_) {
static_cast<RootWindowDelegate*>([window_ delegate]).force_close = force;
[window_ performClose:nil];
}
}
CefRefPtr<CefBrowser> RootWindowMac::GetBrowser() const {
REQUIRE_MAIN_THREAD();
if (browser_window_)
return browser_window_->GetBrowser();
return NULL;
}
ClientWindowHandle RootWindowMac::GetWindowHandle() const {
REQUIRE_MAIN_THREAD();
return [window_ contentView];
}
void RootWindowMac::WindowDestroyed() {
window_ = nil;
window_destroyed_ = true;
NotifyDestroyedIfDone();
}
void RootWindowMac::CreateBrowserWindow(const std::string& startup_url) {
if (with_osr_) {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const bool transparent =
command_line->HasSwitch(switches::kTransparentPaintingEnabled);
const bool show_update_rect =
command_line->HasSwitch(switches::kShowUpdateRect);
browser_window_.reset(new BrowserWindowOsrMac(this, startup_url,
transparent,
show_update_rect));
} else {
browser_window_.reset(new BrowserWindowStdMac(this, startup_url));
}
}
void RootWindowMac::CreateRootWindow(const CefBrowserSettings& settings) {
REQUIRE_MAIN_THREAD();
DCHECK(!window_);
// TODO(port): If no x,y position is specified the window will always appear
// in the upper-left corner. Maybe there's a better default place to put it?
int x = start_rect_.x;
int y = start_rect_.y;
int width, height;
if (start_rect_.IsEmpty()) {
// TODO(port): Also, maybe there's a better way to choose the default size.
width = 800;
height = 600;
} else {
width = start_rect_.width;
height = start_rect_.height;
}
// Create the main window.
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
NSRect window_rect =
NSMakeRect(x, screen_rect.size.height - y, width, height);
window_ = [[UnderlayOpenGLHostingWindow alloc]
initWithContentRect:window_rect
styleMask:(NSTitledWindowMask |
NSClosableWindowMask |
NSMiniaturizableWindowMask |
NSResizableWindowMask )
backing:NSBackingStoreBuffered
defer:NO];
[window_ setTitle:@"cefclient"];
// Create the delegate for control and browser window events.
RootWindowDelegate* delegate =
[[RootWindowDelegate alloc] initWithWindow:window_ andRootWindow:this];
// Rely on the window delegate to clean us up rather than immediately
// releasing when the window gets closed. We use the delegate to do
// everything from the autorelease pool so the window isn't on the stack
// during cleanup (ie, a window close from javascript).
[window_ setReleasedWhenClosed:NO];
NSView* contentView = [window_ contentView];
NSRect contentBounds = [contentView bounds];
if (with_controls_) {
// Create the buttons.
NSRect button_rect = contentBounds;
button_rect.origin.y = window_rect.size.height - URLBAR_HEIGHT +
(URLBAR_HEIGHT - BUTTON_HEIGHT) / 2;
button_rect.size.height = BUTTON_HEIGHT;
button_rect.origin.x += BUTTON_MARGIN;
button_rect.size.width = BUTTON_WIDTH;
contentBounds.size.height -= URLBAR_HEIGHT;
back_button_ = MakeButton(&button_rect, @"Back", contentView);
[back_button_ setTarget:delegate];
[back_button_ setAction:@selector(goBack:)];
[back_button_ setEnabled:NO];
forward_button_ = MakeButton(&button_rect, @"Forward", contentView);
[forward_button_ setTarget:delegate];
[forward_button_ setAction:@selector(goForward:)];
[forward_button_ setEnabled:NO];
reload_button_ = MakeButton(&button_rect, @"Reload", contentView);
[reload_button_ setTarget:delegate];
[reload_button_ setAction:@selector(reload:)];
[reload_button_ setEnabled:NO];
stop_button_ = MakeButton(&button_rect, @"Stop", contentView);
[stop_button_ setTarget:delegate];
[stop_button_ setAction:@selector(stopLoading:)];
[stop_button_ setEnabled:NO];
// Create the URL text field.
button_rect.origin.x += BUTTON_MARGIN;
button_rect.size.width = [contentView bounds].size.width -
button_rect.origin.x - BUTTON_MARGIN;
url_textfield_ = [[NSTextField alloc] initWithFrame:button_rect];
[contentView addSubview:url_textfield_];
[url_textfield_ setAutoresizingMask:
(NSViewWidthSizable | NSViewMinYMargin)];
[url_textfield_ setTarget:delegate];
[url_textfield_ setAction:@selector(takeURLStringValueFrom:)];
[url_textfield_ setEnabled:NO];
[[url_textfield_ cell] setWraps:NO];
[[url_textfield_ cell] setScrollable:YES];
}
if (!is_popup_) {
// Create the browser window.
browser_window_->CreateBrowser(contentView, CefRect(0, 0, width, height),
settings);
} else {
// With popups we already have a browser window. Parent the browser window
// to the root window and show it in the correct location.
browser_window_->ShowPopup(contentView, 0, 0, contentBounds.size.width,
contentBounds.size.height);
}
// Show the window.
Show(ShowNormal);
// Size the window.
SetBounds(x, y, width, height);
}
void RootWindowMac::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
REQUIRE_MAIN_THREAD();
// For popup browsers create the root window once the browser has been
// created.
if (is_popup_)
CreateRootWindow(CefBrowserSettings());
}
void RootWindowMac::OnBrowserWindowDestroyed() {
REQUIRE_MAIN_THREAD();
browser_window_.reset();
if (!window_destroyed_) {
// The browser was destroyed first. This could be due to the use of
// off-screen rendering or execution of JavaScript window.close().
// Close the RootWindow.
Close(true);
}
browser_destroyed_ = true;
NotifyDestroyedIfDone();
}
void RootWindowMac::OnSetAddress(const std::string& url) {
REQUIRE_MAIN_THREAD();
if (url_textfield_) {
std::string urlStr(url);
NSString* str = [NSString stringWithUTF8String:urlStr.c_str()];
[url_textfield_ setStringValue:str];
}
}
void RootWindowMac::OnSetTitle(const std::string& title) {
REQUIRE_MAIN_THREAD();
if (window_) {
std::string titleStr(title);
NSString* str = [NSString stringWithUTF8String:titleStr.c_str()];
[window_ setTitle:str];
}
}
void RootWindowMac::OnSetLoadingState(bool isLoading,
bool canGoBack,
bool canGoForward) {
REQUIRE_MAIN_THREAD();
if (with_controls_) {
[url_textfield_ setEnabled:YES];
[reload_button_ setEnabled:!isLoading];
[stop_button_ setEnabled:isLoading];
[back_button_ setEnabled:canGoBack];
[forward_button_ setEnabled:canGoForward];
}
}
void RootWindowMac::NotifyDestroyedIfDone() {
// Notify once both the window and the browser have been destroyed.
if (window_destroyed_ && browser_destroyed_)
delegate_->OnRootWindowDestroyed(this);
}
// static
scoped_refptr<RootWindow> RootWindow::Create() {
return new RootWindowMac();
}
// static
scoped_refptr<RootWindow> RootWindow::GetForNSWindow(NSWindow* window) {
RootWindowDelegate* delegate =
static_cast<RootWindowDelegate*>([window delegate]);
return [delegate root_window];
}
} // namespace client

View File

@ -15,6 +15,8 @@
#include "cefclient/temp_window_win.h"
#elif defined(OS_LINUX)
#include "cefclient/temp_window_x11.h"
#elif defined(OS_MACOSX)
#include "cefclient/temp_window_mac.h"
#endif
namespace client {
@ -83,6 +85,8 @@ class RootWindowManager : public RootWindow::Delegate {
TempWindowWin temp_window_win_;
#elif defined(OS_LINUX)
TempWindowX11 temp_window_x11_;
#elif defined(OS_MACOSX)
TempWindowMac temp_window_mac_;
#endif
DISALLOW_COPY_AND_ASSIGN(RootWindowManager);

View File

@ -512,7 +512,7 @@ void RootWindowWin::OnPaint() {
void RootWindowWin::OnFocus() {
if (browser_window_)
browser_window_->SetFocus();
browser_window_->SetFocus(true);
}
void RootWindowWin::OnSize(bool minimized) {
@ -703,8 +703,8 @@ void RootWindowWin::OnBrowserWindowDestroyed() {
if (!window_destroyed_) {
// The browser was destroyed first. This could be due to the use of
// off-screen rendering or execution of JavaScript window.close().
// Close the RootWindow asynchronously.
Close(false);
// Close the RootWindow.
Close(true);
}
browser_destroyed_ = true;

View File

@ -0,0 +1,33 @@
// Copyright (c) 2015 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.
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_MAC_H_
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_MAC_H_
#include "cefclient/client_types.h"
namespace client {
// Represents a singleton hidden window that acts at temporary parent for
// popup browsers.
class TempWindowMac {
public:
// Returns the singleton window handle.
static CefWindowHandle GetWindowHandle();
private:
// A single instance will be created/owned by RootWindowManager.
friend class RootWindowManager;
TempWindowMac();
~TempWindowMac();
NSWindow* window_;
DISALLOW_COPY_AND_ASSIGN(TempWindowMac);
};
} // namespace client
#endif // CEF_TESTS_CEFCLIENT_TEMP_WINDOW_MAC_H_

View File

@ -0,0 +1,46 @@
// Copyright (c) 2015 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.
#include "cefclient/temp_window_mac.h"
#include <Cocoa/Cocoa.h>
#include "include/base/cef_logging.h"
#include "include/cef_app.h"
namespace client {
namespace {
TempWindowMac* g_temp_window = NULL;
} // namespace
TempWindowMac::TempWindowMac()
: window_(nil) {
DCHECK(!g_temp_window);
g_temp_window = this;
// Create a borderless non-visible 1x1 window.
window_ = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1)
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
CHECK(window_);
}
TempWindowMac::~TempWindowMac() {
g_temp_window = NULL;
DCHECK(window_);
[window_ close];
}
// static
CefWindowHandle TempWindowMac::GetWindowHandle() {
DCHECK(g_temp_window);
return [g_temp_window->window_ contentView];
}
} // namespace client

View File

@ -5,7 +5,7 @@
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_WIN_H_
#include "cefclient/main_message_loop.h"
#include "include/cef_base.h"
namespace client {

View File

@ -5,7 +5,7 @@
#ifndef CEF_TESTS_CEFCLIENT_TEMP_WINDOW_X11_H_
#define CEF_TESTS_CEFCLIENT_TEMP_WINDOW_X11_H_
#include "cefclient/main_message_loop.h"
#include "include/cef_base.h"
namespace client {