fix: make 'setParentWindow' compatible under Windows (#15775)

This commit is contained in:
Simone Cattaneo 2018-12-13 01:05:16 +01:00 committed by Shelley Vohr
parent 4250f84272
commit 649633bbb7
4 changed files with 23 additions and 24 deletions

View file

@ -671,6 +671,7 @@ void TopLevelWindow::SetParentWindow(v8::Local<v8::Value> value,
parent_window_.Reset(); parent_window_.Reset();
window_->SetParentWindow(nullptr); window_->SetParentWindow(nullptr);
} else if (mate::ConvertFromV8(isolate(), value, &parent)) { } else if (mate::ConvertFromV8(isolate(), value, &parent)) {
RemoveFromParentChildWindows();
parent_window_.Reset(isolate(), value); parent_window_.Reset(isolate(), value);
window_->SetParentWindow(parent->window_.get()); window_->SetParentWindow(parent->window_.get());
parent->child_windows_.Set(isolate(), weak_map_id(), GetWrapper()); parent->child_windows_.Set(isolate(), weak_map_id(), GetWrapper());
@ -1061,9 +1062,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setContentProtection", &TopLevelWindow::SetContentProtection) .SetMethod("setContentProtection", &TopLevelWindow::SetContentProtection)
.SetMethod("setFocusable", &TopLevelWindow::SetFocusable) .SetMethod("setFocusable", &TopLevelWindow::SetFocusable)
.SetMethod("setMenu", &TopLevelWindow::SetMenu) .SetMethod("setMenu", &TopLevelWindow::SetMenu)
#if !defined(OS_WIN)
.SetMethod("setParentWindow", &TopLevelWindow::SetParentWindow) .SetMethod("setParentWindow", &TopLevelWindow::SetParentWindow)
#endif
.SetMethod("setBrowserView", &TopLevelWindow::SetBrowserView) .SetMethod("setBrowserView", &TopLevelWindow::SetBrowserView)
.SetMethod("getNativeWindowHandle", .SetMethod("getNativeWindowHandle",
&TopLevelWindow::GetNativeWindowHandle) &TopLevelWindow::GetNativeWindowHandle)

View file

@ -989,20 +989,27 @@ void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
XSetTransientForHint( XSetTransientForHint(
xdisplay, GetAcceleratedWidget(), xdisplay, GetAcceleratedWidget(),
parent ? parent->GetAcceleratedWidget() : DefaultRootWindow(xdisplay)); parent ? parent->GetAcceleratedWidget() : DefaultRootWindow(xdisplay));
#elif defined(OS_WIN) && defined(DEBUG) #elif defined(OS_WIN)
// Should work, but does not, it seems that the views toolkit doesn't support // To set parentship between windows into Windows is better to play with the
// reparenting on desktop. // owner instead of the parent, as Windows natively seems to do if a parent
if (parent) { // is specified at window creation time.
::SetParent(GetAcceleratedWidget(), parent->GetAcceleratedWidget()); // For do this we must NOT use the ::SetParent function, instead we must use
views::Widget::ReparentNativeView(GetNativeWindow(), // the ::GetWindowLongPtr or ::SetWindowLongPtr functions with "nIndex" set
parent->GetNativeWindow()); // to "GWLP_HWNDPARENT" which actually means the window owner.
wm::AddTransientChild(parent->GetNativeWindow(), GetNativeWindow()); HWND hwndParent = parent ? parent->GetAcceleratedWidget() : NULL;
} else { if (hwndParent ==
if (!GetNativeWindow()->parent()) (HWND)::GetWindowLongPtr(GetAcceleratedWidget(), GWLP_HWNDPARENT))
return; return;
::SetParent(GetAcceleratedWidget(), NULL); ::SetWindowLongPtr(GetAcceleratedWidget(), GWLP_HWNDPARENT,
views::Widget::ReparentNativeView(GetNativeWindow(), nullptr); (LONG_PTR)hwndParent);
wm::RemoveTransientChild(GetNativeWindow()->parent(), GetNativeWindow()); // Ensures the visibility
if (IsVisible()) {
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement(GetAcceleratedWidget(), &wp);
::ShowWindow(GetAcceleratedWidget(), SW_HIDE);
::ShowWindow(GetAcceleratedWidget(), wp.showCmd);
::BringWindowToTop(GetAcceleratedWidget());
} }
#endif #endif
} }

View file

@ -122,7 +122,6 @@ state is `hidden` in order to minimize power consumption.
* On macOS the child windows will keep the relative position to parent window * On macOS the child windows will keep the relative position to parent window
when parent window moves, while on Windows and Linux child windows will not when parent window moves, while on Windows and Linux child windows will not
move. move.
* On Windows it is not supported to change parent window dynamically.
* On Linux the type of modal windows will be changed to `dialog`. * On Linux the type of modal windows will be changed to `dialog`.
* On Linux many desktop environments do not support hiding a modal window. * On Linux many desktop environments do not support hiding a modal window.
@ -1529,7 +1528,7 @@ On Windows it calls SetWindowDisplayAffinity with `WDA_MONITOR`.
Changes whether the window can be focused. Changes whether the window can be focused.
#### `win.setParentWindow(parent)` _Linux_ _macOS_ #### `win.setParentWindow(parent)`
* `parent` BrowserWindow * `parent` BrowserWindow

View file

@ -2957,12 +2957,6 @@ describe('BrowserWindow module', () => {
}) })
describe('win.setParentWindow(parent)', () => { describe('win.setParentWindow(parent)', () => {
before(function () {
if (process.platform === 'win32') {
this.skip()
}
})
beforeEach(() => { beforeEach(() => {
if (c != null) c.destroy() if (c != null) c.destroy()
c = new BrowserWindow({ show: false }) c = new BrowserWindow({ show: false })