Chromium Code Reviews

Side by Side Diff: chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm

Issue 1430023002: Enable AutoResize for Constrained Web Dialogs for Mac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h" 5 #include "chrome/browser/ui/webui/constrained_web_dialog_delegate_base.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include "base/mac/scoped_nsobject.h" 9 #include "base/mac/scoped_nsobject.h"
10 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h" 10 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_wi ndow.h"
11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" 11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialo g_sheet.h" 12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialo g_sheet.h"
13 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
14 #include "content/public/browser/render_view_host.h"
13 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_contents_observer.h"
14 #include "ui/gfx/geometry/size.h" 17 #include "ui/gfx/geometry/size.h"
15 #include "ui/web_dialogs/web_dialog_delegate.h" 18 #include "ui/web_dialogs/web_dialog_delegate.h"
16 #include "ui/web_dialogs/web_dialog_ui.h" 19 #include "ui/web_dialogs/web_dialog_ui.h"
17 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h" 20 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
18 21
19 using content::WebContents; 22 using content::WebContents;
20 using ui::WebDialogDelegate; 23 using ui::WebDialogDelegate;
21 using ui::WebDialogWebContentsDelegate; 24 using ui::WebDialogWebContentsDelegate;
22 25
23 namespace { 26 namespace {
24 27
28 class ConstrainedWebDialogDelegateMac;
29
30 // WebContentsObserver that tracks the lifetime of the WebContents to avoid
31 // potential use after destruction.
32 class InitiatorWebContentsObserver
erikchen 2015/11/11 21:22:30 What's the point of this class? Why not just use W
apacible 2015/11/12 02:02:24 Removed.
33 : public content::WebContentsObserver {
34 public:
35 explicit InitiatorWebContentsObserver(content::WebContents* web_contents)
36 : content::WebContentsObserver(web_contents) {
37 }
38
39 private:
40 DISALLOW_COPY_AND_ASSIGN(InitiatorWebContentsObserver);
41 };
42
43 class WebDialogWebContentsDelegateMac
erikchen 2015/11/11 21:22:30 Provide a comment indicating the purpose of this c
apacible 2015/11/12 02:02:24 Done.
44 : public ui::WebDialogWebContentsDelegate {
45 public:
46 WebDialogWebContentsDelegateMac(content::BrowserContext* browser_context,
47 InitiatorWebContentsObserver* observer,
48 ConstrainedWebDialogDelegateBase* delegate)
49 : ui::WebDialogWebContentsDelegate(browser_context,
50 new ChromeWebContentsHandler()),
51 initiator_observer_(observer),
52 delegate_(delegate) {
53 }
54 ~WebDialogWebContentsDelegateMac() override {}
55
56 void ResizeDueToAutoResize(content::WebContents* source,
57 const gfx::Size& preferred_size) override {
58 if (!initiator_observer_->web_contents())
59 return;
60 delegate_->ResizeToGivenSize(preferred_size);
61 }
62
63 private:
64 // weak, owned by ConstrainedWebDialogDelegateViewMac.
65 InitiatorWebContentsObserver* const initiator_observer_;
66 ConstrainedWebDialogDelegateBase* delegate_; // weak, owns us.
erikchen 2015/11/11 21:22:30 "us" is ambiguous. For both this member, and the o
apacible 2015/11/12 02:02:24 Done.
67
68 DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateMac);
69 };
70
25 class ConstrainedWebDialogDelegateMac 71 class ConstrainedWebDialogDelegateMac
26 : public ConstrainedWebDialogDelegateBase { 72 : public ConstrainedWebDialogDelegateBase {
27 public: 73 public:
28 ConstrainedWebDialogDelegateMac( 74 ConstrainedWebDialogDelegateMac(
29 content::BrowserContext* browser_context, 75 content::BrowserContext* browser_context,
30 WebDialogDelegate* delegate) 76 WebDialogDelegate* delegate,
31 : ConstrainedWebDialogDelegateBase(browser_context, delegate, NULL) {} 77 InitiatorWebContentsObserver* observer)
78 : ConstrainedWebDialogDelegateBase(browser_context, delegate,
79 new WebDialogWebContentsDelegateMac(browser_context, observer,
erikchen 2015/11/11 21:22:30 Can you add a comment to the constructor of Constr
apacible 2015/11/12 02:02:23 Done.
80 this)) {}
32 81
33 // WebDialogWebContentsDelegate interface. 82 // WebDialogWebContentsDelegate interface.
34 void CloseContents(WebContents* source) override { 83 void CloseContents(WebContents* source) override {
35 window_->CloseWebContentsModalDialog(); 84 window_->CloseWebContentsModalDialog();
36 } 85 }
37 86
87 // ConstrainedWebDialogDelegateBase:
88 void ResizeToGivenSize(const gfx::Size size) override {
89 NSSize updated_preferred_size = NSMakeSize(size.width(),
90 size.height());
91 [window_->sheet() ResizeWithNewSize:updated_preferred_size];
92 }
93
38 void set_window(ConstrainedWindowMac* window) { window_ = window; } 94 void set_window(ConstrainedWindowMac* window) { window_ = window; }
39 ConstrainedWindowMac* window() const { return window_; } 95 ConstrainedWindowMac* window() const { return window_; }
40 96
41 private: 97 private:
42 // Weak, owned by ConstrainedWebDialogDelegateViewMac. 98 // Weak, owned by ConstrainedWebDialogDelegateViewMac.
43 ConstrainedWindowMac* window_; 99 ConstrainedWindowMac* window_;
44 100
45 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateMac); 101 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateMac);
46 }; 102 };
47 103
48 } // namespace 104 } // namespace
49 105
50 class ConstrainedWebDialogDelegateViewMac : 106 class ConstrainedWebDialogDelegateViewMac :
51 public ConstrainedWindowMacDelegate, 107 public ConstrainedWindowMacDelegate,
52 public ConstrainedWebDialogDelegate { 108 public ConstrainedWebDialogDelegate,
109 public content::WebContentsObserver {
53 110
54 public: 111 public:
55 ConstrainedWebDialogDelegateViewMac( 112 ConstrainedWebDialogDelegateViewMac(
56 content::BrowserContext* browser_context, 113 content::BrowserContext* browser_context,
57 WebDialogDelegate* delegate, 114 WebDialogDelegate* delegate,
58 content::WebContents* web_contents); 115 content::WebContents* web_contents,
116 const gfx::Size& min_size,
117 const gfx::Size& max_size);
59 ~ConstrainedWebDialogDelegateViewMac() override {} 118 ~ConstrainedWebDialogDelegateViewMac() override {}
60 119
61 // ConstrainedWebDialogDelegate interface 120 // ConstrainedWebDialogDelegate interface
62 const WebDialogDelegate* GetWebDialogDelegate() const override { 121 const WebDialogDelegate* GetWebDialogDelegate() const override {
63 return impl_->GetWebDialogDelegate(); 122 return impl_->GetWebDialogDelegate();
64 } 123 }
65 WebDialogDelegate* GetWebDialogDelegate() override { 124 WebDialogDelegate* GetWebDialogDelegate() override {
66 return impl_->GetWebDialogDelegate(); 125 return impl_->GetWebDialogDelegate();
67 } 126 }
68 void OnDialogCloseFromWebUI() override { 127 void OnDialogCloseFromWebUI() override {
69 return impl_->OnDialogCloseFromWebUI(); 128 return impl_->OnDialogCloseFromWebUI();
70 } 129 }
71 void ReleaseWebContentsOnDialogClose() override { 130 void ReleaseWebContentsOnDialogClose() override {
72 return impl_->ReleaseWebContentsOnDialogClose(); 131 return impl_->ReleaseWebContentsOnDialogClose();
73 } 132 }
74 gfx::NativeWindow GetNativeDialog() override { return window_; } 133 gfx::NativeWindow GetNativeDialog() override { return window_; }
75 WebContents* GetWebContents() override { return impl_->GetWebContents(); } 134 WebContents* GetWebContents() override { return impl_->GetWebContents(); }
76 gfx::Size GetMinimumSize() const override { 135 gfx::Size GetMinimumSize() const override {
77 NOTIMPLEMENTED(); 136 return min_size_;
78 return gfx::Size();
79 } 137 }
80 gfx::Size GetMaximumSize() const override { 138 gfx::Size GetMaximumSize() const override {
81 NOTIMPLEMENTED(); 139 return max_size_;
82 return gfx::Size();
83 } 140 }
84 gfx::Size GetPreferredSize() const override { 141 gfx::Size GetPreferredSize() const override {
85 NOTIMPLEMENTED(); 142 gfx::Size size;
erikchen 2015/11/11 21:22:30 What does it mean for the preferred size to be 0,0
apacible 2015/11/12 02:02:23 Done.
86 return gfx::Size(); 143 if (!impl_->closed_via_webui()) {
144 NSRect frame = [window_ frame];
145 size = gfx::Size(frame.size.width, frame.size.height);
146 }
147 return size;
148 }
149
150 // content::WebContentsObserver:
151 void RenderViewCreated(content::RenderViewHost* render_view_host) override {
152 if (!max_size_.IsEmpty())
153 EnableAutoResize();
154 }
155 void RenderViewHostChanged(content::RenderViewHost* old_host,
156 content::RenderViewHost* new_host) override {
157 if (!max_size_.IsEmpty())
erikchen 2015/11/11 21:22:30 Shouldn't this conditional, and the other ones in
apacible 2015/11/12 02:02:23 These should actually all be DCHECK as they're all
apacible 2015/11/13 00:04:00 Updating this - Since ConstrainedWebDialogDelegate
158 EnableAutoResize();
159 }
160 void DocumentOnLoadCompletedInMainFrame() override {
161 if (!max_size_.IsEmpty()) {
162 EnableAutoResize();
163 if (initiator_observer_.web_contents())
164 ShowDialog();
165 }
87 } 166 }
88 167
89 // ConstrainedWindowMacDelegate interface 168 // ConstrainedWindowMacDelegate interface
90 void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override { 169 void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override {
91 if (!impl_->closed_via_webui()) 170 if (!impl_->closed_via_webui())
92 GetWebDialogDelegate()->OnDialogClosed(""); 171 GetWebDialogDelegate()->OnDialogClosed("");
93 delete this; 172 delete this;
94 } 173 }
95 174
175 void ShowDialog() {
176 constrained_window_->ShowDialog();
177 }
178
96 private: 179 private:
180 void EnableAutoResize() {
181 content::RenderViewHost* render_view_host =
erikchen 2015/11/11 21:22:30 This relies on the assumption that GetWebContents(
apacible 2015/11/12 02:02:24 Done.
182 GetWebContents()->GetRenderViewHost();
183 render_view_host->EnableAutoResize(min_size_, max_size_);
184 }
185
186 InitiatorWebContentsObserver initiator_observer_;
97 scoped_ptr<ConstrainedWebDialogDelegateMac> impl_; 187 scoped_ptr<ConstrainedWebDialogDelegateMac> impl_;
98 scoped_ptr<ConstrainedWindowMac> constrained_window_; 188 scoped_ptr<ConstrainedWindowMac> constrained_window_;
99 base::scoped_nsobject<NSWindow> window_; 189 base::scoped_nsobject<NSWindow> window_;
100 190
191 // Minimum and maximum sizes to determine dialog bounds for auto-resizing.
192 const gfx::Size min_size_;
193 const gfx::Size max_size_;
erikchen 2015/11/11 21:22:30 It looks like this object has two internal states:
apacible 2015/11/12 02:02:23 Done.
194
101 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewMac); 195 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewMac);
102 }; 196 };
103 197
104 ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac( 198 ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac(
105 content::BrowserContext* browser_context, 199 content::BrowserContext* browser_context,
106 WebDialogDelegate* delegate, 200 WebDialogDelegate* delegate,
107 content::WebContents* web_contents) 201 content::WebContents* web_contents,
108 : impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate)) { 202 const gfx::Size& min_size,
203 const gfx::Size& max_size)
204 : initiator_observer_(web_contents),
205 impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate,
206 &initiator_observer_)),
207 min_size_(min_size),
208 max_size_(max_size) {
209 if (!max_size_.IsEmpty())
210 Observe(GetWebContents());
211
109 // Create a window to hold web_contents in the constrained sheet: 212 // Create a window to hold web_contents in the constrained sheet:
110 gfx::Size size; 213 gfx::Size size;
111 delegate->GetDialogSize(&size); 214 delegate->GetDialogSize(&size);
112 NSRect frame = NSMakeRect(0, 0, size.width(), size.height()); 215 NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
113 216
114 window_.reset( 217 window_.reset([[ConstrainedWindowCustomWindow alloc]
115 [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]); 218 initWithContentRect:frame]);
116 [GetWebContents()->GetNativeView() setFrame:frame]; 219 [GetWebContents()->GetNativeView() setFrame:frame];
117 [GetWebContents()->GetNativeView() setAutoresizingMask: 220 [GetWebContents()->GetNativeView() setAutoresizingMask:
118 NSViewWidthSizable|NSViewHeightSizable]; 221 NSViewWidthSizable|NSViewHeightSizable];
119 [[window_ contentView] addSubview:GetWebContents()->GetNativeView()]; 222 [[window_ contentView] addSubview:GetWebContents()->GetNativeView()];
120 223
121 base::scoped_nsobject<WebDialogConstrainedWindowSheet> sheet( 224 base::scoped_nsobject<WebDialogConstrainedWindowSheet> sheet(
122 [[WebDialogConstrainedWindowSheet alloc] initWithCustomWindow:window_ 225 [[WebDialogConstrainedWindowSheet alloc] initWithCustomWindow:window_
123 webDialogDelegate:delegate]); 226 webDialogDelegate:delegate]);
124 constrained_window_.reset(new ConstrainedWindowMac( 227
125 this, web_contents, sheet)); 228 if (max_size_.IsEmpty()) {
229 constrained_window_.reset(ShowWebModalDialogMac(
230 this, web_contents, sheet));
231 } else {
232 constrained_window_.reset(CreateWebModalDialogMac(
233 this, web_contents, sheet));
234 }
126 235
127 impl_->set_window(constrained_window_.get()); 236 impl_->set_window(constrained_window_.get());
128 } 237 }
129 238
130 ConstrainedWebDialogDelegate* ShowConstrainedWebDialog( 239 ConstrainedWebDialogDelegate* ShowConstrainedWebDialog(
131 content::BrowserContext* browser_context, 240 content::BrowserContext* browser_context,
132 WebDialogDelegate* delegate, 241 WebDialogDelegate* delegate,
133 content::WebContents* web_contents) { 242 content::WebContents* web_contents) {
134 // Deleted when the dialog closes. 243 // Deleted when the dialog closes.
135 ConstrainedWebDialogDelegateViewMac* constrained_delegate = 244 ConstrainedWebDialogDelegateViewMac* constrained_delegate =
136 new ConstrainedWebDialogDelegateViewMac( 245 new ConstrainedWebDialogDelegateViewMac(
137 browser_context, delegate, web_contents); 246 browser_context, delegate, web_contents,
247 gfx::Size(), gfx::Size());
138 return constrained_delegate; 248 return constrained_delegate;
139 } 249 }
250
251 ConstrainedWebDialogDelegate* ShowConstrainedWebDialogWithAutoResize(
252 content::BrowserContext* browser_context,
253 WebDialogDelegate* delegate,
254 content::WebContents* web_contents,
255 const gfx::Size& min_size,
256 const gfx::Size& max_size) {
257 DCHECK(!min_size.IsEmpty());
258 DCHECK(!max_size.IsEmpty());
259 // Deleted when the dialog closes.
260 ConstrainedWebDialogDelegateViewMac* constrained_delegate =
261 new ConstrainedWebDialogDelegateViewMac(
262 browser_context, delegate, web_contents,
263 min_size, max_size);
264 return constrained_delegate;
265 }
OLDNEW

Powered by Google App Engine