diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 308ff31dea9f..b72c62704ed2 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -97,9 +97,16 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) mate::Dictionary(isolate, web_contents->GetWrapper()).Set( "browserWindowOptions", options); + // The parent window. + mate::Handle parent; + if (options.Get("parent", &parent)) + parent_window_.Reset(isolate, parent.ToV8()); + // Creates BrowserWindow. - window_.reset(NativeWindow::Create(web_contents->managed_web_contents(), - options)); + window_.reset(NativeWindow::Create( + web_contents->managed_web_contents(), + options, + parent.IsEmpty() ? nullptr : parent->window_.get())); web_contents->SetOwnerWindow(window_.get()); window_->InitFromOptions(options); window_->AddObserver(this); @@ -122,6 +129,17 @@ Window::~Window() { base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release()); } +void Window::AfterInit(v8::Isolate* isolate) { + mate::TrackableObject::AfterInit(isolate); + + // We can only append this window to parent window's child windows after this + // window's JS wrapper gets initialized. + mate::Handle parent; + if (!parent_window_.IsEmpty() && + mate::ConvertFromV8(isolate, GetParentWindow(), &parent)) + parent->child_windows_.Set(isolate, ID(), GetWrapper()); +} + void Window::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 92b41e775d69..e5522f958e07 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -55,6 +55,9 @@ class Window : public mate::TrackableObject, Window(v8::Isolate* isolate, const mate::Dictionary& options); ~Window() override; + // TrackableObject: + void AfterInit(v8::Isolate* isolate) override; + // NativeWindowObserver: void WillCloseWindow(bool* prevent_default) override; void OnWindowClosed() override; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 120d399ad709..bcfa487b9750 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -81,7 +81,8 @@ class NativeWindow : public base::SupportsUserData, // managing the window's live. static NativeWindow* Create( brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options); + const mate::Dictionary& options, + NativeWindow* parent = nullptr); // Find a window from its WebContents static NativeWindow* FromWebContents(content::WebContents* web_contents); diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 357cbd55ff32..0806cfa28c3d 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -22,7 +22,8 @@ namespace atom { class NativeWindowMac : public NativeWindow { public: NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options); + const mate::Dictionary& options, + NativeWindow* parent); ~NativeWindowMac() override; // NativeWindow: diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9e9a948f94c9..90b62cf7d2d1 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -453,7 +453,8 @@ namespace atom { NativeWindowMac::NativeWindowMac( brightray::InspectableWebContents* web_contents, - const mate::Dictionary& options) + const mate::Dictionary& options, + NativeWindow* parent) : NativeWindow(web_contents, options), is_kiosk_(false), attention_request_id_(0), @@ -526,6 +527,10 @@ NativeWindowMac::NativeWindowMac( window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]); [window_ setDelegate:window_delegate_]; + if (parent) { + SetParentWindow(parent); + } + if (transparent()) { // Setting the background color to clear will also hide the shadow. [window_ setBackgroundColor:[NSColor clearColor]]; @@ -1197,8 +1202,9 @@ void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) { // static NativeWindow* NativeWindow::Create( brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options) { - return new NativeWindowMac(inspectable_web_contents, options); + const mate::Dictionary& options, + NativeWindow* parent) { + return new NativeWindowMac(inspectable_web_contents, options, parent); } } // namespace atom diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index a1081da12a13..4000af5ce842 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -126,7 +126,8 @@ class NativeWindowClientView : public views::ClientView { NativeWindowViews::NativeWindowViews( brightray::InspectableWebContents* web_contents, - const mate::Dictionary& options) + const mate::Dictionary& options, + NativeWindow* parent) : NativeWindow(web_contents, options), window_(new views::Widget), web_view_(inspectable_web_contents()->GetView()->GetView()), @@ -1139,8 +1140,9 @@ ui::WindowShowState NativeWindowViews::GetRestoredState() { // static NativeWindow* NativeWindow::Create( brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options) { - return new NativeWindowViews(inspectable_web_contents, options); + const mate::Dictionary& options, + NativeWindow* parent) { + return new NativeWindowViews(inspectable_web_contents, options, parent); } } // namespace atom diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index f876a8bec241..95a95120f46d 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -42,7 +42,8 @@ class NativeWindowViews : public NativeWindow, public views::WidgetObserver { public: NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents, - const mate::Dictionary& options); + const mate::Dictionary& options, + NativeWindow* parent); ~NativeWindowViews() override; // NativeWindow: diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 5b7794ab6ea3..109789be1469 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -849,7 +849,32 @@ describe('browser-window module', function () { c = null }) + describe('parent option', function () { + beforeEach(function () { + if (c != null) c.destroy() + c = new BrowserWindow({show: false, parent: w}) + }) + + it('sets parent window', function () { + assert.equal(c.getParentWindow(), w) + }) + + it('adds window to child windows of parent', function () { + assert.deepEqual(w.getChildWindows(), [c]) + }) + + it('removes from child windows of parent when window is closed', function (done) { + c.once('closed', () => { + assert.deepEqual(w.getChildWindows(), []) + done() + }) + c.close() + }) + }) + describe('win.setParentWindow(parent)', function () { + if (process.platform !== 'darwin') return + it('sets parent window', function () { assert.equal(w.getParentWindow(), null) assert.equal(c.getParentWindow(), null)