Add win.getChildWindows() API
authorCheng Zhao <zcbenz@gmail.com>
Fri, 17 Jun 2016 07:57:03 +0000 (16:57 +0900)
committerCheng Zhao <zcbenz@gmail.com>
Mon, 20 Jun 2016 02:16:41 +0000 (11:16 +0900)
atom/browser/api/atom_api_window.cc
atom/browser/api/atom_api_window.h
atom/common/key_weak_map.h

index 3e47003..3e1bb6a 100644 (file)
@@ -136,6 +136,8 @@ void Window::OnWindowClosed() {
 
   Emit("closed");
 
+  RemoveFromParentChildWindows();
+
   // Destroy the native class when window is closed.
   base::MessageLoop::current()->PostTask(FROM_HERE, GetDestroyClosure());
 }
@@ -650,13 +652,17 @@ void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
   window_->SetAspectRatio(aspect_ratio, extra_size);
 }
 
-void Window::SetParentWindow(mate::Arguments* args) {
-  v8::Local<v8::Value> value;
-  NativeWindow* parent;
-  if (args->GetNext(&value) &&
-      mate::ConvertFromV8(isolate(), value, &parent)) {
+void Window::SetParentWindow(v8::Local<v8::Value> value,
+                             mate::Arguments* args) {
+  mate::Handle<Window> parent;
+  if (value->IsNull()) {
+    RemoveFromParentChildWindows();
+    parent_window_.Reset();
+    window_->SetParentWindow(nullptr);
+  } else if (mate::ConvertFromV8(isolate(), value, &parent)) {
     parent_window_.Reset(isolate(), value);
-    window_->SetParentWindow(parent);
+    window_->SetParentWindow(parent->window_.get());
+    parent->child_windows_.Set(isolate(), ID(), GetWrapper());
   } else {
     args->ThrowError("Must pass BrowserWindow instance or null");
   }
@@ -669,6 +675,10 @@ v8::Local<v8::Value> Window::GetParentWindow() {
     return v8::Local<v8::Value>::New(isolate(), parent_window_);
 }
 
+std::vector<v8::Local<v8::Object>> Window::GetChildWindows() {
+  return child_windows_.Values(isolate());
+}
+
 v8::Local<v8::Value> Window::GetNativeWindowHandle() {
   gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
   return ToBuffer(
@@ -694,6 +704,15 @@ v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
     return v8::Local<v8::Value>::New(isolate, web_contents_);
 }
 
+void Window::RemoveFromParentChildWindows() {
+  if (parent_window_.IsEmpty())
+    return;
+
+  mate::Handle<Window> parent;
+  if (mate::ConvertFromV8(isolate(), GetParentWindow(), &parent))
+    parent->child_windows_.Remove(ID());
+}
+
 // static
 void Window::BuildPrototype(v8::Isolate* isolate,
                             v8::Local<v8::ObjectTemplate> prototype) {
@@ -718,6 +737,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
       .SetMethod("setAspectRatio", &Window::SetAspectRatio)
       .SetMethod("setParentWindow", &Window::SetParentWindow)
       .SetMethod("getParentWindow", &Window::GetParentWindow)
+      .SetMethod("getChildWindows", &Window::GetChildWindows)
       .SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
       .SetMethod("getBounds", &Window::GetBounds)
       .SetMethod("setBounds", &Window::SetBounds)
index 0078548..0cc238a 100644 (file)
@@ -6,15 +6,16 @@
 #define ATOM_BROWSER_API_ATOM_API_WINDOW_H_
 
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
-#include "base/memory/scoped_ptr.h"
 #include "ui/gfx/image/image.h"
 #include "atom/browser/api/trackable_object.h"
 #include "atom/browser/native_window.h"
 #include "atom/browser/native_window_observer.h"
 #include "atom/common/api/atom_api_native_image.h"
+#include "atom/common/key_weak_map.h"
 #include "native_mate/handle.h"
 
 class GURL;
@@ -159,8 +160,9 @@ class Window : public mate::TrackableObject<Window>,
   void SetMenuBarVisibility(bool visible);
   bool IsMenuBarVisible();
   void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
-  void SetParentWindow(mate::Arguments* args);
+  void SetParentWindow(v8::Local<v8::Value> value, mate::Arguments* args);
   v8::Local<v8::Value> GetParentWindow();
+  std::vector<v8::Local<v8::Object>> GetChildWindows();
   v8::Local<v8::Value> GetNativeWindowHandle();
 
 #if defined(OS_WIN)
@@ -183,6 +185,9 @@ class Window : public mate::TrackableObject<Window>,
   int32_t ID() const;
   v8::Local<v8::Value> WebContents(v8::Isolate* isolate);
 
+  // Helpers.
+  void RemoveFromParentChildWindows();
+
 #if defined(OS_WIN)
   typedef std::map<UINT, MessageCallback> MessageCallbackMap;
   MessageCallbackMap messages_callback_map_;
@@ -191,6 +196,7 @@ class Window : public mate::TrackableObject<Window>,
   v8::Global<v8::Value> web_contents_;
   v8::Global<v8::Value> menu_;
   v8::Global<v8::Value> parent_window_;
+  KeyWeakMap<int> child_windows_;
 
   api::WebContents* api_web_contents_;
 
index bce34bf..9c66785 100644 (file)
 
 namespace atom {
 
-namespace internal {
-
-}  // namespace internal
-
 // Like ES6's WeakMap, but the key is Integer and the value is Weak Pointer.
 template<typename K>
 class KeyWeakMap {