diff options
author | tapted <tapted@chromium.org> | 2015-03-17 14:28:24 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-17 21:29:01 +0000 |
commit | 3de6ad4c2b4c8f52daa2119a24063cd9309460e6 (patch) | |
tree | efabd3548f24e8ff1a066e8cd5e1add2cb7007c4 /ui/views/cocoa/bridged_native_widget.mm | |
parent | 50442ee97f3212f38c8cbb29228293dfa1c17ce4 (diff) | |
download | chromium_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.mm | 35 |
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); + } } } |