mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into 1937_uncached_char_top_fix
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@ services:
|
||||
volumes:
|
||||
- ./:/usr/src/app
|
||||
ports:
|
||||
- ${XTERMJS_PORT:3000}:3000
|
||||
- ${XTERMJS_PORT:-3000}:3000
|
||||
command: ["npm", "start"]
|
||||
|
||||
watch:
|
||||
|
||||
+6
-2
@@ -1284,7 +1284,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (this._terminal.element) {
|
||||
this._terminal.element.classList.add('enable-mouse-events');
|
||||
}
|
||||
this._terminal.selectionManager.disable();
|
||||
if (this._terminal.selectionManager) {
|
||||
this._terminal.selectionManager.disable();
|
||||
}
|
||||
this._terminal.log('Binding to mouse events.');
|
||||
break;
|
||||
case 1004: // send focusin/focusout events
|
||||
@@ -1474,7 +1476,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (this._terminal.element) {
|
||||
this._terminal.element.classList.remove('enable-mouse-events');
|
||||
}
|
||||
this._terminal.selectionManager.enable();
|
||||
if (this._terminal.selectionManager) {
|
||||
this._terminal.selectionManager.enable();
|
||||
}
|
||||
break;
|
||||
case 1004: // send focusin/focusout events
|
||||
this._terminal.sendFocus = false;
|
||||
|
||||
+24
-11
@@ -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;
|
||||
@@ -738,6 +740,11 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
|
||||
this.mouseHelper = new MouseHelper(this.renderer);
|
||||
// apply mouse event classes set by escape codes before terminal was attached
|
||||
this.element.classList.toggle('enable-mouse-events', this.mouseEvents);
|
||||
if (this.mouseEvents) {
|
||||
this.selectionManager.disable();
|
||||
} else {
|
||||
this.selectionManager.enable();
|
||||
}
|
||||
|
||||
if (this.options.screenReaderMode) {
|
||||
// Note that this must be done *after* the renderer is created in order to
|
||||
@@ -1343,19 +1350,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;
|
||||
}
|
||||
@@ -1373,12 +1381,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 = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ export class Renderer extends EventEmitter implements IRenderer {
|
||||
// Detect whether IntersectionObserver is detected and enable renderer pause
|
||||
// and resume based on terminal visibility if so
|
||||
if ('IntersectionObserver' in window) {
|
||||
const observer = new IntersectionObserver(e => this.onIntersectionChange(e[0]), { threshold: 0 });
|
||||
const observer = new IntersectionObserver(e => this.onIntersectionChange(e[e.length - 1]), { threshold: 0 });
|
||||
observer.observe(this._terminal.element);
|
||||
this.register({ dispose: () => observer.disconnect() });
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user