<html>
    <head>
      <base href="https://bugs.webkit.org/" />
    </head>
    <body><span class="vcard"><a class="email" href="mailto:cgarcia&#64;igalia.com" title="Carlos Garcia Campos &lt;cgarcia&#64;igalia.com&gt;"> <span class="fn">Carlos Garcia Campos</span></a>
</span> changed
              <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [GTK] Add kinetic scrolling"
   href="https://bugs.webkit.org/show_bug.cgi?id=155750">bug 155750</a>
        <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">Attachment #281354 Flags</td>
           <td>review?, commit-queue?
           </td>
           <td>review-, commit-queue-
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [GTK] Add kinetic scrolling"
   href="https://bugs.webkit.org/show_bug.cgi?id=155750#c21">Comment # 21</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [GTK] Add kinetic scrolling"
   href="https://bugs.webkit.org/show_bug.cgi?id=155750">bug 155750</a>
              from <span class="vcard"><a class="email" href="mailto:cgarcia&#64;igalia.com" title="Carlos Garcia Campos &lt;cgarcia&#64;igalia.com&gt;"> <span class="fn">Carlos Garcia Campos</span></a>
</span></b>
        <pre>Comment on <span class=""><a href="attachment.cgi?id=281354&amp;action=diff" name="attach_281354" title="[GTK] Add kinetic scrolling">attachment 281354</a> <a href="attachment.cgi?id=281354&amp;action=edit" title="[GTK] Add kinetic scrolling">[details]</a></span>
[GTK] Add kinetic scrolling

View in context: <a href="https://bugs.webkit.org/attachment.cgi?id=281354&amp;action=review">https://bugs.webkit.org/attachment.cgi?id=281354&amp;action=review</a>

Sorry for the delay reviewing this. Looks quite good in general, but there are still several minor issues to solve. Also, please check the EWS after submitting a patch to make sure it builds.

<span class="quote">&gt; Source/WebCore/platform/PlatformWheelEvent.h:168
&gt; +        bool useLatchedEventElement() const { return false; }
&gt; +        bool isEndOfNonMomentumScroll() const;
&gt; +        bool isTransitioningToMomentumScroll() const;</span >

We should reorder what we share with cocoa instead of duplicating it

<span class="quote">&gt; Source/WebCore/platform/PlatformWheelEvent.h:198
&gt; +#elif PLATFORM(GTK)
&gt; +        PlatformWheelEventPhase m_phase { PlatformWheelEventPhaseNone };
&gt; +        PlatformWheelEventPhase m_momentumPhase { PlatformWheelEventPhaseNone };
&gt;  #endif</span >

Ditto.

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.cpp:126
&gt; +bool ScrollAnimationKinetic::scroll(ScrollbarOrientation, ScrollGranularity, float, float)
&gt; +{
&gt; +    // This method isn't needed and shouldn't do anything as 'scroll' isn't
&gt; +    // how this animation needs to be used, use 'start' instead.
&gt; +    return true;
&gt; +}</span >

We could move this to the header then, with the comment before the function, or even consider making scroll not pure virtual, I guess I assumed all animations would have to implement this when I added it.

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.cpp:136
&gt; +    m_position = position;</span >

I wonder if we really need to save the current position, since we are not actually scrolling, and the initial position is always passed to start()

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.cpp:152
&gt; +        m_position.x(), velocity.x());
&gt; +    m_verticalData = PerAxisData(m_scrollableArea.minimumScrollPosition().y(),
&gt; +        m_scrollableArea.maximumScrollPosition().y(),
&gt; +        m_position.y(), velocity.y());</span >

We could use initialPosition.x(), initialPosition.y() here

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.cpp:173
&gt; +    m_position = FloatPoint(m_horizontalData.position(), m_verticalData.position());
&gt; +
&gt; +    m_notifyPositionChangedFunction(FloatPoint(m_position));</span >

And pass the position directly to the callback

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.h:57
&gt; +        double m_lower { 0 };
&gt; +        double m_upper { 0 };
&gt; +
&gt; +        double m_coef1 { 0 };
&gt; +        double m_coef2 { 0 };
&gt; +
&gt; +        double m_elapsedTime { 0 };
&gt; +        double m_position { 0 };
&gt; +        double m_velocity { 0 };</span >

