Add WindowList class to manage all windows.

This commit is contained in:
Cheng Zhao 2013-05-02 22:54:09 +08:00
parent 43d42ca57f
commit 264f085afb
7 changed files with 187 additions and 19 deletions

View file

@ -51,6 +51,9 @@
'browser/native_window_mac.h',
'browser/native_window_mac.mm',
'browser/native_window_observer.h',
'browser/window_list.cc',
'browser/window_list.h',
'browser/window_list_observer.h',
'common/api/api_messages.cc',
'common/api/api_messages.h',
'common/api/atom_api_clipboard.cc',

View file

@ -6,7 +6,7 @@
#include "base/auto_reset.h"
#include "base/logging.h"
#include "browser/native_window.h"
#include "browser/window_list.h"
@implementation AtomApplication
@ -28,9 +28,11 @@
}
- (IBAction)closeAllWindows:(id)sender {
std::vector<atom::NativeWindow*> windows = atom::NativeWindow::windows();
for (size_t i = 0; i < windows.size(); ++i)
windows[i]->Close();
atom::WindowList* window_list = atom::WindowList::GetInstance();
if (window_list->size() == 0)
[self terminate:self];
window_list->CloseAllWindows();
}
@end

View file

@ -4,7 +4,6 @@
#include "browser/native_window.h"
#include <algorithm>
#include <string>
#include "base/utf_string_conversions.h"
@ -15,6 +14,7 @@
#include "browser/atom_browser_context.h"
#include "browser/atom_browser_main_parts.h"
#include "browser/atom_javascript_dialog_manager.h"
#include "browser/window_list.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
@ -32,9 +32,6 @@ using content::NavigationEntry;
namespace atom {
// static
std::vector<NativeWindow*> NativeWindow::windows_;
NativeWindow::NativeWindow(content::WebContents* web_contents,
base::DictionaryValue* options)
: content::WebContentsObserver(web_contents),
@ -43,7 +40,7 @@ NativeWindow::NativeWindow(content::WebContents* web_contents,
brightray::InspectableWebContents::Create(web_contents)) {
web_contents->SetDelegate(this);
windows_.push_back(this);
WindowList::AddWindow(this);
// Get notified of title updated message.
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
@ -66,7 +63,8 @@ NativeWindow* NativeWindow::Create(base::DictionaryValue* options) {
NativeWindow* NativeWindow::FromProcessIDAndRoutingID(int process_id,
int routing_id) {
// Stupid iterating.
for (auto window : windows_) {
WindowList& window_list = *WindowList::GetInstance();
for (auto window : window_list) {
content::WebContents* web_contents = window->GetWebContents();
int window_process_id = web_contents->GetRenderProcessHost()->GetID();
int window_routing_id = web_contents->GetRoutingID();
@ -160,8 +158,7 @@ void NativeWindow::NotifyWindowClosed() {
return;
is_closed_ = true;
windows_.erase(std::remove(windows_.begin(), windows_.end(), this),
windows_.end());
WindowList::RemoveWindow(this);
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowClosed());
}

View file

@ -6,7 +6,6 @@
#define ATOM_BROWSER_NATIVE_WINDOW_H_
#include <iosfwd>
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
@ -59,9 +58,6 @@ class NativeWindow : public content::WebContentsDelegate,
static NativeWindow* FromProcessIDAndRoutingID(int process_id,
int routing_id);
// Return all opened windows.
static std::vector<NativeWindow*> windows() { return windows_; }
void InitFromOptions(base::DictionaryValue* options);
virtual void Close() = 0;
@ -156,9 +152,6 @@ class NativeWindow : public content::WebContentsDelegate,
// Observers of this window.
ObserverList<NativeWindowObserver> observers_;
// Stores all windows.
static std::vector<NativeWindow*> windows_;
bool is_closed_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;

77
browser/window_list.cc Normal file
View file

@ -0,0 +1,77 @@
// 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/window_list.h"
#include <algorithm>
#include "base/logging.h"
#include "browser/native_window.h"
#include "browser/window_list_observer.h"
namespace atom {
// static
base::LazyInstance<ObserverList<WindowListObserver>>::Leaky
WindowList::observers_ = LAZY_INSTANCE_INITIALIZER;
// static
WindowList* WindowList::instance_ = NULL;
// static
WindowList* WindowList::GetInstance() {
if (!instance_)
instance_ = new WindowList;
return instance_;
}
// static
void WindowList::AddWindow(NativeWindow* window) {
DCHECK(window);
// Push |window| on the appropriate list instance.
WindowVector& windows = GetInstance()->windows_;
windows.push_back(window);
FOR_EACH_OBSERVER(WindowListObserver, observers_.Get(),
OnWindowAdded(window));
}
// static
void WindowList::RemoveWindow(NativeWindow* window) {
WindowVector& windows = GetInstance()->windows_;
windows.erase(std::remove(windows.begin(), windows.end(), window),
windows.end());
FOR_EACH_OBSERVER(WindowListObserver, observers_.Get(),
OnWindowRemoved(window));
if (windows.size() == 0)
FOR_EACH_OBSERVER(WindowListObserver, observers_.Get(),
OnWindowAllClosed());
}
// static
void WindowList::AddObserver(WindowListObserver* observer) {
observers_.Get().AddObserver(observer);
}
// static
void WindowList::RemoveObserver(WindowListObserver* observer) {
observers_.Get().RemoveObserver(observer);
}
// static
void WindowList::CloseAllWindows() {
WindowVector windows = GetInstance()->windows_;
for (size_t i = 0; i < windows.size(); ++i)
windows[i]->Close();
}
WindowList::WindowList() {
}
WindowList::~WindowList() {
}
} // namespace atom

66
browser/window_list.h Normal file
View file

@ -0,0 +1,66 @@
// 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_WINDOW_LIST_H_
#define ATOM_BROWSER_WINDOW_LIST_H_
#include <vector>
#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/observer_list.h"
namespace atom {
class NativeWindow;
class WindowListObserver;
class WindowList {
public:
typedef std::vector<NativeWindow*> WindowVector;
typedef WindowVector::const_iterator const_iterator;
typedef WindowVector::const_reverse_iterator const_reverse_iterator;
// Windows are added to the list before they have constructed windows,
// so the |window()| member function may return NULL.
const_iterator begin() const { return windows_.begin(); }
const_iterator end() const { return windows_.end(); }
bool empty() const { return windows_.empty(); }
size_t size() const { return windows_.size(); }
NativeWindow* get(size_t index) const { return windows_[index]; }
static WindowList* GetInstance();
// Adds or removes |window| from the list it is associated with.
static void AddWindow(NativeWindow* window);
static void RemoveWindow(NativeWindow* window);
// Adds and removes |observer| from the observer list.
static void AddObserver(WindowListObserver* observer);
static void RemoveObserver(WindowListObserver* observer);
// Closes all windows.
static void CloseAllWindows();
private:
WindowList();
~WindowList();
// A vector of the windows in this list, in the order they were added.
WindowVector windows_;
// A list of observers which will be notified of every window addition and
// removal across all WindowLists.
static base::LazyInstance<ObserverList<WindowListObserver>>::Leaky observers_;
static WindowList* instance_;
DISALLOW_COPY_AND_ASSIGN(WindowList);
};
} // namespace atom
#endif // ATOM_BROWSER_WINDOW_LIST_H_

View file

@ -0,0 +1,30 @@
// 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_BROSER_WINDOW_LIST_OBSERVER_H_
#define ATOM_BROSER_WINDOW_LIST_OBSERVER_H_
namespace atom {
class NativeWindow;
class WindowListObserver {
public:
// Called immediately after a window is added to the list.
virtual void OnWindowAdded(NativeWindow* window) {}
// Called immediately after a window is removed from the list.
virtual void OnWindowRemoved(NativeWindow* window) {}
// Called immediately after all windows are closed.
virtual void OnWindowAllClosed() {}
protected:
virtual ~WindowListObserver() {}
};
} // namespace atom
#endif // ATOM_BROSER_WINDOW_LIST_OBSERVER_H_