summaryrefslogtreecommitdiffstats
path: root/ui/views/cocoa/bridged_native_widget.mm
diff options
context:
space:
mode:
authortapted <tapted@chromium.org>2015-03-17 14:28:24 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-17 21:29:01 +0000
commit3de6ad4c2b4c8f52daa2119a24063cd9309460e6 (patch)
treeefabd3548f24e8ff1a066e8cd5e1add2cb7007c4 /ui/views/cocoa/bridged_native_widget.mm
parent50442ee97f3212f38c8cbb29228293dfa1c17ce4 (diff)
downloadchromium_src-3de6ad4c2b4c8f52daa2119a24063cd9309460e6.zip
chromium_src-3de6ad4c2b4c8f52daa2119a24063cd9309460e6.tar.gz
chromium_src-3de6ad4c2b4c8f52daa2119a24063cd9309460e6.tar.bz2
MacViews: Implement Window-modal dialogs using sheets
These are used, e.g., for the Bookmark -> Edit... dialogs on Cocoa and Views. This gets WidgetTestInteractive.*Window*ModalWindowDestroyedActivationTest passing. WidgetTestInteractive.*System*ModalWindowReleasesCapture is disabled in this CL. System modal windows are not needed on Mac. Currently the implementation on MacViews assumes all modal dialogs are shown using a sheet. On Cocoa, this is not always true for WebContents-Modal dialogs (e.g. cookies and site data), but it is true for some WebContents-Modal dialogs (e.g. certificate information). A follow-up will add logic to ensure WebContents-Modal dialogs are handled appropriately, and have good test coverage. After this all tests pass on the current mac trybot configuration with toolkit_views=1. BUG=403679 Review URL: https://codereview.chromium.org/993253002 Cr-Commit-Position: refs/heads/master@{#320977}
Diffstat (limited to 'ui/views/cocoa/bridged_native_widget.mm')
-rw-r--r--ui/views/cocoa/bridged_native_widget.mm35
1 files changed, 33 insertions, 2 deletions
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
index dfea779..74ac56af 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);
+ }
}
}