-
Notifications
You must be signed in to change notification settings - Fork 68
/
main_mac.mm
172 lines (143 loc) · 6.25 KB
/
main_mac.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright (c) 2017 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "examples/shared/main.h"
#import <Cocoa/Cocoa.h>
#include "include/cef_application_mac.h"
#include "include/wrapper/cef_helpers.h"
#import "include/wrapper/cef_library_loader.h"
#include "examples/shared/app_factory.h"
#include "examples/shared/client_manager.h"
#include "examples/shared/main_util.h"
// Receives notifications from the application.
@interface SharedAppDelegate : NSObject <NSApplicationDelegate>
- (void)createApplication:(id)object;
- (void)tryToTerminateApplication:(NSApplication*)app;
@end
// Provide the CefAppProtocol implementation required by CEF.
@interface SharedApplication : NSApplication <CefAppProtocol> {
@private
BOOL handlingSendEvent_;
}
@end
@implementation SharedApplication
- (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 {
SharedAppDelegate* delegate =
static_cast<SharedAppDelegate*>([NSApp delegate]);
[delegate tryToTerminateApplication:self];
// Return, don't exit. The application is responsible for exiting on its own.
}
@end
@implementation SharedAppDelegate
// 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 {
shared::ClientManager* manager = shared::ClientManager::GetInstance();
if (manager && !manager->IsClosing())
manager->CloseAllBrowsers(false);
}
- (NSApplicationTerminateReply)applicationShouldTerminate:
(NSApplication*)sender {
return NSTerminateNow;
}
@end
namespace shared {
// 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;
// Scoped AutoRelease pool.
@autoreleasepool {
// Provide CEF with command-line arguments.
CefMainArgs main_args(argc, argv);
// Create a temporary CommandLine object.
CefRefPtr<CefCommandLine> command_line = CreateCommandLine(main_args);
// Create a CefApp for the browser process. Other processes are handled by
// process_helper_mac.cc.
CefRefPtr<CefApp> app = CreateBrowserProcessApp();
// Initialize the SharedApplication instance.
[SharedApplication sharedApplication];
// Create the singleton manager instance.
ClientManager manager;
// Specify CEF global settings here.
CefSettings settings;
// Initialize the CEF browser process. The first browser instance will be
// created in CefBrowserProcessHandler::OnContextInitialized() after CEF has
// been initialized. May return false if initialization fails or if early
// exit is desired (for example, due to process singleton relaunch
// behavior).
if (!CefInitialize(main_args, settings, app, nullptr)) {
return 1;
}
// Create the application delegate.
NSObject* delegate = [[SharedAppDelegate 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();
}
return 0;
}
} // namespace shared