Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "core/input/MouseEventManager.h" | 5 #include "core/input/MouseEventManager.h" |
| 6 | 6 |
| 7 #include "core/clipboard/DataObject.h" | 7 #include "core/clipboard/DataObject.h" |
| 8 #include "core/clipboard/DataTransfer.h" | 8 #include "core/clipboard/DataTransfer.h" |
| 9 #include "core/dom/Element.h" | 9 #include "core/dom/Element.h" |
| 10 #include "core/dom/ElementTraversal.h" | 10 #include "core/dom/ElementTraversal.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 Traversal<HTMLCanvasElement>::FirstAncestorOrSelf(*element); | 49 Traversal<HTMLCanvasElement>::FirstAncestorOrSelf(*element); |
| 50 // In this case, the event target is canvas and mouse rerouting doesn't | 50 // In this case, the event target is canvas and mouse rerouting doesn't |
| 51 // happen. | 51 // happen. |
| 52 if (canvas == element) | 52 if (canvas == element) |
| 53 return String(); | 53 return String(); |
| 54 return canvas->GetIdFromControl(element); | 54 return canvas->GetIdFromControl(element); |
| 55 } | 55 } |
| 56 | 56 |
| 57 // The amount of time to wait before sending a fake mouse event triggered | 57 // The amount of time to wait before sending a fake mouse event triggered |
| 58 // during a scroll. | 58 // during a scroll. |
| 59 const double kFakeMouseMoveInterval = 0.1; | 59 constexpr double kFakeMouseMoveIntervalDuringScroll = 0.1; |
| 60 | |
| 61 // The amount of time to wait before sending a fake mouse event on style and | |
| 62 // layout changes sets to 50Hz, same as common screen refresh rate. | |
| 63 constexpr double kFakeMouseMoveIntervalPerFrame = 0.02; | |
| 60 | 64 |
| 61 // TODO(crbug.com/653490): Read these values from the OS. | 65 // TODO(crbug.com/653490): Read these values from the OS. |
| 62 #if OS(MACOSX) | 66 #if OS(MACOSX) |
| 63 const int kDragThresholdX = 3; | 67 const int kDragThresholdX = 3; |
| 64 const int kDragThresholdY = 3; | 68 const int kDragThresholdY = 3; |
| 65 constexpr TimeDelta kTextDragDelay = TimeDelta::FromSecondsD(0.15); | 69 constexpr TimeDelta kTextDragDelay = TimeDelta::FromSecondsD(0.15); |
| 66 #else | 70 #else |
| 67 const int kDragThresholdX = 4; | 71 const int kDragThresholdX = 4; |
| 68 const int kDragThresholdY = 4; | 72 const int kDragThresholdY = 4; |
| 69 constexpr TimeDelta kTextDragDelay = TimeDelta::FromSecondsD(0.0); | 73 constexpr TimeDelta kTextDragDelay = TimeDelta::FromSecondsD(0.0); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 : EventTypeNames::auxclick, | 305 : EventTypeNames::auxclick, |
| 302 mev.Event(), mev.CanvasRegionId(), nullptr); | 306 mev.Event(), mev.CanvasRegionId(), nullptr); |
| 303 } | 307 } |
| 304 | 308 |
| 305 return WebInputEventResult::kNotHandled; | 309 return WebInputEventResult::kNotHandled; |
| 306 } | 310 } |
| 307 | 311 |
| 308 void MouseEventManager::FakeMouseMoveEventTimerFired(TimerBase* timer) { | 312 void MouseEventManager::FakeMouseMoveEventTimerFired(TimerBase* timer) { |
| 309 TRACE_EVENT0("input", "MouseEventManager::fakeMouseMoveEventTimerFired"); | 313 TRACE_EVENT0("input", "MouseEventManager::fakeMouseMoveEventTimerFired"); |
| 310 DCHECK(timer == &fake_mouse_move_event_timer_); | 314 DCHECK(timer == &fake_mouse_move_event_timer_); |
| 311 DCHECK(!mouse_pressed_); | |
| 312 | 315 |
| 313 if (is_mouse_position_unknown_) | 316 if (is_mouse_position_unknown_) |
| 314 return; | 317 return; |
| 315 | 318 |
| 316 LocalFrameView* view = frame_->View(); | 319 LocalFrameView* view = frame_->View(); |
| 317 if (!view) | 320 if (!view) |
| 318 return; | 321 return; |
| 319 | 322 |
| 320 if (!frame_->GetPage() || !frame_->GetPage()->GetFocusController().IsActive()) | 323 if (!frame_->GetPage() || !frame_->GetPage()->GetFocusController().IsActive()) |
| 321 return; | 324 return; |
| 322 | 325 |
| 323 // Don't dispatch a synthetic mouse move event if the mouse cursor is not | 326 // Don't dispatch a synthetic mouse move event if the mouse cursor is not |
| 324 // visible to the user. | 327 // visible to the user. |
| 325 if (!frame_->GetPage()->IsCursorVisible()) | 328 if (!frame_->GetPage()->IsCursorVisible()) |
|
Navid Zolghadr
2017/07/05 17:37:33
Does this apply for layout change causing fake eve
lanwei
2017/07/06 03:04:34
I think we should not send the fake mouse move whe
| |
| 326 return; | 329 return; |
| 327 | 330 |
| 331 WebPointerEvent::Button button = WebPointerProperties::Button::kNoButton; | |
| 332 int modifiers = KeyboardEventManager::GetCurrentModifierState() | | |
| 333 WebInputEvent::kRelativeMotionEvent; | |
| 334 if (mouse_pressed_) { | |
| 335 button = WebPointerProperties::Button::kLeft; | |
|
Navid Zolghadr
2017/07/05 17:37:33
Shouldn't this still be kNoButton since we are sen
lanwei
2017/07/06 03:04:34
Yes, I tested when we pressed a button and moved t
| |
| 336 modifiers |= WebInputEvent::kLeftButtonDown; | |
| 337 } | |
| 328 WebMouseEvent fake_mouse_move_event( | 338 WebMouseEvent fake_mouse_move_event( |
| 329 WebInputEvent::kMouseMove, | 339 WebInputEvent::kMouseMove, |
| 330 WebFloatPoint(last_known_mouse_position_.X(), | 340 WebFloatPoint(last_known_mouse_position_.X(), |
| 331 last_known_mouse_position_.Y()), | 341 last_known_mouse_position_.Y()), |
| 332 WebFloatPoint(last_known_mouse_global_position_.X(), | 342 WebFloatPoint(last_known_mouse_global_position_.X(), |
| 333 last_known_mouse_global_position_.Y()), | 343 last_known_mouse_global_position_.Y()), |
| 334 WebPointerProperties::Button::kNoButton, 0, | 344 button, 0, modifiers, TimeTicks::Now().InSeconds()); |
| 335 KeyboardEventManager::GetCurrentModifierState() | | |
| 336 WebInputEvent::Modifiers::kRelativeMotionEvent, | |
| 337 TimeTicks::Now().InSeconds()); | |
| 338 // TODO(dtapuska): Update m_lastKnowMousePosition to be viewport coordinates. | 345 // TODO(dtapuska): Update m_lastKnowMousePosition to be viewport coordinates. |
| 339 fake_mouse_move_event.SetFrameScale(1); | 346 fake_mouse_move_event.SetFrameScale(1); |
| 340 Vector<WebMouseEvent> coalesced_events; | 347 Vector<WebMouseEvent> coalesced_events; |
| 341 frame_->GetEventHandler().HandleMouseMoveEvent(fake_mouse_move_event, | 348 frame_->GetEventHandler().HandleMouseMoveEvent(fake_mouse_move_event, |
| 342 coalesced_events); | 349 coalesced_events); |
| 343 } | 350 } |
| 344 | 351 |
| 345 void MouseEventManager::CancelFakeMouseMoveEvent() { | 352 void MouseEventManager::CancelFakeMouseMoveEvent() { |
| 346 fake_mouse_move_event_timer_.Stop(); | 353 fake_mouse_move_event_timer_.Stop(); |
| 347 } | 354 } |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 574 FloatPoint MouseEventManager::LastKnownMousePositionGlobal() { | 581 FloatPoint MouseEventManager::LastKnownMousePositionGlobal() { |
| 575 return last_known_mouse_global_position_; | 582 return last_known_mouse_global_position_; |
| 576 } | 583 } |
| 577 | 584 |
| 578 void MouseEventManager::SetLastKnownMousePosition(const WebMouseEvent& event) { | 585 void MouseEventManager::SetLastKnownMousePosition(const WebMouseEvent& event) { |
| 579 is_mouse_position_unknown_ = false; | 586 is_mouse_position_unknown_ = false; |
| 580 last_known_mouse_position_ = event.PositionInRootFrame(); | 587 last_known_mouse_position_ = event.PositionInRootFrame(); |
| 581 last_known_mouse_global_position_ = event.PositionInScreen(); | 588 last_known_mouse_global_position_ = event.PositionInScreen(); |
| 582 } | 589 } |
| 583 | 590 |
| 584 void MouseEventManager::DispatchFakeMouseMoveEventSoon() { | 591 void MouseEventManager::DispatchFakeMouseMoveEventSoon( |
| 585 if (mouse_pressed_) | 592 MouseEventManager::FakeMouseMoveReason fake_mouse_move_reason) { |
| 593 if (fake_mouse_move_reason == | |
| 594 MouseEventManager::FakeMouseMoveReason::kDuringScroll && | |
| 595 mouse_pressed_) | |
| 586 return; | 596 return; |
| 587 | 597 |
| 598 // When the mouse position is unknown, we do not send the fake mousemove | |
| 599 // event for now, so we cannot update the hover states and mouse cursor. | |
| 600 // We will fix it soon by keeping the last mouse position somehwhere in | |
| 601 // browser. | |
| 588 if (is_mouse_position_unknown_) | 602 if (is_mouse_position_unknown_) |
| 589 return; | 603 return; |
| 590 | 604 |
| 591 // Reschedule the timer, to prevent dispatching mouse move events | 605 // Reschedule the timer, to prevent dispatching mouse move events |
| 592 // during a scroll. This avoids a potential source of scroll jank. | 606 // during a scroll. This avoids a potential source of scroll jank. |
| 593 fake_mouse_move_event_timer_.StartOneShot(kFakeMouseMoveInterval, | 607 // Or dispatch a fake mouse move to update hover states when the layout |
| 594 BLINK_FROM_HERE); | 608 // changes. |
| 609 double interval = | |
| 610 fake_mouse_move_reason == | |
| 611 MouseEventManager::FakeMouseMoveReason::kDuringScroll | |
| 612 ? kFakeMouseMoveIntervalDuringScroll | |
| 613 : kFakeMouseMoveIntervalPerFrame; | |
| 614 fake_mouse_move_event_timer_.StartOneShot(interval, BLINK_FROM_HERE); | |
| 595 } | 615 } |
| 596 | 616 |
| 597 void MouseEventManager::DispatchFakeMouseMoveEventSoonInQuad( | 617 void MouseEventManager::DispatchFakeMouseMoveEventSoonInQuad( |
| 598 const FloatQuad& quad) { | 618 const FloatQuad& quad) { |
| 599 LocalFrameView* view = frame_->View(); | 619 LocalFrameView* view = frame_->View(); |
| 600 if (!view) | 620 if (!view) |
| 601 return; | 621 return; |
| 602 | 622 |
| 603 if (!quad.ContainsPoint( | 623 if (!quad.ContainsPoint( |
| 604 view->RootFrameToContents(last_known_mouse_position_))) | 624 view->RootFrameToContents(last_known_mouse_position_))) |
| 605 return; | 625 return; |
| 606 | 626 |
| 607 DispatchFakeMouseMoveEventSoon(); | 627 DispatchFakeMouseMoveEventSoon( |
| 628 MouseEventManager::FakeMouseMoveReason::kDuringScroll); | |
| 608 } | 629 } |
| 609 | 630 |
| 610 WebInputEventResult MouseEventManager::HandleMousePressEvent( | 631 WebInputEventResult MouseEventManager::HandleMousePressEvent( |
| 611 const MouseEventWithHitTestResults& event) { | 632 const MouseEventWithHitTestResults& event) { |
| 612 TRACE_EVENT0("blink", "MouseEventManager::handleMousePressEvent"); | 633 TRACE_EVENT0("blink", "MouseEventManager::handleMousePressEvent"); |
| 613 | 634 |
| 614 ResetDragState(); | 635 ResetDragState(); |
| 615 CancelFakeMouseMoveEvent(); | 636 CancelFakeMouseMoveEvent(); |
| 616 | 637 |
| 617 frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); | 638 frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 746 // never sees the mouse release event, which is supposed to reset | 767 // never sees the mouse release event, which is supposed to reset |
| 747 // m_mousePressed... so m_mousePressed ends up remaining true until the | 768 // m_mousePressed... so m_mousePressed ends up remaining true until the |
| 748 // event handler finally gets another mouse released event. Oops. | 769 // event handler finally gets another mouse released event. Oops. |
| 749 // 2. Dragging doesn't start until after a mouse press event, but a drag | 770 // 2. Dragging doesn't start until after a mouse press event, but a drag |
| 750 // that ends as a result of a mouse release does not send a mouse release | 771 // that ends as a result of a mouse release does not send a mouse release |
| 751 // event. As a result, m_mousePressed also ends up remaining true until | 772 // event. As a result, m_mousePressed also ends up remaining true until |
| 752 // the next mouse release event seen by the EventHandler. | 773 // the next mouse release event seen by the EventHandler. |
| 753 // 3. When pressing Esc key while dragging and the object is outside of the | 774 // 3. When pressing Esc key while dragging and the object is outside of the |
| 754 // we get a mouse leave event here | 775 // we get a mouse leave event here |
| 755 if (event.Event().button != WebPointerProperties::Button::kLeft || | 776 if (event.Event().button != WebPointerProperties::Button::kLeft || |
| 756 event.Event().GetType() == WebInputEvent::kMouseLeave) | 777 event.Event().GetType() == WebInputEvent::kMouseLeave) { |
| 757 mouse_pressed_ = false; | 778 mouse_pressed_ = false; |
| 779 } | |
| 758 | 780 |
| 759 if (!mouse_pressed_) | 781 if (!mouse_pressed_) |
| 760 return WebInputEventResult::kNotHandled; | 782 return WebInputEventResult::kNotHandled; |
| 761 | 783 |
| 762 if (event.Event().pointer_type == | 784 if (event.Event().pointer_type == |
| 763 blink::WebPointerProperties::PointerType::kPen) | 785 blink::WebPointerProperties::PointerType::kPen) |
| 764 return WebInputEventResult::kNotHandled; | 786 return WebInputEventResult::kNotHandled; |
| 765 | 787 |
| 766 if (HandleDrag(event, DragInitiator::kMouse)) | 788 if (HandleDrag(event, DragInitiator::kMouse)) |
| 767 return WebInputEventResult::kHandledSystem; | 789 return WebInputEventResult::kHandledSystem; |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1090 } | 1112 } |
| 1091 | 1113 |
| 1092 void MouseEventManager::SetClickCount(int click_count) { | 1114 void MouseEventManager::SetClickCount(int click_count) { |
| 1093 click_count_ = click_count; | 1115 click_count_ = click_count; |
| 1094 } | 1116 } |
| 1095 | 1117 |
| 1096 bool MouseEventManager::MouseDownMayStartDrag() { | 1118 bool MouseEventManager::MouseDownMayStartDrag() { |
| 1097 return mouse_down_may_start_drag_; | 1119 return mouse_down_may_start_drag_; |
| 1098 } | 1120 } |
| 1099 | 1121 |
| 1122 bool MouseEventManager::FakeMouseMovePending() const { | |
| 1123 return fake_mouse_move_event_timer_.IsActive(); | |
| 1124 } | |
| 1125 | |
| 1100 } // namespace blink | 1126 } // namespace blink |
| OLD | NEW |