From 4a231ff09a892e9a7b5cd6e87f11dfb1ca5959e2 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 25 Feb 2026 16:05:22 +0000 Subject: [PATCH] Force chat request height update when codeblock is present (#297706) * Force chat request height update when codeblock is present Fix #288361 * Update src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../chatMarkdownContentPart.ts | 14 +++++++- .../chat/browser/widget/chatListRenderer.ts | 34 +++++++++++-------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts b/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts index 44abea609e9..4255c82e1d1 100644 --- a/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts +++ b/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts @@ -15,6 +15,7 @@ import { findLast } from '../../../../../../base/common/arraysFind.js'; import { Codicon } from '../../../../../../base/common/codicons.js'; import { Lazy } from '../../../../../../base/common/lazy.js'; import { Disposable, DisposableStore, IDisposable, MutableDisposable, toDisposable } from '../../../../../../base/common/lifecycle.js'; +import { Emitter, Event } from '../../../../../../base/common/event.js'; import { autorun, autorunSelfDisposable, derived } from '../../../../../../base/common/observable.js'; import { ScrollbarVisibility } from '../../../../../../base/common/scrollable.js'; import { equalsIgnoreCase } from '../../../../../../base/common/strings.js'; @@ -89,6 +90,10 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP readonly codeblocksPartId = String(++ChatMarkdownContentPart.ID_POOL); readonly domNode: HTMLElement; + // This Event exists for one specific scenario and the pattern shouldn't be copied without a good reason + private readonly _onDidChangeHeight = this._register(new Emitter()); + readonly onDidChangeHeight: Event = this._onDidChangeHeight.event; + private readonly allRefs: IDisposableReference[] = []; private readonly _codeblocks: IMarkdownPartCodeBlockInfo[] = []; @@ -407,7 +412,14 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP this._codeblocks[data.codeBlockPartIndex].codemapperUri = e.codemapperUri; }); - editorInfo.render(data, currentWidth); + editorInfo.render(data, currentWidth).then(() => { + // There is a scenario where we set the model on the editor in a request and the ResizeObserver is not triggered. + // Work around it with this targeted onDidHeightChange. But this pattern generally shouldn't be necessary and + // shouldn't be copied elsewhere. + if (!this._store.isDisposed && isRequestVM(data.element)) { + this._onDidChangeHeight.fire(); + } + }); return ref; } diff --git a/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts index ce6710d72ef..87681d808ce 100644 --- a/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts @@ -324,6 +324,23 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { - if (!template.currentElement) { - return; - } - const entry = entries[0]; if (entry) { - const height = entry.borderBoxSize.at(0)?.blockSize; - if (height === 0 || !height || !template.rowContainer.isConnected) { - // Don't fire for changes that happen from the row being removed from the DOM - return; - } - - const normalizedHeight = Math.ceil(height); - template.currentElement.currentRenderedHeight = normalizedHeight; - if (template.currentElement !== this._elementBeingRendered) { - this._onDidChangeItemHeight.fire({ element: template.currentElement, height: normalizedHeight }); - } + this.fireItemHeightChange(template, entry.borderBoxSize.at(0)?.blockSize); } })); templateDisposables.add(resizeObserver.observe(rowContainer)); @@ -2384,6 +2387,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer this.fireItemHeightChange(templateData))); if (isRequestVM(element)) { markdownPart.domNode.tabIndex = 0; if (this.configService.getValue('chat.editRequests') === 'inline' && this.rendererOptions.editable) {