We don't use m_ prefix for struct members.

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.h:67
&gt; +    bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier) override;
&gt; +    void stop() override;
&gt; +    void updateVisibleLengths() override { }
&gt; +    void setCurrentPosition(const FloatPoint&amp;) override;</span >

I don't think these should be public.

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.h:77
&gt; +    PerAxisData m_horizontalData { PerAxisData(0, 0, 0, 0) };
&gt; +    PerAxisData m_verticalData { PerAxisData(0, 0, 0, 0) };</span >

You don't need to initialize these, all PerAxisData members are initialized.

<span class="quote">&gt; Source/WebCore/platform/ScrollAnimationKinetic.h:81
&gt; +</span >

Extra line here.

<span class="quote">&gt; Source/WebCore/platform/graphics/FloatPoint.h:125
&gt; +    bool isOrigin() const { return m_x == 0.0 &amp;&amp; m_y == 0.0; }
&gt; +</span >

We don't compare to 0 in WebKit. I would leave this change to FloatPoint to a separate patch, since the rest of the patch is GTK+ specific, and just check x, y in the code. Also note that IntPoint has this methods as isZero(), so we should be consistent here.

<span class="quote">&gt; Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp:91
&gt; +    m_phase = event-&gt;is_stop ?
&gt; +        PlatformWheelEventPhaseEnded :
&gt; +        PlatformWheelEventPhaseChanged;</span >

I don't understand this. When is it None then? Why is initially changed?

<span class="quote">&gt; Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp:93
&gt; +    m_phase = event-&gt;direction == GDK_SCROLL_SMOOTH &amp;&amp; m_deltaX == 0.0 &amp;&amp; m_deltaY = 0.0 ?</span >

We don't compare to 0 in WebKit, see <a href="https://webkit.org/code-style-guidelines/#null-false-and-zero">https://webkit.org/code-style-guidelines/#null-false-and-zero</a>

<span class="quote">&gt; Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp:98
&gt; +    m_phase = PlatformWheelEventPhaseChanged;</span >

Do we really need this? m_pahse is initialized in the header and will not be used in GTK+2 for sure.

<span class="quote">&gt; Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp:101
&gt; +    m_momentumPhase = PlatformWheelEventPhaseNone;</span >

This is already None as initialized in the header.

<span class="quote">&gt; Source/WebCore/platform/gtk/PlatformWheelEventGtk.cpp:116
&gt; +    return isTransitioningToMomentumScroll() ? FloatPoint(m_wheelTicksX, m_wheelTicksY) : FloatPoint();</span >

FloatPoint() -&gt; { }

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:79
&gt; +        updatePosition(FloatPoint(position));</span >

updatePosition(WTFMove(position));

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:94
&gt; +#if ENABLE(SMOOTH_SCROLLING)
&gt;      if (!m_scrollableArea.scrollAnimatorEnabled() || granularity == ScrollByPrecisePixel)
&gt;          return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
&gt;  
&gt;      ensureSmoothScrollingAnimation();
&gt; -    return m_animation-&gt;scroll(orientation, granularity, step, multiplier);
&gt; +    return m_smoothAnimation-&gt;scroll(orientation, granularity, step, multiplier);
&gt; +#else
&gt; +    return ScrollAnimator::scroll(orientation, granularity, step, multiplier);
&gt; +#endif</span >

I think we could just keep this inside the #if ENABLE(SMOOTH_SCROLLING) as it was before, since you are not adding anything for non smooth scrolling.

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:108
&gt; +    updatePosition(FloatPoint(position));</span >

updatePosition(WTFMove(position));

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:114
&gt; +        return FloatPoint();</span >

return { };

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:120
&gt; +        return FloatPoint();</span >

Ditto.

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:128
&gt; +    return FloatPoint(accumDelta.x() * -1000 / (last - first), accumDelta.y() * -1000 / (last - first));</span >

