mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2024-12-26 17:42:35 +01:00
019611c764
Under ARC (Automatic Reference Counting), assigning to an Objective-C pointer has different semantics than assigning to a void* pointer. This makes it dangerous to treat the same memory address as an Objective-C pointer in some cases and as a "regular C pointer" in other cases. This change removes the conditional type defines and instead uses void* everywhere. Explicit type casting in combination with ARC annotations makes it safe to get typed Objective-C pointers from the void* pointers. This change enables ARC by default in the CEF binary distribution CMake configuration for the cefclient and cefsimple sample applications. It can be disabled by adding `-DOPTION_USE_ARC=Off` to the CMake command line. ARC is not supported when building Chromium due to the substantial number of changes that would be required in the Chromium code base.
166 lines
6.1 KiB
Plaintext
166 lines
6.1 KiB
Plaintext
// Copyright (c) 2013 The Chromium Embedded Framework Authors.
|
|
// Portions copyright (c) 2010 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
#include "include/cef_application_mac.h"
|
|
#include "include/wrapper/cef_helpers.h"
|
|
#include "include/wrapper/cef_library_loader.h"
|
|
#include "tests/cefsimple/simple_app.h"
|
|
#include "tests/cefsimple/simple_handler.h"
|
|
|
|
// Receives notifications from the application.
|
|
@interface SimpleAppDelegate : NSObject <NSApplicationDelegate>
|
|
- (void)createApplication:(id)object;
|
|
- (void)tryToTerminateApplication:(NSApplication*)app;
|
|
@end
|
|
|
|
// Provide the CefAppProtocol implementation required by CEF.
|
|
@interface SimpleApplication : NSApplication <CefAppProtocol> {
|
|
@private
|
|
BOOL handlingSendEvent_;
|
|
}
|
|
@end
|
|
|
|
@implementation SimpleApplication
|
|
- (BOOL)isHandlingSendEvent {
|
|
return handlingSendEvent_;
|
|
}
|
|
|
|
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
|
|
handlingSendEvent_ = handlingSendEvent;
|
|
}
|
|
|
|
- (void)sendEvent:(NSEvent*)event {
|
|
CefScopedSendingEvent sendingEventScoper;
|
|
[super sendEvent:event];
|
|
}
|
|
|
|
// |-terminate:| is the entry point for orderly "quit" operations in Cocoa. This
|
|
// includes the application menu's quit menu item and keyboard equivalent, the
|
|
// application's dock icon menu's quit menu item, "quit" (not "force quit") in
|
|
// the Activity Monitor, and quits triggered by user logout and system restart
|
|
// and shutdown.
|
|
//
|
|
// The default |-terminate:| implementation ends the process by calling exit(),
|
|
// and thus never leaves the main run loop. This is unsuitable for Chromium
|
|
// since Chromium depends on leaving the main run loop to perform an orderly
|
|
// shutdown. We support the normal |-terminate:| interface by overriding the
|
|
// default implementation. Our implementation, which is very specific to the
|
|
// needs of Chromium, works by asking the application delegate to terminate
|
|
// using its |-tryToTerminateApplication:| method.
|
|
//
|
|
// |-tryToTerminateApplication:| differs from the standard
|
|
// |-applicationShouldTerminate:| in that no special event loop is run in the
|
|
// case that immediate termination is not possible (e.g., if dialog boxes
|
|
// allowing the user to cancel have to be shown). Instead, this method tries to
|
|
// close all browsers by calling CloseBrowser(false) via
|
|
// ClientHandler::CloseAllBrowsers. Calling CloseBrowser will result in a call
|
|
// to ClientHandler::DoClose and execution of |-performClose:| on the NSWindow.
|
|
// DoClose sets a flag that is used to differentiate between new close events
|
|
// (e.g., user clicked the window close button) and in-progress close events
|
|
// (e.g., user approved the close window dialog). The NSWindowDelegate
|
|
// |-windowShouldClose:| method checks this flag and either calls
|
|
// CloseBrowser(false) in the case of a new close event or destructs the
|
|
// NSWindow in the case of an in-progress close event.
|
|
// ClientHandler::OnBeforeClose will be called after the CEF NSView hosted in
|
|
// the NSWindow is dealloc'ed.
|
|
//
|
|
// After the final browser window has closed ClientHandler::OnBeforeClose will
|
|
// begin actual tear-down of the application by calling CefQuitMessageLoop.
|
|
// This ends the NSApplication event loop and execution then returns to the
|
|
// main() function for cleanup before application termination.
|
|
//
|
|
// The standard |-applicationShouldTerminate:| is not supported, and code paths
|
|
// leading to it must be redirected.
|
|
- (void)terminate:(id)sender {
|
|
SimpleAppDelegate* delegate =
|
|
static_cast<SimpleAppDelegate*>([NSApp delegate]);
|
|
[delegate tryToTerminateApplication:self];
|
|
// Return, don't exit. The application is responsible for exiting on its own.
|
|
}
|
|
@end
|
|
|
|
@implementation SimpleAppDelegate
|
|
|
|
// Create the application on the UI thread.
|
|
- (void)createApplication:(id)object {
|
|
[NSApplication sharedApplication];
|
|
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
|
|
owner:NSApp
|
|
topLevelObjects:nil];
|
|
|
|
// Set the delegate for application events.
|
|
[[NSApplication sharedApplication] setDelegate:self];
|
|
}
|
|
|
|
- (void)tryToTerminateApplication:(NSApplication*)app {
|
|
SimpleHandler* handler = SimpleHandler::GetInstance();
|
|
if (handler && !handler->IsClosing())
|
|
handler->CloseAllBrowsers(false);
|
|
}
|
|
|
|
- (NSApplicationTerminateReply)applicationShouldTerminate:
|
|
(NSApplication*)sender {
|
|
return NSTerminateNow;
|
|
}
|
|
@end
|
|
|
|
// Entry point function for the browser process.
|
|
int main(int argc, char* argv[]) {
|
|
// Load the CEF framework library at runtime instead of linking directly
|
|
// as required by the macOS sandbox implementation.
|
|
CefScopedLibraryLoader library_loader;
|
|
if (!library_loader.LoadInMain())
|
|
return 1;
|
|
|
|
// Provide CEF with command-line arguments.
|
|
CefMainArgs main_args(argc, argv);
|
|
|
|
@autoreleasepool {
|
|
// Initialize the SimpleApplication instance.
|
|
[SimpleApplication sharedApplication];
|
|
|
|
// Specify CEF global settings here.
|
|
CefSettings settings;
|
|
|
|
// When generating projects with CMake the CEF_USE_SANDBOX value will be
|
|
// defined automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line
|
|
// to disable use of the sandbox.
|
|
#if !defined(CEF_USE_SANDBOX)
|
|
settings.no_sandbox = true;
|
|
#endif
|
|
|
|
// SimpleApp implements application-level callbacks for the browser process.
|
|
// It will create the first browser instance in OnContextInitialized() after
|
|
// CEF has initialized.
|
|
CefRefPtr<SimpleApp> app(new SimpleApp);
|
|
|
|
// Initialize CEF for the browser process.
|
|
CefInitialize(main_args, settings, app.get(), NULL);
|
|
|
|
// Create the application delegate.
|
|
NSObject* delegate = [[SimpleAppDelegate alloc] init];
|
|
[delegate performSelectorOnMainThread:@selector(createApplication:)
|
|
withObject:nil
|
|
waitUntilDone:NO];
|
|
|
|
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
|
|
// called.
|
|
CefRunMessageLoop();
|
|
|
|
// Shut down CEF.
|
|
CefShutdown();
|
|
|
|
// Release the delegate.
|
|
#if !__has_feature(objc_arc)
|
|
[delegate release];
|
|
#endif // !__has_feature(objc_arc)
|
|
delegate = nil;
|
|
} // @autoreleasepool
|
|
|
|
return 0;
|
|
}
|