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(
"browserWindowOptions", options);
// The parent window.
mate::Handle<Window> 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<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) {
*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() override;
// TrackableObject:
void AfterInit(v8::Isolate* isolate) override;
// NativeWindowObserver:
void WillCloseWindow(bool* prevent_default) override;
void OnWindowClosed() override;

View file

@ -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);

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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)