fix: all children showing when showing child window (#40062)

This commit is contained in:
Shelley Vohr 2023-10-05 15:19:57 +02:00 committed by GitHub
parent 5ad69df52e
commit 3392d9a2e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 4 deletions

View file

@ -189,6 +189,9 @@ class NativeWindowMac : public NativeWindow,
has_deferred_window_close_ = defer_close; has_deferred_window_close_ = defer_close;
} }
void set_wants_to_be_visible(bool visible) { wants_to_be_visible_ = visible; }
bool wants_to_be_visible() const { return wants_to_be_visible_; }
enum class VisualEffectState { enum class VisualEffectState {
kFollowWindow, kFollowWindow,
kActive, kActive,
@ -255,6 +258,10 @@ class NativeWindowMac : public NativeWindow,
// transition is complete. // transition is complete.
bool has_deferred_window_close_ = false; bool has_deferred_window_close_ = false;
// If true, the window is either visible, or wants to be visible but is
// currently hidden due to having a hidden parent.
bool wants_to_be_visible_ = false;
NSInteger attention_request_id_ = 0; // identifier from requestUserAttention NSInteger attention_request_id_ = 0; // identifier from requestUserAttention
// The presentation options before entering kiosk mode. // The presentation options before entering kiosk mode.

View file

@ -483,6 +483,8 @@ void NativeWindowMac::Show() {
return; return;
} }
set_wants_to_be_visible(true);
// Reattach the window to the parent to actually show it. // Reattach the window to the parent to actually show it.
if (parent()) if (parent())
InternalSetParentWindow(parent(), true); InternalSetParentWindow(parent(), true);
@ -515,6 +517,10 @@ void NativeWindowMac::Hide() {
return; return;
} }
// If the window wants to be visible and has a parent, then the parent may
// order it back in (in the period between orderOut: and close).
set_wants_to_be_visible(false);
DetachChildren(); DetachChildren();
// Detach the window from the parent before. // Detach the window from the parent before.
@ -650,6 +656,9 @@ void NativeWindowMac::RemoveChildFromParentWindow() {
void NativeWindowMac::AttachChildren() { void NativeWindowMac::AttachChildren() {
for (auto* child : child_windows_) { for (auto* child : child_windows_) {
if (!static_cast<NativeWindowMac*>(child)->wants_to_be_visible())
continue;
auto* child_nswindow = child->GetNativeWindow().GetNativeNSWindow(); auto* child_nswindow = child->GetNativeWindow().GetNativeNSWindow();
if ([child_nswindow parentWindow] == window_) if ([child_nswindow parentWindow] == window_)
continue; continue;
@ -663,8 +672,6 @@ void NativeWindowMac::AttachChildren() {
} }
void NativeWindowMac::DetachChildren() { void NativeWindowMac::DetachChildren() {
DCHECK(child_windows_.size() == [[window_ childWindows] count]);
// Hide all children before hiding/minimizing the window. // Hide all children before hiding/minimizing the window.
// NativeWidgetNSWindowBridge::NotifyVisibilityChangeDown() // NativeWidgetNSWindowBridge::NotifyVisibilityChangeDown()
// will DCHECK otherwise. // will DCHECK otherwise.

View file

@ -258,6 +258,7 @@ using FullScreenTransitionState =
[super windowDidMiniaturize:notification]; [super windowDidMiniaturize:notification];
is_minimized_ = true; is_minimized_ = true;
shell_->set_wants_to_be_visible(false);
shell_->NotifyWindowMinimize(); shell_->NotifyWindowMinimize();
} }
@ -265,6 +266,7 @@ using FullScreenTransitionState =
[super windowDidDeminiaturize:notification]; [super windowDidDeminiaturize:notification];
is_minimized_ = false; is_minimized_ = false;
shell_->set_wants_to_be_visible(true);
shell_->AttachChildren(); shell_->AttachChildren();
shell_->SetWindowLevel(level_); shell_->SetWindowLevel(level_);
shell_->NotifyWindowRestore(); shell_->NotifyWindowRestore();

View file

@ -4680,7 +4680,27 @@ describe('BrowserWindow module', () => {
expect(w.getChildWindows().length).to.equal(0); expect(w.getChildWindows().length).to.equal(0);
}); });
ifit(process.platform === 'darwin')('child window matches visibility when visibility changes', async () => { ifit(process.platform === 'darwin')('only shows the intended window when a child with siblings is shown', async () => {
const w = new BrowserWindow({ show: false });
const childOne = new BrowserWindow({ show: false, parent: w });
const childTwo = new BrowserWindow({ show: false, parent: w });
const parentShown = once(w, 'show');
w.show();
await parentShown;
expect(childOne.isVisible()).to.be.false('childOne is visible');
expect(childTwo.isVisible()).to.be.false('childTwo is visible');
const childOneShown = once(childOne, 'show');
childOne.show();
await childOneShown;
expect(childOne.isVisible()).to.be.true('childOne is not visible');
expect(childTwo.isVisible()).to.be.false('childTwo is visible');
});
ifit(process.platform === 'darwin')('child matches parent visibility when parent visibility changes', async () => {
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w }); const c = new BrowserWindow({ show: false, parent: w });
@ -4707,7 +4727,7 @@ describe('BrowserWindow module', () => {
expect(c.isVisible()).to.be.true('child is visible'); expect(c.isVisible()).to.be.true('child is visible');
}); });
ifit(process.platform === 'darwin')('matches child window visibility when visibility changes', async () => { ifit(process.platform === 'darwin')('parent matches child visibility when child visibility changes', async () => {
const w = new BrowserWindow({ show: false }); const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w }); const c = new BrowserWindow({ show: false, parent: w });