RESOLVED FIXED219074
scroll-padding should affect paging operations
https://bugs.webkit.org/show_bug.cgi?id=219074
Summary scroll-padding should affect paging operations
Martin Robinson
Reported 2020-11-18 02:14:01 PST
The specification [1] reads: These offsets reduce the region of the scrollport that is considered “viewable” for scrolling operations: they have no effect on layout, on the scroll origin or initial position, or on whether or not an element is considered actually visible, but should affect whether an element or the caret is considered scrolled into view (e.g. for targetting or focusing operations), and reduce the amount of scrolling for paging operations (such as using the PgUp and PgDn keys or triggering equivalent operations from the scrollbar) so that within the optimal viewing region of the scrollport the user sees a continuous stream of content. This bug is specifically for tracking the implementation of scroll-padding's effect on paging operations. 1. https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding
Attachments
Patch (23.40 KB, patch)
2021-01-18 01:32 PST, Martin Robinson
no flags
Patch (24.51 KB, patch)
2021-01-18 03:18 PST, Martin Robinson
ews-feeder: commit-queue-
Patch (24.53 KB, patch)
2021-01-18 04:52 PST, Martin Robinson
no flags
Patch (26.36 KB, patch)
2021-01-20 01:30 PST, Martin Robinson
no flags
Patch (26.42 KB, patch)
2021-01-25 00:54 PST, Martin Robinson
no flags
Radar WebKit Bug Importer
Comment 1 2020-11-26 03:23:47 PST
Martin Robinson
Comment 2 2021-01-18 01:32:03 PST
Martin Robinson
Comment 3 2021-01-18 03:18:07 PST
Martin Robinson
Comment 4 2021-01-18 04:52:44 PST
Simon Fraser (smfr)
Comment 5 2021-01-19 09:47:15 PST
Comment on attachment 417829 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=417829&action=review > Source/WebCore/rendering/RenderLayerModelObject.cpp:176 > + if (oldStyle && oldStyle->scrollPadding() != newStyle.scrollPadding()) { Does a change to scrollPadding only trigger this code? What does RenderStyle::diff() return when only scroll padding changes?
Martin Robinson
Comment 6 2021-01-20 00:49:59 PST
(In reply to Simon Fraser (smfr) from comment #5) > Comment on attachment 417829 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=417829&action=review > > > Source/WebCore/rendering/RenderLayerModelObject.cpp:176 > > + if (oldStyle && oldStyle->scrollPadding() != newStyle.scrollPadding()) { > > Does a change to scrollPadding only trigger this code? What does > RenderStyle::diff() return when only scroll padding changes? It does trigger when only changing scrollPadding (verified by changing this property in the console and with the inspector). RenderStyle:diff() between the old and new styles returns StyleDifference::Equal here.
Martin Robinson
Comment 7 2021-01-20 01:30:55 PST
Simon Fraser (smfr)
Comment 8 2021-01-20 10:14:51 PST
(In reply to Martin Robinson from comment #6) > (In reply to Simon Fraser (smfr) from comment #5) > > Comment on attachment 417829 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=417829&action=review > > > > > Source/WebCore/rendering/RenderLayerModelObject.cpp:176 > > > + if (oldStyle && oldStyle->scrollPadding() != newStyle.scrollPadding()) { > > > > Does a change to scrollPadding only trigger this code? What does > > RenderStyle::diff() return when only scroll padding changes? > > It does trigger when only changing scrollPadding (verified by changing this > property in the console and with the inspector). RenderStyle:diff() between > the old and new styles returns StyleDifference::Equal here. How does that work then? Maybe inspector triggers some additional style recalcs/layouts that make this work. Try a testcase that changes scroll padding on a timer.
Martin Robinson
Comment 9 2021-01-20 10:16:41 PST
(In reply to Simon Fraser (smfr) from comment #8) > How does that work then? Maybe inspector triggers some additional style > recalcs/layouts that make this work. > > Try a testcase that changes scroll padding on a timer. That's a really good question. One of the tests already does modify scroll-padding multiple times using CSSOM, which is the main reason that I realized I needed this new bit of code here. Tomorrow I'll see if I can figure out why this is triggered.
Martin Robinson
Comment 10 2021-01-21 03:20:33 PST
(In reply to Martin Robinson from comment #9) > (In reply to Simon Fraser (smfr) from comment #8) > > > How does that work then? Maybe inspector triggers some additional style > > recalcs/layouts that make this work. > > > > Try a testcase that changes scroll padding on a timer. > > That's a really good question. One of the tests already does modify > scroll-padding multiple times using CSSOM, which is the main reason that I > realized I needed this new bit of code here. Tomorrow I'll see if I can > figure out why this is triggered. Here are the results of my investigation. This is the call stack leading up to RenderLayerModelObject::styleDidChange(...): 1 0x5099732c5 WebCore::RenderBox::styleDidChange(WebCore::StyleDifference, WebCore::RenderStyle const*) 2 0x509948afa WebCore::RenderBlock::styleDidChange(WebCore::StyleDifference, WebCore::RenderStyle const*) 3 0x509963d59 WebCore::RenderBlockFlow::styleDidChange(WebCore::StyleDifference, WebCore::RenderStyle const*) 4 0x5099a8ffd WebCore::RenderElement::setStyle(WebCore::RenderStyle&&, WebCore::StyleDifference) 5 0x509b56434 WebCore::RenderTreeUpdater::updateElementRenderer(WebCore::Element&, WebCore::Style::ElementUpdates const&) 6 0x509b55690 WebCore::RenderTreeUpdater::updateRenderTree(WebCore::ContainerNode&) 7 0x509b5519b WebCore::RenderTreeUpdater::commit(std::__1::unique_ptr<WebCore::Style::Update const, std::__1::default_delete<WebCore::Style::Update const> >) 8 0x509046a89 WebCore::Document::updateRenderTree(std::__1::unique_ptr<WebCore::Style::Update const, std::__1::default_delete<WebCore::Style::Update const> >) 9 0x509046e06 WebCore::Document::resolveStyle(WebCore::Document::ResolveStyleType) 10 0x509047277 WebCore::Document::updateStyleIfNeeded() 11 0x5096f9f96 WebCore::ThreadTimers::sharedTimerFiredInternal() 12 0x50972082f WebCore::timerFired(__CFRunLoopTimer*, void*) 13 0x7fff2043090d __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ 14 0x7fff204303e8 __CFRunLoopDoTimer 15 0x7fff2042ff42 __CFRunLoopDoTimers 16 0x7fff2041657f __CFRunLoopRun 17 0x7fff204156ce CFRunLoopRunSpecific 18 0x7fff211a2fa1 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] 19 0x7fff21231384 -[NSRunLoop(NSRunLoop) run] 20 0x7fff2006c3dd _xpc_objc_main 21 0x7fff2006be65 _xpc_copy_xpcservice_dictionary 22 0x10997e2e4 WebKit::XPCServiceMain(int, char const**) 23 0x7fff2033a621 start The style difference is calculated in RenderElement::setStyle(...): StyleDifference diff = StyleDifference::Equal; OptionSet<StyleDifferenceContextSensitiveProperty> contextSensitiveProperties; if (m_hasInitializedStyle) diff = m_style.diff(style, contextSensitiveProperties); diff = std::max(diff, minimalStyleDifference); diff = adjustStyleDifference(diff, contextSensitiveProperties); Style::loadPendingResources(style, document(), element()); auto didRepaint = repaintBeforeStyleChange(diff, m_style, style); styleWillChange(diff, style); It seems that even if the difference is calculated as StyleDifference::Equal, which it is in this case, styleWillChange(...) is still called and we still reach RenderLayerModelObject styleDidChange(). The method itself does not consult the StyleDifference, but relies of checking the difference of certain properties between the old and new style to update the RenderLayer or FrameView. In that respect, my change does not work differently, but I'm not sure if the pre-existing approach is correct or not.
Simon Fraser (smfr)
Comment 11 2021-01-21 10:21:30 PST
I think it's working through luck. Ideally we'd be able to optimize away styleWill/DidChange if the diff is Equal
Martin Robinson
Comment 12 2021-01-22 03:28:29 PST
(In reply to Simon Fraser (smfr) from comment #11) > I think it's working through luck. Ideally we'd be able to optimize away > styleWill/DidChange if the diff is Equal Could it be that there is currently no kind of StyleDifference that captures this sort of change? Changing the padding shouldn't require a full relayout or a repaint. Instead it should just modify what happens when a scrolling operation happens in the future.
Simon Fraser (smfr)
Comment 13 2021-01-22 10:15:06 PST
You're right, our style difference flags are too coarse-grained.
EWS
Comment 14 2021-01-25 00:43:31 PST
commit-queue failed to commit attachment 417953 [details] to WebKit repository.
Martin Robinson
Comment 15 2021-01-25 00:54:42 PST
EWS
Comment 16 2021-01-25 01:45:53 PST
Committed r271788: <https://trac.webkit.org/changeset/271788> All reviewed patches have been landed. Closing bug and clearing flags on attachment 418259 [details].
Note You need to log in before you can comment on or make changes to this bug.