mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Move a bunch of scroll logic into CoreTerminal
This change will now reset userScrolling on RIS
This commit is contained in:
+5
-73
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface IBufferService {
|
||||
readonly rows: number;
|
||||
readonly buffer: IBuffer;
|
||||
readonly buffers: IBufferSet;
|
||||
isUserScrolling: boolean;
|
||||
|
||||
onResize: IEvent<{ cols: number, rows: number }>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user