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

Side by Side Diff: third_party/WebKit/Source/web/WebViewImpl.cpp

Issue 2485693003: Drag-and-drop: DragEnter, DragOver, DragLeave, DragDrop (Closed)
Patch Set: Rebased. More fixes. Created 4 years, 1 month 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 // invocations. 234 // invocations.
235 static Vector<std::unique_ptr<ScopedPageLoadDeferrer>>& 235 static Vector<std::unique_ptr<ScopedPageLoadDeferrer>>&
236 pageLoadDeferrerStack() { 236 pageLoadDeferrerStack() {
237 DEFINE_STATIC_LOCAL(Vector<std::unique_ptr<ScopedPageLoadDeferrer>>, 237 DEFINE_STATIC_LOCAL(Vector<std::unique_ptr<ScopedPageLoadDeferrer>>,
238 deferrerStack, ()); 238 deferrerStack, ());
239 return deferrerStack; 239 return deferrerStack;
240 } 240 }
241 241
242 // Ensure that the WebDragOperation enum values stay in sync with the original 242 // Ensure that the WebDragOperation enum values stay in sync with the original
243 // DragOperation constants. 243 // DragOperation constants.
244 // TODO(paulmeyer): Move this into WebFrameWidgetBase once all drag-and-drop
245 // functions are out of WebViewImpl. See crbug.com/647249.
244 #define STATIC_ASSERT_ENUM(a, b) \ 246 #define STATIC_ASSERT_ENUM(a, b) \
245 static_assert(static_cast<int>(a) == static_cast<int>(b), \ 247 static_assert(static_cast<int>(a) == static_cast<int>(b), \
246 "mismatching enum : " #a) 248 "mismatching enum : " #a)
247 STATIC_ASSERT_ENUM(DragOperationNone, WebDragOperationNone); 249 STATIC_ASSERT_ENUM(DragOperationNone, WebDragOperationNone);
248 STATIC_ASSERT_ENUM(DragOperationCopy, WebDragOperationCopy); 250 STATIC_ASSERT_ENUM(DragOperationCopy, WebDragOperationCopy);
249 STATIC_ASSERT_ENUM(DragOperationLink, WebDragOperationLink); 251 STATIC_ASSERT_ENUM(DragOperationLink, WebDragOperationLink);
250 STATIC_ASSERT_ENUM(DragOperationGeneric, WebDragOperationGeneric); 252 STATIC_ASSERT_ENUM(DragOperationGeneric, WebDragOperationGeneric);
251 STATIC_ASSERT_ENUM(DragOperationPrivate, WebDragOperationPrivate); 253 STATIC_ASSERT_ENUM(DragOperationPrivate, WebDragOperationPrivate);
252 STATIC_ASSERT_ENUM(DragOperationMove, WebDragOperationMove); 254 STATIC_ASSERT_ENUM(DragOperationMove, WebDragOperationMove);
253 STATIC_ASSERT_ENUM(DragOperationDelete, WebDragOperationDelete); 255 STATIC_ASSERT_ENUM(DragOperationDelete, WebDragOperationDelete);
254 STATIC_ASSERT_ENUM(DragOperationEvery, WebDragOperationEvery); 256 STATIC_ASSERT_ENUM(DragOperationEvery, WebDragOperationEvery);
255 257
256 static bool shouldUseExternalPopupMenus = false; 258 static bool shouldUseExternalPopupMenus = false;
257 259
258 namespace { 260 namespace {
259 261
260 class UserGestureNotifier {
261 public:
262 // If a UserGestureIndicator is created for a user gesture since the last
263 // page load and *userGestureObserved is false, the UserGestureNotifier
264 // will notify the client and set *userGestureObserved to true.
265 UserGestureNotifier(WebLocalFrameImpl*, bool* userGestureObserved);
266 ~UserGestureNotifier();
267
268 private:
269 Persistent<WebLocalFrameImpl> m_frame;
270 bool* const m_userGestureObserved;
271 };
272
273 UserGestureNotifier::UserGestureNotifier(WebLocalFrameImpl* frame,
274 bool* userGestureObserved)
275 : m_frame(frame), m_userGestureObserved(userGestureObserved) {
276 DCHECK(m_userGestureObserved);
277 }
278
279 UserGestureNotifier::~UserGestureNotifier() {
280 if (!*m_userGestureObserved &&
281 m_frame->frame()->document()->hasReceivedUserGesture()) {
282 *m_userGestureObserved = true;
283 if (m_frame && m_frame->autofillClient())
284 m_frame->autofillClient()->firstUserGestureObserved();
285 }
286 }
287
288 class EmptyEventListener final : public EventListener { 262 class EmptyEventListener final : public EventListener {
289 public: 263 public:
290 static EmptyEventListener* create() { return new EmptyEventListener(); } 264 static EmptyEventListener* create() { return new EmptyEventListener(); }
291 265
292 bool operator==(const EventListener& other) const override { 266 bool operator==(const EventListener& other) const override {
293 return this == &other; 267 return this == &other;
294 } 268 }
295 269
296 private: 270 private:
297 EmptyEventListener() : EventListener(CPPEventListenerType) {} 271 EmptyEventListener() : EventListener(CPPEventListenerType) {}
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 m_doubleTapZoomPageScaleFactor(0), 377 m_doubleTapZoomPageScaleFactor(0),
404 m_doubleTapZoomPending(false), 378 m_doubleTapZoomPending(false),
405 m_enableFakePageScaleAnimationForTesting(false), 379 m_enableFakePageScaleAnimationForTesting(false),
406 m_fakePageScaleAnimationPageScaleFactor(0), 380 m_fakePageScaleAnimationPageScaleFactor(0),
407 m_fakePageScaleAnimationUseAnchor(false), 381 m_fakePageScaleAnimationUseAnchor(false),
408 m_doingDragAndDrop(false), 382 m_doingDragAndDrop(false),
409 m_ignoreInputEvents(false), 383 m_ignoreInputEvents(false),
410 m_compositorDeviceScaleFactorOverride(0), 384 m_compositorDeviceScaleFactorOverride(0),
411 m_suppressNextKeypressEvent(false), 385 m_suppressNextKeypressEvent(false),
412 m_imeAcceptEvents(true), 386 m_imeAcceptEvents(true),
413 m_operationsAllowed(WebDragOperationNone),
414 m_dragOperation(WebDragOperationNone),
415 m_devToolsEmulator(nullptr), 387 m_devToolsEmulator(nullptr),
416 m_isTransparent(false), 388 m_isTransparent(false),
417 m_tabsToLinks(false), 389 m_tabsToLinks(false),
418 m_layerTreeView(nullptr), 390 m_layerTreeView(nullptr),
419 m_rootLayer(nullptr), 391 m_rootLayer(nullptr),
420 m_rootGraphicsLayer(nullptr), 392 m_rootGraphicsLayer(nullptr),
421 m_visualViewportContainerLayer(nullptr), 393 m_visualViewportContainerLayer(nullptr),
422 m_matchesHeuristicsForGpuRasterization(false), 394 m_matchesHeuristicsForGpuRasterization(false),
423 m_flingModifier(0), 395 m_flingModifier(0),
424 m_flingSourceDevice(WebGestureDeviceUninitialized), 396 m_flingSourceDevice(WebGestureDeviceUninitialized),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 448
477 WebViewImpl::~WebViewImpl() { 449 WebViewImpl::~WebViewImpl() {
478 DCHECK(!m_page); 450 DCHECK(!m_page);
479 451
480 // Each highlight uses m_owningWebViewImpl->m_linkHighlightsTimeline 452 // Each highlight uses m_owningWebViewImpl->m_linkHighlightsTimeline
481 // in destructor. m_linkHighlightsTimeline might be destroyed earlier 453 // in destructor. m_linkHighlightsTimeline might be destroyed earlier
482 // than m_linkHighlights. 454 // than m_linkHighlights.
483 DCHECK(m_linkHighlights.isEmpty()); 455 DCHECK(m_linkHighlights.isEmpty());
484 } 456 }
485 457
458 WebViewImpl::UserGestureNotifier::UserGestureNotifier(WebViewImpl* view)
459 : m_frame(view->mainFrameImpl()),
460 m_userGestureObserved(&view->m_userGestureObserved) {
461 DCHECK(m_userGestureObserved);
462 }
463
464 WebViewImpl::UserGestureNotifier::~UserGestureNotifier() {
465 if (!*m_userGestureObserved &&
466 m_frame->frame()->document()->hasReceivedUserGesture()) {
467 *m_userGestureObserved = true;
468 if (m_frame && m_frame->autofillClient())
469 m_frame->autofillClient()->firstUserGestureObserved();
470 }
471 }
472
486 WebDevToolsAgentImpl* WebViewImpl::mainFrameDevToolsAgentImpl() { 473 WebDevToolsAgentImpl* WebViewImpl::mainFrameDevToolsAgentImpl() {
487 WebLocalFrameImpl* mainFrame = mainFrameImpl(); 474 WebLocalFrameImpl* mainFrame = mainFrameImpl();
488 return mainFrame ? mainFrame->devToolsAgentImpl() : nullptr; 475 return mainFrame ? mainFrame->devToolsAgentImpl() : nullptr;
489 } 476 }
490 477
491 InspectorOverlay* WebViewImpl::inspectorOverlay() { 478 InspectorOverlay* WebViewImpl::inspectorOverlay() {
492 if (WebDevToolsAgentImpl* devtools = mainFrameDevToolsAgentImpl()) 479 if (WebDevToolsAgentImpl* devtools = mainFrameDevToolsAgentImpl())
493 return devtools->overlay(); 480 return devtools->overlay();
494 return nullptr; 481 return nullptr;
495 } 482 }
(...skipping 1635 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 2118
2132 WebInputEventResult WebViewImpl::handleInputEvent( 2119 WebInputEventResult WebViewImpl::handleInputEvent(
2133 const WebInputEvent& inputEvent) { 2120 const WebInputEvent& inputEvent) {
2134 // TODO(dcheng): The fact that this is getting called when there is no local 2121 // TODO(dcheng): The fact that this is getting called when there is no local
2135 // main frame is problematic and probably indicates a bug in the input event 2122 // main frame is problematic and probably indicates a bug in the input event
2136 // routing code. 2123 // routing code.
2137 if (!mainFrameImpl()) 2124 if (!mainFrameImpl())
2138 return WebInputEventResult::NotHandled; 2125 return WebInputEventResult::NotHandled;
2139 2126
2140 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient(); 2127 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient();
2141 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved); 2128 UserGestureNotifier notifier(this);
2142 // On the first input event since page load, |notifier| instructs the 2129 // On the first input event since page load, |notifier| instructs the
2143 // autofill client to unblock values of password input fields of any forms 2130 // autofill client to unblock values of password input fields of any forms
2144 // on the page. There is a single input event, GestureTap, which can both 2131 // on the page. There is a single input event, GestureTap, which can both
2145 // be the first event after page load, and cause a form submission. In that 2132 // be the first event after page load, and cause a form submission. In that
2146 // case, the form submission happens before the autofill client is told 2133 // case, the form submission happens before the autofill client is told
2147 // to unblock the password values, and so the password values are not 2134 // to unblock the password values, and so the password values are not
2148 // submitted. To avoid that, GestureTap is handled explicitly: 2135 // submitted. To avoid that, GestureTap is handled explicitly:
2149 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) { 2136 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) {
2150 m_userGestureObserved = true; 2137 m_userGestureObserved = true;
2151 autofillClient->firstUserGestureObserved(); 2138 autofillClient->firstUserGestureObserved();
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after
3430 3417
3431 void WebViewImpl::dragSourceSystemDragEnded() { 3418 void WebViewImpl::dragSourceSystemDragEnded() {
3432 // It's possible for us to get this callback while not doing a drag if 3419 // It's possible for us to get this callback while not doing a drag if
3433 // it's from a previous page that got unloaded. 3420 // it's from a previous page that got unloaded.
3434 if (m_doingDragAndDrop) { 3421 if (m_doingDragAndDrop) {
3435 m_page->dragController().dragEnded(); 3422 m_page->dragController().dragEnded();
3436 m_doingDragAndDrop = false; 3423 m_doingDragAndDrop = false;
3437 } 3424 }
3438 } 3425 }
3439 3426
3440 WebDragOperation WebViewImpl::dragTargetDragEnter(
3441 const WebDragData& webDragData,
3442 const WebPoint& pointInViewport,
3443 const WebPoint& screenPoint,
3444 WebDragOperationsMask operationsAllowed,
3445 int modifiers) {
3446 DCHECK(!m_currentDragData);
3447
3448 m_currentDragData = DataObject::create(webDragData);
3449 m_operationsAllowed = operationsAllowed;
3450
3451 return dragTargetDragEnterOrOver(pointInViewport, screenPoint, DragEnter,
3452 modifiers);
3453 }
3454
3455 WebDragOperation WebViewImpl::dragTargetDragOver(
3456 const WebPoint& pointInViewport,
3457 const WebPoint& screenPoint,
3458 WebDragOperationsMask operationsAllowed,
3459 int modifiers) {
3460 m_operationsAllowed = operationsAllowed;
3461
3462 return dragTargetDragEnterOrOver(pointInViewport, screenPoint, DragOver,
3463 modifiers);
3464 }
3465
3466 void WebViewImpl::dragTargetDragLeave() {
3467 DCHECK(m_currentDragData);
3468
3469 DragData dragData(m_currentDragData.get(), IntPoint(), IntPoint(),
3470 static_cast<DragOperation>(m_operationsAllowed));
3471
3472 m_page->dragController().dragExited(&dragData);
3473
3474 // FIXME: why is the drag scroll timer not stopped here?
3475
3476 m_dragOperation = WebDragOperationNone;
3477 m_currentDragData = nullptr;
3478 }
3479
3480 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData,
3481 const WebPoint& pointInViewport,
3482 const WebPoint& screenPoint,
3483 int modifiers) {
3484 WebPoint pointInRootFrame(
3485 page()->frameHost().visualViewport().viewportToRootFrame(
3486 pointInViewport));
3487
3488 DCHECK(m_currentDragData);
3489 m_currentDragData = DataObject::create(webDragData);
3490 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved);
3491
3492 // If this webview transitions from the "drop accepting" state to the "not
3493 // accepting" state, then our IPC message reply indicating that may be in-
3494 // flight, or else delayed by javascript processing in this webview. If a
3495 // drop happens before our IPC reply has reached the browser process, then
3496 // the browser forwards the drop to this webview. So only allow a drop to
3497 // proceed if our webview m_dragOperation state is not DragOperationNone.
3498
3499 if (m_dragOperation ==
3500 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop.
3501 dragTargetDragLeave();
3502 return;
3503 }
3504
3505 m_currentDragData->setModifiers(modifiers);
3506 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint,
3507 static_cast<DragOperation>(m_operationsAllowed));
3508
3509 m_page->dragController().performDrag(&dragData);
3510
3511 m_dragOperation = WebDragOperationNone;
3512 m_currentDragData = nullptr;
3513 }
3514
3515 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) { 3427 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) {
3516 Vector<uint32_t> result; 3428 Vector<uint32_t> result;
3517 for (Frame* frame = m_page->mainFrame(); frame; 3429 for (Frame* frame = m_page->mainFrame(); frame;
3518 frame = frame->tree().traverseNext()) { 3430 frame = frame->tree().traverseNext()) {
3519 if (!frame->isLocalFrame()) 3431 if (!frame->isLocalFrame())
3520 continue; 3432 continue;
3521 const DocumentMarkerVector& documentMarkers = 3433 const DocumentMarkerVector& documentMarkers =
3522 toLocalFrame(frame)->document()->markers().markers(); 3434 toLocalFrame(frame)->document()->markers().markers();
3523 for (size_t i = 0; i < documentMarkers.size(); ++i) 3435 for (size_t i = 0; i < documentMarkers.size(); ++i)
3524 result.append(documentMarkers[i]->hash()); 3436 result.append(documentMarkers[i]->hash());
3525 } 3437 }
3526 markers->assign(result); 3438 markers->assign(result);
3527 } 3439 }
3528 3440
3529 void WebViewImpl::removeSpellingMarkersUnderWords( 3441 void WebViewImpl::removeSpellingMarkersUnderWords(
3530 const WebVector<WebString>& words) { 3442 const WebVector<WebString>& words) {
3531 Vector<String> convertedWords; 3443 Vector<String> convertedWords;
3532 convertedWords.append(words.data(), words.size()); 3444 convertedWords.append(words.data(), words.size());
3533 3445
3534 for (Frame* frame = m_page->mainFrame(); frame; 3446 for (Frame* frame = m_page->mainFrame(); frame;
3535 frame = frame->tree().traverseNext()) { 3447 frame = frame->tree().traverseNext()) {
3536 if (frame->isLocalFrame()) 3448 if (frame->isLocalFrame())
3537 toLocalFrame(frame)->removeSpellingMarkersUnderWords(convertedWords); 3449 toLocalFrame(frame)->removeSpellingMarkersUnderWords(convertedWords);
3538 } 3450 }
3539 } 3451 }
3540 3452
3541 WebDragOperation WebViewImpl::dragTargetDragEnterOrOver(
3542 const WebPoint& pointInViewport,
3543 const WebPoint& screenPoint,
3544 DragAction dragAction,
3545 int modifiers) {
3546 DCHECK(m_currentDragData);
3547
3548 WebPoint pointInRootFrame(
3549 page()->frameHost().visualViewport().viewportToRootFrame(
3550 pointInViewport));
3551
3552 m_currentDragData->setModifiers(modifiers);
3553 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint,
3554 static_cast<DragOperation>(m_operationsAllowed));
3555
3556 DragSession dragSession;
3557 dragSession = m_page->dragController().dragEnteredOrUpdated(&dragData);
3558
3559 DragOperation dropEffect = dragSession.operation;
3560
3561 // Mask the drop effect operation against the drag source's allowed
3562 // operations.
3563 if (!(dropEffect & dragData.draggingSourceOperationMask()))
3564 dropEffect = DragOperationNone;
3565
3566 m_dragOperation = static_cast<WebDragOperation>(dropEffect);
3567
3568 return m_dragOperation;
3569 }
3570
3571 void WebViewImpl::sendResizeEventAndRepaint() { 3453 void WebViewImpl::sendResizeEventAndRepaint() {
3572 // FIXME: This is wrong. The FrameView is responsible sending a resizeEvent 3454 // FIXME: This is wrong. The FrameView is responsible sending a resizeEvent
3573 // as part of layout. Layout is also responsible for sending invalidations 3455 // as part of layout. Layout is also responsible for sending invalidations
3574 // to the embedder. This method and all callers may be wrong. -- eseidel. 3456 // to the embedder. This method and all callers may be wrong. -- eseidel.
3575 if (mainFrameImpl()->frameView()) { 3457 if (mainFrameImpl()->frameView()) {
3576 // Enqueues the resize event. 3458 // Enqueues the resize event.
3577 mainFrameImpl()->frame()->document()->enqueueResizeEvent(); 3459 mainFrameImpl()->frame()->document()->enqueueResizeEvent();
3578 } 3460 }
3579 3461
3580 if (m_client) { 3462 if (m_client) {
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after
4366 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) 4248 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame())
4367 return nullptr; 4249 return nullptr;
4368 return focusedFrame; 4250 return focusedFrame;
4369 } 4251 }
4370 4252
4371 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { 4253 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const {
4372 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; 4254 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr;
4373 } 4255 }
4374 4256
4375 } // namespace blink 4257 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/web/WebViewImpl.h ('k') | third_party/WebKit/Source/web/tests/WebViewTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698