Files
atom/native/atom_window_controller.mm
Adam Roben a3c48df25b Move all code and resources into Atom.framework
All our native code now gets built into Atom.framework. Atom.app and
Atom Helper.app both link against this framework. All resources other
than a couple of main-bundle-only ones (e.g., atom.icns) go into
Atom.framework.

Note that this means that there's no compile- or link-time separation
between main process code and helper process code. We could introduce a
compile-time separation by building main process and helper process code
into separate static libraries with mutually exclusive include paths, if
we want.

Atom.framework exports a single symbol: AtomMain(). Atom.app and Atom
Helper.app contain a single source file: main.cpp. main() just calls
AtomMain().

All frameworks are placed in Atom.app/Contents/Frameworks. We now link
against all frameworks using @rpath-based install names, which allows
Atom.app and Atom Helper.app to find them automatically based on their
own LD_RUNPATH_SEARCH_PATH settings. We use install_name_tool at build
time on each of our three binaries (Atom.app, Atom Helper.app,
Atom.framework) to set the install names.

By reducing duplication of code and resources between Atom.app and Atom
Helper.app (and the EH/NP copies of Atom Helper.app), this reduces the
size of the total installed Atom.app bundle from 145MB to 82MB. By
compiling .coffee and .cson files only once, clean build time drops from
114 seconds to 79 seconds on my MacBook Pro.
2013-03-01 16:35:42 -05:00

256 lines
9.0 KiB
Plaintext

