Merge branch 'master' into master

This commit is contained in:
jerch
2019-03-07 23:28:26 +01:00
committed by GitHub
6 changed files with 45 additions and 15 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ services:
volumes:
- ./:/usr/src/app
ports:
- ${XTERMJS_PORT:3000}:3000
- ${XTERMJS_PORT:-3000}:3000
command: ["npm", "start"]
watch:
+5 -1
View File
@@ -211,7 +211,7 @@ export class Buffer implements IBuffer {
this.scrollBottom = newRows - 1;
if (this._hasScrollback) {
if (this._isReflowEnabled) {
this._reflow(newCols, newRows);
// Trim the end of the line off if cols shrunk
@@ -226,6 +226,10 @@ export class Buffer implements IBuffer {
this._rows = newRows;
}
private get _isReflowEnabled(): boolean {
return this._hasScrollback && !(this._terminal as any).isWinptyCompatEnabled;
}
private _reflow(newCols: number, newRows: number): void {
if (this._cols === newCols) {
return;
+19 -11
View File
@@ -64,10 +64,12 @@ const document = (typeof window !== 'undefined') ? window.document : null;
const WRITE_BUFFER_PAUSE_THRESHOLD = 5;
/**
* The number of writes to perform in a single batch before allowing the
* renderer to catch up with a 0ms setTimeout.
* The max number of ms to spend on writes before allowing the renderer to
* catch up with a 0ms setTimeout. A value of < 33 to keep us close to
* 30fps, and a value of < 16 to try to run at 60fps. Of course, the real FPS
* depends on the time it takes for the renderer to draw the frame.
*/
const WRITE_BATCH_SIZE = 300;
const WRITE_TIMEOUT_MS = 12;
const MINIMUM_COLS = 2; // Less than 2 can mess with wide chars
const MINIMUM_ROWS = 1;
@@ -1342,19 +1344,20 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
}
}
protected _innerWrite(): void {
protected _innerWrite(bufferOffset: number = 0): void {
// Ensure the terminal isn't disposed
if (this._isDisposed) {
this.writeBuffer = [];
}
const writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);
while (writeBatch.length > 0) {
const data = writeBatch.shift();
const startTime = Date.now();
while (this.writeBuffer.length > bufferOffset) {
const data = this.writeBuffer[bufferOffset];
bufferOffset++;
// If XOFF was sent in order to catch up with the pty process, resume it if
// the writeBuffer is empty to allow more data to come in.
if (this._xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {
// we reached the end of the writeBuffer to allow more data to come in.
if (this._xoffSentToCatchUp && this.writeBuffer.length === bufferOffset) {
this.handler(C0.DC1);
this._xoffSentToCatchUp = false;
}
@@ -1372,12 +1375,17 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
this.updateRange(this.buffer.y);
this.refresh(this._refreshStart, this._refreshEnd);
if (Date.now() - startTime >= WRITE_TIMEOUT_MS) {
break;
}
}
if (this.writeBuffer.length > 0) {
if (this.writeBuffer.length > bufferOffset) {
// Allow renderer to catch up before processing the next batch
setTimeout(() => this._innerWrite(), 0);
setTimeout(() => this._innerWrite(bufferOffset), 0);
} else {
this._writeInProgress = false;
this.writeBuffer = [];
}
}
+2
View File
@@ -19,6 +19,8 @@ export function winptyCompatInit(terminal: Terminal): void {
return;
}
(addonTerminal._core as any).isWinptyCompatEnabled = true;
// Winpty does not support wraparound mode which means that lines will never
// be marked as wrapped. This causes issues for things like copying a line
// retaining the wrapped new line characters or if consumers are listening
+2 -2
View File
@@ -241,7 +241,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
this._ctx.fillText(
charData[CHAR_DATA_CHAR_INDEX],
x * this._scaledCellWidth + this._scaledCharLeft,
(y + 0.5) * this._scaledCellHeight + this._scaledCharTop);
y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight / 2);
}
/**
@@ -316,7 +316,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
this._ctx.fillText(
chars,
x * this._scaledCellWidth + this._scaledCharLeft,
(y + 0.5) * this._scaledCellHeight + this._scaledCharTop);
y * this._scaledCellHeight + this._scaledCharTop + this._scaledCharHeight / 2);
this._ctx.restore();
}
+16
View File
@@ -23,6 +23,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
private _areZonesActive: boolean = false;
private _mouseMoveListener: (e: MouseEvent) => any;
private _mouseLeaveListener: (e: MouseEvent) => any;
private _clickListener: (e: MouseEvent) => any;
private _tooltipTimeout: number = null;
@@ -38,6 +39,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
// These events are expensive, only listen to it when mouse zones are active
this._mouseMoveListener = e => this._onMouseMove(e);
this._mouseLeaveListener = e => this._onMouseLeave(e);
this._clickListener = e => this._onClick(e);
}
@@ -89,6 +91,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
if (!this._areZonesActive) {
this._areZonesActive = true;
this._terminal.element.addEventListener('mousemove', this._mouseMoveListener);
this._terminal.element.addEventListener('mouseleave', this._mouseLeaveListener);
this._terminal.element.addEventListener('click', this._clickListener);
}
}
@@ -97,6 +100,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
if (this._areZonesActive) {
this._areZonesActive = false;
this._terminal.element.removeEventListener('mousemove', this._mouseMoveListener);
this._terminal.element.removeEventListener('mouseleave', this._mouseLeaveListener);
this._terminal.element.removeEventListener('click', this._clickListener);
}
}
@@ -169,6 +173,18 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
}
}
private _onMouseLeave(e: MouseEvent): void {
// Fire the hover end callback and cancel any existing timer if the mouse
// leaves the terminal element
if (this._currentZone) {
this._currentZone.leaveCallback();
this._currentZone = null;
if (this._tooltipTimeout) {
clearTimeout(this._tooltipTimeout);
}
}
}
private _onClick(e: MouseEvent): void {
// Find the active zone and click it if found
const zone = this._findZoneEventAt(e);