Skip to content

Commit ad0f931

Browse files
author
Philip Withnall
committed
kinetic-scroll-view: Grow the motion buffer over time
The motion buffer contains a history of motion events for the current scrolling action, starting from the initial touch event. This is used at the release of the scroll to work out an average origin coordinate, which is then used in the calculation of whether to use kinetic scrolling. Previously, the oldest entry in the motion buffer was removed if the buffer filled up, then the buffer was expanded in size. This meant that for scrolling actions with many motion events, the average taken over the events would quickly creep towards the location of the most recent motion event. This meant that, often, the threshold for starting a kinetic scroll was not reached, and hence kinetic scrolling would not happen. Stop removing the oldest entry from the buffer, and instead grow it indefinitely. This does make the widget prone to consuming all the system’s memory if the user scrolls around for a _very_ long time. This may be better fixed by calculating a moving average instead, and eliminating the motion buffer. clutter-project#98
1 parent 07d5575 commit ad0f931

1 file changed

Lines changed: 13 additions & 5 deletions

File tree

mx/mx-kinetic-scroll-view.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,7 @@ motion_event_cb (ClutterActor *actor,
832832

833833
g_object_get (G_OBJECT (settings),
834834
"drag-threshold", &threshold, NULL);
835+
g_assert (priv->motion_buffer->len > 0);
835836
motion = &g_array_index (priv->motion_buffer,
836837
MxKineticScrollViewMotion, 0);
837838

@@ -915,6 +916,7 @@ motion_event_cb (ClutterActor *actor,
915916
return FALSE;
916917
}
917918

919+
g_assert (priv->motion_buffer->len > 0);
918920
LOG_DEBUG (scroll, "motion dx=%f dy=%f",
919921
ABS (g_array_index (priv->motion_buffer, MxKineticScrollViewMotion, priv->motion_buffer->len - 1).x - x),
920922
ABS (g_array_index (priv->motion_buffer, MxKineticScrollViewMotion, priv->motion_buffer->len - 1).y - y));
@@ -927,6 +929,7 @@ motion_event_cb (ClutterActor *actor,
927929
mx_scrollable_get_adjustments (MX_SCROLLABLE (priv->child),
928930
&hadjust, &vadjust);
929931

932+
g_assert (priv->last_motion < priv->motion_buffer->len);
930933
motion = &g_array_index (priv->motion_buffer,
931934
MxKineticScrollViewMotion,
932935
priv->last_motion);
@@ -974,10 +977,8 @@ motion_event_cb (ClutterActor *actor,
974977
priv->last_motion ++;
975978
if (priv->last_motion == priv->motion_buffer->len)
976979
{
977-
LOG_DEBUG (scroll, "reset");
978-
priv->motion_buffer = g_array_remove_index (priv->motion_buffer, 0);
979-
g_array_set_size (priv->motion_buffer, priv->last_motion);
980-
priv->last_motion --;
980+
LOG_DEBUG (scroll, "increase buffer size to %u", priv->last_motion);
981+
g_array_set_size (priv->motion_buffer, priv->last_motion + 1);
981982
}
982983

983984
motion = &g_array_index (priv->motion_buffer,
@@ -1301,6 +1302,13 @@ release_event (MxKineticScrollView *scroll,
13011302

13021303
/* Get average position/time of last x mouse events */
13031304
priv->last_motion ++;
1305+
if (priv->last_motion == priv->motion_buffer->len)
1306+
{
1307+
LOG_DEBUG (scroll, "increase buffer size to %u",
1308+
priv->last_motion);
1309+
g_array_set_size (priv->motion_buffer, priv->last_motion + 1);
1310+
}
1311+
13041312
x_origin = y_origin = 0;
13051313
motion_time = (GTimeVal){ 0, 0 };
13061314
for (i = 0; i < priv->last_motion; i++)
@@ -1736,7 +1744,7 @@ mx_kinetic_scroll_view_init (MxKineticScrollView *self)
17361744
KINETIC_SCROLL_VIEW_PRIVATE (self);
17371745

17381746
priv->motion_buffer =
1739-
g_array_sized_new (FALSE, TRUE, sizeof (MxKineticScrollViewMotion), 3);
1747+
g_array_sized_new (FALSE, TRUE, sizeof (MxKineticScrollViewMotion), 30);
17401748
g_array_set_size (priv->motion_buffer, 3);
17411749
priv->decel_rate = 1.1f;
17421750
priv->button = 1;

0 commit comments

Comments
 (0)