Move a bunch of scroll logic into CoreTerminal

This change will now reset userScrolling on RIS
This commit is contained in:
Daniel Imms
2020-04-26 09:54:44 -07:00
parent 46e7fc61cc
commit 21bcef5008
5 changed files with 80 additions and 75 deletions
+5 -73
View File
@@ -85,9 +85,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
private _selectionService: ISelectionService;
private _soundService: ISoundService;
// Store if user went browsing history in scrollback
private _userScrolling: boolean;
/**
* Records whether the keydown event has already been handled and triggered a data event, if so
* the keypress event should not trigger a data event but should still print to the textarea so
@@ -113,8 +110,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._onKey.event; }
private _onRender = new EventEmitter<{ start: number, end: number }>();
public get onRender(): IEvent<{ start: number, end: number }> { return this._onRender.event; }
private _onScroll = new EventEmitter<number>();
public get onScroll(): IEvent<number> { return this._onScroll.event; }
private _onSelectionChange = new EventEmitter<void>();
public get onSelectionChange(): IEvent<void> { return this._onSelectionChange.event; }
private _onTitleChange = new EventEmitter<string>();
@@ -178,7 +173,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
this._customKeyEventHandler = null;
this._userScrolling = false;
if (!this.linkifier) {
this.linkifier = this._instantiationService.createInstance(Linkifier);
}
@@ -862,13 +856,13 @@ export class Terminal extends CoreTerminal implements ITerminal {
if (!willBufferBeTrimmed) {
this.buffer.ybase++;
// Only scroll the ydisp with ybase if the user has not scrolled up
if (!this._userScrolling) {
if (!this._bufferService.isUserScrolling) {
this.buffer.ydisp++;
}
} else {
// When the buffer is full and the user has scrolled up, keep the text
// stable unless ydisp is right at the top
if (this._userScrolling) {
if (this._bufferService.isUserScrolling) {
this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0);
}
}
@@ -882,7 +876,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
// Move the viewport to the bottom of the buffer unless the user is
// scrolling.
if (!this._userScrolling) {
if (!this._bufferService.isUserScrolling) {
this.buffer.ydisp = this.buffer.ybase;
}
@@ -892,67 +886,11 @@ export class Terminal extends CoreTerminal implements ITerminal {
this._onScroll.fire(this.buffer.ydisp);
}
/**
* Scroll the display of the terminal
* @param disp The number of lines to scroll down (negative scroll up).
* @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used
* to avoid unwanted events being handled by the viewport when the event was triggered from the
* viewport originally.
*/
public scrollLines(disp: number, suppressScrollEvent?: boolean): void {
if (disp < 0) {
if (this.buffer.ydisp === 0) {
return;
}
this._userScrolling = true;
} else if (disp + this.buffer.ydisp >= this.buffer.ybase) {
this._userScrolling = false;
}
const oldYdisp = this.buffer.ydisp;
this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0);
// No change occurred, don't trigger scroll/refresh
if (oldYdisp === this.buffer.ydisp) {
return;
}
if (!suppressScrollEvent) {
this._onScroll.fire(this.buffer.ydisp);
}
super.scrollLines(disp, suppressScrollEvent);
this.refresh(0, this.rows - 1);
}
/**
* Scroll the display of the terminal by a number of pages.
* @param pageCount The number of pages to scroll (negative scrolls up).
*/
public scrollPages(pageCount: number): void {
this.scrollLines(pageCount * (this.rows - 1));
}
/**
* Scrolls the display of the terminal to the top.
*/
public scrollToTop(): void {
this.scrollLines(-this.buffer.ydisp);
}
/**
* Scrolls the display of the terminal to the bottom.
*/
public scrollToBottom(): void {
this.scrollLines(this.buffer.ybase - this.buffer.ydisp);
}
public scrollToLine(line: number): void {
const scrollAmount = line - this.buffer.ydisp;
if (scrollAmount !== 0) {
this.scrollLines(scrollAmount);
}
}
public paste(data: string): void {
paste(data, this.textarea, this._coreService);
}
@@ -1299,19 +1237,13 @@ export class Terminal extends CoreTerminal implements ITerminal {
this.options.rows = this.rows;
this.options.cols = this.cols;
const customKeyEventHandler = this._customKeyEventHandler;
const userScrolling = this._userScrolling;
this._setup();
this._inputHandler.reset();
this._bufferService.reset();
this._charsetService.reset();
this._coreService.reset();
this._coreMouseService.reset();
super.reset();
this._selectionService?.reset();
// reattach
this._customKeyEventHandler = customKeyEventHandler;
this._userScrolling = userScrolling;
// do a full screen refresh
this.refresh(0, this.rows - 1);
+70 -2
View File
@@ -64,6 +64,8 @@ export abstract class CoreTerminal extends Disposable {
public get onLineFeed(): IEvent<void> { return this._onLineFeed.event; }
private _onResize = new EventEmitter<{ cols: number, rows: number }>();
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._onResize.event; }
protected _onScroll = new EventEmitter<number>();
public get onScroll(): IEvent<number> { return this._onScroll.event; }
public get cols(): number { return this._bufferService.cols; }
public get rows(): number { return this._bufferService.rows; }
@@ -136,6 +138,66 @@ export abstract class CoreTerminal extends Disposable {
this._bufferService.resize(x, y);
}
/**
* Scroll the display of the terminal
* @param disp The number of lines to scroll down (negative scroll up).
* @param suppressScrollEvent Don't emit the scroll event as scrollLines. This is used
* to avoid unwanted events being handled by the viewport when the event was triggered from the
* viewport originally.
*/
public scrollLines(disp: number, suppressScrollEvent?: boolean): void {
const buffer = this._bufferService.buffer;
if (disp < 0) {
if (buffer.ydisp === 0) {
return;
}
this._bufferService.isUserScrolling = true;
} else if (disp + buffer.ydisp >= buffer.ybase) {
this._bufferService.isUserScrolling = false;
}
const oldYdisp = buffer.ydisp;
buffer.ydisp = Math.max(Math.min(buffer.ydisp + disp, buffer.ybase), 0);
// No change occurred, don't trigger scroll/refresh
if (oldYdisp === buffer.ydisp) {
return;
}
if (!suppressScrollEvent) {
this._onScroll.fire(buffer.ydisp);
}
}
/**
* Scroll the display of the terminal by a number of pages.
* @param pageCount The number of pages to scroll (negative scrolls up).
*/
public scrollPages(pageCount: number): void {
this.scrollLines(pageCount * (this.rows - 1));
}
/**
* Scrolls the display of the terminal to the top.
*/
public scrollToTop(): void {
this.scrollLines(-this._bufferService.buffer.ydisp);
}
/**
* Scrolls the display of the terminal to the bottom.
*/
public scrollToBottom(): void {
this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);
}
public scrollToLine(line: number): void {
const scrollAmount = line - this._bufferService.buffer.ydisp;
if (scrollAmount !== 0) {
this.scrollLines(scrollAmount);
}
}
/** Add handler for ESC escape sequence. See xterm.d.ts for details. */
public addEscHandler(id: IFunctionIdentifier, callback: () => boolean): IDisposable {
return this._inputHandler.addEscHandler(id, callback);
@@ -162,6 +224,14 @@ export abstract class CoreTerminal extends Disposable {
}
}
public reset(): void {
this._inputHandler.reset();
this._bufferService.reset();
this._charsetService.reset();
this._coreService.reset();
this._coreMouseService.reset();
}
protected _updateOptions(key: string): void {
// TODO: These listeners should be owned by individual components
switch (key) {
@@ -194,6 +264,4 @@ export abstract class CoreTerminal extends Disposable {
};
}
}
public abstract scrollToBottom(): void;
}
+1
View File
@@ -17,6 +17,7 @@ export class MockBufferService implements IBufferService {
public get buffer(): IBuffer { return this.buffers.active; }
public buffers: IBufferSet = {} as any;
public onResize: IEvent<{ cols: number, rows: number }> = new EventEmitter<{ cols: number, rows: number }>().event;
public isUserScrolling: boolean = false;
constructor(
public cols: number,
public rows: number,
+3
View File
@@ -17,6 +17,8 @@ export class BufferService implements IBufferService {
public cols: number;
public rows: number;
public buffers: IBufferSet;
/** Whether the user is scrolling (locks the scroll position) */
public isUserScrolling: boolean = false;
private _onResize = new EventEmitter<{ cols: number, rows: number }>();
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._onResize.event; }
@@ -41,5 +43,6 @@ export class BufferService implements IBufferService {
public reset(): void {
this.buffers = new BufferSet(this._optionsService, this);
this.isUserScrolling = false;
}
}
+1
View File
@@ -16,6 +16,7 @@ export interface IBufferService {
readonly rows: number;
readonly buffer: IBuffer;
readonly buffers: IBufferSet;
isUserScrolling: boolean;
onResize: IEvent<{ cols: number, rows: number }>;