And here you could also use { }

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:135
&gt; +    m_scrollHistory.removeAllMatching([&amp;] (PlatformWheelEvent&amp; otherEvent) -&gt; bool {</span >

Capture explicitly event, instead of using &amp;

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:140
&gt; +        m_kineticAnimation-&gt;start(m_currentPosition, computeVelocity());</span >

Don't we need to add the event to the history in this case too?

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:141
&gt; +</span >

Extra line here.

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.cpp:147
&gt; +</span >

Ditto.

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.h:34
&gt; +#include &quot;ScrollAnimationKinetic.h&quot;</span >

Why do you need to include this in the header?

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.h:48
&gt; -#if ENABLE(SMOOTH_SCROLLING)
&gt;      bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier) override;</span >

scroll is still specific to smooth scrolling

<span class="quote">&gt; Source/WebCore/platform/gtk/ScrollAnimatorGtk.h:81
&gt; +    std::unique_ptr&lt;ScrollAnimationKinetic&gt; m_kineticAnimation;</span >

This should be ScrollAnimation not ScrollAnimationKinetic

<span class="quote">&gt; Source/WebKit2/Shared/NativeWebWheelEvent.h:55
&gt; +    NativeWebWheelEvent(GdkEvent*, WebWheelEvent::Phase, WebWheelEvent::Phase momentumPhase);</span >

Maybe instead of adding a new constructor we could add the phase parameters with default values

<span class="quote">&gt; Source/WebKit2/Shared/WebEvent.h:218
&gt; +#elif PLATFORM(GTK)
&gt; +    Phase phase() const { return static_cast&lt;Phase&gt;(m_phase); }
&gt; +    Phase momentumPhase() const { return static_cast&lt;Phase&gt;(m_momentumPhase); }
&gt;  #endif</span >

We should reorder things to share with coca, instead of duplicating.

<span class="quote">&gt; Source/WebKit2/Shared/WebEvent.h:241
&gt; +#elif PLATFORM(GTK)
&gt; +    uint32_t m_phase { Phase::PhaseNone }; // Phase
&gt; +    uint32_t m_momentumPhase { Phase::PhaseNone }; // Phase
&gt;  #endif</span >

Ditto. Comments here // Phase don't really add anything, so I would remove them.

<span class="quote">&gt; Source/WebKit2/Shared/WebEventConversion.cpp:151
&gt; +#if PLATFORM(GTK)
&gt; +inline WebCore::PlatformWheelEventPhase&amp; operator|=(WebCore::PlatformWheelEventPhase&amp; self, WebCore::PlatformWheelEventPhase other)
&gt; +{
&gt; +    return self = static_cast&lt;WebCore::PlatformWheelEventPhase&gt;(self | other);
&gt; +}
&gt; +
&gt; +static WebCore::PlatformWheelEventPhase toPlatformWheeleventPhase(WebWheelEvent::Phase phase)
&gt; +{
&gt; +    WebCore::PlatformWheelEventPhase result = WebCore::PlatformWheelEventPhase::PlatformWheelEventPhaseNone;
&gt; +
&gt; +    if (phase &amp; WebWheelEvent::Phase::PhaseBegan)
&gt; +        result |= WebCore::PlatformWheelEventPhase::PlatformWheelEventPhaseBegan;
&gt; +    if (phase &amp; WebWheelEvent::Phase::PhaseStationary)
&gt; +        result |= WebCore::PlatformWheelEventPhase::PlatformWheelEventPhaseStationary;
&gt; +    if (phase &amp; WebWheelEvent::Phase::PhaseChanged)
&gt; +        result |= WebCore::PlatformWheelEventPhase::PlatformWheelEventPhaseChanged;
&gt; +    if (phase &amp; WebWheelEvent::Phase::PhaseEnded)
&gt; +        result |= WebCore::PlatformWheelEventPhase::PlatformWheelEventPhaseEnded;
&gt; +    if (phase &amp; WebWheelEvent::Phase::PhaseCancelled)
&gt; +        result |= WebCore::PlatformWheelEventPhase::PlatformWheelEventPhaseCancelled;
&gt; +    if (phase &amp; WebWheelEvent::Phase::PhaseMayBegin)
&gt; +        result |= WebCore::PlatformWheelEventPhase::PlatformWheelEventPhaseMayBegin;
&gt; +
&gt; +    return result;
&gt; +}
&gt; +#endif</span >

I agree we shouldn't cast directly between WebKit and WebCore types, but this code should be shared with mac. Since they are casting, I suggest to share their current code for now to make this patch simpoler, and propose a new patch to do conversions instead of casts.

<span class="quote">&gt; Source/WebKit2/Shared/WebEventConversion.cpp:191
&gt; +#elif PLATFORM(GTK)
&gt; +        m_phase = toPlatformWheeleventPhase(webEvent.phase());
&gt; +        m_momentumPhase = toPlatformWheeleventPhase(webEvent.momentumPhase());
&gt;  #endif</span >

And then we could reuse this code too, instead of duplicate.

<span class="quote">&gt; Source/WebKit2/Shared/WebWheelEvent.cpp:105
&gt; +#elif PLATFORM(GTK)
&gt; +    encoder &lt;&lt; m_phase;
&gt; +    encoder &lt;&lt; m_momentumPhase;
&gt;  #endif</span >

Reorder things here too share the code with cocoa

<span class="quote">&gt; Source/WebKit2/Shared/WebWheelEvent.cpp:139
&gt; +#elif PLATFORM(GTK)
&gt; +    if (!decoder.decode(t.m_phase))
&gt; +        return false;
&gt; +    if (!decoder.decode(t.m_momentumPhase))
&gt; +        return false;</span >

Ditto.

<span class="quote">&gt; Source/WebKit2/Shared/gtk/WebEventFactory.cpp:165
&gt; +WebWheelEvent WebEventFactory::createWebWheelEvent(const GdkEvent* event, WebWheelEvent::Phase phase, WebWheelEvent::Phase momentumPhase)</span >

Here we could probably also keep a single method just with default values for the phases.

<span class="quote">&gt; Source/WebKit2/UIProcess/WebPageProxy.cpp:1819
&gt; -        if (m_wheelEventQueue.size() &lt; wheelEventQueueSizeThreshold)
&gt; +        if (m_wheelEventQueue.size() &lt; wheelEventQueueSizeThreshold &amp;&amp; canSkipWheelEvent(event))</span >

m_wheelEventQueue.size() &lt; wheelEventQueueSizeThreshold is also a condition to skip wheel events. So, I would replace all this with just if (!shouldProcessWheelEventNow(event)) and move the condition to the function. Note that we are not actually skipping events, just queuing them to process them later when we have a batch. So, the main question is why we are doing this, and why this doesn't work for us in this case. Because maybe this is just a matter of using 0 as threshold for the GTK+ port, and we always process wheel events immediately.

<span class="quote">&gt; Source/WebKit2/UIProcess/WebPageProxy.cpp:1865
&gt; +#if !PLATFORM(GTK)
&gt; +bool WebPageProxy::canSkipWheelEvent(const WebWheelEvent&amp;)
&gt; +{
&gt; +    return true;
&gt; +}
&gt; +#endif</span >

Since we are adding platform ifdefs in cross-platform code in any case here, I would keep the function common, checking the event queue size for all platforms, and then adding an #ifdef for GTK+, something like:

bool WebPageProxy::shouldProcessWheelEventNow(const WebWheelEvent&amp; event)
{
    if (m_wheelEventQueue.size() &gt;= wheelEventQueueSizeThreshold)
        return true;
#if PLATFORM(GTK)
return ....
#endif
}

Another way to avoid platform ifdefs here would be to add a method to WebWheelEvent, something like shouldBeProcessesImmediately or something like that, with a default implementation returning false, and a GTK+ implementation. I still don't understand the whole thing to propose any of the solution, though. In any case, we should explain this in the changelog and add a comment in the code as well.

<span class="quote">&gt; Source/WebKit2/UIProcess/gtk/GestureController.cpp:80
&gt; -void GestureController::DragGesture::handleDrag(const GdkEvent* event, double x, double y)
&gt; +static GUniquePtr&lt;GdkEvent&gt; newScrollEvent(const GdkEvent* event, double x, double y, double deltaX, double deltaY, gboolean isStop)</span >

use create instead of new</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>