b994ae8174
OS X's application termination doesn't work very well with C++ message loops. Especially when we return NSTerminateLater for shouldTerminate, it would be impossible for the C++ message loop to quit, because unless we explictly let NSApp terminate the application, the message loop would think the application is not terminated and will run forever. The fix is to simply ignore the Cocoa's application termination request and let the C++ message loop deal with it compeletey. But we had the side effect that atom-shell would always cancel OS X's shutdown request, this is also the approach chosen by Chromium. Fixes #229. Fixes atom/atom#1864.
123 lines
2.8 KiB
C++
123 lines
2.8 KiB
C++
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "atom/browser/browser.h"
|
|
|
|
#include <string>
|
|
|
|
#include "atom/browser/atom_browser_main_parts.h"
|
|
#include "atom/browser/window_list.h"
|
|
#include "base/message_loop/message_loop.h"
|
|
|
|
namespace atom {
|
|
|
|
Browser::Browser()
|
|
: is_quiting_(false) {
|
|
WindowList::AddObserver(this);
|
|
}
|
|
|
|
Browser::~Browser() {
|
|
WindowList::RemoveObserver(this);
|
|
}
|
|
|
|
// static
|
|
Browser* Browser::Get() {
|
|
return AtomBrowserMainParts::Get()->browser();
|
|
}
|
|
|
|
void Browser::Quit() {
|
|
is_quiting_ = true;
|
|
|
|
atom::WindowList* window_list = atom::WindowList::GetInstance();
|
|
if (window_list->size() == 0)
|
|
NotifyAndShutdown();
|
|
|
|
window_list->CloseAllWindows();
|
|
}
|
|
|
|
void Browser::Shutdown() {
|
|
is_quiting_ = true;
|
|
base::MessageLoop::current()->Quit();
|
|
}
|
|
|
|
std::string Browser::GetVersion() const {
|
|
if (version_override_.empty()) {
|
|
std::string version = GetExecutableFileVersion();
|
|
if (!version.empty())
|
|
return version;
|
|
}
|
|
|
|
return version_override_;
|
|
}
|
|
|
|
void Browser::SetVersion(const std::string& version) {
|
|
version_override_ = version;
|
|
}
|
|
|
|
std::string Browser::GetName() const {
|
|
if (name_override_.empty()) {
|
|
std::string name = GetExecutableFileProductName();
|
|
if (!name.empty())
|
|
return name;
|
|
}
|
|
|
|
return name_override_;
|
|
}
|
|
|
|
void Browser::SetName(const std::string& name) {
|
|
name_override_ = name;
|
|
}
|
|
|
|
bool Browser::OpenFile(const std::string& file_path) {
|
|
bool prevent_default = false;
|
|
FOR_EACH_OBSERVER(BrowserObserver,
|
|
observers_,
|
|
OnOpenFile(&prevent_default, file_path));
|
|
|
|
return prevent_default;
|
|
}
|
|
|
|
void Browser::OpenURL(const std::string& url) {
|
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnOpenURL(url));
|
|
}
|
|
|
|
void Browser::ActivateWithNoOpenWindows() {
|
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnActivateWithNoOpenWindows());
|
|
}
|
|
|
|
void Browser::WillFinishLaunching() {
|
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWillFinishLaunching());
|
|
}
|
|
|
|
void Browser::DidFinishLaunching() {
|
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnFinishLaunching());
|
|
}
|
|
|
|
void Browser::NotifyAndShutdown() {
|
|
bool prevent_default = false;
|
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWillQuit(&prevent_default));
|
|
|
|
if (prevent_default) {
|
|
is_quiting_ = false;
|
|
return;
|
|
}
|
|
|
|
Shutdown();
|
|
}
|
|
|
|
void Browser::OnWindowCloseCancelled(NativeWindow* window) {
|
|
if (is_quiting_)
|
|
// Once a beforeunload handler has prevented the closing, we think the quit
|
|
// is cancelled too.
|
|
is_quiting_ = false;
|
|
}
|
|
|
|
void Browser::OnWindowAllClosed() {
|
|
if (is_quiting_)
|
|
NotifyAndShutdown();
|
|
else
|
|
FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWindowAllClosed());
|
|
}
|
|
|
|
} // namespace atom
|