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

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

Issue 2485693003: Drag-and-drop: DragEnter, DragOver, DragLeave, DragDrop (Closed)
Patch Set: Rebased. 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 // invocations. 233 // invocations.
234 static Vector<std::unique_ptr<ScopedPageLoadDeferrer>>& 234 static Vector<std::unique_ptr<ScopedPageLoadDeferrer>>&
235 pageLoadDeferrerStack() { 235 pageLoadDeferrerStack() {
236 DEFINE_STATIC_LOCAL(Vector<std::unique_ptr<ScopedPageLoadDeferrer>>, 236 DEFINE_STATIC_LOCAL(Vector<std::unique_ptr<ScopedPageLoadDeferrer>>,
237 deferrerStack, ()); 237 deferrerStack, ());
238 return deferrerStack; 238 return deferrerStack;
239 } 239 }
240 240
241 // Ensure that the WebDragOperation enum values stay in sync with the original 241 // Ensure that the WebDragOperation enum values stay in sync with the original
242 // DragOperation constants. 242 // DragOperation constants.
243 // TODO(paulmeyer): Move this into WebFrameWidgetBase once all drag-and-drop
244 // functions are out of WebViewImpl.
243 #define STATIC_ASSERT_ENUM(a, b) \ 245 #define STATIC_ASSERT_ENUM(a, b) \
244 static_assert(static_cast<int>(a) == static_cast<int>(b), \ 246 static_assert(static_cast<int>(a) == static_cast<int>(b), \
245 "mismatching enum : " #a) 247 "mismatching enum : " #a)
246 STATIC_ASSERT_ENUM(DragOperationNone, WebDragOperationNone); 248 STATIC_ASSERT_ENUM(DragOperationNone, WebDragOperationNone);
247 STATIC_ASSERT_ENUM(DragOperationCopy, WebDragOperationCopy); 249 STATIC_ASSERT_ENUM(DragOperationCopy, WebDragOperationCopy);
248 STATIC_ASSERT_ENUM(DragOperationLink, WebDragOperationLink); 250 STATIC_ASSERT_ENUM(DragOperationLink, WebDragOperationLink);
249 STATIC_ASSERT_ENUM(DragOperationGeneric, WebDragOperationGeneric); 251 STATIC_ASSERT_ENUM(DragOperationGeneric, WebDragOperationGeneric);
250 STATIC_ASSERT_ENUM(DragOperationPrivate, WebDragOperationPrivate); 252 STATIC_ASSERT_ENUM(DragOperationPrivate, WebDragOperationPrivate);
251 STATIC_ASSERT_ENUM(DragOperationMove, WebDragOperationMove); 253 STATIC_ASSERT_ENUM(DragOperationMove, WebDragOperationMove);
252 STATIC_ASSERT_ENUM(DragOperationDelete, WebDragOperationDelete); 254 STATIC_ASSERT_ENUM(DragOperationDelete, WebDragOperationDelete);
253 STATIC_ASSERT_ENUM(DragOperationEvery, WebDragOperationEvery); 255 STATIC_ASSERT_ENUM(DragOperationEvery, WebDragOperationEvery);
254 256
255 static bool shouldUseExternalPopupMenus = false; 257 static bool shouldUseExternalPopupMenus = false;
256 258
257 namespace { 259 namespace {
258 260
259 class UserGestureNotifier {
260 public:
261 // If a UserGestureIndicator is created for a user gesture since the last
262 // page load and *userGestureObserved is false, the UserGestureNotifier
263 // will notify the client and set *userGestureObserved to true.
264 UserGestureNotifier(WebLocalFrameImpl*, bool* userGestureObserved);
265 ~UserGestureNotifier();
266
267 private:
268 Persistent<WebLocalFrameImpl> m_frame;
269 bool* const m_userGestureObserved;
270 };
271
272 UserGestureNotifier::UserGestureNotifier(WebLocalFrameImpl* frame,
273 bool* userGestureObserved)
274 : m_frame(frame), m_userGestureObserved(userGestureObserved) {
275 DCHECK(m_userGestureObserved);
276 }
277
278 UserGestureNotifier::~UserGestureNotifier() {
279 if (!*m_userGestureObserved &&
280 m_frame->frame()->document()->hasReceivedUserGesture()) {
281 *m_userGestureObserved = true;
282 if (m_frame && m_frame->autofillClient())
283 m_frame->autofillClient()->firstUserGestureObserved();
284 }
285 }
286
287 class EmptyEventListener final : public EventListener { 261 class EmptyEventListener final : public EventListener {
288 public: 262 public:
289 static EmptyEventListener* create() { return new EmptyEventListener(); } 263 static EmptyEventListener* create() { return new EmptyEventListener(); }
290 264
291 bool operator==(const EventListener& other) const override { 265 bool operator==(const EventListener& other) const override {
292 return this == &other; 266 return this == &other;
293 } 267 }
294 268
295 private: 269 private:
296 EmptyEventListener() : EventListener(CPPEventListenerType) {} 270 EmptyEventListener() : EventListener(CPPEventListenerType) {}
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 m_doubleTapZoomPageScaleFactor(0), 376 m_doubleTapZoomPageScaleFactor(0),
403 m_doubleTapZoomPending(false), 377 m_doubleTapZoomPending(false),
404 m_enableFakePageScaleAnimationForTesting(false), 378 m_enableFakePageScaleAnimationForTesting(false),
405 m_fakePageScaleAnimationPageScaleFactor(0), 379 m_fakePageScaleAnimationPageScaleFactor(0),
406 m_fakePageScaleAnimationUseAnchor(false), 380 m_fakePageScaleAnimationUseAnchor(false),
407 m_doingDragAndDrop(false), 381 m_doingDragAndDrop(false),
408 m_ignoreInputEvents(false), 382 m_ignoreInputEvents(false),
409 m_compositorDeviceScaleFactorOverride(0), 383 m_compositorDeviceScaleFactorOverride(0),
410 m_suppressNextKeypressEvent(false), 384 m_suppressNextKeypressEvent(false),
411 m_imeAcceptEvents(true), 385 m_imeAcceptEvents(true),
412 m_operationsAllowed(WebDragOperationNone),
413 m_dragOperation(WebDragOperationNone),
414 m_devToolsEmulator(nullptr), 386 m_devToolsEmulator(nullptr),
415 m_isTransparent(false), 387 m_isTransparent(false),
416 m_tabsToLinks(false), 388 m_tabsToLinks(false),
417 m_layerTreeView(nullptr), 389 m_layerTreeView(nullptr),
418 m_rootLayer(nullptr), 390 m_rootLayer(nullptr),
419 m_rootGraphicsLayer(nullptr), 391 m_rootGraphicsLayer(nullptr),
420 m_visualViewportContainerLayer(nullptr), 392 m_visualViewportContainerLayer(nullptr),
421 m_matchesHeuristicsForGpuRasterization(false), 393 m_matchesHeuristicsForGpuRasterization(false),
422 m_flingModifier(0), 394 m_flingModifier(0),
423 m_flingSourceDevice(WebGestureDeviceUninitialized), 395 m_flingSourceDevice(WebGestureDeviceUninitialized),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 447
476 WebViewImpl::~WebViewImpl() { 448 WebViewImpl::~WebViewImpl() {
477 DCHECK(!m_page); 449 DCHECK(!m_page);
478 450
479 // Each highlight uses m_owningWebViewImpl->m_linkHighlightsTimeline 451 // Each highlight uses m_owningWebViewImpl->m_linkHighlightsTimeline
480 // in destructor. m_linkHighlightsTimeline might be destroyed earlier 452 // in destructor. m_linkHighlightsTimeline might be destroyed earlier
481 // than m_linkHighlights. 453 // than m_linkHighlights.
482 DCHECK(m_linkHighlights.isEmpty()); 454 DCHECK(m_linkHighlights.isEmpty());
483 } 455 }
484 456
457 WebViewImpl::UserGestureNotifier::UserGestureNotifier(WebViewImpl* view)
458 : m_frame(view->mainFrameImpl()),
459 m_userGestureObserved(&view->m_userGestureObserved) {
460 DCHECK(m_userGestureObserved);
461 }
462
463 WebViewImpl::UserGestureNotifier::~UserGestureNotifier() {
464 if (!*m_userGestureObserved &&
465 m_frame->frame()->document()->hasReceivedUserGesture()) {
466 *m_userGestureObserved = true;
467 if (m_frame && m_frame->autofillClient())
468 m_frame->autofillClient()->firstUserGestureObserved();
469 }
470 }
471
485 WebDevToolsAgentImpl* WebViewImpl::mainFrameDevToolsAgentImpl() { 472 WebDevToolsAgentImpl* WebViewImpl::mainFrameDevToolsAgentImpl() {
486 WebLocalFrameImpl* mainFrame = mainFrameImpl(); 473 WebLocalFrameImpl* mainFrame = mainFrameImpl();
487 return mainFrame ? mainFrame->devToolsAgentImpl() : nullptr; 474 return mainFrame ? mainFrame->devToolsAgentImpl() : nullptr;
488 } 475 }
489 476
490 InspectorOverlay* WebViewImpl::inspectorOverlay() { 477 InspectorOverlay* WebViewImpl::inspectorOverlay() {
491 if (WebDevToolsAgentImpl* devtools = mainFrameDevToolsAgentImpl()) 478 if (WebDevToolsAgentImpl* devtools = mainFrameDevToolsAgentImpl())
492 return devtools->overlay(); 479 return devtools->overlay();
493 return nullptr; 480 return nullptr;
494 } 481 }
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 2101
2115 WebInputEventResult WebViewImpl::handleInputEvent( 2102 WebInputEventResult WebViewImpl::handleInputEvent(
2116 const WebInputEvent& inputEvent) { 2103 const WebInputEvent& inputEvent) {
2117 // TODO(dcheng): The fact that this is getting called when there is no local 2104 // TODO(dcheng): The fact that this is getting called when there is no local
2118 // main frame is problematic and probably indicates a bug in the input event 2105 // main frame is problematic and probably indicates a bug in the input event
2119 // routing code. 2106 // routing code.
2120 if (!mainFrameImpl()) 2107 if (!mainFrameImpl())
2121 return WebInputEventResult::NotHandled; 2108 return WebInputEventResult::NotHandled;
2122 2109
2123 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient(); 2110 WebAutofillClient* autofillClient = mainFrameImpl()->autofillClient();
2124 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved); 2111 UserGestureNotifier notifier(this);
2125 // On the first input event since page load, |notifier| instructs the 2112 // On the first input event since page load, |notifier| instructs the
2126 // autofill client to unblock values of password input fields of any forms 2113 // autofill client to unblock values of password input fields of any forms
2127 // on the page. There is a single input event, GestureTap, which can both 2114 // on the page. There is a single input event, GestureTap, which can both
2128 // be the first event after page load, and cause a form submission. In that 2115 // be the first event after page load, and cause a form submission. In that
2129 // case, the form submission happens before the autofill client is told 2116 // case, the form submission happens before the autofill client is told
2130 // to unblock the password values, and so the password values are not 2117 // to unblock the password values, and so the password values are not
2131 // submitted. To avoid that, GestureTap is handled explicitly: 2118 // submitted. To avoid that, GestureTap is handled explicitly:
2132 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) { 2119 if (inputEvent.type == WebInputEvent::GestureTap && autofillClient) {
2133 m_userGestureObserved = true; 2120 m_userGestureObserved = true;
2134 autofillClient->firstUserGestureObserved(); 2121 autofillClient->firstUserGestureObserved();
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
3507 3494
3508 void WebViewImpl::dragSourceSystemDragEnded() { 3495 void WebViewImpl::dragSourceSystemDragEnded() {
3509 // It's possible for us to get this callback while not doing a drag if 3496 // It's possible for us to get this callback while not doing a drag if
3510 // it's from a previous page that got unloaded. 3497 // it's from a previous page that got unloaded.
3511 if (m_doingDragAndDrop) { 3498 if (m_doingDragAndDrop) {
3512 m_page->dragController().dragEnded(); 3499 m_page->dragController().dragEnded();
3513 m_doingDragAndDrop = false; 3500 m_doingDragAndDrop = false;
3514 } 3501 }
3515 } 3502 }
3516 3503
3517 WebDragOperation WebViewImpl::dragTargetDragEnter(
3518 const WebDragData& webDragData,
3519 const WebPoint& pointInViewport,
3520 const WebPoint& screenPoint,
3521 WebDragOperationsMask operationsAllowed,
3522 int modifiers) {
3523 DCHECK(!m_currentDragData);
3524
3525 m_currentDragData = DataObject::create(webDragData);
3526 m_operationsAllowed = operationsAllowed;
3527
3528 return dragTargetDragEnterOrOver(pointInViewport, screenPoint, DragEnter,
3529 modifiers);
3530 }
3531
3532 WebDragOperation WebViewImpl::dragTargetDragOver(
3533 const WebPoint& pointInViewport,
3534 const WebPoint& screenPoint,
3535 WebDragOperationsMask operationsAllowed,
3536 int modifiers) {
3537 m_operationsAllowed = operationsAllowed;
3538
3539 return dragTargetDragEnterOrOver(pointInViewport, screenPoint, DragOver,
3540 modifiers);
3541 }
3542
3543 void WebViewImpl::dragTargetDragLeave() {
3544 DCHECK(m_currentDragData);
3545
3546 DragData dragData(m_currentDragData.get(), IntPoint(), IntPoint(),
3547 static_cast<DragOperation>(m_operationsAllowed));
3548
3549 m_page->dragController().dragExited(&dragData);
3550
3551 // FIXME: why is the drag scroll timer not stopped here?
3552
3553 m_dragOperation = WebDragOperationNone;
3554 m_currentDragData = nullptr;
3555 }
3556
3557 void WebViewImpl::dragTargetDrop(const WebDragData& webDragData,
3558 const WebPoint& pointInViewport,
3559 const WebPoint& screenPoint,
3560 int modifiers) {
3561 WebPoint pointInRootFrame(
3562 page()->frameHost().visualViewport().viewportToRootFrame(
3563 pointInViewport));
3564
3565 DCHECK(m_currentDragData);
3566 m_currentDragData = DataObject::create(webDragData);
3567 UserGestureNotifier notifier(mainFrameImpl(), &m_userGestureObserved);
3568
3569 // If this webview transitions from the "drop accepting" state to the "not
3570 // accepting" state, then our IPC message reply indicating that may be in-
3571 // flight, or else delayed by javascript processing in this webview. If a
3572 // drop happens before our IPC reply has reached the browser process, then
3573 // the browser forwards the drop to this webview. So only allow a drop to
3574 // proceed if our webview m_dragOperation state is not DragOperationNone.
3575
3576 if (m_dragOperation ==
3577 WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop.
3578 dragTargetDragLeave();
3579 return;
3580 }
3581
3582 m_currentDragData->setModifiers(modifiers);
3583 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint,
3584 static_cast<DragOperation>(m_operationsAllowed));
3585
3586 m_page->dragController().performDrag(&dragData);
3587
3588 m_dragOperation = WebDragOperationNone;
3589 m_currentDragData = nullptr;
3590 }
3591
3592 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) { 3504 void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers) {
3593 Vector<uint32_t> result; 3505 Vector<uint32_t> result;
3594 for (Frame* frame = m_page->mainFrame(); frame; 3506 for (Frame* frame = m_page->mainFrame(); frame;
3595 frame = frame->tree().traverseNext()) { 3507 frame = frame->tree().traverseNext()) {
3596 if (!frame->isLocalFrame()) 3508 if (!frame->isLocalFrame())
3597 continue; 3509 continue;
3598 const DocumentMarkerVector& documentMarkers = 3510 const DocumentMarkerVector& documentMarkers =
3599 toLocalFrame(frame)->document()->markers().markers(); 3511 toLocalFrame(frame)->document()->markers().markers();
3600 for (size_t i = 0; i < documentMarkers.size(); ++i) 3512 for (size_t i = 0; i < documentMarkers.size(); ++i)
3601 result.append(documentMarkers[i]->hash()); 3513 result.append(documentMarkers[i]->hash());
3602 } 3514 }
3603 markers->assign(result); 3515 markers->assign(result);
3604 } 3516 }
3605 3517
3606 void WebViewImpl::removeSpellingMarkersUnderWords( 3518 void WebViewImpl::removeSpellingMarkersUnderWords(
3607 const WebVector<WebString>& words) { 3519 const WebVector<WebString>& words) {
3608 Vector<String> convertedWords; 3520 Vector<String> convertedWords;
3609 convertedWords.append(words.data(), words.size()); 3521 convertedWords.append(words.data(), words.size());
3610 3522
3611 for (Frame* frame = m_page->mainFrame(); frame; 3523 for (Frame* frame = m_page->mainFrame(); frame;
3612 frame = frame->tree().traverseNext()) { 3524 frame = frame->tree().traverseNext()) {
3613 if (frame->isLocalFrame()) 3525 if (frame->isLocalFrame())
3614 toLocalFrame(frame)->removeSpellingMarkersUnderWords(convertedWords); 3526 toLocalFrame(frame)->removeSpellingMarkersUnderWords(convertedWords);
3615 } 3527 }
3616 } 3528 }
3617 3529
3618 WebDragOperation WebViewImpl::dragTargetDragEnterOrOver(
3619 const WebPoint& pointInViewport,
3620 const WebPoint& screenPoint,
3621 DragAction dragAction,
3622 int modifiers) {
3623 DCHECK(m_currentDragData);
3624
3625 WebPoint pointInRootFrame(
3626 page()->frameHost().visualViewport().viewportToRootFrame(
3627 pointInViewport));
3628
3629 m_currentDragData->setModifiers(modifiers);
3630 DragData dragData(m_currentDragData.get(), pointInRootFrame, screenPoint,
3631 static_cast<DragOperation>(m_operationsAllowed));
3632
3633 DragSession dragSession;
3634 dragSession = m_page->dragController().dragEnteredOrUpdated(&dragData);
3635
3636 DragOperation dropEffect = dragSession.operation;
3637
3638 // Mask the drop effect operation against the drag source's allowed
3639 // operations.
3640 if (!(dropEffect & dragData.draggingSourceOperationMask()))
3641 dropEffect = DragOperationNone;
3642
3643 m_dragOperation = static_cast<WebDragOperation>(dropEffect);
3644
3645 return m_dragOperation;
3646 }
3647
3648 void WebViewImpl::sendResizeEventAndRepaint() { 3530 void WebViewImpl::sendResizeEventAndRepaint() {
3649 // FIXME: This is wrong. The FrameView is responsible sending a resizeEvent 3531 // FIXME: This is wrong. The FrameView is responsible sending a resizeEvent
3650 // as part of layout. Layout is also responsible for sending invalidations 3532 // as part of layout. Layout is also responsible for sending invalidations
3651 // to the embedder. This method and all callers may be wrong. -- eseidel. 3533 // to the embedder. This method and all callers may be wrong. -- eseidel.
3652 if (mainFrameImpl()->frameView()) { 3534 if (mainFrameImpl()->frameView()) {
3653 // Enqueues the resize event. 3535 // Enqueues the resize event.
3654 mainFrameImpl()->frame()->document()->enqueueResizeEvent(); 3536 mainFrameImpl()->frame()->document()->enqueueResizeEvent();
3655 } 3537 }
3656 3538
3657 if (m_client) { 3539 if (m_client) {
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
4440 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame()) 4322 if (focusedFrame->localFrameRoot() != mainFrameImpl()->frame())
4441 return nullptr; 4323 return nullptr;
4442 return focusedFrame; 4324 return focusedFrame;
4443 } 4325 }
4444 4326
4445 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const { 4327 LocalFrame* WebViewImpl::focusedLocalFrameAvailableForIme() const {
4446 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr; 4328 return m_imeAcceptEvents ? focusedLocalFrameInWidget() : nullptr;
4447 } 4329 }
4448 4330
4449 } // namespace blink 4331 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698