Merge pull request #5980 from xtermjs/cursor/browser-functional-fixes-b5c0

fix(browser): debounce, render, mouse coords, and CoreBrowserTerminal
This commit is contained in:
Daniel Imms
2026-06-01 09:23:57 -07:00
committed by GitHub
6 changed files with 15 additions and 14 deletions
+1 -1
View File
@@ -505,7 +505,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
this.textarea,
parent.ownerDocument.defaultView ?? window,
// Force unsafe null in node.js environment for tests
this._document ?? (typeof window !== 'undefined') ? window.document : null as any
this._document ?? ((typeof window !== 'undefined') ? window.document : null as any)
));
this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);
+3 -5
View File
@@ -23,7 +23,7 @@ export class RenderDebouncer implements IRenderDebouncerWithCallback {
}
public dispose(): void {
if (this._animationFrame) {
if (this._animationFrame !== undefined) {
this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame);
this._animationFrame = undefined;
}
@@ -31,9 +31,7 @@ export class RenderDebouncer implements IRenderDebouncerWithCallback {
public addRefreshCallback(callback: FrameRequestCallback): number {
this._refreshCallbacks.push(callback);
if (!this._animationFrame) {
this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());
}
this._animationFrame ??= this._coreBrowserService.window.requestAnimationFrame(() => this._innerRefresh());
return this._animationFrame;
}
@@ -46,7 +44,7 @@ export class RenderDebouncer implements IRenderDebouncerWithCallback {
this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;
this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;
if (this._animationFrame) {
if (this._animationFrame !== undefined) {
return;
}
+9 -2
View File
@@ -3,10 +3,10 @@
* @license MIT
*/
const RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second
import { IRenderDebouncer } from './Types';
const RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second
/**
* Debounces calls to update screen readers to update at most once configurable interval of time.
*/
@@ -31,7 +31,9 @@ export class TimeBasedDebouncer implements IRenderDebouncer {
public dispose(): void {
if (this._refreshTimeoutID) {
clearTimeout(this._refreshTimeoutID);
this._refreshTimeoutID = undefined;
}
this._additionalRefreshRequested = false;
}
public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {
@@ -48,6 +50,11 @@ export class TimeBasedDebouncer implements IRenderDebouncer {
const refreshRequestTime: number = performance.now();
if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {
// Enough time has elapsed since the last refresh; refresh immediately
if (this._refreshTimeoutID !== undefined) {
clearTimeout(this._refreshTimeoutID);
this._refreshTimeoutID = undefined;
this._additionalRefreshRequested = false;
}
this._lastRefreshMs = refreshRequestTime;
this._innerRefresh();
} else if (!this._additionalRefreshRequested) {
-4
View File
@@ -37,10 +37,6 @@ export function getCoords(window: Pick<Window, 'getComputedStyle'>, event: Pick<
}
const coords = getCoordsRelativeToElement(window, event, element);
if (!coords) {
return undefined;
}
coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);
coords[1] = Math.ceil(coords[1] / cssCellHeight);
+1 -1
View File
@@ -156,7 +156,7 @@ function wrappedRowsForRow(currentRow: number, bufferService: IBufferService): n
*/
function horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {
let startRow;
if (moveToRequestedRow(targetX, targetY, bufferService, applicationCursor).length > 0) {
if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {
startRow = targetY - wrappedRowsForRow(targetY, bufferService);
} else {
startRow = startY;
+1 -1
View File
@@ -694,7 +694,7 @@ class CursorBlinkStateManager {
}
private _clearIdleTimer(): void {
if (this._idleTimeout) {
if (this._idleTimeout !== undefined) {
this._coreBrowserService.window.clearTimeout(this._idleTimeout);
this._idleTimeout = undefined;
}