Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make 'setParentWindow' compatible under Windows #15775

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions atom/browser/api/atom_api_top_level_window.cc
Expand Up @@ -671,6 +671,7 @@ void TopLevelWindow::SetParentWindow(v8::Local<v8::Value> value,
parent_window_.Reset();
window_->SetParentWindow(nullptr);
} else if (mate::ConvertFromV8(isolate(), value, &parent)) {
RemoveFromParentChildWindows();
parent_window_.Reset(isolate(), value);
window_->SetParentWindow(parent->window_.get());
parent->child_windows_.Set(isolate(), weak_map_id(), GetWrapper());
Expand Down Expand Up @@ -1061,9 +1062,7 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setContentProtection", &TopLevelWindow::SetContentProtection)
.SetMethod("setFocusable", &TopLevelWindow::SetFocusable)
.SetMethod("setMenu", &TopLevelWindow::SetMenu)
#if !defined(OS_WIN)
.SetMethod("setParentWindow", &TopLevelWindow::SetParentWindow)
#endif
.SetMethod("setBrowserView", &TopLevelWindow::SetBrowserView)
.SetMethod("getNativeWindowHandle",
&TopLevelWindow::GetNativeWindowHandle)
Expand Down
35 changes: 21 additions & 14 deletions atom/browser/native_window_views.cc
Expand Up @@ -989,20 +989,27 @@ void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
XSetTransientForHint(
xdisplay, GetAcceleratedWidget(),
parent ? parent->GetAcceleratedWidget() : DefaultRootWindow(xdisplay));
#elif defined(OS_WIN) && defined(DEBUG)
// Should work, but does not, it seems that the views toolkit doesn't support
// reparenting on desktop.
if (parent) {
::SetParent(GetAcceleratedWidget(), parent->GetAcceleratedWidget());
views::Widget::ReparentNativeView(GetNativeWindow(),
parent->GetNativeWindow());
wm::AddTransientChild(parent->GetNativeWindow(), GetNativeWindow());
} else {
if (!GetNativeWindow()->parent())
return;
::SetParent(GetAcceleratedWidget(), NULL);
views::Widget::ReparentNativeView(GetNativeWindow(), nullptr);
wm::RemoveTransientChild(GetNativeWindow()->parent(), GetNativeWindow());
#elif defined(OS_WIN)
// To set parentship between windows into Windows is better to play with the
// owner instead of the parent, as Windows natively seems to do if a parent
// is specified at window creation time.
// For do this we must NOT use the ::SetParent function, instead we must use
// the ::GetWindowLongPtr or ::SetWindowLongPtr functions with "nIndex" set
// to "GWLP_HWNDPARENT" which actually means the window owner.
HWND hwndParent = parent ? parent->GetAcceleratedWidget() : NULL;
if (hwndParent ==
(HWND)::GetWindowLongPtr(GetAcceleratedWidget(), GWLP_HWNDPARENT))
return;
::SetWindowLongPtr(GetAcceleratedWidget(), GWLP_HWNDPARENT,
(LONG_PTR)hwndParent);
// 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
}
Expand Down
3 changes: 1 addition & 2 deletions docs/api/browser-window.md
Expand Up @@ -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
when parent window moves, while on Windows and Linux child windows will not
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 many desktop environments do not support hiding a modal window.

Expand Down Expand Up @@ -1529,7 +1528,7 @@ On Windows it calls SetWindowDisplayAffinity with `WDA_MONITOR`.

Changes whether the window can be focused.

#### `win.setParentWindow(parent)` _Linux_ _macOS_
#### `win.setParentWindow(parent)`

* `parent` BrowserWindow

Expand Down
6 changes: 0 additions & 6 deletions spec/api-browser-window-spec.js
Expand Up @@ -2957,12 +2957,6 @@ describe('BrowserWindow module', () => {
})

describe('win.setParentWindow(parent)', () => {
before(function () {
if (process.platform === 'win32') {
this.skip()
}
})

beforeEach(() => {
if (c != null) c.destroy()
c = new BrowserWindow({ show: false })
Expand Down