diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index c7cb9da56583f..d2792bef5090b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -987,6 +987,11 @@ export interface IXtermTerminal { readonly onDidChangeSelection: Event; + /** + * Gets a view of the current texture atlas used by the renderers. + */ + readonly textureAtlas: Promise | undefined; + /** * The position of the terminal. */ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index c6c85fe83bf6a..2682d46275004 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -55,6 +55,8 @@ import { clearShellFileHistory, getCommandHistory } from 'vs/workbench/contrib/t import { Categories } from 'vs/platform/action/common/actionCommonCategories'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { TerminalCapability } from 'vs/platform/terminal/common/capabilities/capabilities'; +import { IFileService } from 'vs/platform/files/common/files'; +import { VSBuffer } from 'vs/base/common/buffer'; export const switchTerminalActionViewItemSeparator = '\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500'; export const switchTerminalShowTabsTitle = localize('showTerminalTabs', "Show Tabs"); @@ -2226,6 +2228,43 @@ export function registerTerminalActions() { clearShellFileHistory(); } }); + registerAction2(class extends Action2 { + constructor() { + super({ + id: TerminalCommandId.ShowTextureAtlas, + title: { value: localize('workbench.action.terminal.showTextureAtlas', "Show Terminal Texture Atlas"), original: 'Show Terminal Texture Atlas' }, + f1: true, + category: Categories.Developer.value, + precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated) + }); + } + async run(accessor: ServicesAccessor) { + const terminalService = accessor.get(ITerminalService); + const fileService = accessor.get(IFileService); + const openerService = accessor.get(IOpenerService); + const workspaceContextService = accessor.get(IWorkspaceContextService); + const bitmap = await terminalService.activeInstance?.xterm?.textureAtlas; + if (!bitmap) { + return; + } + const cwdUri = workspaceContextService.getWorkspace().folders[0].uri; + const fileUri = URI.joinPath(cwdUri, 'textureAtlas.png'); + const canvas = document.createElement('canvas'); + canvas.width = bitmap.width; + canvas.height = bitmap.height; + const ctx = canvas.getContext('bitmaprenderer'); + if (!ctx) { + return; + } + ctx.transferFromImageBitmap(bitmap); + const blob = await new Promise((res) => canvas.toBlob(res)); + if (!blob) { + return; + } + await fileService.writeFile(fileUri, VSBuffer.wrap(new Uint8Array(await blob.arrayBuffer()))); + openerService.open(fileUri); + } + }); registerAction2(class extends Action2 { constructor() { super({ diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 892e5411f86af..e0c3c536b5bc7 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -121,6 +121,14 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II } get target(): TerminalLocation | undefined { return this._target; } + get textureAtlas(): Promise | undefined { + const canvas = this._webglAddon?.textureAtlas || this._canvasAddon?.textureAtlas; + if (!canvas) { + return undefined; + } + return createImageBitmap(canvas); + } + /** * @param xtermCtor The xterm.js constructor, this is passed in so it can be fetched lazily * outside of this class such that {@link raw} is not nullable. diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 7d3d05d5e16ab..2f6901c8d823e 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -573,6 +573,7 @@ export const enum TerminalCommandId { SetDimensions = 'workbench.action.terminal.setDimensions', ClearCommandHistory = 'workbench.action.terminal.clearCommandHistory', WriteDataToTerminal = 'workbench.action.terminal.writeDataToTerminal', + ShowTextureAtlas = 'workbench.action.terminal.showTextureAtlas', } export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [