diff --git a/src/vs/editor/browser/controller/keyboardHandler.ts b/src/vs/editor/browser/controller/keyboardHandler.ts index b39aa5c1ddb..cf522ce6c91 100644 --- a/src/vs/editor/browser/controller/keyboardHandler.ts +++ b/src/vs/editor/browser/controller/keyboardHandler.ts @@ -312,8 +312,9 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable { return false; } + private _lastCursorSelectionChanged:editorCommon.IViewCursorSelectionChangedEvent = null; public onCursorSelectionChanged(e:editorCommon.IViewCursorSelectionChangedEvent): boolean { - this.textAreaHandler.setCursorSelections(e.selection, e.secondarySelections); + this._lastCursorSelectionChanged = e; return false; } @@ -328,4 +329,12 @@ export class KeyboardHandler extends ViewEventHandler implements IDisposable { return false; } + public writeToTextArea(): void { + if (this._lastCursorSelectionChanged) { + let e = this._lastCursorSelectionChanged; + this._lastCursorSelectionChanged = null; + this.textAreaHandler.setCursorSelections(e.selection, e.secondarySelections); + } + } + } \ No newline at end of file diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 64598734c1c..b2429b76b49 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -889,6 +889,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp if (!this.viewLines.shouldRender() && viewPartsToRender.length === 0) { // Nothing to render + this.keyboardHandler.writeToTextArea(); t.stop(); return; } @@ -896,11 +897,15 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp let linesViewportData = this.layoutProvider.getLinesViewportData(); if (this.viewLines.shouldRender()) { - this.viewLines.renderText(linesViewportData); + this.viewLines.renderText(linesViewportData, () => { + this.keyboardHandler.writeToTextArea(); + }); this.viewLines.onDidRender(); // Rendering of viewLines might cause scroll events to occur, so collect view parts to render again viewPartsToRender = this._getViewPartsToRender(); + } else { + this.keyboardHandler.writeToTextArea(); } let renderingContext = this.createRenderingContext(linesViewportData); diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index 6b1476c040e..11573fa2c96 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -375,7 +375,7 @@ export class ViewLines extends ViewLayer { throw new Error('Not supported'); } - public renderText(linesViewportData:editorCommon.ViewLinesViewportData): void { + public renderText(linesViewportData:editorCommon.ViewLinesViewportData, onAfterLinesRendered:()=>void): void { if (!this.shouldRender()) { throw new Error('I did not ask to render!'); } @@ -387,7 +387,10 @@ export class ViewLines extends ViewLayer { this.domNode.setWidth(this._layoutProvider.getScrollWidth()); this.domNode.setHeight(Math.min(this._layoutProvider.getTotalHeight(), 1000000)); - // (2) compute horizontal scroll position: + // (2) execute DOM writing that forces sync layout (e.g. textArea manipulation) + onAfterLinesRendered(); + + // (3) compute horizontal scroll position: // - this must happen after the lines are in the DOM since it might need a line that rendered just now // - it might change `scrollWidth` and `scrollLeft` if (this._lastCursorRevealRangeHorizontallyEvent) { @@ -410,6 +413,7 @@ export class ViewLines extends ViewLayer { this._layoutProvider.setScrollLeft(newScrollLeft.scrollLeft); } + // (4) handle scrolling let somethingChanged = false; if (browser.canUseTranslate3d) { var transform = 'translate3d(' + -this._layoutProvider.getScrollLeft() + 'px, ' + linesViewportData.visibleRangesDeltaTop + 'px, 0px)'; @@ -418,6 +422,8 @@ export class ViewLines extends ViewLayer { somethingChanged = StyleMutator.setTop(this.domNode.domNode.parentNode, linesViewportData.visibleRangesDeltaTop) || somethingChanged; // TODO@Alex somethingChanged = StyleMutator.setLeft(this.domNode.domNode.parentNode, -this._layoutProvider.getScrollLeft()) || somethingChanged; // TODO@Alex } + + // (5) reset cached client rect left if scrolling changed something if (somethingChanged) { this._lastRenderedData.resetDomNodeClientRectLeft(); }