| 1032 | |
| 1033 | // Sticky headers: apply cached-measurement clamp inside the scroll frame so the |
| 1034 | // transform lands in the same VSYNC as the scroll gesture. No layout thrash. |
| 1035 | updateStickyHeaders(/*refreshCache=*/false); |
| 1036 | |
| 1037 | setCalculatedViewportNeedsUpdate(); |
| 1038 | }); |
| 1039 | } |
| 1040 | |
| 1041 | std::optional<Point> ViewNode::onScroll(const Point& directionDependentContentOffset, |
| 1042 | const Point& directionDependentUnclampedContentOffset, |
| 1043 | const Point& directionDependentVelocity) { |
| 1044 | if (isUpdatingScrollSpecs()) { |
| 1045 | return std::nullopt; |
| 1046 | } |
| 1047 | |
| 1048 | auto backendString = getBackendString(getBackend(_viewNodeTree)); |
| 1049 | auto metrics = Metrics::scopedOnScrollLatency(getMetrics(), getModuleName(), backendString); |
| 1050 | |
| 1051 | auto& scrollState = getOrCreateScrollState(); |
| 1052 | |
| 1053 | if (!scrollState.updateDirectionDependentContentOffset(directionDependentContentOffset, |
| 1054 | directionDependentUnclampedContentOffset)) { |
| 1055 | return std::nullopt; |
| 1056 | } |
| 1057 | |
| 1058 | auto directionAgnosticVelocity = |
| 1059 | directionAgnosticVelocityFromDirectionDependentVelocity(directionDependentVelocity); |
| 1060 | handleOnScroll( |
no test coverage detected