Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: ui/views/controls/webview/webview.cc

Issue 173803002: Redesigns the text input focus handling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed review comments. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 "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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698