Changeset 283393 in webkit
- Timestamp:
- Oct 1, 2021, 1:25:48 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
platform/ScrollingEffectsController.h (modified) (1 diff)
-
platform/mac/ScrollingEffectsController.mm (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r283392 r283393 1 2021-10-01 Simon Fraser <simon.fraser@apple.com> 2 3 Further cleanup of macOS rubberbanding code 4 https://bugs.webkit.org/show_bug.cgi?id=231087 5 6 Reviewed by Alan Bujtas. 7 8 Split chunks of rubber-banding logic into their own functions for clarity, 9 separating the "compute the delta" and "apply the delta" parts. 10 11 * platform/ScrollingEffectsController.h: 12 * platform/mac/ScrollingEffectsController.mm: 13 (WebCore::ScrollingEffectsController::handleWheelEvent): 14 (WebCore::ScrollingEffectsController::modifyScrollDeltaForStretching): 15 (WebCore::ScrollingEffectsController::applyScrollDeltaWithStretching): 16 1 17 2021-10-01 Alan Bujtas <zalan@apple.com> 2 18 -
trunk/Source/WebCore/platform/ScrollingEffectsController.h
r283355 r283393 199 199 void stopDeferringWheelEventTestCompletionDueToScrollSnapping(); 200 200 201 bool modifyScrollDeltaForStretching(const PlatformWheelEvent&, FloatSize&, bool isHorizontallyStretched, bool isVerticallyStretched); 202 bool applyScrollDeltaWithStretching(const PlatformWheelEvent&, FloatSize, bool isHorizontallyStretched, bool isVerticallyStretched); 203 201 204 void startRubberbandAnimationIfNecessary(); 202 205 void startRubberbandAnimation(); -
trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm
r283355 r283393 177 177 } 178 178 179 // Reset unapplied overscroll because we may decide to remove delta at various points and put it into this value.180 auto delta = std::exchange(m_unappliedOverscrollDelta, { });181 182 179 IntSize stretchAmount = m_client.stretchAmount(); 183 180 bool isVerticallyStretched = stretchAmount.height(); 184 181 bool isHorizontallyStretched = stretchAmount.width(); 185 182 186 auto eventCoalescedDelta = (isVerticallyStretched || isHorizontallyStretched) ? -wheelEvent.unacceleratedScrollingDelta() : -wheelEvent.delta(); 187 delta += eventCoalescedDelta; 188 189 // FIXME: All of the code below could be simplified since predominantAxis is known, and we zero out the delta on the other axis. 190 auto affectedSide = affectedSideOnDominantAxis(delta); 191 192 float deltaX = delta.width(); 193 float deltaY = delta.height(); 194 195 bool shouldStretch = false; 183 // Much of this code, including this use of unaccelerated deltas when stretched, is based on AppKit behavior. 184 auto eventDelta = (isVerticallyStretched || isHorizontallyStretched) ? -wheelEvent.unacceleratedScrollingDelta() : -wheelEvent.delta(); 185 186 // Reset unapplied overscroll because we may decide to remove delta at various points and put it into this value. 187 auto delta = std::exchange(m_unappliedOverscrollDelta, { }); 188 delta += eventDelta; 196 189 197 190 auto momentumPhase = wheelEvent.momentumPhase(); 198 199 191 if (!m_momentumScrollInProgress && (momentumPhase == PlatformWheelEventPhase::Began || momentumPhase == PlatformWheelEventPhase::Changed)) 200 192 m_momentumScrollInProgress = true; 201 193 194 bool shouldStretch = false; 202 195 auto timeDelta = wheelEvent.timestamp() - m_lastMomentumScrollTimestamp; 203 196 if (m_inScrollGesture || m_momentumScrollInProgress) { 204 197 if (m_lastMomentumScrollTimestamp && timeDelta > 0_s && timeDelta < scrollVelocityZeroingTimeout) { 205 m_momentumVelocity = event CoalescedDelta / timeDelta.seconds();198 m_momentumVelocity = eventDelta / timeDelta.seconds(); 206 199 m_lastMomentumScrollTimestamp = wheelEvent.timestamp(); 207 200 } else { … … 210 203 } 211 204 212 if (isVerticallyStretched) { 213 if (!isHorizontallyStretched && isHorizontalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) { 214 // Stretching only in the vertical. 215 if (deltaY && (fabsf(deltaX / deltaY) < rubberbandDirectionLockStretchRatio)) 216 deltaX = 0; 217 else if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) { 218 m_unappliedOverscrollDelta.expand(deltaX, 0); 219 deltaX = 0; 220 } else 221 m_unappliedOverscrollDelta.expand(deltaX, 0); 222 } 223 } else if (isHorizontallyStretched) { 224 // Stretching only in the horizontal. 225 if (isVerticalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) { 226 if (deltaX && (fabsf(deltaY / deltaX) < rubberbandDirectionLockStretchRatio)) 227 deltaY = 0; 228 else if (fabsf(deltaY) < rubberbandMinimumRequiredDeltaBeforeStretch) { 229 m_unappliedOverscrollDelta.expand(0, deltaY); 230 deltaY = 0; 231 } else 232 m_unappliedOverscrollDelta.expand(0, deltaY); 233 } 234 } else { 235 // Not stretching at all yet. 236 if (affectedSide && m_client.isPinnedOnSide(*affectedSide)) { 237 if (fabsf(deltaY) >= fabsf(deltaX)) { 238 if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) { 239 m_unappliedOverscrollDelta.expand(deltaX, 0); 240 deltaX = 0; 241 } else 242 m_unappliedOverscrollDelta.expand(deltaX, 0); 243 } 244 245 if (!m_client.allowsHorizontalStretching(wheelEvent)) 246 deltaX = 0; 247 248 if (!m_client.allowsVerticalStretching(wheelEvent)) 249 deltaY = 0; 250 251 shouldStretch = deltaX || deltaY; 252 } 253 } 205 shouldStretch = modifyScrollDeltaForStretching(wheelEvent, delta, isHorizontallyStretched, isVerticallyStretched); 254 206 } 255 207 256 208 bool handled = true; 257 209 258 if (deltaX || deltaY) { 259 if (!(shouldStretch || isVerticallyStretched || isHorizontallyStretched)) { 260 if (deltaY) { 261 deltaY *= scrollWheelMultiplier(); 262 m_client.immediateScrollBy(FloatSize(0, deltaY)); 263 } 264 if (deltaX) { 265 deltaX *= scrollWheelMultiplier(); 266 m_client.immediateScrollBy(FloatSize(deltaX, 0)); 267 } 268 } else { 269 affectedSide = affectedSideOnDominantAxis({ deltaX, deltaY }); 270 if (deltaX) { 271 if (!m_client.allowsHorizontalStretching(wheelEvent)) { 272 deltaX = 0; 273 eventCoalescedDelta.setWidth(0); 274 handled = false; 275 } else if (!isHorizontallyStretched && !m_client.isPinnedOnSide(*affectedSide)) { 276 deltaX *= scrollWheelMultiplier(); 277 278 m_client.immediateScrollByWithoutContentEdgeConstraints(FloatSize(deltaX, 0)); 279 deltaX = 0; 280 } 281 } 282 283 if (deltaY) { 284 if (!m_client.allowsVerticalStretching(wheelEvent)) { 285 deltaY = 0; 286 eventCoalescedDelta.setHeight(0); 287 handled = false; 288 } else if (!isVerticallyStretched && !m_client.isPinnedOnSide(*affectedSide)) { 289 deltaY *= scrollWheelMultiplier(); 290 291 m_client.immediateScrollByWithoutContentEdgeConstraints(FloatSize(0, deltaY)); 292 deltaY = 0; 293 } 294 } 295 296 IntSize stretchAmount = m_client.stretchAmount(); 297 210 if (!delta.isZero()) { 211 if (shouldStretch || isVerticallyStretched || isHorizontallyStretched) { 212 if (delta.width() && !m_client.allowsHorizontalStretching(wheelEvent)) 213 handled = false; 214 215 if (delta.height() && !m_client.allowsVerticalStretching(wheelEvent)) 216 handled = false; 217 218 bool canStartAnimation = applyScrollDeltaWithStretching(wheelEvent, delta, isHorizontallyStretched, isVerticallyStretched); 298 219 if (m_momentumScrollInProgress) { 299 auto sideAffectedByEventDelta = affectedSideOnDominantAxis(eventCoalescedDelta); 300 if ((!sideAffectedByEventDelta || m_client.isPinnedOnSide(*sideAffectedByEventDelta)) && m_lastMomentumScrollTimestamp) { 220 if (canStartAnimation && m_lastMomentumScrollTimestamp) { 301 221 m_ignoreMomentumScrolls = true; 302 222 m_momentumScrollInProgress = false; … … 304 224 } 305 225 } 306 307 m_stretchScrollForce.setWidth(m_stretchScrollForce.width() + deltaX); 308 m_stretchScrollForce.setHeight(m_stretchScrollForce.height() + deltaY); 309 310 FloatSize dampedDelta(ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.width())), ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.height()))); 311 312 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController::handleWheelEvent() - stretchScrollForce " << m_stretchScrollForce << " move delta " << FloatSize(deltaX, deltaY) << " dampedDelta " << dampedDelta); 313 314 m_client.immediateScrollByWithoutContentEdgeConstraints(dampedDelta - stretchAmount); 226 } else { 227 delta.scale(scrollWheelMultiplier()); 228 m_client.immediateScrollBy(delta); 315 229 } 316 230 } … … 325 239 326 240 return handled; 241 } 242 243 bool ScrollingEffectsController::modifyScrollDeltaForStretching(const PlatformWheelEvent& wheelEvent, FloatSize& delta, bool isHorizontallyStretched, bool isVerticallyStretched) 244 { 245 auto affectedSide = affectedSideOnDominantAxis(delta); 246 if (isVerticallyStretched) { 247 if (!isHorizontallyStretched && isHorizontalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) { 248 // Stretching only in the vertical. 249 if (delta.height() && (fabsf(delta.width() / delta.height()) < rubberbandDirectionLockStretchRatio)) 250 delta.setWidth(0); 251 else if (fabsf(delta.width()) < rubberbandMinimumRequiredDeltaBeforeStretch) { 252 m_unappliedOverscrollDelta.expand(delta.width(), 0); 253 delta.setWidth(0); 254 } else 255 m_unappliedOverscrollDelta.expand(delta.width(), 0); 256 } 257 258 return false; 259 } 260 261 if (isHorizontallyStretched) { 262 // Stretching only in the horizontal. 263 if (isVerticalSide(affectedSide) && m_client.isPinnedOnSide(*affectedSide)) { 264 if (delta.width() && (fabsf(delta.height() / delta.width()) < rubberbandDirectionLockStretchRatio)) 265 delta.setHeight(0); 266 else if (fabsf(delta.height()) < rubberbandMinimumRequiredDeltaBeforeStretch) { 267 m_unappliedOverscrollDelta.expand(0, delta.height()); 268 delta.setHeight(0); 269 } else 270 m_unappliedOverscrollDelta.expand(0, delta.height()); 271 } 272 273 return false; 274 } 275 276 // Not stretching at all yet. 277 if (affectedSide && m_client.isPinnedOnSide(*affectedSide)) { 278 if (fabsf(delta.height()) >= fabsf(delta.width())) { 279 if (fabsf(delta.width()) < rubberbandMinimumRequiredDeltaBeforeStretch) { 280 m_unappliedOverscrollDelta.expand(delta.width(), 0); 281 delta.setWidth(0); 282 } else 283 m_unappliedOverscrollDelta.expand(delta.width(), 0); 284 } 285 286 if (!m_client.allowsHorizontalStretching(wheelEvent)) 287 delta.setWidth(0); 288 289 if (!m_client.allowsVerticalStretching(wheelEvent)) 290 delta.setHeight(0); 291 292 return !delta.isZero(); 293 } 294 295 return false; 296 } 297 298 bool ScrollingEffectsController::applyScrollDeltaWithStretching(const PlatformWheelEvent& wheelEvent, FloatSize delta, bool isHorizontallyStretched, bool isVerticallyStretched) 299 { 300 auto eventDelta = (isVerticallyStretched || isHorizontallyStretched) ? -wheelEvent.unacceleratedScrollingDelta() : -wheelEvent.delta(); 301 auto affectedSide = affectedSideOnDominantAxis(delta); 302 303 FloatSize deltaToScroll; 304 305 if (delta.width()) { 306 if (!m_client.allowsHorizontalStretching(wheelEvent)) { 307 delta.setWidth(0); 308 eventDelta.setWidth(0); 309 } else if (!isHorizontallyStretched && !m_client.isPinnedOnSide(*affectedSide)) { 310 delta.scale(scrollWheelMultiplier(), 1); 311 deltaToScroll += FloatSize { delta.width(), 0 }; 312 delta.setWidth(0); 313 } 314 } 315 316 if (delta.height()) { 317 if (!m_client.allowsVerticalStretching(wheelEvent)) { 318 delta.setHeight(0); 319 eventDelta.setHeight(0); 320 } else if (!isVerticallyStretched && !m_client.isPinnedOnSide(*affectedSide)) { 321 delta.scale(1, scrollWheelMultiplier()); 322 deltaToScroll += FloatSize { 0, delta.height() }; 323 delta.setHeight(0); 324 } 325 } 326 327 if (!deltaToScroll.isZero()) 328 m_client.immediateScrollByWithoutContentEdgeConstraints(deltaToScroll); 329 330 bool canStartAnimation = false; 331 if (m_momentumScrollInProgress) { 332 // Compute canStartAnimation, which looks at isPinnedOnSide(), before applying the stretch delta. 333 auto sideAffectedByEventDelta = affectedSideOnDominantAxis(eventDelta); 334 canStartAnimation = !sideAffectedByEventDelta || m_client.isPinnedOnSide(*sideAffectedByEventDelta); 335 } 336 337 m_stretchScrollForce += delta; 338 auto dampedDelta = FloatSize { 339 ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.width())), 340 ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.height())) 341 }; 342 343 LOG_WITH_STREAM(ScrollAnimations, stream << "ScrollingEffectsController::applyScrollDeltaWithStretching() - stretchScrollForce " << m_stretchScrollForce << " move delta " << delta << " dampedDelta " << dampedDelta); 344 345 auto stretchAmount = m_client.stretchAmount(); 346 m_client.immediateScrollByWithoutContentEdgeConstraints(dampedDelta - stretchAmount); 347 348 return canStartAnimation; 327 349 } 328 350
Note:
See TracChangeset
for help on using the changeset viewer.