| Index: ui/views/cocoa/bridged_native_widget.mm
|
| diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
|
| index 24bba74dd91727e12fe250c3c02c4b1145875e10..9a5149aa31e6721e182130cfbf01c41722d2550d 100644
|
| --- a/ui/views/cocoa/bridged_native_widget.mm
|
| +++ b/ui/views/cocoa/bridged_native_widget.mm
|
| @@ -293,11 +293,7 @@ BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent)
|
| }
|
|
|
| BridgedNativeWidget::~BridgedNativeWidget() {
|
| - RemoveOrDestroyChildren();
|
| - DCHECK(child_windows_.empty());
|
| - SetFocusManager(NULL);
|
| - SetRootView(NULL);
|
| - DestroyCompositor();
|
| + bool close_window = false;
|
| if ([window_ delegate]) {
|
| // If the delegate is still set on a modal dialog, it means it was not
|
| // closed via [NSApplication endSheet:]. This is probably OK if the widget
|
| @@ -308,12 +304,31 @@ BridgedNativeWidget::~BridgedNativeWidget() {
|
| // So ban it. Modal dialogs should be closed via Widget::Close().
|
| DCHECK(!native_widget_mac_->IsWindowModalSheet());
|
|
|
| - // If the delegate is still set, it means OnWindowWillClose has not been
|
| - // called and the window is still open. Calling -[NSWindow close] will
|
| - // synchronously call OnWindowWillClose and notify NativeWidgetMac.
|
| + // If the delegate is still set, it means OnWindowWillClose() has not been
|
| + // called and the window is still open. Usually, -[NSWindow close] would
|
| + // synchronously call OnWindowWillClose() which removes the delegate and
|
| + // notifies NativeWidgetMac, which then calls this with a nil delegate.
|
| + // For other teardown flows (e.g. Widget::WIDGET_OWNS_NATIVE_WIDGET or
|
| + // Widget::CloseNow()) the delegate must first be cleared to avoid AppKit
|
| + // calling back into the bridge. This means OnWindowWillClose() needs to be
|
| + // invoked manually, which is done below.
|
| + // Note that if the window has children it can't be closed until the
|
| + // children are gone, but removing child windows calls into AppKit for the
|
| + // parent window, so the delegate must be cleared first.
|
| + [window_ setDelegate:nil];
|
| + close_window = true;
|
| + }
|
| +
|
| + RemoveOrDestroyChildren();
|
| + DCHECK(child_windows_.empty());
|
| + SetFocusManager(nullptr);
|
| + SetRootView(nullptr);
|
| + DestroyCompositor();
|
| +
|
| + if (close_window) {
|
| + OnWindowWillClose();
|
| [window_ close];
|
| }
|
| - DCHECK(![window_ delegate]);
|
| }
|
|
|
| void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window,
|
|
|