From f8c1f5a32f552338267da6b693fc24a256e3ffa2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:30:58 -0800 Subject: [PATCH 1/7] Add idle timeout which pauses cursor blink Fixes #4628 --- .../src/CursorBlinkStateManager.ts | 61 +++++++++++++++++++ addons/addon-webgl/src/WebglRenderer.ts | 2 + src/browser/renderer/dom/DomRenderer.ts | 54 +++++++++++++++- 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/addons/addon-webgl/src/CursorBlinkStateManager.ts b/addons/addon-webgl/src/CursorBlinkStateManager.ts index c5bb0870..36f2a909 100644 --- a/addons/addon-webgl/src/CursorBlinkStateManager.ts +++ b/addons/addon-webgl/src/CursorBlinkStateManager.ts @@ -10,12 +10,19 @@ import { ICoreBrowserService } from 'browser/services/Services'; */ const BLINK_INTERVAL = 600; +/** + * The idle time after which cursor blinking stops (2 minutes). + */ +const IDLE_TIMEOUT = 5000; //2 * 60 * 1000; + export class CursorBlinkStateManager { public isCursorVisible: boolean; private _animationFrame: number | undefined; private _blinkStartTimeout: number | undefined; private _blinkInterval: number | undefined; + private _idleTimeout: number | undefined; + private _isIdlePaused: boolean = false; /** * The time at which the animation frame was restarted, this is used on the @@ -31,6 +38,7 @@ export class CursorBlinkStateManager { this.isCursorVisible = true; if (this._coreBrowserService.isFocused) { this._restartInterval(); + this._resetIdleTimer(); } } @@ -49,9 +57,16 @@ export class CursorBlinkStateManager { this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame); this._animationFrame = undefined; } + if (this._idleTimeout) { + this._coreBrowserService.window.clearTimeout(this._idleTimeout); + this._idleTimeout = undefined; + } } public restartBlinkAnimation(): void { + if (this._isIdlePaused) { + this._resetIdleTimer(); + } if (this.isPaused) { return; } @@ -121,6 +136,7 @@ export class CursorBlinkStateManager { public pause(): void { this.isCursorVisible = true; + this._isIdlePaused = false; if (this._blinkInterval) { this._coreBrowserService.window.clearInterval(this._blinkInterval); this._blinkInterval = undefined; @@ -133,6 +149,10 @@ export class CursorBlinkStateManager { this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame); this._animationFrame = undefined; } + if (this._idleTimeout) { + this._coreBrowserService.window.clearTimeout(this._idleTimeout); + this._idleTimeout = undefined; + } } public resume(): void { @@ -141,6 +161,47 @@ export class CursorBlinkStateManager { this._animationTimeRestarted = undefined; this._restartInterval(); + this._resetIdleTimer(); this.restartBlinkAnimation(); } + + /** + * Resets the idle timer. If the terminal is idle for IDLE_TIMEOUT, cursor + * blinking will stop. + */ + private _resetIdleTimer(): void { + this._isIdlePaused = false; + if (this._idleTimeout) { + this._coreBrowserService.window.clearTimeout(this._idleTimeout); + } + this._idleTimeout = this._coreBrowserService.window.setTimeout(() => { + this._stopBlinkingDueToIdle(); + }, IDLE_TIMEOUT); + } + + /** + * Stops cursor blinking due to idle timeout. + */ + private _stopBlinkingDueToIdle(): void { + // Make cursor visible and stop blinking + this.isCursorVisible = true; + this._isIdlePaused = true; + if (this._blinkInterval) { + this._coreBrowserService.window.clearInterval(this._blinkInterval); + this._blinkInterval = undefined; + } + if (this._blinkStartTimeout) { + this._coreBrowserService.window.clearTimeout(this._blinkStartTimeout); + this._blinkStartTimeout = undefined; + } + if (this._animationFrame) { + this._coreBrowserService.window.cancelAnimationFrame(this._animationFrame); + this._animationFrame = undefined; + } + // Clear the idle timeout as we've already acted on it + this._coreBrowserService.window.clearTimeout(this._idleTimeout); + this._idleTimeout = undefined; + // Trigger a render to show the cursor in its final visible state + this._renderCallback(); + } } diff --git a/addons/addon-webgl/src/WebglRenderer.ts b/addons/addon-webgl/src/WebglRenderer.ts index fb14b3c0..987d587c 100644 --- a/addons/addon-webgl/src/WebglRenderer.ts +++ b/addons/addon-webgl/src/WebglRenderer.ts @@ -136,6 +136,8 @@ export class WebglRenderer extends Disposable implements IRenderer { this._observerDisposable.value = observeDevicePixelDimensions(this._canvas, w, (w, h) => this._setCanvasDevicePixelDimensions(w, h)); })); + this._register(addDisposableListener(this._coreBrowserService.mainDocument, 'mousedown', () => this._cursorBlinkStateManager.value?.restartBlinkAnimation())); + this._core.screenElement!.appendChild(this._canvas); [this._rectangleRenderer.value, this._glyphRenderer.value] = this._initializeWebGLState(); diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 1c271797..454adb1f 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -15,6 +15,7 @@ import { color } from 'common/Color'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IBufferService, ICoreService, IInstantiationService, IOptionsService } from 'common/services/Services'; import { Emitter } from 'vs/base/common/event'; +import { addDisposableListener } from 'vs/base/browser/dom'; const TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-'; @@ -23,6 +24,12 @@ const FG_CLASS_PREFIX = 'xterm-fg-'; const BG_CLASS_PREFIX = 'xterm-bg-'; const FOCUS_CLASS = 'xterm-focus'; const SELECTION_CLASS = 'xterm-selection'; +const CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'; + +/** + * The idle time after which cursor blinking stops (2 minutes). + */ +const IDLE_TIMEOUT = 5000; // 2 * 60 * 1000; let nextTerminalId = 1; @@ -42,6 +49,7 @@ export class DomRenderer extends Disposable implements IRenderer { private _selectionContainer: HTMLElement; private _widthCache: WidthCache; private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel(); + private _idleTimeout: number | undefined; public dimensions: IRenderDimensions; @@ -89,6 +97,8 @@ export class DomRenderer extends Disposable implements IRenderer { this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e))); this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e))); + this._register(addDisposableListener(this._document, 'mousedown', () => this._resetIdleTimer())); + this._register(toDisposable(() => { this._element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass); @@ -99,6 +109,7 @@ export class DomRenderer extends Disposable implements IRenderer { this._widthCache.dispose(); this._themeStyleElement.remove(); this._dimensionsStyleElement.remove(); + this._clearIdleTimer(); })); this._widthCache = new WidthCache(this._document, this._helperContainer); @@ -225,6 +236,10 @@ export class DomRenderer extends Disposable implements IRenderer { `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` + ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` + `}` + + // Disable cursor blinking when idle + `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` + + ` animation: none !important;` + + `}` + // !important helps fix an issue where the cursor will not render on top of the selection, // however it's very hard to fix this issue and retain the blink animation without the use of // !important. So this edge case fails when cursor blink is on. @@ -328,11 +343,14 @@ export class DomRenderer extends Disposable implements IRenderer { public handleBlur(): void { this._rowContainer.classList.remove(FOCUS_CLASS); + this._clearIdleTimer(); this.renderRows(0, this._bufferService.rows - 1); } public handleFocus(): void { this._rowContainer.classList.add(FOCUS_CLASS); + this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS); + this._resetIdleTimer(); this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y); } @@ -406,7 +424,8 @@ export class DomRenderer extends Disposable implements IRenderer { } public handleCursorMove(): void { - // No-op, the cursor is drawn when rows are drawn + // Reset idle timer on cursor movement (which happens on input) + this._resetIdleTimer(); } private _handleOptionsChanged(): void { @@ -539,4 +558,37 @@ export class DomRenderer extends Disposable implements IRenderer { ); } } + + /** + * Resets the idle timer. If the terminal is idle for IDLE_TIMEOUT, cursor + * blinking will stop. + */ + private _resetIdleTimer(): void { + if (!this._coreBrowserService.isFocused) { + return; + } + this._clearIdleTimer(); + this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS); + this._idleTimeout = this._coreBrowserService.window.setTimeout(() => { + this._stopBlinkingDueToIdle(); + }, IDLE_TIMEOUT); + } + + /** + * Clears the idle timer. + */ + private _clearIdleTimer(): void { + if (this._idleTimeout) { + this._coreBrowserService.window.clearTimeout(this._idleTimeout); + this._idleTimeout = undefined; + } + } + + /** + * Stops cursor blinking due to idle timeout. + */ + private _stopBlinkingDueToIdle(): void { + this._rowContainer.classList.add(CURSOR_BLINK_IDLE_CLASS); + this._idleTimeout = undefined; + } } From 7d1f74fb8bfbda54e77fc50e202e17b69a600d6b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:33:51 -0800 Subject: [PATCH 2/7] Use const enums for constants --- .../src/CursorBlinkStateManager.ts | 28 ++++++++++--------- src/browser/renderer/dom/DomRenderer.ts | 12 ++++---- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/addons/addon-webgl/src/CursorBlinkStateManager.ts b/addons/addon-webgl/src/CursorBlinkStateManager.ts index 36f2a909..1346cbc3 100644 --- a/addons/addon-webgl/src/CursorBlinkStateManager.ts +++ b/addons/addon-webgl/src/CursorBlinkStateManager.ts @@ -5,15 +5,17 @@ import { ICoreBrowserService } from 'browser/services/Services'; -/** - * The time between cursor blinks. - */ -const BLINK_INTERVAL = 600; +const enum Constants { + /** + * The time between cursor blinks. + */ + BLINK_INTERVAL = 600, -/** - * The idle time after which cursor blinking stops (2 minutes). - */ -const IDLE_TIMEOUT = 5000; //2 * 60 * 1000; + /** + * The idle time after which cursor blinking stops. + */ + IDLE_TIMEOUT = 5 * 60 * 1000 +} export class CursorBlinkStateManager { public isCursorVisible: boolean; @@ -82,7 +84,7 @@ export class CursorBlinkStateManager { } } - private _restartInterval(timeToStart: number = BLINK_INTERVAL): void { + private _restartInterval(timeToStart: number = Constants.BLINK_INTERVAL): void { // Clear any existing interval if (this._blinkInterval) { this._coreBrowserService.window.clearInterval(this._blinkInterval); @@ -97,7 +99,7 @@ export class CursorBlinkStateManager { // Check if another animation restart was requested while this was being // started if (this._animationTimeRestarted) { - const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted); + const time = Constants.BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted); this._animationTimeRestarted = undefined; if (time > 0) { this._restartInterval(time); @@ -118,7 +120,7 @@ export class CursorBlinkStateManager { if (this._animationTimeRestarted) { // calc time diff // Make restart interval do a setTimeout initially? - const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted); + const time = Constants.BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted); this._animationTimeRestarted = undefined; this._restartInterval(time); return; @@ -130,7 +132,7 @@ export class CursorBlinkStateManager { this._renderCallback(); this._animationFrame = undefined; }); - }, BLINK_INTERVAL); + }, Constants.BLINK_INTERVAL); }, timeToStart); } @@ -176,7 +178,7 @@ export class CursorBlinkStateManager { } this._idleTimeout = this._coreBrowserService.window.setTimeout(() => { this._stopBlinkingDueToIdle(); - }, IDLE_TIMEOUT); + }, Constants.IDLE_TIMEOUT); } /** diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 454adb1f..f5f50146 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -26,10 +26,12 @@ const FOCUS_CLASS = 'xterm-focus'; const SELECTION_CLASS = 'xterm-selection'; const CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'; -/** - * The idle time after which cursor blinking stops (2 minutes). - */ -const IDLE_TIMEOUT = 5000; // 2 * 60 * 1000; +const enum Constants { + /** + * The idle time after which cursor blinking stops. + */ + IDLE_TIMEOUT = 5 * 60 * 1000 +} let nextTerminalId = 1; @@ -571,7 +573,7 @@ export class DomRenderer extends Disposable implements IRenderer { this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS); this._idleTimeout = this._coreBrowserService.window.setTimeout(() => { this._stopBlinkingDueToIdle(); - }, IDLE_TIMEOUT); + }, Constants.IDLE_TIMEOUT); } /** From 2e1651baddc256c6eb1d80d04fddecf3bcd23a63 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:35:57 -0800 Subject: [PATCH 3/7] Pull dom renderer blink management into class --- src/browser/renderer/dom/DomRenderer.ts | 64 +++++++++++++++++-------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index f5f50146..58e2d873 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -51,7 +51,7 @@ export class DomRenderer extends Disposable implements IRenderer { private _selectionContainer: HTMLElement; private _widthCache: WidthCache; private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel(); - private _idleTimeout: number | undefined; + private _cursorBlinkStateManager: CursorBlinkStateManager; public dimensions: IRenderDimensions; @@ -99,7 +99,9 @@ export class DomRenderer extends Disposable implements IRenderer { this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e))); this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e))); - this._register(addDisposableListener(this._document, 'mousedown', () => this._resetIdleTimer())); + this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService); + this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation())); + this._register(toDisposable(() => this._cursorBlinkStateManager.dispose())); this._register(toDisposable(() => { this._element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass); @@ -111,7 +113,6 @@ export class DomRenderer extends Disposable implements IRenderer { this._widthCache.dispose(); this._themeStyleElement.remove(); this._dimensionsStyleElement.remove(); - this._clearIdleTimer(); })); this._widthCache = new WidthCache(this._document, this._helperContainer); @@ -345,14 +346,13 @@ export class DomRenderer extends Disposable implements IRenderer { public handleBlur(): void { this._rowContainer.classList.remove(FOCUS_CLASS); - this._clearIdleTimer(); + this._cursorBlinkStateManager.pause(); this.renderRows(0, this._bufferService.rows - 1); } public handleFocus(): void { this._rowContainer.classList.add(FOCUS_CLASS); - this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS); - this._resetIdleTimer(); + this._cursorBlinkStateManager.resume(); this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y); } @@ -427,7 +427,7 @@ export class DomRenderer extends Disposable implements IRenderer { public handleCursorMove(): void { // Reset idle timer on cursor movement (which happens on input) - this._resetIdleTimer(); + this._cursorBlinkStateManager.restartBlinkAnimation(); } private _handleOptionsChanged(): void { @@ -560,25 +560,51 @@ export class DomRenderer extends Disposable implements IRenderer { ); } } +} - /** - * Resets the idle timer. If the terminal is idle for IDLE_TIMEOUT, cursor - * blinking will stop. - */ - private _resetIdleTimer(): void { - if (!this._coreBrowserService.isFocused) { - return; +class CursorBlinkStateManager { + private _idleTimeout: number | undefined; + private _isIdlePaused: boolean = false; + + constructor( + private readonly _rowContainer: HTMLElement, + private readonly _coreBrowserService: ICoreBrowserService + ) { + if (this._coreBrowserService.isFocused) { + this._resetIdleTimer(); } + } + + public dispose(): void { this._clearIdleTimer(); + } + + public restartBlinkAnimation(): void { + if (this._isIdlePaused) { + this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS); + } + this._resetIdleTimer(); + } + + public pause(): void { + this._isIdlePaused = false; + this._clearIdleTimer(); + } + + public resume(): void { + this._isIdlePaused = false; this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS); + this._resetIdleTimer(); + } + + private _resetIdleTimer(): void { + this._isIdlePaused = false; + this._clearIdleTimer(); this._idleTimeout = this._coreBrowserService.window.setTimeout(() => { this._stopBlinkingDueToIdle(); }, Constants.IDLE_TIMEOUT); } - /** - * Clears the idle timer. - */ private _clearIdleTimer(): void { if (this._idleTimeout) { this._coreBrowserService.window.clearTimeout(this._idleTimeout); @@ -586,11 +612,9 @@ export class DomRenderer extends Disposable implements IRenderer { } } - /** - * Stops cursor blinking due to idle timeout. - */ private _stopBlinkingDueToIdle(): void { this._rowContainer.classList.add(CURSOR_BLINK_IDLE_CLASS); + this._isIdlePaused = true; this._idleTimeout = undefined; } } From 4985c9f3f90db9c5a2c67f1324d848f1ac637f28 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:37:25 -0800 Subject: [PATCH 4/7] Use shared constant for idle timeout --- addons/addon-webgl/src/CursorBlinkStateManager.ts | 8 ++------ src/browser/renderer/dom/DomRenderer.ts | 11 ++--------- src/browser/renderer/shared/Constants.ts | 7 +++++++ 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/addons/addon-webgl/src/CursorBlinkStateManager.ts b/addons/addon-webgl/src/CursorBlinkStateManager.ts index 1346cbc3..615fc200 100644 --- a/addons/addon-webgl/src/CursorBlinkStateManager.ts +++ b/addons/addon-webgl/src/CursorBlinkStateManager.ts @@ -3,6 +3,7 @@ * @license MIT */ +import { RendererConstants } from 'browser/renderer/shared/Constants'; import { ICoreBrowserService } from 'browser/services/Services'; const enum Constants { @@ -10,11 +11,6 @@ const enum Constants { * The time between cursor blinks. */ BLINK_INTERVAL = 600, - - /** - * The idle time after which cursor blinking stops. - */ - IDLE_TIMEOUT = 5 * 60 * 1000 } export class CursorBlinkStateManager { @@ -178,7 +174,7 @@ export class CursorBlinkStateManager { } this._idleTimeout = this._coreBrowserService.window.setTimeout(() => { this._stopBlinkingDueToIdle(); - }, Constants.IDLE_TIMEOUT); + }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT); } /** diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 58e2d873..b1c136f2 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -5,7 +5,7 @@ import { DomRendererRowFactory, RowCss } from 'browser/renderer/dom/DomRendererRowFactory'; import { WidthCache } from 'browser/renderer/dom/WidthCache'; -import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants'; +import { INVERTED_DEFAULT_COLOR, RendererConstants } from 'browser/renderer/shared/Constants'; import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils'; import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel'; import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from 'browser/renderer/shared/Types'; @@ -26,13 +26,6 @@ const FOCUS_CLASS = 'xterm-focus'; const SELECTION_CLASS = 'xterm-selection'; const CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'; -const enum Constants { - /** - * The idle time after which cursor blinking stops. - */ - IDLE_TIMEOUT = 5 * 60 * 1000 -} - let nextTerminalId = 1; /** @@ -602,7 +595,7 @@ class CursorBlinkStateManager { this._clearIdleTimer(); this._idleTimeout = this._coreBrowserService.window.setTimeout(() => { this._stopBlinkingDueToIdle(); - }, Constants.IDLE_TIMEOUT); + }, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT); } private _clearIdleTimer(): void { diff --git a/src/browser/renderer/shared/Constants.ts b/src/browser/renderer/shared/Constants.ts index 4bc4f985..32d44bf1 100644 --- a/src/browser/renderer/shared/Constants.ts +++ b/src/browser/renderer/shared/Constants.ts @@ -4,3 +4,10 @@ */ export const INVERTED_DEFAULT_COLOR = 257; + +export const enum RendererConstants { + /** + * The idle time after which cursor blinking stops. + */ + CURSOR_BLINK_IDLE_TIMEOUT = 5 * 60 * 1000 +} \ No newline at end of file From a966f7d591652ba496843f1c9c072265167882b9 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:41:21 -0800 Subject: [PATCH 5/7] Explain idle in cursorBlink option --- typings/xterm-headless.d.ts | 4 +++- typings/xterm.d.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/typings/xterm-headless.d.ts b/typings/xterm-headless.d.ts index 26f970f1..b3d94ed2 100644 --- a/typings/xterm-headless.d.ts +++ b/typings/xterm-headless.d.ts @@ -49,7 +49,9 @@ declare module '@xterm/headless' { convertEol?: boolean; /** - * Whether the cursor blinks. + * Whether the cursor blinks. The blinking will stop after 5 minutes of idle + * time (refreshed by clicking, focusing or the cursor moving). The default + * is false. */ cursorBlink?: boolean; diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 8e34a00e..7bfba9c8 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -58,7 +58,9 @@ declare module '@xterm/xterm' { convertEol?: boolean; /** - * Whether the cursor blinks. + * Whether the cursor blinks. The blinking will stop after 5 minutes of idle + * time (refreshed by clicking, focusing or the cursor moving). The default + * is false. */ cursorBlink?: boolean; From 8a5ffc1bb1677698659a71f0686af588338447b9 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:42:22 -0800 Subject: [PATCH 6/7] Tidy comments --- addons/addon-webgl/src/CursorBlinkStateManager.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/addon-webgl/src/CursorBlinkStateManager.ts b/addons/addon-webgl/src/CursorBlinkStateManager.ts index 615fc200..688aee7b 100644 --- a/addons/addon-webgl/src/CursorBlinkStateManager.ts +++ b/addons/addon-webgl/src/CursorBlinkStateManager.ts @@ -164,8 +164,8 @@ export class CursorBlinkStateManager { } /** - * Resets the idle timer. If the terminal is idle for IDLE_TIMEOUT, cursor - * blinking will stop. + * Resets the idle timer. If the terminal is idle for the idle timeout period, + * the cursor blinking will stop. */ private _resetIdleTimer(): void { this._isIdlePaused = false; From 2c32ef5963308cab40e1597278d5e2c8d26d221c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:53:03 -0800 Subject: [PATCH 7/7] Fix lint --- src/browser/renderer/shared/Constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/renderer/shared/Constants.ts b/src/browser/renderer/shared/Constants.ts index 32d44bf1..5b6665c9 100644 --- a/src/browser/renderer/shared/Constants.ts +++ b/src/browser/renderer/shared/Constants.ts @@ -10,4 +10,4 @@ export const enum RendererConstants { * The idle time after which cursor blinking stops. */ CURSOR_BLINK_IDLE_TIMEOUT = 5 * 60 * 1000 -} \ No newline at end of file +}