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 dfea779a80e6311d75e8896aa0e9f7e438233a09..74ac56afef7c75d65389c033a4bb91660b175658 100644 |
--- a/ui/views/cocoa/bridged_native_widget.mm |
+++ b/ui/views/cocoa/bridged_native_widget.mm |
@@ -87,6 +87,15 @@ BridgedNativeWidget::~BridgedNativeWidget() { |
SetRootView(NULL); |
DestroyCompositor(); |
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 |
+ // was never shown. But Cocoa ignores close() calls on open sheets. Calling |
+ // endSheet: here would work, but it messes up assumptions elsewhere. E.g. |
+ // DialogClientView assumes its delegate is alive when closing, which isn't |
+ // true after endSheet: synchronously calls OnNativeWidgetDestroyed(). |
+ // So ban it. Modal dialogs should be closed via Widget::Close(). |
+ DCHECK(!native_widget_mac_->GetWidget()->IsModal()); |
+ |
// 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. |
@@ -180,6 +189,13 @@ void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) { |
// due to unpredictable OSX treatment. |
DCHECK(!new_bounds.IsEmpty()) << "Zero-sized windows not supported on Mac"; |
+ if (native_widget_mac_->GetWidget()->IsModal()) { |
+ // Modal dialogs are positioned by Cocoa. Just update the size. |
+ [window_ |
+ setContentSize:NSMakeSize(new_bounds.width(), new_bounds.height())]; |
+ return; |
+ } |
+ |
gfx::Rect actual_new_bounds(new_bounds); |
if (parent_ && |
@@ -239,6 +255,18 @@ void BridgedNativeWidget::SetVisibilityState(WindowVisibilityState new_state) { |
return; |
} |
+ if (native_widget_mac_->GetWidget()->IsModal()) { |
+ NSWindow* parent_window = parent_->ns_window(); |
+ DCHECK(parent_window); |
+ |
+ [NSApp beginSheet:window_ |
+ modalForWindow:parent_window |
+ modalDelegate:[window_ delegate] |
+ didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) |
+ contextInfo:nullptr]; |
+ return; |
+ } |
+ |
if (new_state == SHOW_AND_ACTIVATE_WINDOW) { |
[window_ makeKeyAndOrderFront:nil]; |
[NSApp activateIgnoringOtherApps:YES]; |
@@ -450,10 +478,13 @@ void BridgedNativeWidget::OnWindowKeyStatusChangedTo(bool is_key) { |
// The contentView is the BridgedContentView hosting the views::RootView. The |
// focus manager will already know if a native subview has focus. |
if ([window_ contentView] == [window_ firstResponder]) { |
- if (is_key) |
+ if (is_key) { |
+ widget->OnNativeFocus(); |
widget->GetFocusManager()->RestoreFocusedView(); |
- else |
+ } else { |
+ widget->OnNativeBlur(); |
widget->GetFocusManager()->StoreFocusedView(true); |
+ } |
} |
} |