Bug 211884 - Cursor should not update on a 20ms timer
Summary: Cursor should not update on a 20ms timer
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: UI Events (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Antoine Quint
URL:
Keywords: InRadar
: 209494 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-05-14 02:12 PDT by Antoine Quint
Modified: 2020-05-15 14:27 PDT (History)
9 users (show)

See Also:


Attachments
Patch (9.82 KB, patch)
2020-05-14 03:23 PDT, Antoine Quint
no flags Details | Formatted Diff | Diff
Patch (9.89 KB, patch)
2020-05-14 03:26 PDT, Antoine Quint
no flags Details | Formatted Diff | Diff
Patch (9.89 KB, patch)
2020-05-14 03:37 PDT, Antoine Quint
no flags Details | Formatted Diff | Diff
Patch (9.82 KB, patch)
2020-05-14 03:43 PDT, Antoine Quint
no flags Details | Formatted Diff | Diff
Patch (3.39 KB, patch)
2020-05-14 09:34 PDT, Antoine Quint
simon.fraser: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Antoine Quint 2020-05-14 02:12:37 PDT
In EventHandler, the cursor is updated on a timer scheduled with 20ms:

    // The amount of time to wait for a cursor update on style and layout changes
    // Set to 50Hz, no need to be faster than common screen refresh rate
    static const Seconds cursorUpdateInterval { 20_ms };

If the cursor should be updated only as the display refreshes, then it should be timed when the display refreshes and not use some canned timer.
Comment 1 Radar WebKit Bug Importer 2020-05-14 02:12:56 PDT
<rdar://problem/63220368>
Comment 2 Antoine Quint 2020-05-14 02:19:28 PDT
Should we be calling EventHandler::updateCursor() under Page::updateRendering() and schedule a page rendering instead of using m_cursorUpdateTimer.startOneShot(cursorUpdateInterval)?
Comment 3 Antoine Quint 2020-05-14 03:23:13 PDT
Created attachment 399346 [details]
Patch
Comment 4 Antoine Quint 2020-05-14 03:26:13 PDT
Created attachment 399347 [details]
Patch
Comment 5 Antoine Quint 2020-05-14 03:37:46 PDT
Created attachment 399348 [details]
Patch
Comment 6 Antoine Quint 2020-05-14 03:43:16 PDT
Created attachment 399349 [details]
Patch
Comment 7 Antoine Quint 2020-05-14 04:58:04 PDT
*** Bug 209494 has been marked as a duplicate of this bug. ***
Comment 8 Antti Koivisto 2020-05-14 05:07:25 PDT
Comment on attachment 399349 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=399349&action=review

> Source/WebCore/dom/Document.cpp:8520
> +void Document::updateCursorIfNeeded()
> +{
> +    if (frame())
> +        frame()->eventHandler().updateCursorIfNeeded();
> +}

Maybe this function is not needed at all?

> Source/WebCore/page/EventHandler.cpp:3153
> +    m_scheduledCursorUpdate = true;

m_hasScheduledCursorUpdate?
Comment 9 Antti Koivisto 2020-05-14 05:11:49 PDT
Comment on attachment 399349 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=399349&action=review

> LayoutTests/fast/events/mouse-cursor-no-mousemove.html:52
> +    await new Promise(resolve => setTimeout(resolve, 100));

Why not use rAF here too?
Comment 10 Antoine Quint 2020-05-14 05:18:16 PDT
(In reply to Antti Koivisto from comment #9)
> Comment on attachment 399349 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=399349&action=review
> 
> > LayoutTests/fast/events/mouse-cursor-no-mousemove.html:52
> > +    await new Promise(resolve => setTimeout(resolve, 100));
> 
> Why not use rAF here too?

This part of the test tests an ancient change where a synthetic "mousemove" was seemingly dispatched when changing "cursor" styles and we want to make sure it doesn't happen. I'm not sure what a good timeout is here because I don't know what the old timer was, but at any rate nothing should happen during that time. I just reduced it from by 50ms since this was the timer for the check that is now performed with a rAF.
Comment 11 Antoine Quint 2020-05-14 05:31:09 PDT
Committed r261686: <https://trac.webkit.org/changeset/261686>
Comment 12 Simon Fraser (smfr) 2020-05-14 08:18:52 PDT
Comment on attachment 399349 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=399349&action=review

> Source/WebCore/page/Page.cpp:1367
> +    forEachDocument([] (Document& document) {
> +        document.updateCursorIfNeeded();
> +    });

Shouldn't this happen after anything that can change style? If style is changed in a rAF callback, it should be reflected.

>>> LayoutTests/fast/events/mouse-cursor-no-mousemove.html:52
>>> +    await new Promise(resolve => setTimeout(resolve, 100));
>> 
>> Why not use rAF here too?
> 
> This part of the test tests an ancient change where a synthetic "mousemove" was seemingly dispatched when changing "cursor" styles and we want to make sure it doesn't happen. I'm not sure what a good timeout is here because I don't know what the old timer was, but at any rate nothing should happen during that time. I just reduced it from by 50ms since this was the timer for the check that is now performed with a rAF.

await UIHelper.delayFor() or await UIHelper.animationFrame().
Comment 13 Antoine Quint 2020-05-14 09:27:24 PDT
(In reply to Simon Fraser (smfr) from comment #12)
> Comment on attachment 399349 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=399349&action=review
> 
> > Source/WebCore/page/Page.cpp:1367
> > +    forEachDocument([] (Document& document) {
> > +        document.updateCursorIfNeeded();
> > +    });
> 
> Shouldn't this happen after anything that can change style? If style is
> changed in a rAF callback, it should be reflected.

That makes sense, I'll address this in a followup.

> >>> LayoutTests/fast/events/mouse-cursor-no-mousemove.html:52
> >>> +    await new Promise(resolve => setTimeout(resolve, 100));
> >> 
> >> Why not use rAF here too?
> > 
> > This part of the test tests an ancient change where a synthetic "mousemove" was seemingly dispatched when changing "cursor" styles and we want to make sure it doesn't happen. I'm not sure what a good timeout is here because I don't know what the old timer was, but at any rate nothing should happen during that time. I just reduced it from by 50ms since this was the timer for the check that is now performed with a rAF.
> 
> await UIHelper.delayFor() or await UIHelper.animationFrame().

Why? Just changing one line with another line doesn't simplify the test, and I don't need to pull in another test file. This code is straightforward.
Comment 14 Antoine Quint 2020-05-14 09:34:38 PDT
Reopening to attach new patch.
Comment 15 Antoine Quint 2020-05-14 09:34:40 PDT
Created attachment 399371 [details]
Patch
Comment 16 Simon Fraser (smfr) 2020-05-14 10:59:54 PDT
Comment on attachment 399371 [details]
Patch

I think you should add a test that changes cursor style in rAF, and then uses internals.getCurrentCursorInfo to see if got the new cursor.
Comment 17 Antoine Quint 2020-05-14 11:39:48 PDT
(In reply to Simon Fraser (smfr) from comment #16)
> Comment on attachment 399371 [details]
> Patch
> 
> I think you should add a test that changes cursor style in rAF, and then
> uses internals.getCurrentCursorInfo to see if got the new cursor.

Good call! Will do.
Comment 18 Antoine Quint 2020-05-15 06:19:37 PDT
Committed r261741: <https://trac.webkit.org/changeset/261741>
Comment 19 Ryan Haddad 2020-05-15 13:16:24 PDT
The test added with this change is consistently failing on iOS:

--- /Volumes/Data/slave/ios-simulator-13-release-tests-wk2/build/layout-test-results/fast/events/mouse-cursor-udpate-during-raf-expected.txt
+++ /Volumes/Data/slave/ios-simulator-13-release-tests-wk2/build/layout-test-results/fast/events/mouse-cursor-udpate-during-raf-actual.txt
@@ -5,13 +5,13 @@
 
 
 Moved pointer over the target, cursor should be Pointer.
-Cursor info: type=Pointer hotSpot=0,0
+Cursor info: FAIL: Cursor details not available on this platform.
 
 Setting cursor via CSS during next animation frame, cursor should be Pointer still.
-Cursor info: type=Pointer hotSpot=0,0
+Cursor info: FAIL: Cursor details not available on this platform.
 
 Waited until next run loop, cursor should be Help.
-Cursor info: type=Help hotSpot=0,0
+Cursor info: FAIL: Cursor details not available on this platform.
 
 PASS successfullyParsed is true
Comment 20 Antoine Quint 2020-05-15 14:21:55 PDT
Oops, I guess this test makes no sense on iOS and needs to be skipped!
Comment 21 Antoine Quint 2020-05-15 14:27:15 PDT
Committed r261760: <https://trac.webkit.org/changeset/261760>