Add Browser class to controll when the application should quit.

This commit is contained in:
Cheng Zhao 2013-05-02 23:43:23 +08:00
parent 8cf1050730
commit d151d494bd
12 changed files with 138 additions and 7 deletions

View file

@ -46,6 +46,9 @@
'browser/atom_event_processing_window.mm',
'browser/atom_javascript_dialog_manager.cc',
'browser/atom_javascript_dialog_manager.h',
'browser/browser.cc',
'browser/browser.h',
'browser/browser_mac.mm',
'browser/native_window.cc',
'browser/native_window.h',
'browser/native_window_mac.h',

View file

@ -5,8 +5,7 @@
#import "browser/atom_application_mac.h"
#include "base/auto_reset.h"
#include "base/logging.h"
#include "browser/window_list.h"
#include "browser/browser.h"
@implementation AtomApplication
@ -28,11 +27,7 @@
}
- (IBAction)closeAllWindows:(id)sender {
atom::WindowList* window_list = atom::WindowList::GetInstance();
if (window_list->size() == 0)
[self terminate:self];
window_list->CloseAllWindows();
atom::Browser::Get()->Quit();
}
@end

View file

@ -7,6 +7,7 @@
#include "browser/api/atom_browser_bindings.h"
#include "browser/atom_browser_client.h"
#include "browser/atom_browser_context.h"
#include "browser/browser.h"
#include "common/node_bindings.h"
#include "vendor/node/src/node.h"
#include "vendor/node/src/node_internals.h"
@ -18,6 +19,7 @@ AtomBrowserMainParts* AtomBrowserMainParts::self_ = NULL;
AtomBrowserMainParts::AtomBrowserMainParts()
: atom_bindings_(new AtomBrowserBindings),
browser_(new Browser),
node_bindings_(NodeBindings::Create(true)) {
DCHECK(!self_) << "Cannot have two AtomBrowserMainParts";
self_ = this;

View file

@ -10,6 +10,7 @@
namespace atom {
class AtomBrowserBindings;
class Browser;
class NodeBindings;
class AtomBrowserMainParts : public brightray::BrowserMainParts {
@ -20,6 +21,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
static AtomBrowserMainParts* Get();
AtomBrowserBindings* atom_bindings() { return atom_bindings_.get(); }
Browser* browser() { return browser_.get(); }
protected:
// Implementations of brightray::BrowserMainParts.
@ -32,6 +34,7 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
private:
scoped_ptr<AtomBrowserBindings> atom_bindings_;
scoped_ptr<Browser> browser_;
scoped_ptr<NodeBindings> node_bindings_;
static AtomBrowserMainParts* self_;

46
browser/browser.cc Normal file
View file

@ -0,0 +1,46 @@
// 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 "browser/browser.h"
#include "browser/atom_browser_main_parts.h"
#include "browser/window_list.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() {
atom::WindowList* window_list = atom::WindowList::GetInstance();
if (window_list->size() == 0)
Terminate();
is_quiting_ = true;
window_list->CloseAllWindows();
}
void Browser::OnWindowCloseCancelled(NativeWindow* window) {
// Once a beforeunload handler has prevented the closing, we think the quit
// is cancelled too.
is_quiting_ = false;
}
void Browser::OnWindowAllClosed() {
if (is_quiting_)
Terminate();
}
} // namespace atom

43
browser/browser.h Normal file
View file

@ -0,0 +1,43 @@
// 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.
#ifndef ATOM_BROWSER_BROWSER_H_
#define ATOM_BROWSER_BROWSER_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "browser/window_list_observer.h"
namespace atom {
// This class is used for control application-wide operations.
class Browser : public WindowListObserver {
public:
Browser();
~Browser();
static Browser* Get();
// Try to close all windows and quit the application.
void Quit();
// Quit the application immediately without cleanup work.
void Terminate();
bool is_quiting() const { return is_quiting_; }
protected:
bool is_quiting_;
private:
// WindowListObserver implementations:
virtual void OnWindowCloseCancelled(NativeWindow* window) OVERRIDE;
virtual void OnWindowAllClosed() OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(Browser);
};
} // namespace atom
#endif // ATOM_BROWSER_BROWSER_H_

15
browser/browser_mac.mm Normal file
View file

@ -0,0 +1,15 @@
// 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 "browser/browser.h"
#import "browser/atom_application_mac.h"
namespace atom {
void Browser::Terminate() {
[[AtomApplication sharedApplication] terminate:nil];
}
} // namespace atom

View file

@ -188,6 +188,15 @@ content::JavaScriptDialogManager* NativeWindow::GetJavaScriptDialogManager() {
return dialog_manager_.get();
}
void NativeWindow::BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) {
*proceed_to_fire_unload = proceed;
if (!proceed)
WindowList::WindowCloseCancelled(this);
}
void NativeWindow::CloseContents(content::WebContents* source) {
// When the web contents is gone, close the window immediately, but the
// memory will not be freed until you call delete.

View file

@ -128,6 +128,9 @@ class NativeWindow : public content::WebContentsDelegate,
content::WebContents* new_contents) OVERRIDE;
virtual content::JavaScriptDialogManager*
GetJavaScriptDialogManager() OVERRIDE;
virtual void BeforeUnloadFired(content::WebContents* tab,
bool proceed,
bool* proceed_to_fire_unload) OVERRIDE;
virtual void CloseContents(content::WebContents* source) OVERRIDE;
// Implementations of content::WebContentsObserver.

View file

@ -51,6 +51,12 @@ void WindowList::RemoveWindow(NativeWindow* window) {
OnWindowAllClosed());
}
// static
void WindowList::WindowCloseCancelled(NativeWindow* window) {
FOR_EACH_OBSERVER(WindowListObserver, observers_.Get(),
OnWindowCloseCancelled(window));
}
// static
void WindowList::AddObserver(WindowListObserver* observer) {
observers_.Get().AddObserver(observer);

View file

@ -38,6 +38,9 @@ class WindowList {
static void AddWindow(NativeWindow* window);
static void RemoveWindow(NativeWindow* window);
// Called by window when a close is cancelled by beforeunload handler.
static void WindowCloseCancelled(NativeWindow* window);
// Adds and removes |observer| from the observer list.
static void AddObserver(WindowListObserver* observer);
static void RemoveObserver(WindowListObserver* observer);

View file

@ -17,6 +17,9 @@ class WindowListObserver {
// Called immediately after a window is removed from the list.
virtual void OnWindowRemoved(NativeWindow* window) {}
// Called when a window close is cancelled by beforeunload handler.
virtual void OnWindowCloseCancelled(NativeWindow* window) {}
// Called immediately after all windows are closed.
virtual void OnWindowAllClosed() {}