Add "parent" option for BrowserWindow

This commit is contained in:
Cheng Zhao 2016-06-19 12:06:08 +09:00
parent 473413e874
commit 85ba382027
8 changed files with 68 additions and 11 deletions

View file

@ -97,9 +97,16 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options)
mate::Dictionary(isolate, web_contents->GetWrapper()).Set( mate::Dictionary(isolate, web_contents->GetWrapper()).Set(
"browserWindowOptions", options); "browserWindowOptions", options);
// The parent window.
mate::Handle<Window> parent;
if (options.Get("parent", &parent))
parent_window_.Reset(isolate, parent.ToV8());
// Creates BrowserWindow. // Creates BrowserWindow.
window_.reset(NativeWindow::Create(web_contents->managed_web_contents(), window_.reset(NativeWindow::Create(
options)); web_contents->managed_web_contents(),
options,
parent.IsEmpty() ? nullptr : parent->window_.get()));
web_contents->SetOwnerWindow(window_.get()); web_contents->SetOwnerWindow(window_.get());
window_->InitFromOptions(options); window_->InitFromOptions(options);
window_->AddObserver(this); window_->AddObserver(this);
@ -122,6 +129,17 @@ Window::~Window() {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release()); base::MessageLoop::current()->DeleteSoon(FROM_HERE, window_.release());
} }
void Window::AfterInit(v8::Isolate* isolate) {
mate::TrackableObject<Window>::AfterInit(isolate);
// We can only append this window to parent window's child windows after this
// window's JS wrapper gets initialized.
mate::Handle<Window> parent;
if (!parent_window_.IsEmpty() &&
mate::ConvertFromV8(isolate, GetParentWindow(), &parent))
parent->child_windows_.Set(isolate, ID(), GetWrapper());
}
void Window::WillCloseWindow(bool* prevent_default) { void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close"); *prevent_default = Emit("close");
} }

View file

@ -55,6 +55,9 @@ class Window : public mate::TrackableObject<Window>,
Window(v8::Isolate* isolate, const mate::Dictionary& options); Window(v8::Isolate* isolate, const mate::Dictionary& options);
~Window() override; ~Window() override;
// TrackableObject:
void AfterInit(v8::Isolate* isolate) override;
// NativeWindowObserver: // NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override; void WillCloseWindow(bool* prevent_default) override;
void OnWindowClosed() override; void OnWindowClosed() override;

View file

@ -81,7 +81,8 @@ class NativeWindow : public base::SupportsUserData,
// managing the window's live. // managing the window's live.
static NativeWindow* Create( static NativeWindow* Create(
brightray::InspectableWebContents* inspectable_web_contents, brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options); const mate::Dictionary& options,
NativeWindow* parent = nullptr);
// Find a window from its WebContents // Find a window from its WebContents
static NativeWindow* FromWebContents(content::WebContents* web_contents); static NativeWindow* FromWebContents(content::WebContents* web_contents);

View file

@ -22,7 +22,8 @@ namespace atom {
class NativeWindowMac : public NativeWindow { class NativeWindowMac : public NativeWindow {
public: public:
NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents, NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options); const mate::Dictionary& options,
NativeWindow* parent);
~NativeWindowMac() override; ~NativeWindowMac() override;
// NativeWindow: // NativeWindow:

View file

@ -453,7 +453,8 @@ namespace atom {
NativeWindowMac::NativeWindowMac( NativeWindowMac::NativeWindowMac(
brightray::InspectableWebContents* web_contents, brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options) const mate::Dictionary& options,
NativeWindow* parent)
: NativeWindow(web_contents, options), : NativeWindow(web_contents, options),
is_kiosk_(false), is_kiosk_(false),
attention_request_id_(0), attention_request_id_(0),
@ -526,6 +527,10 @@ NativeWindowMac::NativeWindowMac(
window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]); window_delegate_.reset([[AtomNSWindowDelegate alloc] initWithShell:this]);
[window_ setDelegate:window_delegate_]; [window_ setDelegate:window_delegate_];
if (parent) {
SetParentWindow(parent);
}
if (transparent()) { if (transparent()) {
// Setting the background color to clear will also hide the shadow. // Setting the background color to clear will also hide the shadow.
[window_ setBackgroundColor:[NSColor clearColor]]; [window_ setBackgroundColor:[NSColor clearColor]];
@ -1197,8 +1202,9 @@ void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) {
// static // static
NativeWindow* NativeWindow::Create( NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents, brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) { const mate::Dictionary& options,
return new NativeWindowMac(inspectable_web_contents, options); NativeWindow* parent) {
return new NativeWindowMac(inspectable_web_contents, options, parent);
} }
} // namespace atom } // namespace atom

View file

@ -126,7 +126,8 @@ class NativeWindowClientView : public views::ClientView {
NativeWindowViews::NativeWindowViews( NativeWindowViews::NativeWindowViews(
brightray::InspectableWebContents* web_contents, brightray::InspectableWebContents* web_contents,
const mate::Dictionary& options) const mate::Dictionary& options,
NativeWindow* parent)
: NativeWindow(web_contents, options), : NativeWindow(web_contents, options),
window_(new views::Widget), window_(new views::Widget),
web_view_(inspectable_web_contents()->GetView()->GetView()), web_view_(inspectable_web_contents()->GetView()->GetView()),
@ -1139,8 +1140,9 @@ ui::WindowShowState NativeWindowViews::GetRestoredState() {
// static // static
NativeWindow* NativeWindow::Create( NativeWindow* NativeWindow::Create(
brightray::InspectableWebContents* inspectable_web_contents, brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options) { const mate::Dictionary& options,
return new NativeWindowViews(inspectable_web_contents, options); NativeWindow* parent) {
return new NativeWindowViews(inspectable_web_contents, options, parent);
} }
} // namespace atom } // namespace atom

View file

@ -42,7 +42,8 @@ class NativeWindowViews : public NativeWindow,
public views::WidgetObserver { public views::WidgetObserver {
public: public:
NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents, NativeWindowViews(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options); const mate::Dictionary& options,
NativeWindow* parent);
~NativeWindowViews() override; ~NativeWindowViews() override;
// NativeWindow: // NativeWindow:

View file

@ -849,7 +849,32 @@ describe('browser-window module', function () {
c = null 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 () { describe('win.setParentWindow(parent)', function () {
if (process.platform !== 'darwin') return
it('sets parent window', function () { it('sets parent window', function () {
assert.equal(w.getParentWindow(), null) assert.equal(w.getParentWindow(), null)
assert.equal(c.getParentWindow(), null) assert.equal(c.getParentWindow(), null)