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

Side by Side Diff: webkit/glue/webview_impl.cc

Issue 151195: Simplifying renderer focus management (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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
« no previous file with comments | « webkit/glue/webview_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2007 Google Inc. All Rights Reserved. 2 * Copyright 2007 Google Inc. All Rights Reserved.
3 * 3 *
4 * Portions Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 4 * Portions Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
5 * 5 *
6 * ***** BEGIN LICENSE BLOCK ***** 6 * ***** BEGIN LICENSE BLOCK *****
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 373
374 page_->backForwardList()->setClient(&back_forward_list_client_impl_); 374 page_->backForwardList()->setClient(&back_forward_list_client_impl_);
375 375
376 // The group name identifies a namespace of pages. I'm not sure how it's 376 // The group name identifies a namespace of pages. I'm not sure how it's
377 // intended to be used, but keeping all pages in the same group works for us. 377 // intended to be used, but keeping all pages in the same group works for us.
378 page_->setGroupName("default"); 378 page_->setGroupName("default");
379 } 379 }
380 380
381 WebViewImpl::~WebViewImpl() { 381 WebViewImpl::~WebViewImpl() {
382 DCHECK(page_ == NULL); 382 DCHECK(page_ == NULL);
383 ReleaseFocusReferences();
384 for (std::set<ImageResourceFetcher*>::iterator i = image_fetchers_.begin(); 383 for (std::set<ImageResourceFetcher*>::iterator i = image_fetchers_.begin();
385 i != image_fetchers_.end(); ++i) { 384 i != image_fetchers_.end(); ++i) {
386 delete *i; 385 delete *i;
387 } 386 }
388 } 387 }
389 388
390 RenderTheme* WebViewImpl::theme() const { 389 RenderTheme* WebViewImpl::theme() const {
391 return page_.get() ? page_->theme() : RenderTheme::defaultTheme().get(); 390 return page_.get() ? page_->theme() : RenderTheme::defaultTheme().get();
392 } 391 }
393 392
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 1090
1092 void WebViewImpl::StopLoading() { 1091 void WebViewImpl::StopLoading() {
1093 main_frame()->StopLoading(); 1092 main_frame()->StopLoading();
1094 } 1093 }
1095 1094
1096 void WebViewImpl::SetBackForwardListSize(int size) { 1095 void WebViewImpl::SetBackForwardListSize(int size) {
1097 page_->backForwardList()->setCapacity(size); 1096 page_->backForwardList()->setCapacity(size);
1098 } 1097 }
1099 1098
1100 void WebViewImpl::ClearFocusedNode() { 1099 void WebViewImpl::ClearFocusedNode() {
1101 // Get the last focused frame or the mainframe. 1100 if (!page_.get())
1102 RefPtr<Frame> frame = last_focused_frame_; 1101 return;
1103 if (!frame.get() && page_.get()) 1102
1104 frame = page_->mainFrame(); 1103 RefPtr<Frame> frame = page_->mainFrame();
1105 if (!frame.get()) 1104 if (!frame.get())
1106 return; 1105 return;
1107 1106
1108 RefPtr<Document> document = frame->document(); 1107 RefPtr<Document> document = frame->document();
1109 if (!document.get()) 1108 if (!document.get())
1110 return; 1109 return;
1111 1110
1112 RefPtr<Node> old_focused_node = document->focusedNode(); 1111 RefPtr<Node> old_focused_node = document->focusedNode();
1113 1112
1114 // Clear the focused node. 1113 // Clear the focused node.
1115 document->setFocusedNode(NULL); 1114 document->setFocusedNode(NULL);
1116 1115
1117 if (!old_focused_node.get()) 1116 if (!old_focused_node.get())
1118 return; 1117 return;
1119 1118
1120 // If a text field has focus, we need to make sure the selection controller 1119 // If a text field has focus, we need to make sure the selection controller
1121 // knows to remove selection from it. Otherwise, the text field is still 1120 // knows to remove selection from it. Otherwise, the text field is still
1122 // processing keyboard events even though focus has been moved to the page and 1121 // processing keyboard events even though focus has been moved to the page and
1123 // keystrokes get eaten as a result. 1122 // keystrokes get eaten as a result.
1124 if (old_focused_node->hasTagName(HTMLNames::textareaTag) || 1123 if (old_focused_node->hasTagName(HTMLNames::textareaTag) ||
1125 (old_focused_node->hasTagName(HTMLNames::inputTag) && 1124 (old_focused_node->hasTagName(HTMLNames::inputTag) &&
1126 static_cast<HTMLInputElement*>(old_focused_node.get())->isTextField())) { 1125 static_cast<HTMLInputElement*>(old_focused_node.get())->isTextField())) {
1127 // Clear the selection. 1126 // Clear the selection.
1128 SelectionController* selection = frame->selection(); 1127 SelectionController* selection = frame->selection();
1129 selection->clear(); 1128 selection->clear();
1130 } 1129 }
1131 } 1130 }
1132 1131
1133 void WebViewImpl::SetFocus(bool enable) { 1132 void WebViewImpl::SetFocus(bool enable) {
1133 page_->focusController()->setFocused(enable);
1134 if (enable) { 1134 if (enable) {
1135 // Getting the focused frame will have the side-effect of setting the main 1135 // Note that we don't call setActive() when disabled as this cause extra
1136 // frame as the focused frame if it is not already focused. Otherwise, if 1136 // focus/blur events to be dispatched.
1137 // there is already a focused frame, then this does nothing. 1137 page_->focusController()->setActive(true);
1138 GetFocusedFrame();
1139 if (page_.get() && page_->mainFrame()) {
1140 Frame* frame = page_->mainFrame();
1141 if (!frame->selection()->isFocusedAndActive()) {
1142 // No one has focus yet, try to restore focus.
1143 RestoreFocus();
1144 page_->focusController()->setActive(true);
1145 }
1146 Frame* focused_frame = page_->focusController()->focusedOrMainFrame();
1147 frame->selection()->setFocused(frame == focused_frame);
1148 }
1149 ime_accept_events_ = true; 1138 ime_accept_events_ = true;
1150 } else { 1139 } else {
1151 HideAutoCompletePopup(); 1140 HideAutoCompletePopup();
1152 1141
1153 // Clear out who last had focus. If someone has focus, the refs will be
1154 // updated below.
1155 ReleaseFocusReferences();
1156
1157 // Clear focus on the currently focused frame if any. 1142 // Clear focus on the currently focused frame if any.
1158 if (!page_.get()) 1143 if (!page_.get())
1159 return; 1144 return;
1160 1145
1161 Frame* frame = page_->mainFrame(); 1146 Frame* frame = page_->mainFrame();
1162 if (!frame) 1147 if (!frame)
1163 return; 1148 return;
1164 1149
1165 RefPtr<Frame> focused = page_->focusController()->focusedFrame(); 1150 RefPtr<Frame> focused_frame = page_->focusController()->focusedFrame();
1166 if (focused.get()) { 1151 if (focused_frame.get()) {
1167 // Update the focus refs, this way we can give focus back appropriately.
1168 // It's entirely possible to have a focused document, but not a focused
1169 // node.
1170 RefPtr<Document> document = focused->document();
1171 last_focused_frame_ = focused;
1172 if (document.get()) {
1173 RefPtr<Node> focused_node = document->focusedNode();
1174 if (focused_node.get()) {
1175 // To workaround bug #792423, we do not blur the focused node. This
1176 // should be reenabled when we merge a WebKit that has the fix for
1177 // http://bugs.webkit.org/show_bug.cgi?id=16928.
1178 // last_focused_node_ = focused_node;
1179 // document->setFocusedNode(NULL);
1180 }
1181 }
1182 page_->focusController()->setFocusedFrame(0);
1183
1184 // Finish an ongoing composition to delete the composition node. 1152 // Finish an ongoing composition to delete the composition node.
1185 Editor* editor = focused->editor(); 1153 Editor* editor = focused_frame->editor();
1186 if (editor && editor->hasComposition()) 1154 if (editor && editor->hasComposition())
1187 editor->confirmComposition(); 1155 editor->confirmComposition();
1188 ime_accept_events_ = false; 1156 ime_accept_events_ = false;
1189 } 1157 }
1190 // Make sure the main frame doesn't think it has focus.
1191 if (frame != focused.get())
1192 frame->selection()->setFocused(false);
1193 }
1194 }
1195
1196 // TODO(jcampan): http://b/issue?id=1157486 this is needed to work-around
1197 // issues caused by the fix for bug #792423 and should be removed when that
1198 // bug is fixed.
1199 void WebViewImpl::StoreFocusForFrame(WebFrame* frame) {
1200 DCHECK(frame);
1201
1202 // We only want to store focus info if we are the focused frame and if we have
1203 // not stored it already.
1204 WebCore::Frame* webcore_frame = static_cast<WebFrameImpl*>(frame)->frame();
1205 if (last_focused_frame_.get() != webcore_frame || last_focused_node_.get())
1206 return;
1207
1208 // Clear out who last had focus. If someone has focus, the refs will be
1209 // updated below.
1210 ReleaseFocusReferences();
1211
1212 last_focused_frame_ = webcore_frame;
1213 RefPtr<Document> document = last_focused_frame_->document();
1214 if (document.get()) {
1215 RefPtr<Node> focused_node = document->focusedNode();
1216 if (focused_node.get()) {
1217 last_focused_node_ = focused_node;
1218 document->setFocusedNode(NULL);
1219 }
1220 } 1158 }
1221 } 1159 }
1222 1160
1223 bool WebViewImpl::ImeSetComposition(int string_type, 1161 bool WebViewImpl::ImeSetComposition(int string_type,
1224 int cursor_position, 1162 int cursor_position,
1225 int target_start, 1163 int target_start,
1226 int target_end, 1164 int target_end,
1227 const std::wstring& ime_string) { 1165 const std::wstring& ime_string) {
1228 Frame* focused = GetFocusedWebCoreFrame(); 1166 Frame* focused = GetFocusedWebCoreFrame();
1229 if (!focused || !ime_accept_events_) { 1167 if (!focused || !ime_accept_events_) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 case WEB_TEXT_DIRECTION_RTL: 1301 case WEB_TEXT_DIRECTION_RTL:
1364 editor->setBaseWritingDirection(WebCore::RightToLeftWritingDirection); 1302 editor->setBaseWritingDirection(WebCore::RightToLeftWritingDirection);
1365 break; 1303 break;
1366 1304
1367 default: 1305 default:
1368 NOTIMPLEMENTED(); 1306 NOTIMPLEMENTED();
1369 break; 1307 break;
1370 } 1308 }
1371 } 1309 }
1372 1310
1373 void WebViewImpl::RestoreFocus() {
1374 if (last_focused_frame_.get()) {
1375 if (last_focused_frame_->page()) {
1376 // last_focused_frame_ can be detached from the frame tree, thus,
1377 // its page can be null.
1378 last_focused_frame_->page()->focusController()->setFocusedFrame(
1379 last_focused_frame_.get());
1380 }
1381 if (last_focused_node_.get()) {
1382 // last_focused_node_ may be null, make sure it's valid before trying to
1383 // focus it.
1384 static_cast<Element*>(last_focused_node_.get())->focus();
1385 }
1386 // And clear out the refs.
1387 ReleaseFocusReferences();
1388 }
1389 }
1390
1391 void WebViewImpl::SetInitialFocus(bool reverse) { 1311 void WebViewImpl::SetInitialFocus(bool reverse) {
1392 if (page_.get()) { 1312 if (page_.get()) {
1393 // So RestoreFocus does not focus anything when it is called.
1394 ReleaseFocusReferences();
1395
1396 // Since we don't have a keyboard event, we'll create one. 1313 // Since we don't have a keyboard event, we'll create one.
1397 WebKeyboardEvent keyboard_event; 1314 WebKeyboardEvent keyboard_event;
1398 keyboard_event.type = WebInputEvent::RawKeyDown; 1315 keyboard_event.type = WebInputEvent::RawKeyDown;
1399 if (reverse) 1316 if (reverse)
1400 keyboard_event.modifiers = WebInputEvent::ShiftKey; 1317 keyboard_event.modifiers = WebInputEvent::ShiftKey;
1401 // VK_TAB which is only defined on Windows. 1318 // VK_TAB which is only defined on Windows.
1402 keyboard_event.windowsKeyCode = 0x09; 1319 keyboard_event.windowsKeyCode = 0x09;
1403 MakePlatformKeyboardEvent platform_event(keyboard_event); 1320 MakePlatformKeyboardEvent platform_event(keyboard_event);
1404 RefPtr<KeyboardEvent> webkit_event = 1321 RefPtr<KeyboardEvent> webkit_event =
1405 KeyboardEvent::create(platform_event, NULL); 1322 KeyboardEvent::create(platform_event, NULL);
1406 page()->focusController()->setInitialFocus( 1323 page()->focusController()->setInitialFocus(
1407 reverse ? WebCore::FocusDirectionBackward : 1324 reverse ? WebCore::FocusDirectionBackward :
1408 WebCore::FocusDirectionForward, 1325 WebCore::FocusDirectionForward,
1409 webkit_event.get()); 1326 webkit_event.get());
1410 } 1327 }
1411 } 1328 }
1412 1329
1413 // Releases references used to restore focus.
1414 void WebViewImpl::ReleaseFocusReferences() {
1415 if (last_focused_frame_.get()) {
1416 last_focused_frame_.release();
1417 last_focused_node_.release();
1418 }
1419 }
1420
1421 bool WebViewImpl::DownloadImage(int id, const GURL& image_url, int image_size) { 1330 bool WebViewImpl::DownloadImage(int id, const GURL& image_url, int image_size) {
1422 if (!page_.get()) 1331 if (!page_.get())
1423 return false; 1332 return false;
1424 image_fetchers_.insert( 1333 image_fetchers_.insert(
1425 new ImageResourceFetcher(this, id, image_url, image_size)); 1334 new ImageResourceFetcher(this, id, image_url, image_size));
1426 return true; 1335 return true;
1427 } 1336 }
1428 1337
1429 void WebViewImpl::SetPreferences(const WebPreferences& preferences) { 1338 void WebViewImpl::SetPreferences(const WebPreferences& preferences) {
1430 if (!page_.get()) 1339 if (!page_.get())
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 1850
1942 return document->focusedNode(); 1851 return document->focusedNode();
1943 } 1852 }
1944 1853
1945 HitTestResult WebViewImpl::HitTestResultForWindowPos(const IntPoint& pos) { 1854 HitTestResult WebViewImpl::HitTestResultForWindowPos(const IntPoint& pos) {
1946 IntPoint doc_point( 1855 IntPoint doc_point(
1947 page_->mainFrame()->view()->windowToContents(pos)); 1856 page_->mainFrame()->view()->windowToContents(pos));
1948 return page_->mainFrame()->eventHandler()-> 1857 return page_->mainFrame()->eventHandler()->
1949 hitTestResultAtPoint(doc_point, false); 1858 hitTestResultAtPoint(doc_point, false);
1950 } 1859 }
OLDNEW
« no previous file with comments | « webkit/glue/webview_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698