diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues index 35ea9042ef5..0423e9e3afc 100644 --- a/.vscode/notebooks/api.github-issues +++ b/.vscode/notebooks/api.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPO=repo:microsoft/vscode\n$MILESTONE=milestone:\"October 2024\"" + "value": "$REPO=repo:microsoft/vscode\n$MILESTONE=milestone:\"November 2024\"" }, { "kind": 1, diff --git a/.vscode/notebooks/my-work.github-issues b/.vscode/notebooks/my-work.github-issues index c58ceae0d01..7577d9626c8 100644 --- a/.vscode/notebooks/my-work.github-issues +++ b/.vscode/notebooks/my-work.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n// current milestone name\n$MILESTONE=milestone:\"October 2024\"\n" + "value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n// current milestone name\n$MILESTONE=milestone:\"November 2024\"\n" }, { "kind": 1, diff --git a/src/vs/editor/browser/gpu/atlas/textureAtlas.ts b/src/vs/editor/browser/gpu/atlas/textureAtlas.ts index e8b8ad73c7a..fb9ac44f4a8 100644 --- a/src/vs/editor/browser/gpu/atlas/textureAtlas.ts +++ b/src/vs/editor/browser/gpu/atlas/textureAtlas.ts @@ -5,6 +5,7 @@ import { getActiveWindow } from '../../../../base/browser/dom.js'; import { CharCode } from '../../../../base/common/charCode.js'; +import { BugIndicatingError } from '../../../../base/common/errors.js'; import { Emitter, Event } from '../../../../base/common/event.js'; import { Disposable, dispose, MutableDisposable, toDisposable } from '../../../../base/common/lifecycle.js'; import { ThreeKeyMap } from '../../../../base/common/map.js'; @@ -22,7 +23,7 @@ export interface ITextureAtlasOptions { } export class TextureAtlas extends Disposable { - private _colorMap!: string[]; + private _colorMap?: string[]; private readonly _warmUpTask: MutableDisposable = this._register(new MutableDisposable()); private readonly _warmedUpRasterizers = new Set(); private readonly _allocatorType: AllocatorType; @@ -60,7 +61,9 @@ export class TextureAtlas extends Disposable { this._allocatorType = options?.allocatorType ?? 'slab'; this._register(Event.runAndSubscribe(this._themeService.onDidColorThemeChange, () => { - // TODO: Clear entire atlas on theme change + if (this._colorMap) { + this.clear(); + } this._colorMap = this._themeService.getColorTheme().tokenColorMap; })); @@ -147,13 +150,17 @@ export class TextureAtlas extends Disposable { * is distrubuted over multiple idle callbacks to avoid blocking the main thread. */ private _warmUpAtlas(rasterizer: IGlyphRasterizer): void { + const colorMap = this._colorMap; + if (!colorMap) { + throw new BugIndicatingError('Cannot warm atlas without color map'); + } this._warmUpTask.value?.clear(); const taskQueue = this._warmUpTask.value = new IdleTaskQueue(); // Warm up using roughly the larger glyphs first to help optimize atlas allocation // A-Z for (let code = CharCode.A; code <= CharCode.Z; code++) { taskQueue.enqueue(() => { - for (const fgColor of this._colorMap.keys()) { + for (const fgColor of colorMap.keys()) { this.getGlyph(rasterizer, String.fromCharCode(code), (fgColor << MetadataConsts.FOREGROUND_OFFSET) & MetadataConsts.FOREGROUND_MASK); } }); @@ -161,7 +168,7 @@ export class TextureAtlas extends Disposable { // a-z for (let code = CharCode.a; code <= CharCode.z; code++) { taskQueue.enqueue(() => { - for (const fgColor of this._colorMap.keys()) { + for (const fgColor of colorMap.keys()) { this.getGlyph(rasterizer, String.fromCharCode(code), (fgColor << MetadataConsts.FOREGROUND_OFFSET) & MetadataConsts.FOREGROUND_MASK); } }); @@ -169,7 +176,7 @@ export class TextureAtlas extends Disposable { // Remaining ascii for (let code = CharCode.ExclamationMark; code <= CharCode.Tilde; code++) { taskQueue.enqueue(() => { - for (const fgColor of this._colorMap.keys()) { + for (const fgColor of colorMap.keys()) { this.getGlyph(rasterizer, String.fromCharCode(code), (fgColor << MetadataConsts.FOREGROUND_OFFSET) & MetadataConsts.FOREGROUND_MASK); } }); diff --git a/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts b/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts index a661ef64bcc..8c0d35ee85e 100644 --- a/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts +++ b/src/vs/editor/browser/gpu/atlas/textureAtlasPage.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event } from '../../../../base/common/event.js'; import { Disposable, toDisposable } from '../../../../base/common/lifecycle.js'; import { ThreeKeyMap } from '../../../../base/common/map.js'; import { ILogService, LogLevel } from '../../../../platform/log/common/log.js'; @@ -46,11 +45,12 @@ export class TextureAtlasPage extends Disposable implements IReadableTextureAtla pageSize: number, allocatorType: AllocatorType, @ILogService private readonly _logService: ILogService, - @IThemeService private readonly _themeService: IThemeService, + @IThemeService themeService: IThemeService, ) { super(); this._canvas = new OffscreenCanvas(pageSize, pageSize); + this._colorMap = themeService.getColorTheme().tokenColorMap; switch (allocatorType) { case 'shelf': this._allocator = new TextureAtlasShelfAllocator(this._canvas, textureIndex); break; @@ -58,11 +58,6 @@ export class TextureAtlasPage extends Disposable implements IReadableTextureAtla default: this._allocator = allocatorType(this._canvas, textureIndex); break; } - this._register(Event.runAndSubscribe(this._themeService.onDidColorThemeChange, () => { - // TODO: Clear entire atlas on theme change - this._colorMap = this._themeService.getColorTheme().tokenColorMap; - })); - // Reduce impact of a memory leak if this object is not released this._register(toDisposable(() => { this._canvas.width = 1; diff --git a/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts b/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts index 693bfc1f5da..b31a5f62fd9 100644 --- a/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts +++ b/src/vs/editor/browser/viewParts/viewLinesGpu/viewLinesGpu.ts @@ -40,6 +40,7 @@ export class ViewLinesGpu extends ViewPart implements IViewLines { private readonly canvas: HTMLCanvasElement; + private _initViewportData?: ViewportData[]; private _lastViewportData?: ViewportData; private _lastViewLineOptions?: ViewLineOptions; @@ -285,6 +286,16 @@ export class ViewLinesGpu extends ViewPart implements IViewLines { // endregion Bind group this._initialized = true; + + // Render the initial viewport immediately after initialization + if (this._initViewportData) { + // HACK: Rendering multiple times in the same frame like this isn't ideal, but there + // isn't an easy way to merge viewport data + for (const viewportData of this._initViewportData) { + this.renderText(viewportData); + } + this._initViewportData = undefined; + } } private _updateAtlasStorageBufferAndTexture() { @@ -361,6 +372,9 @@ export class ViewLinesGpu extends ViewPart implements IViewLines { public renderText(viewportData: ViewportData): void { if (this._initialized) { return this._renderText(viewportData); + } else { + this._initViewportData = this._initViewportData ?? []; + this._initViewportData.push(viewportData); } } diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts index 679d5981eee..e1346874c6b 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts @@ -85,7 +85,10 @@ class SubmitWithoutDispatchingAction extends Action2 { precondition: ContextKeyExpr.and( ChatContextKeys.inputHasText, ChatContextKeys.requestInProgress.negate(), - ContextKeyExpr.and(ChatContextKeys.location.isEqualTo(ChatAgentLocation.Panel))), + ContextKeyExpr.and(ContextKeyExpr.or( + ChatContextKeys.location.isEqualTo(ChatAgentLocation.Panel), + ChatContextKeys.location.isEqualTo(ChatAgentLocation.Editor), + ))), keybinding: { when: ChatContextKeys.inChatInput, primary: KeyMod.Alt | KeyMod.Shift | KeyCode.Enter, @@ -140,7 +143,8 @@ export class ChatSubmitSecondaryAgentAction extends Action2 { menu: { id: MenuId.ChatExecuteSecondary, group: 'group_1', - order: 3 + order: 3, + when: ContextKeyExpr.equals(ChatContextKeys.location.key, ChatAgentLocation.Panel) }, keybinding: { when: ChatContextKeys.inChatInput, @@ -185,12 +189,22 @@ class SendToChatEditingAction extends Action2 { id: MenuId.ChatExecuteSecondary, group: 'group_1', order: 4, - when: ContextKeyExpr.and(ChatContextKeys.enabled, ChatContextKeys.editingParticipantRegistered, ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession)) + when: ContextKeyExpr.and( + ChatContextKeys.enabled, + ChatContextKeys.editingParticipantRegistered, + ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession), + ChatContextKeys.location.notEqualsTo(ChatAgentLocation.Editor) + ) }, keybinding: { weight: KeybindingWeight.WorkbenchContrib, primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter, - when: ContextKeyExpr.and(ChatContextKeys.enabled, ChatContextKeys.editingParticipantRegistered, ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession)) + when: ContextKeyExpr.and( + ChatContextKeys.enabled, + ChatContextKeys.editingParticipantRegistered, + ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession), + ChatContextKeys.location.notEqualsTo(ChatAgentLocation.Editor), + ) } }); } @@ -258,7 +272,9 @@ class SendToNewChatAction extends Action2 { f1: false, menu: { id: MenuId.ChatExecuteSecondary, - group: 'group_2' + group: 'group_2', + when: ContextKeyExpr.equals(ChatContextKeys.location.key, ChatAgentLocation.Panel) + }, keybinding: { weight: KeybindingWeight.WorkbenchContrib, diff --git a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts index f49f8d1200b..ea567472e54 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.ts @@ -57,6 +57,27 @@ abstract class WorkingSetAction extends Action2 { abstract runWorkingSetAction(accessor: ServicesAccessor, currentEditingSession: IChatEditingSession, chatWidget: IChatWidget | undefined, ...uris: URI[]): any; } +registerAction2(class AddFileToWorkingSet extends WorkingSetAction { + constructor() { + super({ + id: 'chatEditing.addFileToWorkingSet', + title: localize2('addFileToWorkingSet', 'Add File'), + icon: Codicon.plus, + menu: [{ + id: MenuId.ChatEditingWidgetModifiedFilesToolbar, + when: ContextKeyExpr.equals(chatEditingWidgetFileStateContextKey.key, WorkingSetEntryState.Transient), + order: 0, + group: 'navigation' + }], + }); + } + + async runWorkingSetAction(_accessor: ServicesAccessor, currentEditingSession: IChatEditingSession, _chatWidget: IChatWidget, ...uris: URI[]): Promise { + for (const uri of uris) { + currentEditingSession.addFileToWorkingSet(uri); + } + } +}); registerAction2(class RemoveFileFromWorkingSet extends WorkingSetAction { constructor() { diff --git a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts index 862cc70a0f5..3c958b3c61f 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSession.ts @@ -467,7 +467,8 @@ export class ChatEditingSession extends Disposable implements IChatEditingSessio } addFileToWorkingSet(resource: URI) { - if (!this._workingSet.has(resource)) { + const state = this._workingSet.get(resource); + if (state === undefined || state === WorkingSetEntryState.Transient) { this._workingSet.set(resource, WorkingSetEntryState.Attached); // Convert all transient entries to attachments diff --git a/src/vs/workbench/contrib/chat/browser/chatEditorActions.ts b/src/vs/workbench/contrib/chat/browser/chatEditorActions.ts index f9130999950..c9d3ad368c7 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditorActions.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditorActions.ts @@ -6,7 +6,7 @@ import { isCodeEditor } from '../../../../editor/browser/editorBrowser.js'; import { localize2 } from '../../../../nls.js'; import { ServicesAccessor } from '../../../../editor/browser/editorExtensions.js'; import { Codicon } from '../../../../base/common/codicons.js'; -import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js'; +import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js'; import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js'; import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js'; import { CHAT_CATEGORY } from './actions/chatActions.js'; @@ -35,13 +35,7 @@ abstract class NavigateAction extends Action2 { weight: KeybindingWeight.EditorContrib, when: ContextKeyExpr.and(ctxHasEditorModification, EditorContextKeys.focus), }, - f1: true, - menu: { - id: MenuId.EditorTitle, - group: 'navigation', - order: next ? -100 : -101, - when: ctxHasEditorModification - } + f1: true }); } @@ -75,12 +69,7 @@ abstract class AcceptDiscardAction extends Action2 { icon: accept ? Codicon.check : Codicon.discard, - menu: { - id: MenuId.EditorTitle, - group: 'navigation', - order: accept ? -103 : -102, - when: ctxHasEditorModification - } + f1: true, }); } diff --git a/src/vs/workbench/contrib/chat/browser/chatEditorOverlay.ts b/src/vs/workbench/contrib/chat/browser/chatEditorOverlay.ts index 6b2fa7a694b..b1e6480bf3b 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditorOverlay.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditorOverlay.ts @@ -19,6 +19,9 @@ import { Range } from '../../../../editor/common/core/range.js'; import { Codicon } from '../../../../base/common/codicons.js'; import { ThemeIcon } from '../../../../base/common/themables.js'; import { ChatEditorController } from './chatEditorController.js'; +import { IViewsService } from '../../../services/views/common/viewsService.js'; +import { EDITS_VIEW_ID } from './chat.js'; +import { ActionViewItem } from '../../../../base/browser/ui/actionbar/actionViewItems.js'; class ChatEditorOverlayWidget implements IOverlayWidget { @@ -33,20 +36,21 @@ class ChatEditorOverlayWidget implements IOverlayWidget { constructor( private readonly _editor: ICodeEditor, @IEditorService private readonly _editorService: IEditorService, + @IViewsService private readonly _viewsService: IViewsService, @IInstantiationService instaService: IInstantiationService, ) { this._domNode = document.createElement('div'); this._domNode.classList.add('chat-editor-overlay-widget'); - const progressNode = document.createElement('div'); - progressNode.classList.add('progress-container'); - progressNode.classList.add(...ThemeIcon.asClassNameArray(ThemeIcon.modify(Codicon.loading, 'spin'))); - this._domNode.appendChild(progressNode); - - const toolbarContainer = document.createElement('div'); - toolbarContainer.classList.add('toolbar-container'); - this._domNode.appendChild(toolbarContainer); - this._toolbar = instaService.createInstance(WorkbenchToolBar, toolbarContainer, {}); + this._toolbar = instaService.createInstance(WorkbenchToolBar, this._domNode, { + telemetrySource: 'chatEditor.overlayToolbar', + actionViewItemProvider: (action, options) => { + if (action.id === 'accept' || action.id === 'discard') { + return new ActionViewItem(undefined, action, { ...options, label: true, icon: false }); + } + return undefined; + } + }); } dispose() { @@ -104,9 +108,20 @@ class ChatEditorOverlayWidget implements IOverlayWidget { this._domNode.classList.toggle('busy', busy); const groups = [[ + toAction({ + id: 'open', + label: localize('open', 'Open Chat Edit'), + class: ThemeIcon.asClassName(busy + ? ThemeIcon.modify(Codicon.loading, 'spin') + : Codicon.goToEditingSession), + run: async () => { + await this._viewsService.openView(EDITS_VIEW_ID); + } + }), toAction({ id: 'accept', - label: localize('accept', 'Accept Chat Edits'), + label: localize('accept', 'Accept'), + tooltip: localize('acceptTooltip', 'Accept Chat Edits'), class: ThemeIcon.asClassName(Codicon.check), enabled: !busy && modified, run: () => { @@ -116,7 +131,8 @@ class ChatEditorOverlayWidget implements IOverlayWidget { }), toAction({ id: 'discard', - label: localize('discard', 'Discard Chat Edits'), + label: localize('discard', 'Discard'), + tooltip: localize('discardTooltip', 'Discard Chat Edits'), class: ThemeIcon.asClassName(Codicon.discard), enabled: !busy && modified, run: () => { diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index 75fb31996ab..c9a33ded7d9 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -629,7 +629,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge hoverDelegate, hiddenItemStrategy: HiddenItemStrategy.Ignore, // keep it lean when hiding items and avoid a "..." overflow menu actionViewItemProvider: (action, options) => { - if (this.location === ChatAgentLocation.Panel) { + if (this.location === ChatAgentLocation.Panel || this.location === ChatAgentLocation.Editor) { if ((action.id === SubmitAction.ID || action.id === CancelAction.ID) && action instanceof MenuItemAction) { const dropdownAction = this.instantiationService.createInstance(MenuItemAction, { id: 'chat.moreExecuteActions', title: localize('notebook.moreExecuteActionsLabel', "More..."), icon: Codicon.chevronDown }, undefined, undefined, undefined, undefined); return this.instantiationService.createInstance(ChatSubmitDropdownActionItem, action, dropdownAction, options); diff --git a/src/vs/workbench/contrib/chat/browser/media/chatEditorOverlay.css b/src/vs/workbench/contrib/chat/browser/media/chatEditorOverlay.css index 2f51a7bcaf2..9529bd58c19 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chatEditorOverlay.css +++ b/src/vs/workbench/contrib/chat/browser/media/chatEditorOverlay.css @@ -4,35 +4,26 @@ *--------------------------------------------------------------------------------------------*/ .chat-editor-overlay-widget { - padding: 4px; + padding: 0px; color: var(--vscode-button-foreground); background-color: var(--vscode-button-background); - border-radius: 2px; + border-radius: 5px; border: 1px solid var(--vscode-contrastBorder); display: flex; align-items: center } - -.chat-editor-overlay-widget .progress-container { - display: none; - padding: 0 4px; +.chat-editor-overlay-widget .action-item > .action-label { + padding: 5px; } -.chat-editor-overlay-widget.busy .progress-container { - display: inherit; -} - -.chat-editor-overlay-widget .progress-container.codicon { +.chat-editor-overlay-widget .action-item > .action-label.codicon { color: var(--vscode-button-foreground); } -.chat-editor-overlay-widget .toolbar-container .action-item > .action-label.codicon { - color: var(--vscode-button-foreground); -} - -.chat-editor-overlay-widget .toolbar-container .action-item.disabled > .action-label.codicon::before, -.chat-editor-overlay-widget .toolbar-container .action-item.disabled > .action-label.codicon { +.chat-editor-overlay-widget .action-item.disabled > .action-label.codicon::before, +.chat-editor-overlay-widget .action-item.disabled > .action-label.codicon, +.chat-editor-overlay-widget .action-item.disabled > .action-label { color: var(--vscode-button-foreground); opacity: 0.7; } diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatActions.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatActions.ts index 761e762b43b..4f5756b8556 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatActions.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatActions.ts @@ -60,7 +60,10 @@ registerActiveXtermAction({ keybinding: { primary: KeyCode.Escape, secondary: [KeyMod.Shift | KeyCode.Escape], - when: ContextKeyExpr.and(TerminalChatContextKeys.focused, TerminalChatContextKeys.visible), + when: ContextKeyExpr.and( + ContextKeyExpr.or(TerminalContextKeys.focus, TerminalChatContextKeys.focused), + TerminalChatContextKeys.visible + ), weight: KeybindingWeight.WorkbenchContrib, }, icon: Codicon.close, @@ -70,9 +73,7 @@ registerActiveXtermAction({ order: 2 }, f1: true, - precondition: ContextKeyExpr.and( - ContextKeyExpr.and(TerminalChatContextKeys.focused, TerminalChatContextKeys.visible) - ), + precondition: TerminalChatContextKeys.visible, run: (_xterm, _accessor, activeInstance) => { if (isDetachedTerminalInstance(activeInstance)) { return;