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()) |
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; |
| 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 // TODO(lanwei): When the mouse position is unknown, we do not send the fake |
| 599 // mousemove event for now, so we cannot update the hover states and mouse |
| 600 // cursor. We should keep the last mouse position somewhere in browser. |
| 601 // Please see crbug.com/307375, crbug.com/714378. |
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 |