mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Quit message loop when last browser is closed
Previously CefShutdown() was called after closing the windows which would prevent them from running their beforeunload callbacks and saving state properly when cmd-Q the application. Now the number of open browsers is tracked and the message loop is quit and the windows are autoreleased only after the browser is ready to be closed. Closes #493
This commit is contained in:
@@ -265,11 +265,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)notification {
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:
|
||||
(NSApplication *)sender {
|
||||
for (NSWindow *window in [self windows]) {
|
||||
[window performClose:self];
|
||||
}
|
||||
CefShutdown();
|
||||
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
# pragma mark CefAppProtocol
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include "include/cef_app.h"
|
||||
#include "include/cef_path_util.h"
|
||||
#include "include/cef_process_util.h"
|
||||
#include "include/cef_task.h"
|
||||
@@ -14,7 +15,9 @@
|
||||
#define REQUIRE_IO_THREAD() assert(CefCurrentlyOn(TID_IO));
|
||||
#define REQUIRE_FILE_THREAD() assert(CefCurrentlyOn(TID_FILE));
|
||||
|
||||
AtomCefClient::AtomCefClient(){
|
||||
static int numberOfOpenBrowsers = 0;
|
||||
|
||||
AtomCefClient::AtomCefClient() {
|
||||
}
|
||||
|
||||
AtomCefClient::AtomCefClient(bool handlePasteboardCommands, bool ignoreTitleChanges) {
|
||||
@@ -167,17 +170,22 @@ bool AtomCefClient::OnKeyEvent(CefRefPtr<CefBrowser> browser,
|
||||
void AtomCefClient::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
// REQUIRE_UI_THREAD(); // When uncommented this fails when app is terminated
|
||||
m_Browser = NULL;
|
||||
numberOfOpenBrowsers--;
|
||||
if (numberOfOpenBrowsers == 0) {
|
||||
CefQuitMessageLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void AtomCefClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
AutoLock lock_scope(this);
|
||||
if (!m_Browser.get()) {
|
||||
if (!m_Browser.get()) {
|
||||
m_Browser = browser;
|
||||
}
|
||||
|
||||
GetBrowser()->GetHost()->SetFocus(true);
|
||||
numberOfOpenBrowsers++;
|
||||
}
|
||||
|
||||
void AtomCefClient::OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
|
||||
@@ -86,6 +86,7 @@ class AtomCefClient : public CefClient,
|
||||
// CefLifeSpanHandler methods
|
||||
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||
|
||||
|
||||
// CefLoadHandler methods
|
||||
@@ -100,11 +101,13 @@ class AtomCefClient : public CefClient,
|
||||
|
||||
bool Save(const std::string& path, const std::string& data);
|
||||
void RestartRendererProcess(CefRefPtr<CefBrowser> browser);
|
||||
bool IsClosed() { return m_IsClosed; };
|
||||
|
||||
protected:
|
||||
CefRefPtr<CefBrowser> m_Browser;
|
||||
bool m_HandlePasteboardCommands = false;
|
||||
bool m_IgnoreTitleChanges = false;
|
||||
bool m_IsClosed = false;
|
||||
|
||||
void FocusNextWindow();
|
||||
void FocusPreviousWindow();
|
||||
|
||||
@@ -156,7 +156,7 @@ void AtomCefClient::Exit(int status) {
|
||||
}
|
||||
|
||||
void AtomCefClient::Log(const char *message) {
|
||||
std::cout << message << "\n";
|
||||
NSLog(@"%s", message);
|
||||
}
|
||||
|
||||
void AtomCefClient::GetVersion(int replyId, CefRefPtr<CefBrowser> browser) {
|
||||
@@ -169,3 +169,10 @@ void AtomCefClient::GetVersion(int replyId, CefRefPtr<CefBrowser> browser) {
|
||||
replyArguments->SetList(0, CreateReplyDescriptor(replyId, 0));
|
||||
browser->SendProcessMessage(PID_RENDERER, replyMessage);
|
||||
}
|
||||
|
||||
bool AtomCefClient::DoClose(CefRefPtr<CefBrowser> browser) {
|
||||
m_IsClosed = true;
|
||||
NSWindow *window = [browser->GetHost()->GetWindowHandle() window];
|
||||
[window performClose:window];
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ int AtomMain(int argc, char* argv[]) {
|
||||
[mainNib instantiateWithOwner:application topLevelObjects:nil];
|
||||
|
||||
CefRunMessageLoop();
|
||||
CefShutdown();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -177,6 +177,10 @@
|
||||
[self addBrowserToView:self.webView url:[urlString UTF8String] cefHandler:_cefClient];
|
||||
}
|
||||
|
||||
- (BOOL)isBrowserUsable {
|
||||
return _cefClient && !_cefClient->IsClosed() && _cefClient->GetBrowser();
|
||||
}
|
||||
|
||||
- (void)toggleDevTools {
|
||||
if (_devToolsView) {
|
||||
[self hideDevTools];
|
||||
@@ -188,22 +192,21 @@
|
||||
|
||||
- (void)showDevTools {
|
||||
if (_devToolsView) return;
|
||||
if (![self isBrowserUsable]) 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];
|
||||
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];
|
||||
[_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];
|
||||
}
|
||||
_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 {
|
||||
@@ -212,17 +215,19 @@
|
||||
[_devToolsView release];
|
||||
_devToolsView = nil;
|
||||
_cefDevToolsClient = NULL;
|
||||
_cefClient->GetBrowser()->GetHost()->SetFocus(true);
|
||||
if ([self isBrowserUsable]) {
|
||||
_cefClient->GetBrowser()->GetHost()->SetFocus(true);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)openPath:(NSString*)path {
|
||||
if (_cefClient && _cefClient->GetBrowser()) {
|
||||
CefRefPtr<CefProcessMessage> openMessage = CefProcessMessage::Create("openPath");
|
||||
CefRefPtr<CefListValue> openArguments = openMessage->GetArgumentList();
|
||||
openArguments->SetSize(1);
|
||||
openArguments->SetString(0, [path UTF8String]);
|
||||
_cefClient->GetBrowser()->SendProcessMessage(PID_RENDERER, openMessage);
|
||||
}
|
||||
if (![self isBrowserUsable]) return;
|
||||
|
||||
CefRefPtr<CefProcessMessage> openMessage = CefProcessMessage::Create("openPath");
|
||||
CefRefPtr<CefListValue> openArguments = openMessage->GetArgumentList();
|
||||
openArguments->SetSize(1);
|
||||
openArguments->SetString(0, [path UTF8String]);
|
||||
_cefClient->GetBrowser()->SendProcessMessage(PID_RENDERER, openMessage);
|
||||
}
|
||||
|
||||
- (void)setPidToKillOnClose:(NSNumber *)pid {
|
||||
@@ -239,14 +244,15 @@
|
||||
}
|
||||
|
||||
- (void)windowDidBecomeMain:(NSNotification *)notification {
|
||||
if (_cefClient && _cefClient->GetBrowser()) {
|
||||
if ([self isBrowserUsable]) {
|
||||
_cefClient->GetBrowser()->GetHost()->SetFocus(true);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldClose:(NSNotification *)notification {
|
||||
if (_cefClient && _cefClient->GetBrowser()) {
|
||||
if ([self isBrowserUsable]) {
|
||||
_cefClient->GetBrowser()->GetHost()->CloseBrowser(false);
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (_pidToKillOnClose) kill([_pidToKillOnClose intValue], SIGQUIT);
|
||||
|
||||
Reference in New Issue
Block a user