Commit c97c8e57 authored by Lan Wei's avatar Lan Wei Committed by Commit Bot

Send a fake mouse move event to update hover when threaded scrolls end

In order to remove the timer to send the fake mouse move event, we
decide the best place to send the fake mouse move event is at the next
begin frame right after we have seen a gesture scroll end event.

This CL is only about scrolls happening on compositor. I will work on
scrolls on main thread in a following CL.

Bug: 877132
Change-Id: Ia9c5e8b326a08797ad7f65e1242bb9f2bcb275ee
Reviewed-on: https://chromium-review.googlesource.com/c/1481747
Commit-Queue: Lan Wei <lanwei@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636543}
parent d36178f6
...@@ -1481,6 +1481,11 @@ void WebViewImpl::BeginFrame(base::TimeTicks last_frame_time, ...@@ -1481,6 +1481,11 @@ void WebViewImpl::BeginFrame(base::TimeTicks last_frame_time,
last_frame_time); last_frame_time);
DCHECK(!last_frame_time.is_null()); DCHECK(!last_frame_time.is_null());
if (needs_hover_update_at_begin_frame_) {
MainFrameImpl()->GetFrame()->GetEventHandler().RecomputeMouseHoverState();
needs_hover_update_at_begin_frame_ = false;
}
if (!MainFrameImpl()) if (!MainFrameImpl())
return; return;
...@@ -3305,9 +3310,9 @@ void WebViewImpl::ApplyViewportChanges(const ApplyViewportChangesArgs& args) { ...@@ -3305,9 +3310,9 @@ void WebViewImpl::ApplyViewportChanges(const ApplyViewportChangesArgs& args) {
args.elastic_overscroll_delta.y()); args.elastic_overscroll_delta.y());
UpdateBrowserControlsConstraint(args.browser_controls_constraint); UpdateBrowserControlsConstraint(args.browser_controls_constraint);
if (RuntimeEnabledFeatures::NoHoverDuringScrollEnabled() && needs_hover_update_at_begin_frame_ =
args.scroll_gesture_did_end) args.scroll_gesture_did_end &&
MainFrameImpl()->GetFrame()->GetEventHandler().RecomputeMouseHoverState(); RuntimeEnabledFeatures::NoHoverDuringScrollEnabled();
} }
void WebViewImpl::RecordWheelAndTouchScrollingCount( void WebViewImpl::RecordWheelAndTouchScrollingCount(
......
...@@ -688,6 +688,8 @@ class CORE_EXPORT WebViewImpl final : public WebView, ...@@ -688,6 +688,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
FloatSize elastic_overscroll_; FloatSize elastic_overscroll_;
bool needs_hover_update_at_begin_frame_ = false;
Persistent<EventListener> popup_mouse_wheel_event_listener_; Persistent<EventListener> popup_mouse_wheel_event_listener_;
// The local root whose document has |popup_mouse_wheel_event_listener_| // The local root whose document has |popup_mouse_wheel_event_listener_|
......
...@@ -1254,4 +1254,88 @@ TEST_F(EventHandlerSimTest, TapActiveInFrame) { ...@@ -1254,4 +1254,88 @@ TEST_F(EventHandlerSimTest, TapActiveInFrame) {
EXPECT_FALSE(iframe_doc->GetActiveElement()); EXPECT_FALSE(iframe_doc->GetActiveElement());
} }
// Test that the hover is updated at the next begin frame after the scroll ends.
TEST_F(EventHandlerSimTest, TestUpdateHoverAfterScrollAtBeginFrame) {
RuntimeEnabledFeatures::SetNoHoverDuringScrollEnabled(true);
WebView().MainFrameWidget()->Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
<!DOCTYPE html>
<style>
body, html {
margin: 0;
}
div {
height: 300px;
width: 100%;
}
</style>
<body>
<div class="hoverme" id="line1">hover over me</div>
<div class="hoverme" id="line2">hover over me</div>
<div class="hoverme" id="line3">hover over me</div>
<div class="hoverme" id="line4">hover over me</div>
<div class="hoverme" id="line5">hover over me</div>
</body>
<script>
let array = document.getElementsByClassName('hoverme');
for (let element of array) {
element.addEventListener('mouseover', function (e) {
this.innerHTML = "currently hovered";
});
element.addEventListener('mouseout', function (e) {
this.innerHTML = "was hovered";
});
}
</script>
)HTML");
Compositor().BeginFrame();
// Set mouse position and active web view.
WebMouseEvent mouse_down_event(WebMouseEvent::kMouseDown, WebFloatPoint(1, 1),
WebFloatPoint(1, 1),
WebPointerProperties::Button::kLeft, 1,
WebInputEvent::Modifiers::kLeftButtonDown,
WebInputEvent::GetStaticTimeStampForTests());
mouse_down_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMousePressEvent(
mouse_down_event);
WebMouseEvent mouse_up_event(
WebInputEvent::kMouseUp, WebFloatPoint(1, 1), WebFloatPoint(1, 1),
WebPointerProperties::Button::kLeft, 1, WebInputEvent::kNoModifiers,
WebInputEvent::GetStaticTimeStampForTests());
mouse_up_event.SetFrameScale(1);
GetDocument().GetFrame()->GetEventHandler().HandleMouseReleaseEvent(
mouse_up_event);
WebView().MainFrameWidget()->SetFocus(true);
WebView().SetIsActive(true);
WebElement element1 = GetDocument().getElementById("line1");
WebElement element2 = GetDocument().getElementById("line2");
WebElement element3 = GetDocument().getElementById("line3");
EXPECT_EQ("currently hovered", element1.InnerHTML().Utf8());
EXPECT_EQ("hover over me", element2.InnerHTML().Utf8());
EXPECT_EQ("hover over me", element3.InnerHTML().Utf8());
// Do a compositor scroll and set |scroll_gesture_did_end| to be true.
LocalFrameView* frame_view = GetDocument().View();
frame_view->LayoutViewport()->DidScroll(FloatPoint(0, 500));
WebView().MainFrameWidget()->ApplyViewportChanges(
{gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 0,
cc::BrowserControlsState::kBoth, true});
ASSERT_EQ(500, frame_view->LayoutViewport()->GetScrollOffset().Height());
EXPECT_EQ("currently hovered", element1.InnerHTML().Utf8());
EXPECT_EQ("hover over me", element2.InnerHTML().Utf8());
EXPECT_EQ("hover over me", element3.InnerHTML().Utf8());
// The fake mouse move event is dispatched at the begin frame to update hover.
Compositor().BeginFrame();
EXPECT_EQ("was hovered", element1.InnerHTML().Utf8());
EXPECT_EQ("currently hovered", element2.InnerHTML().Utf8());
EXPECT_EQ("hover over me", element3.InnerHTML().Utf8());
}
} // namespace blink } // namespace blink
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