1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "chrome/browser/ui/cocoa/single_web_contents_dialog_manager_cocoa.h"
7 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
8 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
9 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.h"
10 #include "components/web_modal/web_contents_modal_dialog_host.h"
11 #include "components/web_modal/web_contents_modal_dialog_manager.h"
12 #include "content/public/browser/web_contents.h"
14 SingleWebContentsDialogManagerCocoa::SingleWebContentsDialogManagerCocoa(
15 ConstrainedWindowMac* client,
16 id<ConstrainedWindowSheet> sheet,
17 web_modal::SingleWebContentsDialogManagerDelegate* delegate)
19 sheet_([sheet retain]),
23 client->set_manager(this);
26 SingleWebContentsDialogManagerCocoa::~SingleWebContentsDialogManagerCocoa() {
29 void SingleWebContentsDialogManagerCocoa::Show() {
30 // If a dialog is initially shown on a hidden/background WebContents, the
31 // |delegate_| will defer the Show() until the WebContents is shown. If the
32 // defer happens during tab closure or tab dragging, a suspected data race or
33 // ObserverList ordering may result in |host_| being null here. If the tab is
34 // closing anyway, it doesn't matter. For tab dragging, avoid a crash, but the
35 // user may have to switch tabs again to see the dialog. See
36 // http://crbug.com/514826 for details.
40 NSView* parent_view = host_->GetHostView();
41 // Note that simply [parent_view window] for an inactive tab is nil. However,
42 // the following should always be non-nil for all WebContents containers.
43 NSWindow* parent_window =
44 delegate_->GetWebContents()->GetTopLevelNativeWindow();
46 [[ConstrainedWindowSheetController controllerForParentWindow:parent_window]
47 showSheet:sheet_ forParentView:parent_view];
50 void SingleWebContentsDialogManagerCocoa::Hide() {
51 NSWindow* parent_window =
52 delegate_->GetWebContents()->GetTopLevelNativeWindow();
53 [[ConstrainedWindowSheetController controllerForParentWindow:parent_window]
57 void SingleWebContentsDialogManagerCocoa::Close() {
58 [[ConstrainedWindowSheetController controllerForSheet:sheet_]
60 client_->set_manager(nullptr);
61 client_->OnDialogClosing(); // |client_| might delete itself here.
62 delegate_->WillClose(dialog()); // Deletes |this|.
65 void SingleWebContentsDialogManagerCocoa::Focus() {
68 void SingleWebContentsDialogManagerCocoa::Pulse() {
69 [[ConstrainedWindowSheetController controllerForSheet:sheet_]
73 void SingleWebContentsDialogManagerCocoa::HostChanged(
74 web_modal::WebContentsModalDialogHost* new_host) {
75 // No need to observe the host. For Cocoa, the constrained window controller
76 // will reposition the dialog when necessary. The host can also never change.
77 // Tabs showing a dialog can not be dragged off a Cocoa browser window.
78 // However, closing a tab with a dialog open will set the host back to null.
79 DCHECK_NE(!!host_, !!new_host);
83 gfx::NativeWindow SingleWebContentsDialogManagerCocoa::dialog() {
84 return [sheet_ sheetWindow];