Changeset 104853 in webkit


Ignore:
Timestamp:
Jan 12, 2012 1:28:51 PM (12 years ago)
Author:
andersca@apple.com
Message:

Move wheel event handling to ScrollElasticityController::handleWheelEvent
https://bugs.webkit.org/show_bug.cgi?id=76205

Reviewed by Andreas Kling.

Move the code in ScrollAnimatorMac::smoothScrollWithEvent to ScrollElasticityController::handleWheelEvent and
change ScrollAnimatorMac::handleWheelEvent to just call ScrollElasticityController::handleWheelEvent.
This means that we'll not set m_haveScrolledSincePageLoad = true anymore (we used to set it in ScrollAnimatorMac::smoothScrollWithEvent),
but we already set it to true in ScrollAnimatorMac::handleWheelEvent so it already had no effect.

  • platform/mac/ScrollAnimatorMac.h:
  • platform/mac/ScrollAnimatorMac.mm:

(WebCore::ScrollAnimatorMac::handleWheelEvent):

  • platform/mac/ScrollElasticityController.h:
  • platform/mac/ScrollElasticityController.mm:

(WebCore::elasticDeltaForReboundDelta):
(WebCore::scrollWheelMultiplier):
(WebCore::ScrollElasticityController::handleWheelEvent):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r104851 r104853  
     12012-01-12  Anders Carlsson  <andersca@apple.com>
     2
     3        Move wheel event handling to ScrollElasticityController::handleWheelEvent
     4        https://bugs.webkit.org/show_bug.cgi?id=76205
     5
     6        Reviewed by Andreas Kling.
     7
     8        Move the code in ScrollAnimatorMac::smoothScrollWithEvent to ScrollElasticityController::handleWheelEvent and
     9        change ScrollAnimatorMac::handleWheelEvent to just call ScrollElasticityController::handleWheelEvent.
     10        This means that we'll not set m_haveScrolledSincePageLoad = true anymore (we used to set it in ScrollAnimatorMac::smoothScrollWithEvent),
     11        but we already set it to true in ScrollAnimatorMac::handleWheelEvent so it already had no effect.
     12
     13        * platform/mac/ScrollAnimatorMac.h:
     14        * platform/mac/ScrollAnimatorMac.mm:
     15        (WebCore::ScrollAnimatorMac::handleWheelEvent):
     16        * platform/mac/ScrollElasticityController.h:
     17        * platform/mac/ScrollElasticityController.mm:
     18        (WebCore::elasticDeltaForReboundDelta):
     19        (WebCore::scrollWheelMultiplier):
     20        (WebCore::ScrollElasticityController::handleWheelEvent):
     21
    1222012-01-12  Simon Fraser  <simon.fraser@apple.com>
    223
  • trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h

    r104847 r104853  
    141141    bool pinnedInDirection(float deltaX, float deltaY);
    142142    void snapRubberBandTimerFired(Timer<ScrollAnimatorMac>*);
    143     bool smoothScrollWithEvent(const PlatformWheelEvent&);
    144143    void beginScrollGesture();
    145144    void endScrollGesture();
  • trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm

    r104849 r104853  
    878878#if ENABLE(RUBBER_BANDING)
    879879
    880 static const float scrollVelocityZeroingTimeout = 0.10f;
    881 static const float rubberbandStiffness = 20;
    882 static const float rubberbandDirectionLockStretchRatio = 1;
    883 static const float rubberbandMinimumRequiredDeltaBeforeStretch = 10;
    884 static const float rubberbandAmplitude = 0.31f;
    885 static const float rubberbandPeriod = 1.6f;
    886 
    887 static float elasticDeltaForReboundDelta(float delta)
    888 {
    889     float stiffness = std::max(rubberbandStiffness, 1.0f);
    890     return delta / stiffness;
    891 }
    892 
    893 static float scrollWheelMultiplier()
    894 {
    895     static float multiplier = -1;
    896     if (multiplier < 0) {
    897         multiplier = [[NSUserDefaults standardUserDefaults] floatForKey:@"NSScrollWheelMultiplier"];
    898         if (multiplier <= 0)
    899             multiplier = 1;
    900     }
    901     return multiplier;
    902 }
    903 
    904880static inline bool isScrollingLeftAndShouldNotRubberBand(const PlatformWheelEvent& wheelEvent, ScrollableArea* scrollableArea)
    905881{
     
    959935    }
    960936
    961     return smoothScrollWithEvent(wheelEvent);
     937    return m_scrollElasticityController.handleWheelEvent(wheelEvent);
    962938}
    963939
     
    10931069}
    10941070
    1095 bool ScrollAnimatorMac::smoothScrollWithEvent(const PlatformWheelEvent& wheelEvent)
    1096 {
    1097     bool isMomentumScrollEvent = (wheelEvent.momentumPhase() != PlatformWheelEventPhaseNone);
    1098     if (m_scrollElasticityController.m_ignoreMomentumScrolls && (isMomentumScrollEvent || m_scrollElasticityController.m_snapRubberbandTimerIsActive)) {
    1099         if (wheelEvent.momentumPhase() == PlatformWheelEventPhaseEnded) {
    1100             m_scrollElasticityController.m_ignoreMomentumScrolls = false;
    1101             return true;
    1102         }
    1103         return false;
    1104     }
    1105 
    1106     m_haveScrolledSincePageLoad = true;
    1107 
    1108     float deltaX = m_scrollElasticityController.m_overflowScrollDelta.width();
    1109     float deltaY = m_scrollElasticityController.m_overflowScrollDelta.height();
    1110 
    1111     // Reset overflow values because we may decide to remove delta at various points and put it into overflow.
    1112     m_scrollElasticityController.m_overflowScrollDelta = FloatSize();
    1113 
    1114     float eventCoalescedDeltaX = -wheelEvent.deltaX();
    1115     float eventCoalescedDeltaY = -wheelEvent.deltaY();
    1116 
    1117     deltaX += eventCoalescedDeltaX;
    1118     deltaY += eventCoalescedDeltaY;
    1119 
    1120     // Slightly prefer scrolling vertically by applying the = case to deltaY
    1121     if (fabsf(deltaY) >= fabsf(deltaX))
    1122         deltaX = 0;
    1123     else
    1124         deltaY = 0;
    1125 
    1126     bool isVerticallyStretched = false;
    1127     bool isHorizontallyStretched = false;
    1128     bool shouldStretch = false;
    1129    
    1130     IntSize stretchAmount = m_scrollElasticityController.m_client->stretchAmount();
    1131 
    1132     isHorizontallyStretched = stretchAmount.width();
    1133     isVerticallyStretched = stretchAmount.height();
    1134 
    1135     PlatformWheelEventPhase phase = wheelEvent.momentumPhase();
    1136 
    1137     // If we are starting momentum scrolling then do some setup.
    1138     if (!m_scrollElasticityController.m_momentumScrollInProgress && (phase == PlatformWheelEventPhaseBegan || phase == PlatformWheelEventPhaseChanged))
    1139         m_scrollElasticityController.m_momentumScrollInProgress = true;
    1140 
    1141     CFTimeInterval timeDelta = wheelEvent.timestamp() - m_scrollElasticityController.m_lastMomentumScrollTimestamp;
    1142     if (m_scrollElasticityController.m_inScrollGesture || m_scrollElasticityController.m_momentumScrollInProgress) {
    1143         if (m_scrollElasticityController.m_lastMomentumScrollTimestamp && timeDelta > 0 && timeDelta < scrollVelocityZeroingTimeout) {
    1144             m_scrollElasticityController.m_momentumVelocity.setWidth(eventCoalescedDeltaX / (float)timeDelta);
    1145             m_scrollElasticityController.m_momentumVelocity.setHeight(eventCoalescedDeltaY / (float)timeDelta);
    1146             m_scrollElasticityController.m_lastMomentumScrollTimestamp = wheelEvent.timestamp();
    1147         } else {
    1148             m_scrollElasticityController.m_lastMomentumScrollTimestamp = wheelEvent.timestamp();
    1149             m_scrollElasticityController.m_momentumVelocity = FloatSize();
    1150         }
    1151 
    1152         if (isVerticallyStretched) {
    1153             if (!isHorizontallyStretched && m_scrollElasticityController.m_client->pinnedInDirection(FloatSize(deltaX, 0))) {
    1154                 // Stretching only in the vertical.
    1155                 if (deltaY != 0 && (fabsf(deltaX / deltaY) < rubberbandDirectionLockStretchRatio))
    1156                     deltaX = 0;
    1157                 else if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) {
    1158                     m_scrollElasticityController.m_overflowScrollDelta.setWidth(m_scrollElasticityController.m_overflowScrollDelta.width() + deltaX);
    1159                     deltaX = 0;
    1160                 } else
    1161                     m_scrollElasticityController.m_overflowScrollDelta.setWidth(m_scrollElasticityController.m_overflowScrollDelta.width() + deltaX);
    1162             }
    1163         } else if (isHorizontallyStretched) {
    1164             // Stretching only in the horizontal.
    1165             if (m_scrollElasticityController.m_client->pinnedInDirection(FloatSize(0, deltaY))) {
    1166                 if (deltaX != 0 && (fabsf(deltaY / deltaX) < rubberbandDirectionLockStretchRatio))
    1167                     deltaY = 0;
    1168                 else if (fabsf(deltaY) < rubberbandMinimumRequiredDeltaBeforeStretch) {
    1169                     m_scrollElasticityController.m_overflowScrollDelta.setHeight(m_scrollElasticityController.m_overflowScrollDelta.height() + deltaY);
    1170                     deltaY = 0;
    1171                 } else
    1172                     m_scrollElasticityController.m_overflowScrollDelta.setHeight(m_scrollElasticityController.m_overflowScrollDelta.height() + deltaY);
    1173             }
    1174         } else {
    1175             // Not stretching at all yet.
    1176             if (m_scrollElasticityController.m_client->pinnedInDirection(FloatSize(deltaX, deltaY))) {
    1177                 if (fabsf(deltaY) >= fabsf(deltaX)) {
    1178                     if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) {
    1179                         m_scrollElasticityController.m_overflowScrollDelta.setWidth(m_scrollElasticityController.m_overflowScrollDelta.width() + deltaX);
    1180                         deltaX = 0;
    1181                     } else
    1182                         m_scrollElasticityController.m_overflowScrollDelta.setWidth(m_scrollElasticityController.m_overflowScrollDelta.width() + deltaX);
    1183                 }
    1184                 shouldStretch = true;
    1185             }
    1186         }
    1187     }
    1188 
    1189     if (deltaX != 0 || deltaY != 0) {
    1190         if (!(shouldStretch || isVerticallyStretched || isHorizontallyStretched)) {
    1191             if (deltaY != 0) {
    1192                 deltaY *= scrollWheelMultiplier();
    1193                 m_scrollElasticityController.m_client->immediateScrollBy(FloatSize(0, deltaY));
    1194             }
    1195             if (deltaX != 0) {
    1196                 deltaX *= scrollWheelMultiplier();
    1197                 m_scrollElasticityController.m_client->immediateScrollBy(FloatSize(deltaX, 0));
    1198             }
    1199         } else {
    1200             if (!m_scrollElasticityController.m_client->allowsHorizontalStretching()) {
    1201                 deltaX = 0;
    1202                 eventCoalescedDeltaX = 0;
    1203             } else if ((deltaX != 0) && !isHorizontallyStretched && !pinnedInDirection(deltaX, 0)) {
    1204                 deltaX *= scrollWheelMultiplier();
    1205 
    1206                 m_scrollElasticityController.m_client->immediateScrollByWithoutContentEdgeConstraints(FloatSize(deltaX, 0));
    1207                 deltaX = 0;
    1208             }
    1209            
    1210             if (!m_scrollElasticityController.m_client->allowsVerticalStretching()) {
    1211                 deltaY = 0;
    1212                 eventCoalescedDeltaY = 0;
    1213             } else if ((deltaY != 0) && !isVerticallyStretched && !pinnedInDirection(0, deltaY)) {
    1214                 deltaY *= scrollWheelMultiplier();
    1215 
    1216                 m_scrollElasticityController.m_client->immediateScrollByWithoutContentEdgeConstraints(FloatSize(0, deltaY));
    1217                 deltaY = 0;
    1218             }
    1219            
    1220             IntSize stretchAmount = m_scrollElasticityController.m_client->stretchAmount();
    1221        
    1222             if (m_scrollElasticityController.m_momentumScrollInProgress) {
    1223                 if ((pinnedInDirection(eventCoalescedDeltaX, eventCoalescedDeltaY) || (fabsf(eventCoalescedDeltaX) + fabsf(eventCoalescedDeltaY) <= 0)) && m_scrollElasticityController.m_lastMomentumScrollTimestamp) {
    1224                     m_scrollElasticityController.m_ignoreMomentumScrolls = true;
    1225                     m_scrollElasticityController.m_momentumScrollInProgress = false;
    1226                     m_scrollElasticityController.snapRubberBand();
    1227                 }
    1228             }
    1229 
    1230             m_scrollElasticityController.m_stretchScrollForce.setWidth(m_scrollElasticityController.m_stretchScrollForce.width() + deltaX);
    1231             m_scrollElasticityController.m_stretchScrollForce.setHeight(m_scrollElasticityController.m_stretchScrollForce.height() + deltaY);
    1232 
    1233             FloatSize dampedDelta(ceilf(elasticDeltaForReboundDelta(m_scrollElasticityController.m_stretchScrollForce.width())), ceilf(elasticDeltaForReboundDelta(m_scrollElasticityController.m_stretchScrollForce.height())));
    1234 
    1235             m_scrollElasticityController.m_client->immediateScrollByWithoutContentEdgeConstraints(dampedDelta - stretchAmount);
    1236         }
    1237     }
    1238 
    1239     if (m_scrollElasticityController.m_momentumScrollInProgress && phase == PlatformWheelEventPhaseEnded) {
    1240         m_scrollElasticityController.m_momentumScrollInProgress = false;
    1241         m_scrollElasticityController.m_ignoreMomentumScrolls = false;
    1242         m_scrollElasticityController.m_lastMomentumScrollTimestamp = 0;
    1243     }
    1244 
    1245     return true;
    1246 }
    1247 
    12481071void ScrollAnimatorMac::beginScrollGesture()
    12491072{
  • trunk/Source/WebCore/platform/mac/ScrollElasticityController.h

    r104847 r104853  
    3535namespace WebCore {
    3636
     37class PlatformWheelEvent;
     38
    3739class ScrollElasticityControllerClient {
    3840protected:
     
    6466    void beginScrollGesture();
    6567
     68    bool handleWheelEvent(const PlatformWheelEvent&);
    6669    void snapRubberBandTimerFired();
    6770
  • trunk/Source/WebCore/platform/mac/ScrollElasticityController.mm

    r104846 r104853  
    2727#include "ScrollElasticityController.h"
    2828
     29#include "PlatformWheelEvent.h"
    2930#include <sys/time.h>
    3031#include <sys/sysctl.h>
     
    6869static const float scrollVelocityZeroingTimeout = 0.10f;
    6970static const float rubberbandStiffness = 20;
     71static const float rubberbandDirectionLockStretchRatio = 1;
     72static const float rubberbandMinimumRequiredDeltaBeforeStretch = 10;
    7073static const float rubberbandAmplitude = 0.31f;
    7174static const float rubberbandPeriod = 1.6f;
     
    8083}
    8184
     85static float elasticDeltaForReboundDelta(float delta)
     86{
     87    float stiffness = std::max(rubberbandStiffness, 1.0f);
     88    return delta / stiffness;
     89}
     90
    8291static float reboundDeltaForElasticDelta(float delta)
    8392{
    8493    return delta * rubberbandStiffness;
     94}
     95
     96static float scrollWheelMultiplier()
     97{
     98    static float multiplier = -1;
     99    if (multiplier < 0) {
     100        multiplier = [[NSUserDefaults standardUserDefaults] floatForKey:@"NSScrollWheelMultiplier"];
     101        if (multiplier <= 0)
     102            multiplier = 1;
     103    }
     104    return multiplier;
    85105}
    86106
     
    113133}
    114134
     135bool ScrollElasticityController::handleWheelEvent(const PlatformWheelEvent& wheelEvent)
     136{
     137    bool isMomentumScrollEvent = (wheelEvent.momentumPhase() != PlatformWheelEventPhaseNone);
     138    if (m_ignoreMomentumScrolls && (isMomentumScrollEvent || m_snapRubberbandTimerIsActive)) {
     139        if (wheelEvent.momentumPhase() == PlatformWheelEventPhaseEnded) {
     140            m_ignoreMomentumScrolls = false;
     141            return true;
     142        }
     143        return false;
     144    }
     145
     146    float deltaX = m_overflowScrollDelta.width();
     147    float deltaY = m_overflowScrollDelta.height();
     148
     149    // Reset overflow values because we may decide to remove delta at various points and put it into overflow.
     150    m_overflowScrollDelta = FloatSize();
     151
     152    float eventCoalescedDeltaX = -wheelEvent.deltaX();
     153    float eventCoalescedDeltaY = -wheelEvent.deltaY();
     154
     155    deltaX += eventCoalescedDeltaX;
     156    deltaY += eventCoalescedDeltaY;
     157
     158    // Slightly prefer scrolling vertically by applying the = case to deltaY
     159    if (fabsf(deltaY) >= fabsf(deltaX))
     160        deltaX = 0;
     161    else
     162        deltaY = 0;
     163
     164    bool isVerticallyStretched = false;
     165    bool isHorizontallyStretched = false;
     166    bool shouldStretch = false;
     167
     168    IntSize stretchAmount = m_client->stretchAmount();
     169
     170    isHorizontallyStretched = stretchAmount.width();
     171    isVerticallyStretched = stretchAmount.height();
     172
     173    PlatformWheelEventPhase phase = wheelEvent.momentumPhase();
     174
     175    // If we are starting momentum scrolling then do some setup.
     176    if (!m_momentumScrollInProgress && (phase == PlatformWheelEventPhaseBegan || phase == PlatformWheelEventPhaseChanged))
     177        m_momentumScrollInProgress = true;
     178
     179    CFTimeInterval timeDelta = wheelEvent.timestamp() - m_lastMomentumScrollTimestamp;
     180    if (m_inScrollGesture || m_momentumScrollInProgress) {
     181        if (m_lastMomentumScrollTimestamp && timeDelta > 0 && timeDelta < scrollVelocityZeroingTimeout) {
     182            m_momentumVelocity.setWidth(eventCoalescedDeltaX / (float)timeDelta);
     183            m_momentumVelocity.setHeight(eventCoalescedDeltaY / (float)timeDelta);
     184            m_lastMomentumScrollTimestamp = wheelEvent.timestamp();
     185        } else {
     186            m_lastMomentumScrollTimestamp = wheelEvent.timestamp();
     187            m_momentumVelocity = FloatSize();
     188        }
     189
     190        if (isVerticallyStretched) {
     191            if (!isHorizontallyStretched && m_client->pinnedInDirection(FloatSize(deltaX, 0))) {
     192                // Stretching only in the vertical.
     193                if (deltaY != 0 && (fabsf(deltaX / deltaY) < rubberbandDirectionLockStretchRatio))
     194                    deltaX = 0;
     195                else if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) {
     196                    m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX);
     197                    deltaX = 0;
     198                } else
     199                    m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX);
     200            }
     201        } else if (isHorizontallyStretched) {
     202            // Stretching only in the horizontal.
     203            if (m_client->pinnedInDirection(FloatSize(0, deltaY))) {
     204                if (deltaX != 0 && (fabsf(deltaY / deltaX) < rubberbandDirectionLockStretchRatio))
     205                    deltaY = 0;
     206                else if (fabsf(deltaY) < rubberbandMinimumRequiredDeltaBeforeStretch) {
     207                    m_overflowScrollDelta.setHeight(m_overflowScrollDelta.height() + deltaY);
     208                    deltaY = 0;
     209                } else
     210                    m_overflowScrollDelta.setHeight(m_overflowScrollDelta.height() + deltaY);
     211            }
     212        } else {
     213            // Not stretching at all yet.
     214            if (m_client->pinnedInDirection(FloatSize(deltaX, deltaY))) {
     215                if (fabsf(deltaY) >= fabsf(deltaX)) {
     216                    if (fabsf(deltaX) < rubberbandMinimumRequiredDeltaBeforeStretch) {
     217                        m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX);
     218                        deltaX = 0;
     219                    } else
     220                        m_overflowScrollDelta.setWidth(m_overflowScrollDelta.width() + deltaX);
     221                }
     222                shouldStretch = true;
     223            }
     224        }
     225    }
     226
     227    if (deltaX != 0 || deltaY != 0) {
     228        if (!(shouldStretch || isVerticallyStretched || isHorizontallyStretched)) {
     229            if (deltaY != 0) {
     230                deltaY *= scrollWheelMultiplier();
     231                m_client->immediateScrollBy(FloatSize(0, deltaY));
     232            }
     233            if (deltaX != 0) {
     234                deltaX *= scrollWheelMultiplier();
     235                m_client->immediateScrollBy(FloatSize(deltaX, 0));
     236            }
     237        } else {
     238            if (!m_client->allowsHorizontalStretching()) {
     239                deltaX = 0;
     240                eventCoalescedDeltaX = 0;
     241            } else if ((deltaX != 0) && !isHorizontallyStretched && !m_client->pinnedInDirection(FloatSize(deltaX, 0))) {
     242                deltaX *= scrollWheelMultiplier();
     243
     244                m_client->immediateScrollByWithoutContentEdgeConstraints(FloatSize(deltaX, 0));
     245                deltaX = 0;
     246            }
     247
     248            if (!m_client->allowsVerticalStretching()) {
     249                deltaY = 0;
     250                eventCoalescedDeltaY = 0;
     251            } else if ((deltaY != 0) && !isVerticallyStretched && !m_client->pinnedInDirection(FloatSize(0, deltaY))) {
     252                deltaY *= scrollWheelMultiplier();
     253
     254                m_client->immediateScrollByWithoutContentEdgeConstraints(FloatSize(0, deltaY));
     255                deltaY = 0;
     256            }
     257
     258            IntSize stretchAmount = m_client->stretchAmount();
     259
     260            if (m_momentumScrollInProgress) {
     261                if ((m_client->pinnedInDirection(FloatSize(eventCoalescedDeltaX, eventCoalescedDeltaY)) || (fabsf(eventCoalescedDeltaX) + fabsf(eventCoalescedDeltaY) <= 0)) && m_lastMomentumScrollTimestamp) {
     262                    m_ignoreMomentumScrolls = true;
     263                    m_momentumScrollInProgress = false;
     264                    snapRubberBand();
     265                }
     266            }
     267
     268            m_stretchScrollForce.setWidth(m_stretchScrollForce.width() + deltaX);
     269            m_stretchScrollForce.setHeight(m_stretchScrollForce.height() + deltaY);
     270
     271            FloatSize dampedDelta(ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.width())), ceilf(elasticDeltaForReboundDelta(m_stretchScrollForce.height())));
     272
     273            m_client->immediateScrollByWithoutContentEdgeConstraints(dampedDelta - stretchAmount);
     274        }
     275    }
     276
     277    if (m_momentumScrollInProgress && phase == PlatformWheelEventPhaseEnded) {
     278        m_momentumScrollInProgress = false;
     279        m_ignoreMomentumScrolls = false;
     280        m_lastMomentumScrollTimestamp = 0;
     281    }
     282
     283    return true;
     284}
     285
    115286static inline float roundTowardZero(float num)
    116287{
Note: See TracChangeset for help on using the changeset viewer.