fix: address pr-bug-scan validated finding from #7064

Added clearTerminalWebglAttachBackoff() before both live-addon reattaches in setLigaturesEnabled (pane-lifecycle.ts:153,173), mirroring rebuildAttachedWebgl; blocks the latch guard at pane-webgl-rende
This commit is contained in:
orca-bug-scan-bot
2026-07-02 12:44:26 -07:00
parent c29bf6f3da
commit 8221dfc140
2 changed files with 78 additions and 2 deletions
@@ -6,7 +6,7 @@ import {
markComplexScriptOutput,
resetTerminalWebglSuggestion
} from './pane-webgl-renderer'
import { attachLigatures, openTerminal } from './pane-lifecycle'
import { attachLigatures, openTerminal, setLigaturesEnabled } from './pane-lifecycle'
import {
buildDefaultTerminalOptions,
DEFAULT_TERMINAL_FAST_SCROLL_SENSITIVITY,
@@ -410,6 +410,71 @@ describe('attachLigatures', () => {
})
})
describe('setLigaturesEnabled with a stale attach backoff', () => {
beforeEach(() => {
webglMock.contextLossHandler = null
webglMock.dispose.mockClear()
vi.mocked(WebglAddon).mockClear()
resetTerminalWebglSuggestion()
vi.spyOn(console, 'warn').mockImplementation(() => {})
vi.stubGlobal('navigator', {
platform: 'MacIntel',
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
})
vi.stubGlobal('requestAnimationFrame', (callback: FrameRequestCallback) => {
callback(16)
return 1
})
})
afterEach(() => {
vi.unstubAllGlobals()
vi.restoreAllMocks()
})
// Why: a live WebGL pane must survive a ligature toggle even when another
// pane latched the module-global attach backoff on a transient failure. The
// reattach here has the same "live addon proves context creation works"
// precondition as rebuildAttachedWebgl, so it must clear the backoff too.
function latchAttachBackoffFromUnrelatedPane(): void {
vi.mocked(WebglAddon).mockImplementationOnce(() => {
throw new Error('WebGL2 not supported null')
})
const failingPane = createPane()
failingPane.terminalGpuAcceleration = 'on'
attachWebgl(failingPane)
expect(failingPane.webglAddon).toBeNull()
}
it('keeps a live pane on WebGL when enabling ligatures', () => {
const pane = createPane()
pane.terminalGpuAcceleration = 'on'
attachWebgl(pane)
expect(pane.webglAddon).not.toBeNull()
latchAttachBackoffFromUnrelatedPane()
setLigaturesEnabled(pane, true)
expect(pane.webglAddon).not.toBeNull()
})
it('keeps a live pane on WebGL when disabling ligatures', () => {
const pane = createPane()
pane.terminalGpuAcceleration = 'on'
attachWebgl(pane)
attachLigatures(pane)
expect(pane.webglAddon).not.toBeNull()
expect(pane.ligaturesAddon).not.toBeNull()
latchAttachBackoffFromUnrelatedPane()
setLigaturesEnabled(pane, false)
expect(pane.webglAddon).not.toBeNull()
})
})
describe('openTerminal — Unicode 11 ordering', () => {
beforeEach(() => {
vi.stubGlobal('requestAnimationFrame', () => 1)
@@ -16,7 +16,12 @@ import { activateOrcaTerminalUnicodeProvider } from './pane-terminal-unicode-pro
import { attachTerminalMouseWheelMultiplier } from './pane-terminal-mouse-wheel'
import { attachTerminalScrollIntentTracking } from './terminal-scroll-intent'
import { attachDomRendererFocusClassSync } from './pane-dom-focus-class-sync'
import { attachWebgl, cancelPendingWebglRefresh, disposeWebgl } from './pane-webgl-renderer'
import {
attachWebgl,
cancelPendingWebglRefresh,
clearTerminalWebglAttachBackoff,
disposeWebgl
} from './pane-webgl-renderer'
// ---------------------------------------------------------------------------
// Pane creation, terminal open/close, addon management
@@ -150,6 +155,9 @@ export function attachLigatures(pane: ManagedPaneInternal): void {
// forces a fresh atlas that includes the ligated glyphs.
if (pane.webglAddon) {
disposeWebgl(pane)
// Why: the live addon just proved context creation works, so a stale
// attach backoff from an unrelated pane must not downgrade this one to DOM.
clearTerminalWebglAttachBackoff()
attachWebgl(pane)
}
} catch (err) {
@@ -170,6 +178,9 @@ export function setLigaturesEnabled(pane: ManagedPaneInternal, enabled: boolean)
// renders as the non-ligated fallback immediately.
if (pane.webglAddon) {
disposeWebgl(pane)
// Why: the live addon just proved context creation works, so a stale
// attach backoff from an unrelated pane must not downgrade this one to DOM.
clearTerminalWebglAttachBackoff()
attachWebgl(pane)
}
}