SideBySide2: Fix scrolling alignment errors and reduce jank

CM3 does not compute the height of line widgets if the widget is
offscreen and has not been rendered yet.  This allows rendering large
documents faster, but means Y coordinates from one CM3 do not align
common lines of code in the other CM3 instance.

During scrolling determine the line visible at the top of the
viewport.  Rely on the LineMapper data to locate the common line
either at this position, or the first common line before it.

With the nearest prior common line in hand, compute the distance
between the viewport top and this common line, and add that to the
position of the common line on the other CM3.  This should pixel align
both CM3 instances even if other widgets are not properly measured.

Using this alignment method the view scrolls almost "butter smooth"
under Chrome on a modern MacBook Pro.  It is difficult to tell there
are two synchronized CM3 instances.

Keep the 20ms/40ms timer running during scrolling.  The timer adjusts
the other CM3 every 20ms to ensure it is aligned and cancels after
40ms of no scrolling activity.  Running the timer is a backup measure
to ensure the panes do not fall out of sync.  The 40ms cancel timer
must be kept to "disconnect" the current scrolling event and allow the
other CM3 to control a future scroll attempt.

Most jank and artifacting during throw scrolling is now gone.  This
commit was tested on an edit of a 12,000 line text file containing an
insertion at line 7, and another at 11,838, and 200 lines of context.

Change-Id: I4d2305abcd16040a67a4d3534981d75dd2c3a5d9
2 files changed