Don't defer updates with setImmediate in animation frames

I previously thought this was okay, but now I'm experiencing jitter when
scrolling with the trackpad when updates are deferred, and the frames
seem jagged. So this commit restores a synchronous approach to display
updates whenever we use animation frames.
This commit is contained in:
Nathan Sobo
2014-07-02 09:18:59 -06:00
parent e5ab2c6507
commit 9508909a9f
2 changed files with 21 additions and 16 deletions

View File

@@ -84,7 +84,6 @@ describe "EditorComponent", ->
verticalScrollbarNode.scrollTop = 4.5 * lineHeightInPixels
verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
runSetImmediateCallbacks()
expect(linesNode.style['-webkit-transform']).toBe "translate3d(0px, #{-4.5 * lineHeightInPixels}px, 0px)"
expect(node.querySelectorAll('.line').length).toBe 6 + 4 # margin above and below
@@ -329,7 +328,6 @@ describe "EditorComponent", ->
verticalScrollbarNode.scrollTop = 2.5 * lineHeightInPixels
verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
runSetImmediateCallbacks()
expect(node.querySelectorAll('.line-number').length).toBe 6 + 4 + 1 # line overdraw margin above/below + dummy line number
@@ -520,7 +518,6 @@ describe "EditorComponent", ->
verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
horizontalScrollbarNode.scrollLeft = 3.5 * charWidth
horizontalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
runSetImmediateCallbacks()
cursorNodes = node.querySelectorAll('.cursor')
expect(cursorNodes.length).toBe 2
@@ -877,7 +874,6 @@ describe "EditorComponent", ->
verticalScrollbarNode.scrollTop = 3.5 * lineHeightInPixels
verticalScrollbarNode.dispatchEvent(new UIEvent('scroll'))
runSetImmediateCallbacks()
regions = node.querySelectorAll('.some-highlight .region')
@@ -1397,36 +1393,30 @@ describe "EditorComponent", ->
expect(horizontalScrollbarNode.scrollLeft).toBe 0
node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -5, wheelDeltaY: -10))
runSetImmediateCallbacks()
expect(verticalScrollbarNode.scrollTop).toBe 10
expect(horizontalScrollbarNode.scrollLeft).toBe 0
node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -15, wheelDeltaY: -5))
runSetImmediateCallbacks()
expect(verticalScrollbarNode.scrollTop).toBe 10
expect(horizontalScrollbarNode.scrollLeft).toBe 15
it "updates the scrollLeft or scrollTop according to the scroll sensitivity", ->
atom.config.set('editor.scrollSensitivity', 50)
node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -5, wheelDeltaY: -10))
runSetImmediateCallbacks()
expect(horizontalScrollbarNode.scrollLeft).toBe 0
node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -15, wheelDeltaY: -5))
runSetImmediateCallbacks()
expect(verticalScrollbarNode.scrollTop).toBe 5
expect(horizontalScrollbarNode.scrollLeft).toBe 7
it "uses the previous scrollSensitivity when the value is not an int", ->
atom.config.set('editor.scrollSensitivity', 'nope')
node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -10))
runSetImmediateCallbacks()
expect(verticalScrollbarNode.scrollTop).toBe 10
it "parses negative scrollSensitivity values as positive", ->
atom.config.set('editor.scrollSensitivity', -50)
node.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -10))
runSetImmediateCallbacks()
expect(verticalScrollbarNode.scrollTop).toBe 5
describe "when the mousewheel event's target is a line", ->

View File

@@ -26,6 +26,8 @@ EditorComponent = React.createClass
pendingScrollLeft: null
selectOnMouseMove: false
updateRequested: false
updatesPaused: false
updateRequestedWhilePaused: false
cursorsMoved: false
selectionChanged: false
selectionAdded: false
@@ -203,6 +205,10 @@ EditorComponent = React.createClass
@remeasureCharacterWidthsIfNeeded(prevState)
requestUpdate: ->
if @updatesPaused
@updateRequestedWhilePaused = true
return
if @performSyncUpdates ? EditorComponent.performSyncUpdates
@forceUpdate()
else unless @updateRequested
@@ -211,6 +217,15 @@ EditorComponent = React.createClass
@updateRequested = false
@forceUpdate() if @isMounted()
requestAnimationFrame: (fn) ->
@updatesPaused = true
requestAnimationFrame =>
fn()
@updatesPaused = false
if @updateRequestedWhilePaused and @isMounted()
@updateRequestedWhilePaused = false
@forceUpdate()
getRenderedRowRange: ->
{editor, lineOverdrawMargin} = @props
[visibleStartRow, visibleEndRow] = editor.getVisibleRowRange()
@@ -519,7 +534,7 @@ EditorComponent = React.createClass
@pendingScrollTop = scrollTop
unless animationFramePending
@pauseScrollViewMeasurement()
requestAnimationFrame =>
@requestAnimationFrame =>
pendingScrollTop = @pendingScrollTop
@pendingScrollTop = null
@props.editor.setScrollTop(pendingScrollTop)
@@ -533,7 +548,7 @@ EditorComponent = React.createClass
@pendingScrollLeft = scrollLeft
unless animationFramePending
@pauseScrollViewMeasurement()
requestAnimationFrame =>
@requestAnimationFrame =>
@props.editor.setScrollLeft(@pendingScrollLeft)
@pendingScrollLeft = null
@@ -555,7 +570,7 @@ EditorComponent = React.createClass
unless animationFramePending
@pauseScrollViewMeasurement()
requestAnimationFrame =>
@requestAnimationFrame =>
{editor} = @props
editor.setScrollTop(editor.getScrollTop() + @pendingVerticalScrollDelta)
editor.setScrollLeft(editor.getScrollLeft() + @pendingHorizontalScrollDelta)
@@ -656,7 +671,7 @@ EditorComponent = React.createClass
onScrollTopChanged: ->
@scrollingVertically = true
@requestUpdate()
@onStoppedScrollingAfterDelay ?= debounce(@onStoppedScrolling, 100)
@onStoppedScrollingAfterDelay ?= debounce(@onStoppedScrolling, 200)
@onStoppedScrollingAfterDelay()
onStoppedScrolling: ->
@@ -684,7 +699,7 @@ EditorComponent = React.createClass
lastMousePosition = {}
animationLoop = =>
@pauseScrollViewMeasurement()
requestAnimationFrame =>
@requestAnimationFrame =>
if dragging
screenPosition = @screenPositionForMouseEvent(lastMousePosition)
dragHandler(screenPosition)
@@ -725,7 +740,7 @@ EditorComponent = React.createClass
return if @scrollViewMeasurementRequested
@scrollViewMeasurementRequested = true
requestAnimationFrame =>
@requestAnimationFrame =>
@scrollViewMeasurementRequested = false
@measureScrollView()