#import "include/cef_application_mac.h"
#import "include/cef_client.h"
#import "native/atom_cef_client.h"
#import "native/atom_window_controller.h"
#import "native/atom_application.h"
#import <signal.h>
@implementation AtomWindowController
@synthesize splitView=_splitView;
@synthesize webView=_webView;
@synthesize devToolsView=_devToolsView;
@synthesize pathToOpen=_pathToOpen;
- (void)dealloc {
[_splitView release];
[_devToolsView release];
[_webView release];
[_bootstrapScript release];
[_resourcePath release];
[_pathToOpen release];
_cefClient = NULL;
_cefDevToolsClient = NULL;
[super dealloc];
}
- (id)initWithBootstrapScript:(NSString *)bootstrapScript background:(BOOL)background alwaysUseBundleResourcePath:(BOOL)alwaysUseBundleResourcePath {
self = [super initWithWindowNibName:@"AtomWindow"];
_bootstrapScript = [bootstrapScript retain];
AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication];
_resourcePath = [atomApplication.arguments objectForKey:@"resource-path"];
if (!alwaysUseBundleResourcePath && !_resourcePath) {
NSString *defaultRepositoryPath = @"~/github/atom";
defaultRepositoryPath = [defaultRepositoryPath stringByStandardizingPath];
if ([defaultRepositoryPath characterAtIndex:0] == '/') {
BOOL isDir = false;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:defaultRepositoryPath isDirectory:&isDir];
if (isDir && exists)
_resourcePath = defaultRepositoryPath;
}
}
if (alwaysUseBundleResourcePath || !_resourcePath) {
_resourcePath = [[NSBundle bundleForClass:self.class] resourcePath];
}
[_resourcePath retain];
if (!background) {
[self setShouldCascadeWindows:NO];
[self setWindowFrameAutosaveName:@"AtomWindow"];
NSColor *background = [NSColor colorWithDeviceRed:(51.0/255.0) green:(51.0/255.0f) blue:(51.0/255.0f) alpha:1.0];
[self.window setBackgroundColor:background];
[self showWindow:self];
}
return self;
}
- (id)initWithPath:(NSString *)path {
_pathToOpen = [path retain];
AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication];
BOOL useBundleResourcePath = [atomApplication.arguments objectForKey:@"dev"] == nil;
return [self initWithBootstrapScript:@"window-bootstrap" background:NO alwaysUseBundleResourcePath:useBundleResourcePath];
}
- (id)initDevWithPath:(NSString *)path {
_pathToOpen = [path retain];
AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication];
return [self initWithBootstrapScript:@"window-bootstrap" background:NO alwaysUseBundleResourcePath:false];
}
- (id)initInBackground {
AtomApplication *atomApplication = (AtomApplication *)[AtomApplication sharedApplication];
BOOL useBundleResourcePath = [atomApplication.arguments objectForKey:@"dev"] == nil;
[self initWithBootstrapScript:@"window-bootstrap" background:YES alwaysUseBundleResourcePath:useBundleResourcePath];
[self.window setFrame:NSMakeRect(0, 0, 0, 0) display:NO];
[self.window setExcludedFromWindowsMenu:YES];
[self.window setCollectionBehavior:NSWindowCollectionBehaviorStationary];
return self;
}
- (id)initSpecsThenExit:(BOOL)exitWhenDone {
_runningSpecs = true;
_exitWhenDone = exitWhenDone;
return [self initWithBootstrapScript:@"spec-bootstrap" background:NO alwaysUseBundleResourcePath:NO];
}
- (id)initBenchmarksThenExit:(BOOL)exitWhenDone {
_runningSpecs = true;
_exitWhenDone = exitWhenDone;
return [self initWithBootstrapScript:@"benchmark-bootstrap" background:NO alwaysUseBundleResourcePath:NO];
}
- (void)addBrowserToView:(NSView *)view url:(const char *)url cefHandler:(CefRefPtr<AtomCefClient>)cefClient {
CefBrowserSettings settings;
[self populateBrowserSettings:settings];
CefWindowInfo window_info;
window_info.SetAsChild(view, 0, 0, view.bounds.size.width, view.bounds.size.height);
CefBrowserHost::CreateBrowser(window_info, cefClient.get(), url, settings);
}
- (NSString *)encodeUrlParam:(NSString *)param {
param = [param stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
param = [param stringByReplacingOccurrencesOfString:@"&" withString:@"%26"];
return param;
}
- (void)windowDidLoad {
[self.window setDelegate:self];
[self performSelector:@selector(attachWebView) withObject:nil afterDelay:0];
}
// If this is run directly in windowDidLoad, the web view doesn't
// have the correct initial size based on the frame's last stored size.
// HACK: I hate this and want to place this code directly in windowDidLoad
- (void)attachWebView {
NSURL *url = [[NSBundle bundleForClass:self.class] resourceURL];
NSMutableString *urlString = [NSMutableString string];
[urlString appendString:[[url URLByAppendingPathComponent:@"static/index.html"] absoluteString]];
[urlString appendFormat:@"?bootstrapScript=%@", [self encodeUrlParam:_bootstrapScript]];
[urlString appendFormat:@"&resourcePath=%@", [self encodeUrlParam:_resourcePath]];
if (_exitWhenDone)
[urlString appendString:@"&exitWhenDone=1"];
if (_pathToOpen)
[urlString appendFormat:@"&pathToOpen=%@", [self encodeUrlParam:_pathToOpen]];
_cefClient = new AtomCefClient();
[self.webView setHidden:YES];
[self addBrowserToView:self.webView url:[urlString UTF8String] cefHandler:_cefClient];
}
- (void)toggleDevTools {
if (_devToolsView) {
[self hideDevTools];
}
else {
[self showDevTools];
}
}
- (void)showDevTools {
if (_devToolsView) return;
if (_cefClient && _cefClient->GetBrowser()) {
NSRect webViewFrame = _webView.frame;
NSRect devToolsViewFrame = _webView.frame;
devToolsViewFrame.size.height = NSHeight(webViewFrame) / 3;
webViewFrame.size.height = NSHeight(webViewFrame) - NSHeight(devToolsViewFrame);
[_webView setFrame:webViewFrame];
_devToolsView = [[NSView alloc] initWithFrame:devToolsViewFrame];
[_splitView addSubview:_devToolsView];
[_splitView adjustSubviews];
_cefDevToolsClient = new AtomCefClient(true, true);
std::string devtools_url = _cefClient->GetBrowser()->GetHost()->GetDevToolsURL(true);
[self addBrowserToView:_devToolsView url:devtools_url.c_str() cefHandler:_cefDevToolsClient];
}
}
- (void)hideDevTools {
[_devToolsView removeFromSuperview];
[_splitView adjustSubviews];
[_devToolsView release];
_devToolsView = nil;
_cefDevToolsClient = NULL;
_cefClient->GetBrowser()->GetHost()->SetFocus(true);
}
- (void)setPidToKillOnClose:(NSNumber *)pid {
_pidToKillOnClose = [pid retain];
}
# pragma mark NSWindowDelegate
- (void)windowDidResignMain:(NSNotification *)notification {
if (!_runningSpecs) {
[self.window makeFirstResponder:nil];
}
}
- (void)windowDidBecomeMain:(NSNotification *)notification {
if (_cefClient && _cefClient->GetBrowser()) {
_cefClient->GetBrowser()->GetHost()->SetFocus(true);
}
}
- (BOOL)windowShouldClose:(NSNotification *)notification {
if (_cefClient && _cefClient->GetBrowser()) {
_cefClient->GetBrowser()->SendProcessMessage(PID_RENDERER, CefProcessMessage::Create("shutdown"));
}
if (_pidToKillOnClose) kill([_pidToKillOnClose intValue], SIGQUIT);
[self autorelease];
return YES;
}
- (void)populateBrowserSettings:(CefBrowserSettings &)settings {
CefString(&settings.default_encoding) = "UTF-8";
settings.remote_fonts_disabled = false;
settings.encoding_detector_enabled = false;
settings.javascript_disabled = false;
settings.javascript_open_windows_disallowed = false;
settings.javascript_close_windows_disallowed = false;
settings.javascript_access_clipboard_disallowed = false;
settings.dom_paste_disabled = true;
settings.caret_browsing_enabled = false;
settings.java_disabled = true;
settings.plugins_disabled = true;
settings.universal_access_from_file_urls_allowed = false;
settings.file_access_from_file_urls_allowed = false;
settings.web_security_disabled = true;
settings.xss_auditor_enabled = true;
settings.image_load_disabled = false;
settings.shrink_standalone_images_to_fit = false;
settings.site_specific_quirks_disabled = false;
settings.text_area_resize_disabled = false;
settings.page_cache_disabled = true;
settings.tab_to_links_disabled = true;
settings.hyperlink_auditing_disabled = true;
settings.user_style_sheet_enabled = false;
settings.author_and_user_styles_disabled = false;
settings.local_storage_disabled = false;
settings.databases_disabled = false;
settings.application_cache_disabled = false;
settings.webgl_disabled = false;
settings.accelerated_compositing_disabled = false;
settings.accelerated_layers_disabled = false;
settings.accelerated_video_disabled = false;
settings.accelerated_2d_canvas_disabled = false;
// settings.accelerated_painting_enabled = true;
// settings.accelerated_filters_enabled = true;
settings.accelerated_plugins_disabled = false;
settings.developer_tools_disabled = false;
// settings.fullscreen_enabled = true;
}
@end
@interface GraySplitView : NSSplitView
- (NSColor*)dividerColor;
@end
@implementation GraySplitView
- (NSColor*)dividerColor {
return [NSColor darkGrayColor];
}
@end