Browse Source

fix: dialog fails to show after modal close (#22858)

Shelley Vohr 5 years ago
parent
commit
b14608c2c1

+ 8 - 18
shell/browser/native_window_mac.mm

@@ -597,28 +597,18 @@ void NativeWindowMac::SetContentView(views::View* view) {
 }
 
 void NativeWindowMac::Close() {
-  // When this is a sheet showing, performClose won't work.
-  if (is_modal() && parent() && IsVisible()) {
-    NSWindow* window = parent()->GetNativeWindow().GetNativeNSWindow();
-    if (NSWindow* sheetParent = [window sheetParent]) {
-      base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(base::RetainBlock(^{
-            [sheetParent endSheet:window];
-          })));
-    }
-
-    // Manually emit close event (not triggered from close fn)
-    NotifyWindowCloseButtonClicked();
-    CloseImmediately();
-    return;
-  }
-
   if (!IsClosable()) {
     WindowList::WindowCloseCancelled(this);
     return;
   }
 
   [window_ performClose:nil];
+
+  // Closing a sheet doesn't trigger windowShouldClose,
+  // so we need to manually call it ourselves here.
+  if (is_modal() && parent() && IsVisible()) {
+    NotifyWindowCloseButtonClicked();
+  }
 }
 
 void NativeWindowMac::CloseImmediately() {
@@ -655,9 +645,9 @@ bool NativeWindowMac::IsFocused() {
 
 void NativeWindowMac::Show() {
   if (is_modal() && parent()) {
+    NSWindow* window = parent()->GetNativeWindow().GetNativeNSWindow();
     if ([window_ sheetParent] == nil)
-      [parent()->GetNativeWindow().GetNativeNSWindow()
-                 beginSheet:window_
+      [window beginSheet:window_
           completionHandler:^(NSModalResponse){
           }];
     return;

+ 4 - 0
shell/browser/ui/cocoa/electron_ns_window.mm

@@ -192,6 +192,10 @@ bool ScopedDisableResize::disable_resize_ = false;
         return;
     }
     [self close];
+  } else if (shell_->is_modal() && shell_->parent() && shell_->IsVisible()) {
+    // We don't want to actually call [window close] here since
+    // we've already called endSheet on the modal sheet.
+    return;
   } else {
     [super performClose:sender];
   }

+ 13 - 0
shell/browser/ui/cocoa/electron_ns_window_delegate.mm

@@ -270,6 +270,19 @@ using TitleBarStyle = electron::NativeWindowMac::TitleBarStyle;
 - (void)windowWillClose:(NSNotification*)notification {
   shell_->NotifyWindowClosed();
 
+  // Something called -[NSWindow close] on a sheet rather than calling
+  // -[NSWindow endSheet:] on its parent. If the modal session is not ended
+  // then the parent will never be able to show another sheet. But calling
+  // -endSheet: here will block the thread with an animation, so post a task.
+  if (shell_->is_modal() && shell_->parent() && shell_->IsVisible()) {
+    NSWindow* window = shell_->GetNativeWindow().GetNativeNSWindow();
+    NSWindow* sheetParent = [window sheetParent];
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(base::RetainBlock(^{
+          [sheetParent endSheet:window];
+        })));
+  }
+
   // Clears the delegate when window is going to be closed, since EL Capitan it
   // is possible that the methods of delegate would get called after the window
   // has been closed.