Commit 0d276093 authored by Mustaq Ahmed's avatar Mustaq Ahmed Committed by Commit Bot

Add context menu support at drag-end behind a web preference.

This is an experimental CL that delays the firing of a contextmenu event
from long-press to end-of-drag.  This only affects "stationary" drags of
draggable elements (a drag spanning a few pixels is considered
stationary to accommodate shaky finger movements).  Like regular
contextmenu events, the event can be cancelled to suppress the menu.

The change is gated by a web preference.

Bug: 1096189
Change-Id: Ibd3632ef7066315bebd0a1bfac52186112315ef3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2340287
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806225}
parent 6c964b7c
...@@ -941,6 +941,7 @@ void RenderView::ApplyWebPreferences( ...@@ -941,6 +941,7 @@ void RenderView::ApplyWebPreferences(
} }
settings->SetTouchDragDropEnabled(prefs.touch_drag_drop_enabled); settings->SetTouchDragDropEnabled(prefs.touch_drag_drop_enabled);
settings->SetTouchDragEndContextMenu(prefs.touch_dragend_context_menu);
#if defined(OS_MAC) #if defined(OS_MAC)
web_view->SetMaximumLegibleScale(prefs.default_maximum_page_scale_factor); web_view->SetMaximumLegibleScale(prefs.default_maximum_page_scale_factor);
......
...@@ -363,6 +363,11 @@ struct BLINK_COMMON_EXPORT WebPreferences { ...@@ -363,6 +363,11 @@ struct BLINK_COMMON_EXPORT WebPreferences {
// default value depends on the platform. // default value depends on the platform.
bool touch_drag_drop_enabled; bool touch_drag_drop_enabled;
// Whether the end of a drag fires a contextmenu event and possibly shows a
// context-menu (depends on how the event is handled). Currently touch-drags
// cannot show context menus, see crbug.com/1096189.
bool touch_dragend_context_menu = false;
// We try to keep the default values the same as the default values in // We try to keep the default values the same as the default values in
// chrome, except for the cases where it would require lots of extra work for // chrome, except for the cases where it would require lots of extra work for
// the embedder to use the same default value. // the embedder to use the same default value.
......
...@@ -257,6 +257,7 @@ class WebSettings { ...@@ -257,6 +257,7 @@ class WebSettings {
virtual void SetTextTrackWindowRadius(const WebString&) = 0; virtual void SetTextTrackWindowRadius(const WebString&) = 0;
virtual void SetThreadedScrollingEnabled(bool) = 0; virtual void SetThreadedScrollingEnabled(bool) = 0;
virtual void SetTouchDragDropEnabled(bool) = 0; virtual void SetTouchDragDropEnabled(bool) = 0;
virtual void SetTouchDragEndContextMenu(bool) = 0;
virtual void SetBarrelButtonForDragEnabled(bool) = 0; virtual void SetBarrelButtonForDragEnabled(bool) = 0;
virtual void SetUseLegacyBackgroundSizeShorthandBehavior(bool) = 0; virtual void SetUseLegacyBackgroundSizeShorthandBehavior(bool) = 0;
virtual void SetViewportStyle(WebViewportStyle) = 0; virtual void SetViewportStyle(WebViewportStyle) = 0;
......
...@@ -425,6 +425,10 @@ void WebSettingsImpl::SetTouchDragDropEnabled(bool enabled) { ...@@ -425,6 +425,10 @@ void WebSettingsImpl::SetTouchDragDropEnabled(bool enabled) {
settings_->SetTouchDragDropEnabled(enabled); settings_->SetTouchDragDropEnabled(enabled);
} }
void WebSettingsImpl::SetTouchDragEndContextMenu(bool enabled) {
settings_->SetTouchDragEndContextMenu(enabled);
}
void WebSettingsImpl::SetBarrelButtonForDragEnabled(bool enabled) { void WebSettingsImpl::SetBarrelButtonForDragEnabled(bool enabled) {
settings_->SetBarrelButtonForDragEnabled(enabled); settings_->SetBarrelButtonForDragEnabled(enabled);
} }
......
...@@ -178,6 +178,7 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings { ...@@ -178,6 +178,7 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetTextTrackWindowRadius(const WebString&) override; void SetTextTrackWindowRadius(const WebString&) override;
void SetThreadedScrollingEnabled(bool) override; void SetThreadedScrollingEnabled(bool) override;
void SetTouchDragDropEnabled(bool) override; void SetTouchDragDropEnabled(bool) override;
void SetTouchDragEndContextMenu(bool) override;
void SetBarrelButtonForDragEnabled(bool) override; void SetBarrelButtonForDragEnabled(bool) override;
void SetUseLegacyBackgroundSizeShorthandBehavior(bool) override; void SetUseLegacyBackgroundSizeShorthandBehavior(bool) override;
void SetViewportStyle(WebViewportStyle) override; void SetViewportStyle(WebViewportStyle) override;
......
...@@ -470,6 +470,7 @@ class CORE_EXPORT WebViewImpl final : public WebView, ...@@ -470,6 +470,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
FRIEND_TEST_ALL_PREFIXES(WebViewTest, LongPressImage); FRIEND_TEST_ALL_PREFIXES(WebViewTest, LongPressImage);
FRIEND_TEST_ALL_PREFIXES(WebViewTest, LongPressImageAndThenLongTapImage); FRIEND_TEST_ALL_PREFIXES(WebViewTest, LongPressImageAndThenLongTapImage);
FRIEND_TEST_ALL_PREFIXES(WebViewTest, UpdateTargetURLWithInvalidURL); FRIEND_TEST_ALL_PREFIXES(WebViewTest, UpdateTargetURLWithInvalidURL);
FRIEND_TEST_ALL_PREFIXES(WebViewTest, TouchDragContextMenu);
friend class frame_test_helpers::WebViewHelper; friend class frame_test_helpers::WebViewHelper;
friend class SimCompositor; friend class SimCompositor;
......
...@@ -2940,6 +2940,84 @@ TEST_F(WebViewTest, TouchCancelOnStartDragging) { ...@@ -2940,6 +2940,84 @@ TEST_F(WebViewTest, TouchCancelOnStartDragging) {
EXPECT_EQ("touchcancel", web_view->MainFrameImpl()->GetDocument().Title()); EXPECT_EQ("touchcancel", web_view->MainFrameImpl()->GetDocument().Title());
} }
// Tests that a touch drag context menu is enabled, a dragend shows a context
// menu when there is no drag.
TEST_F(WebViewTest, TouchDragContextMenuWithoutDrag) {
RegisterMockedHttpURLLoad("long_press_draggable_div.html");
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
base_url_ + "long_press_draggable_div.html");
web_view->SettingsImpl()->SetTouchDragDropEnabled(true);
web_view->SettingsImpl()->SetTouchDragEndContextMenu(true);
web_view->MainFrameWidget()->Resize(WebSize(500, 300));
UpdateAllLifecyclePhases();
RunPendingTasks();
WebPointerEvent pointer_down(
WebInputEvent::Type::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch), 5, 5);
pointer_down.SetPositionInWidget(250, 8);
pointer_down.SetPositionInScreen(250, 8);
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pointer_down, ui::LatencyInfo()));
web_view->MainFrameWidget()->DispatchBufferedTouchEvents();
WebString target_id = WebString::FromUTF8("target");
// Simulate long press to start dragging.
EXPECT_TRUE(
TapElementById(WebInputEvent::Type::kGestureLongPress, target_id));
EXPECT_EQ("dragstart", web_view->MainFrameImpl()->GetDocument().Title());
// Simulate the end of a non-moving drag.
const gfx::PointF dragend_point(250, 8);
web_view->MainFrameWidgetBase()->DragSourceEndedAt(
dragend_point, dragend_point, kWebDragOperationNone);
EXPECT_TRUE(
web_view->GetPage()->GetContextMenuController().ContextMenuNodeForFrame(
web_view->MainFrameImpl()->GetFrame()));
}
// Tests that a touch drag context menu is enabled, a dragend does not show a
// context menu after a drag.
TEST_F(WebViewTest, TouchDragContextMenuWithDrag) {
RegisterMockedHttpURLLoad("long_press_draggable_div.html");
WebViewImpl* web_view = web_view_helper_.InitializeAndLoad(
base_url_ + "long_press_draggable_div.html");
web_view->SettingsImpl()->SetTouchDragDropEnabled(true);
web_view->SettingsImpl()->SetTouchDragEndContextMenu(true);
web_view->MainFrameWidget()->Resize(WebSize(500, 300));
UpdateAllLifecyclePhases();
RunPendingTasks();
WebPointerEvent pointer_down(
WebInputEvent::Type::kPointerDown,
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch), 5, 5);
pointer_down.SetPositionInWidget(250, 8);
pointer_down.SetPositionInScreen(250, 8);
web_view->MainFrameWidget()->HandleInputEvent(
WebCoalescedInputEvent(pointer_down, ui::LatencyInfo()));
web_view->MainFrameWidget()->DispatchBufferedTouchEvents();
WebString target_id = WebString::FromUTF8("target");
// Simulate long press to start dragging.
EXPECT_TRUE(
TapElementById(WebInputEvent::Type::kGestureLongPress, target_id));
EXPECT_EQ("dragstart", web_view->MainFrameImpl()->GetDocument().Title());
// Simulate the end of a drag.
const gfx::PointF dragend_point(270, 28);
web_view->MainFrameWidgetBase()->DragSourceEndedAt(
dragend_point, dragend_point, kWebDragOperationNone);
EXPECT_FALSE(
web_view->GetPage()->GetContextMenuController().ContextMenuNodeForFrame(
web_view->MainFrameImpl()->GetFrame()));
}
TEST_F(WebViewTest, showContextMenuOnLongPressingLinks) { TEST_F(WebViewTest, showContextMenuOnLongPressingLinks) {
RegisterMockedHttpURLLoad("long_press_links_and_images.html"); RegisterMockedHttpURLLoad("long_press_links_and_images.html");
......
...@@ -322,6 +322,14 @@ ...@@ -322,6 +322,14 @@
initial: false, initial: false,
}, },
// Fires a contextmenu event when a touch-drag ends, which by default shows
// a context-menu. When implementation issues have been resolved, this
// should be merged to touchDragDropEnabled. See crbug.com/1126473.
{
name: "touchDragEndContextMenu",
initial: false,
},
// Some apps could have a default video poster if it is not set. // Some apps could have a default video poster if it is not set.
{ {
name: "defaultVideoPosterURL", name: "defaultVideoPosterURL",
......
...@@ -1512,7 +1512,7 @@ void EventHandler::ResetMousePositionForPointerUnlock() { ...@@ -1512,7 +1512,7 @@ void EventHandler::ResetMousePositionForPointerUnlock() {
} }
bool EventHandler::LongTapShouldInvokeContextMenu() { bool EventHandler::LongTapShouldInvokeContextMenu() {
return gesture_manager_->LongTapShouldInvokeContextMenu(); return gesture_manager_->GestureContextMenuDeferred();
} }
WebInputEventResult EventHandler::DispatchMousePointerEvent( WebInputEventResult EventHandler::DispatchMousePointerEvent(
...@@ -2296,6 +2296,12 @@ void EventHandler::DragSourceEndedAt(const WebMouseEvent& event, ...@@ -2296,6 +2296,12 @@ void EventHandler::DragSourceEndedAt(const WebMouseEvent& event,
} }
mouse_event_manager_->DragSourceEndedAt(event, operation); mouse_event_manager_->DragSourceEndedAt(event, operation);
if (frame_->GetSettings() &&
frame_->GetSettings()->GetTouchDragDropEnabled() &&
frame_->GetSettings()->GetTouchDragEndContextMenu()) {
gesture_manager_->SendContextMenuEventTouchDragEnd(event);
}
} }
void EventHandler::UpdateDragStateAfterEditDragIfNeeded( void EventHandler::UpdateDragStateAfterEditDragIfNeeded(
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h"
#include "third_party/blink/renderer/core/input/event_handler.h" #include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/event_handling_util.h" #include "third_party/blink/renderer/core/input/event_handling_util.h"
#include "third_party/blink/renderer/core/input/input_device_capabilities.h" #include "third_party/blink/renderer/core/input/input_device_capabilities.h"
...@@ -37,6 +38,14 @@ ...@@ -37,6 +38,14 @@
namespace blink { namespace blink {
namespace {
// The amount of drag (in pixels) that is considered to be within a slop region.
// This allows firing touch dragend contextmenu events for shaky fingers.
const int kTouchDragSlop = 8;
} // namespace
GestureManager::GestureManager(LocalFrame& frame, GestureManager::GestureManager(LocalFrame& frame,
ScrollManager& scroll_manager, ScrollManager& scroll_manager,
MouseEventManager& mouse_event_manager, MouseEventManager& mouse_event_manager,
...@@ -52,7 +61,12 @@ GestureManager::GestureManager(LocalFrame& frame, ...@@ -52,7 +61,12 @@ GestureManager::GestureManager(LocalFrame& frame,
void GestureManager::Clear() { void GestureManager::Clear() {
suppress_mouse_events_from_gestures_ = false; suppress_mouse_events_from_gestures_ = false;
long_tap_should_invoke_context_menu_ = false; ResetLongTapContextMenuStates();
}
void GestureManager::ResetLongTapContextMenuStates() {
gesture_context_menu_deferred_ = false;
long_press_position_in_root_frame_ = gfx::PointF();
} }
void GestureManager::Trace(Visitor* visitor) const { void GestureManager::Trace(Visitor* visitor) const {
...@@ -139,8 +153,8 @@ WebInputEventResult GestureManager::HandleGestureEventInFrame( ...@@ -139,8 +153,8 @@ WebInputEventResult GestureManager::HandleGestureEventInFrame(
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
} }
bool GestureManager::LongTapShouldInvokeContextMenu() const { bool GestureManager::GestureContextMenuDeferred() const {
return long_tap_should_invoke_context_menu_; return gesture_context_menu_deferred_;
} }
WebInputEventResult GestureManager::HandleGestureTapDown( WebInputEventResult GestureManager::HandleGestureTapDown(
...@@ -339,19 +353,20 @@ WebInputEventResult GestureManager::HandleGestureLongPress( ...@@ -339,19 +353,20 @@ WebInputEventResult GestureManager::HandleGestureLongPress(
// overhaul of the touch drag-and-drop code and LongPress is such a special // overhaul of the touch drag-and-drop code and LongPress is such a special
// scenario that it's unlikely to matter much in practice. // scenario that it's unlikely to matter much in practice.
long_press_position_in_root_frame_ = gesture_event.PositionInRootFrame();
HitTestLocation location(frame_->View()->ConvertFromRootFrame( HitTestLocation location(frame_->View()->ConvertFromRootFrame(
FlooredIntPoint(gesture_event.PositionInRootFrame()))); FlooredIntPoint(long_press_position_in_root_frame_)));
HitTestResult hit_test_result = HitTestResult hit_test_result =
frame_->GetEventHandler().HitTestResultAtLocation(location); frame_->GetEventHandler().HitTestResultAtLocation(location);
long_tap_should_invoke_context_menu_ = false; gesture_context_menu_deferred_ = false;
bool hit_test_contains_links = hit_test_result.URLElement() || bool hit_test_contains_links = hit_test_result.URLElement() ||
!hit_test_result.AbsoluteImageURL().IsNull() || !hit_test_result.AbsoluteImageURL().IsNull() ||
!hit_test_result.AbsoluteMediaURL().IsNull(); !hit_test_result.AbsoluteMediaURL().IsNull();
if (!hit_test_contains_links && if (!hit_test_contains_links &&
mouse_event_manager_->HandleDragDropIfPossible(targeted_event)) { mouse_event_manager_->HandleDragDropIfPossible(targeted_event)) {
long_tap_should_invoke_context_menu_ = true; gesture_context_menu_deferred_ = true;
return WebInputEventResult::kHandledSystem; return WebInputEventResult::kHandledSystem;
} }
...@@ -363,7 +378,7 @@ WebInputEventResult GestureManager::HandleGestureLongPress( ...@@ -363,7 +378,7 @@ WebInputEventResult GestureManager::HandleGestureLongPress(
if (frame_->GetSettings() && if (frame_->GetSettings() &&
frame_->GetSettings()->GetShowContextMenuOnMouseUp()) { frame_->GetSettings()->GetShowContextMenuOnMouseUp()) {
long_tap_should_invoke_context_menu_ = true; gesture_context_menu_deferred_ = true;
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
} }
...@@ -375,8 +390,8 @@ WebInputEventResult GestureManager::HandleGestureLongPress( ...@@ -375,8 +390,8 @@ WebInputEventResult GestureManager::HandleGestureLongPress(
WebInputEventResult GestureManager::HandleGestureLongTap( WebInputEventResult GestureManager::HandleGestureLongTap(
const GestureEventWithHitTestResults& targeted_event) { const GestureEventWithHitTestResults& targeted_event) {
if (LongTapShouldInvokeContextMenu()) { if (gesture_context_menu_deferred_) {
long_tap_should_invoke_context_menu_ = false; gesture_context_menu_deferred_ = false;
return SendContextMenuEventForGesture(targeted_event); return SendContextMenuEventForGesture(targeted_event);
} }
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
...@@ -390,6 +405,29 @@ WebInputEventResult GestureManager::HandleGestureTwoFingerTap( ...@@ -390,6 +405,29 @@ WebInputEventResult GestureManager::HandleGestureTwoFingerTap(
return SendContextMenuEventForGesture(targeted_event); return SendContextMenuEventForGesture(targeted_event);
} }
void GestureManager::SendContextMenuEventTouchDragEnd(
const WebMouseEvent& mouse_event) {
if (!gesture_context_menu_deferred_ || suppress_mouse_events_from_gestures_) {
return;
}
const gfx::PointF& positon_in_root_frame = mouse_event.PositionInWidget();
// Don't send contextmenu event if tap position is not within a slop region.
//
// TODO(mustaq): We should be reusing gesture touch-slop region here but it
// seems non-trivial because this code path is called at drag-end, and the
// drag controller does not sync well with gesture recognizer. See the
// blocked-on bugs in https://crbug.com/1096189.
if ((positon_in_root_frame - long_press_position_in_root_frame_).Length() >
kTouchDragSlop)
return;
ContextMenuAllowedScope scope;
frame_->GetEventHandler().SendContextMenuEvent(mouse_event);
ResetLongTapContextMenuStates();
}
WebInputEventResult GestureManager::SendContextMenuEventForGesture( WebInputEventResult GestureManager::SendContextMenuEventForGesture(
const GestureEventWithHitTestResults& targeted_event) { const GestureEventWithHitTestResults& targeted_event) {
const WebGestureEvent& gesture_event = targeted_event.Event(); const WebGestureEvent& gesture_event = targeted_event.Event();
......
...@@ -34,12 +34,25 @@ class CORE_EXPORT GestureManager final ...@@ -34,12 +34,25 @@ class CORE_EXPORT GestureManager final
void Trace(Visitor*) const; void Trace(Visitor*) const;
void Clear(); void Clear();
void ResetLongTapContextMenuStates();
HitTestRequest::HitTestRequestType GetHitTypeForGestureType( HitTestRequest::HitTestRequestType GetHitTypeForGestureType(
WebInputEvent::Type); WebInputEvent::Type);
WebInputEventResult HandleGestureEventInFrame( WebInputEventResult HandleGestureEventInFrame(
const GestureEventWithHitTestResults&); const GestureEventWithHitTestResults&);
bool LongTapShouldInvokeContextMenu() const; bool GestureContextMenuDeferred() const;
// Dispatches contextmenu event for drag-ends that haven't really dragged
// except for a few pixels.
//
// The reason for handling this in GestureManager is the similarity of the
// interaction with long taps. When a drag ends without a drag offset, it is
// effectively a long tap but with one difference: there is no gesture long
// tap event. This is because the drag controller interrupts current gesture
// sequence (cancelling the gesture) at the moment a drag begins, and the
// gesture recognizer does not know if the drag has ended at the originating
// position.
void SendContextMenuEventTouchDragEnd(const WebMouseEvent&);
private: private:
WebInputEventResult HandleGestureShowPress(); WebInputEventResult HandleGestureShowPress();
...@@ -76,7 +89,9 @@ class CORE_EXPORT GestureManager final ...@@ -76,7 +89,9 @@ class CORE_EXPORT GestureManager final
// firing for the current gesture sequence (i.e. until next GestureTapDown). // firing for the current gesture sequence (i.e. until next GestureTapDown).
bool suppress_mouse_events_from_gestures_; bool suppress_mouse_events_from_gestures_;
bool long_tap_should_invoke_context_menu_; bool gesture_context_menu_deferred_;
gfx::PointF long_press_position_in_root_frame_;
const Member<SelectionController> selection_controller_; const Member<SelectionController> selection_controller_;
}; };
......
...@@ -770,38 +770,39 @@ void MouseEventManager::UpdateSelectionForMouseDrag() { ...@@ -770,38 +770,39 @@ void MouseEventManager::UpdateSelectionForMouseDrag() {
bool MouseEventManager::HandleDragDropIfPossible( bool MouseEventManager::HandleDragDropIfPossible(
const GestureEventWithHitTestResults& targeted_event) { const GestureEventWithHitTestResults& targeted_event) {
if (frame_->GetSettings() && if (!frame_->GetSettings() ||
frame_->GetSettings()->GetTouchDragDropEnabled() && frame_->View()) { !frame_->GetSettings()->GetTouchDragDropEnabled() || !frame_->View()) {
const WebGestureEvent& gesture_event = targeted_event.Event(); return false;
unsigned modifiers = gesture_event.GetModifiers();
// TODO(mustaq): Suppressing long-tap MouseEvents could break
// drag-drop. Will do separately because of the risk. crbug.com/606938.
WebMouseEvent mouse_down_event(
WebInputEvent::Type::kMouseDown, gesture_event,
WebPointerProperties::Button::kLeft, 1,
modifiers | WebInputEvent::Modifiers::kLeftButtonDown |
WebInputEvent::Modifiers::kIsCompatibilityEventForTouch,
base::TimeTicks::Now());
mouse_down_ = mouse_down_event;
WebMouseEvent mouse_drag_event(
WebInputEvent::Type::kMouseMove, gesture_event,
WebPointerProperties::Button::kLeft, 1,
modifiers | WebInputEvent::Modifiers::kLeftButtonDown |
WebInputEvent::Modifiers::kIsCompatibilityEventForTouch,
base::TimeTicks::Now());
HitTestRequest request(HitTestRequest::kReadOnly);
MouseEventWithHitTestResults mev =
event_handling_util::PerformMouseEventHitTest(frame_, request,
mouse_drag_event);
mouse_down_may_start_drag_ = true;
ResetDragSource();
mouse_down_pos_ = frame_->View()->ConvertFromRootFrame(
FlooredIntPoint(mouse_drag_event.PositionInRootFrame()));
return HandleDrag(mev, DragInitiator::kTouch);
} }
return false;
const WebGestureEvent& gesture_event = targeted_event.Event();
unsigned modifiers = gesture_event.GetModifiers();
// TODO(mustaq): Suppressing long-tap MouseEvents could break
// drag-drop. Will do separately because of the risk. crbug.com/606938.
WebMouseEvent mouse_down_event(
WebInputEvent::Type::kMouseDown, gesture_event,
WebPointerProperties::Button::kLeft, 1,
modifiers | WebInputEvent::Modifiers::kLeftButtonDown |
WebInputEvent::Modifiers::kIsCompatibilityEventForTouch,
base::TimeTicks::Now());
mouse_down_ = mouse_down_event;
WebMouseEvent mouse_drag_event(
WebInputEvent::Type::kMouseMove, gesture_event,
WebPointerProperties::Button::kLeft, 1,
modifiers | WebInputEvent::Modifiers::kLeftButtonDown |
WebInputEvent::Modifiers::kIsCompatibilityEventForTouch,
base::TimeTicks::Now());
HitTestRequest request(HitTestRequest::kReadOnly);
MouseEventWithHitTestResults mev =
event_handling_util::PerformMouseEventHitTest(frame_, request,
mouse_drag_event);
mouse_down_may_start_drag_ = true;
ResetDragSource();
mouse_down_pos_ = frame_->View()->ConvertFromRootFrame(
FlooredIntPoint(mouse_drag_event.PositionInRootFrame()));
return HandleDrag(mev, DragInitiator::kTouch);
} }
void MouseEventManager::FocusDocumentView() { void MouseEventManager::FocusDocumentView() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment