OLD | NEW |
---|---|
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 "ui/views/controls/webview/webview.h" | 5 #include "ui/views/controls/webview/webview.h" |
6 | 6 |
7 #include "content/public/browser/browser_accessibility_state.h" | 7 #include "content/public/browser/browser_accessibility_state.h" |
8 #include "content/public/browser/browser_context.h" | 8 #include "content/public/browser/browser_context.h" |
9 #include "content/public/browser/navigation_controller.h" | 9 #include "content/public/browser/navigation_controller.h" |
10 #include "content/public/browser/render_view_host.h" | 10 #include "content/public/browser/render_view_host.h" |
11 #include "content/public/browser/render_widget_host_view.h" | 11 #include "content/public/browser/render_widget_host_view.h" |
12 #include "content/public/browser/web_contents.h" | 12 #include "content/public/browser/web_contents.h" |
13 #include "content/public/browser/web_contents_view.h" | 13 #include "content/public/browser/web_contents_view.h" |
14 #include "ipc/ipc_message.h" | 14 #include "ipc/ipc_message.h" |
15 #include "ui/accessibility/ax_enums.h" | 15 #include "ui/accessibility/ax_enums.h" |
16 #include "ui/accessibility/ax_view_state.h" | 16 #include "ui/accessibility/ax_view_state.h" |
17 #include "ui/base/ui_base_switches_util.h" | |
17 #include "ui/events/event.h" | 18 #include "ui/events/event.h" |
18 #include "ui/views/accessibility/native_view_accessibility.h" | 19 #include "ui/views/accessibility/native_view_accessibility.h" |
19 #include "ui/views/controls/native/native_view_host.h" | 20 #include "ui/views/controls/native/native_view_host.h" |
20 #include "ui/views/focus/focus_manager.h" | 21 #include "ui/views/focus/focus_manager.h" |
21 #include "ui/views/views_delegate.h" | 22 #include "ui/views/views_delegate.h" |
22 | 23 |
23 namespace views { | 24 namespace views { |
24 | 25 |
25 // static | 26 // static |
26 const char WebView::kViewClassName[] = "WebView"; | 27 const char WebView::kViewClassName[] = "WebView"; |
(...skipping 17 matching lines...) Expand all Loading... | |
44 | 45 |
45 content::WebContents* WebView::GetWebContents() { | 46 content::WebContents* WebView::GetWebContents() { |
46 if (!web_contents()) { | 47 if (!web_contents()) { |
47 wc_owner_.reset(CreateWebContents(browser_context_)); | 48 wc_owner_.reset(CreateWebContents(browser_context_)); |
48 wc_owner_->SetDelegate(this); | 49 wc_owner_->SetDelegate(this); |
49 SetWebContents(wc_owner_.get()); | 50 SetWebContents(wc_owner_.get()); |
50 } | 51 } |
51 return web_contents(); | 52 return web_contents(); |
52 } | 53 } |
53 | 54 |
54 void WebView::SetWebContents(content::WebContents* replacement) { | 55 void WebView::SetWebContents(content::WebContents* replacement) { |
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
Very good catch. I added it to {Attach,Detach}Web
| |
55 if (replacement == web_contents()) | 56 if (replacement == web_contents()) |
56 return; | 57 return; |
57 DetachWebContents(); | 58 DetachWebContents(); |
58 if (wc_owner_ != replacement) | 59 if (wc_owner_ != replacement) |
59 wc_owner_.reset(); | 60 wc_owner_.reset(); |
60 WebContentsObserver::Observe(replacement); | 61 WebContentsObserver::Observe(replacement); |
61 // web_contents() now returns |replacement| from here onwards. | 62 // web_contents() now returns |replacement| from here onwards. |
62 if (embed_fullscreen_widget_mode_enabled_) { | 63 if (embed_fullscreen_widget_mode_enabled_) { |
63 is_embedding_fullscreen_widget_ = | 64 is_embedding_fullscreen_widget_ = |
64 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); | 65 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 PreferredSizeChanged(); | 104 PreferredSizeChanged(); |
104 } | 105 } |
105 | 106 |
106 //////////////////////////////////////////////////////////////////////////////// | 107 //////////////////////////////////////////////////////////////////////////////// |
107 // WebView, View overrides: | 108 // WebView, View overrides: |
108 | 109 |
109 const char* WebView::GetClassName() const { | 110 const char* WebView::GetClassName() const { |
110 return kViewClassName; | 111 return kViewClassName; |
111 } | 112 } |
112 | 113 |
114 ui::TextInputClient* WebView::GetTextInputClient() { | |
115 if (switches::IsTextInputFocusManagerEnabled() && | |
116 web_contents() && !web_contents()->IsBeingDestroyed()) { | |
117 content::RenderWidgetHostView* host_view = | |
118 web_contents()->GetRenderWidgetHostView(); | |
msw
2014/03/11 23:24:39
Should this ever use web_contents()->GetFullscreen
Yuki
2014/03/12 09:13:15
Very good catch. Updated.
| |
119 if (host_view) | |
120 return host_view->GetTextInputClient(); | |
121 } | |
122 return NULL; | |
123 } | |
124 | |
113 void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 125 void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
114 wcv_holder_->SetSize(bounds().size()); | 126 wcv_holder_->SetSize(bounds().size()); |
115 } | 127 } |
116 | 128 |
117 void WebView::ViewHierarchyChanged( | 129 void WebView::ViewHierarchyChanged( |
118 const ViewHierarchyChangedDetails& details) { | 130 const ViewHierarchyChangedDetails& details) { |
119 if (details.is_add) | 131 if (details.is_add) |
120 AttachWebContents(); | 132 AttachWebContents(); |
121 } | 133 } |
122 | 134 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 } | 199 } |
188 | 200 |
189 bool WebView::EmbedsFullscreenWidget() const { | 201 bool WebView::EmbedsFullscreenWidget() const { |
190 DCHECK(wc_owner_.get()); | 202 DCHECK(wc_owner_.get()); |
191 return embed_fullscreen_widget_mode_enabled_; | 203 return embed_fullscreen_widget_mode_enabled_; |
192 } | 204 } |
193 | 205 |
194 //////////////////////////////////////////////////////////////////////////////// | 206 //////////////////////////////////////////////////////////////////////////////// |
195 // WebView, content::WebContentsObserver implementation: | 207 // WebView, content::WebContentsObserver implementation: |
196 | 208 |
209 void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) { | |
210 // WebView::GetTextInputClient() delegates the text input handling to the | |
211 // underlying content::RenderWidgetHostView. So when the underlying RWHV is | |
212 // destroyed, we have to notify the FocusManager that the focused | |
213 // TextInputClient needs to be updated. | |
214 FocusManager* const focus_manager = GetFocusManager(); | |
215 if (focus_manager) | |
216 focus_manager->OnTextInputClientChanged(this); | |
217 } | |
218 | |
197 void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, | 219 void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, |
198 content::RenderViewHost* new_host) { | 220 content::RenderViewHost* new_host) { |
199 FocusManager* const focus_manager = GetFocusManager(); | 221 FocusManager* const focus_manager = GetFocusManager(); |
200 if (focus_manager && focus_manager->GetFocusedView() == this) | 222 if (focus_manager && focus_manager->GetFocusedView() == this) |
201 OnFocus(); | 223 OnFocus(); |
202 } | 224 } |
203 | 225 |
204 void WebView::WebContentsDestroyed(content::WebContents* web_contents) { | 226 void WebView::WebContentsDestroyed(content::WebContents* web_contents) { |
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
I think no need here. SetWebContents(NULL) handle
| |
205 // We watch for destruction of WebContents that we host but do not own. If we | 227 // We watch for destruction of WebContents that we host but do not own. If we |
206 // own a WebContents that is being destroyed, we're doing the destroying, so | 228 // own a WebContents that is being destroyed, we're doing the destroying, so |
207 // we don't want to recursively tear it down while it's being torn down. | 229 // we don't want to recursively tear it down while it's being torn down. |
208 if (!wc_owner_.get()) | 230 if (!wc_owner_.get()) |
209 SetWebContents(NULL); | 231 SetWebContents(NULL); |
210 } | 232 } |
211 | 233 |
212 void WebView::DidShowFullscreenWidget(int routing_id) { | 234 void WebView::DidShowFullscreenWidget(int routing_id) { |
213 if (embed_fullscreen_widget_mode_enabled_) | 235 if (embed_fullscreen_widget_mode_enabled_) |
214 ReattachForFullscreenChange(true); | 236 ReattachForFullscreenChange(true); |
215 } | 237 } |
216 | 238 |
217 void WebView::DidDestroyFullscreenWidget(int routing_id) { | 239 void WebView::DidDestroyFullscreenWidget(int routing_id) { |
218 if (embed_fullscreen_widget_mode_enabled_) | 240 if (embed_fullscreen_widget_mode_enabled_) |
219 ReattachForFullscreenChange(false); | 241 ReattachForFullscreenChange(false); |
220 } | 242 } |
221 | 243 |
222 //////////////////////////////////////////////////////////////////////////////// | 244 //////////////////////////////////////////////////////////////////////////////// |
223 // WebView, private: | 245 // WebView, private: |
224 | 246 |
225 void WebView::AttachWebContents() { | 247 void WebView::AttachWebContents() { |
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
Done.
| |
226 // Prevents attachment if the WebView isn't already in a Widget, or it's | 248 // Prevents attachment if the WebView isn't already in a Widget, or it's |
227 // already attached. | 249 // already attached. |
228 if (!GetWidget() || !web_contents()) | 250 if (!GetWidget() || !web_contents()) |
229 return; | 251 return; |
230 | 252 |
231 const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ? | 253 const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ? |
232 web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() : | 254 web_contents()->GetFullscreenRenderWidgetHostView()->GetNativeView() : |
233 web_contents()->GetView()->GetNativeView(); | 255 web_contents()->GetView()->GetNativeView(); |
234 if (wcv_holder_->native_view() == view_to_attach) | 256 if (wcv_holder_->native_view() == view_to_attach) |
235 return; | 257 return; |
236 wcv_holder_->Attach(view_to_attach); | 258 wcv_holder_->Attach(view_to_attach); |
237 | 259 |
238 // The view will not be focused automatically when it is attached, so we need | 260 // The view will not be focused automatically when it is attached, so we need |
239 // to pass on focus to it if the FocusManager thinks the view is focused. Note | 261 // to pass on focus to it if the FocusManager thinks the view is focused. Note |
240 // that not every Widget has a focus manager. | 262 // that not every Widget has a focus manager. |
241 FocusManager* const focus_manager = GetFocusManager(); | 263 FocusManager* const focus_manager = GetFocusManager(); |
242 if (focus_manager && focus_manager->GetFocusedView() == this) | 264 if (focus_manager && focus_manager->GetFocusedView() == this) |
243 OnFocus(); | 265 OnFocus(); |
244 | 266 |
245 #if defined(OS_WIN) | 267 #if defined(OS_WIN) |
246 if (!is_embedding_fullscreen_widget_) { | 268 if (!is_embedding_fullscreen_widget_) { |
247 web_contents()->SetParentNativeViewAccessible( | 269 web_contents()->SetParentNativeViewAccessible( |
248 parent()->GetNativeViewAccessible()); | 270 parent()->GetNativeViewAccessible()); |
249 } | 271 } |
250 #endif | 272 #endif |
251 } | 273 } |
252 | 274 |
253 void WebView::DetachWebContents() { | 275 void WebView::DetachWebContents() { |
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
Done.
| |
254 if (web_contents()) { | 276 if (web_contents()) { |
255 wcv_holder_->Detach(); | 277 wcv_holder_->Detach(); |
256 #if defined(OS_WIN) | 278 #if defined(OS_WIN) |
257 if (!is_embedding_fullscreen_widget_) { | 279 if (!is_embedding_fullscreen_widget_) { |
258 #if !defined(USE_AURA) | 280 #if !defined(USE_AURA) |
259 // TODO(beng): This should either not be necessary, or be done implicitly | 281 // TODO(beng): This should either not be necessary, or be done implicitly |
260 // by NativeViewHostWin on Detach(). As it stands, this is needed so that | 282 // by NativeViewHostWin on Detach(). As it stands, this is needed so that |
261 // the of the detached contents knows to tell the renderer it's been | 283 // the of the detached contents knows to tell the renderer it's been |
262 // hidden. | 284 // hidden. |
263 // | 285 // |
264 // Moving this out of here would also mean we wouldn't be potentially | 286 // Moving this out of here would also mean we wouldn't be potentially |
265 // calling member functions on a half-destroyed WebContents. | 287 // calling member functions on a half-destroyed WebContents. |
266 ShowWindow(web_contents()->GetView()->GetNativeView(), SW_HIDE); | 288 ShowWindow(web_contents()->GetView()->GetNativeView(), SW_HIDE); |
267 #else | 289 #else |
268 web_contents()->SetParentNativeViewAccessible(NULL); | 290 web_contents()->SetParentNativeViewAccessible(NULL); |
269 #endif | 291 #endif |
270 } | 292 } |
271 #endif | 293 #endif |
272 } | 294 } |
273 } | 295 } |
274 | 296 |
275 void WebView::ReattachForFullscreenChange(bool enter_fullscreen) { | 297 void WebView::ReattachForFullscreenChange(bool enter_fullscreen) { |
msw
2014/03/11 23:24:39
Should this also call OnTextInputClientChanged?
Yuki
2014/03/12 09:13:15
This method calls DetachWebContents() and then Att
| |
276 DetachWebContents(); | 298 DetachWebContents(); |
277 is_embedding_fullscreen_widget_ = enter_fullscreen && | 299 is_embedding_fullscreen_widget_ = enter_fullscreen && |
278 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); | 300 web_contents() && web_contents()->GetFullscreenRenderWidgetHostView(); |
279 AttachWebContents(); | 301 AttachWebContents(); |
280 } | 302 } |
281 | 303 |
282 content::WebContents* WebView::CreateWebContents( | 304 content::WebContents* WebView::CreateWebContents( |
283 content::BrowserContext* browser_context) { | 305 content::BrowserContext* browser_context) { |
284 content::WebContents* contents = NULL; | 306 content::WebContents* contents = NULL; |
285 if (ViewsDelegate::views_delegate) { | 307 if (ViewsDelegate::views_delegate) { |
286 contents = ViewsDelegate::views_delegate->CreateWebContents( | 308 contents = ViewsDelegate::views_delegate->CreateWebContents( |
287 browser_context, NULL); | 309 browser_context, NULL); |
288 } | 310 } |
289 | 311 |
290 if (!contents) { | 312 if (!contents) { |
291 content::WebContents::CreateParams create_params( | 313 content::WebContents::CreateParams create_params( |
292 browser_context, NULL); | 314 browser_context, NULL); |
293 return content::WebContents::Create(create_params); | 315 return content::WebContents::Create(create_params); |
294 } | 316 } |
295 | 317 |
296 return contents; | 318 return contents; |
297 } | 319 } |
298 | 320 |
299 } // namespace views | 321 } // namespace views |
OLD | NEW |