From 2805a1cf826a99cc0ee482494ed39cf209384da5 Mon Sep 17 00:00:00 2001 From: rsd-darshan Date: Sat, 23 May 2026 18:08:01 +0545 Subject: [PATCH 1/2] fix: refresh scroller layout when tool confirmation dialog is cancelled When the user cancels a subagent tool confirmation dialog, the subagent panel stays expanded at its pre-cancel height. This happens because cancelConfirmation() only calls parent.layout() (relaying the turn widget's children), but never updates the ScrolledComposite's minimum size via refreshScrollerLayout(). On the Continue path this goes unnoticed because subsequent subagent messages trigger a layout refresh; on the Cancel path no further messages arrive, so the panel is stuck. Fix by walking up the ancestor chain after parent.layout() to find the ChatContentViewer and calling refreshScrollerLayout(), which recomputes setMinHeight() and collapses the scroll area correctly. Fixes #169 --- .../eclipse/ui/chat/InvokeToolConfirmationDialog.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java index 745f62a5..c056872f 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java @@ -245,6 +245,17 @@ public void cancelConfirmation() { // Check if parent is still valid before using it if (parent != null && !parent.isDisposed()) { parent.layout(); + // Walk up to refresh the scroll container's minimum size; without this the panel + // stays expanded at its pre-cancel height because ScrolledComposite.setMinHeight() + // is never updated when no further messages arrive after cancellation. + Composite ancestor = parent.getParent(); + while (ancestor != null && !ancestor.isDisposed()) { + if (ancestor instanceof ChatContentViewer) { + ((ChatContentViewer) ancestor).refreshScrollerLayout(); + break; + } + ancestor = ancestor.getParent(); + } } }, this); } From a64f5a66504d5744cb8e67a934b307d000dd8fb7 Mon Sep 17 00:00:00 2001 From: rsd-darshan Date: Sat, 23 May 2026 19:54:29 +0545 Subject: [PATCH 2/2] fix: refresh scroller layout when tool confirmation dialog is cancelled When the user cancels a subagent tool confirmation dialog, the subagent panel stays expanded at its pre-cancel height. This happens because cancelConfirmation() only called parent.layout() (relaying the turn widget's children), but never updated the ScrolledComposite's minimum size via refreshScrollerLayout(). On the Continue path this goes unnoticed because subsequent subagent messages trigger a layout refresh; on the Cancel path no further messages arrive, so the panel is stuck. Fix by passing a Runnable callback from BaseTurnWidget into the dialog at construction time. BaseTurnWidget walks up the ancestor chain once to find ChatContentViewer and captures refreshScrollerLayout() as the callback. cancelConfirmation() calls it after disposal, which recomputes setMinHeight() in a single layout pass and collapses the panel correctly. This also removes the redundant parent.layout() call that preceded the deep layout(true,true) inside refreshScrollerLayout(). Fixes #169 --- .../eclipse/ui/chat/BaseTurnWidget.java | 12 +++++++++- .../ui/chat/InvokeToolConfirmationDialog.java | 22 ++++++------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/BaseTurnWidget.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/BaseTurnWidget.java index 2fcb99d0..e24dd62c 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/BaseTurnWidget.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/BaseTurnWidget.java @@ -591,7 +591,17 @@ public CompletableFuture requestToolExecuti // process all the messages before showing the confirmation dialog reset(); - this.confirmDialog = new InvokeToolConfirmationDialog(this, title, message, input); + Runnable refreshLayout = null; + Composite ancestor = this.getParent(); + while (ancestor != null && !ancestor.isDisposed()) { + if (ancestor instanceof ChatContentViewer) { + final ChatContentViewer viewer = (ChatContentViewer) ancestor; + refreshLayout = viewer::refreshScrollerLayout; + break; + } + ancestor = ancestor.getParent(); + } + this.confirmDialog = new InvokeToolConfirmationDialog(this, title, message, input, refreshLayout); CompletableFuture toolConfirmationFuture = this.confirmDialog .getConfirmationFuture(); diff --git a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java index c056872f..1d6f7d0b 100644 --- a/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java +++ b/com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/InvokeToolConfirmationDialog.java @@ -52,6 +52,7 @@ public class InvokeToolConfirmationDialog extends Composite { private Label titleLbl; private Font boldFont; private Runnable titleFontChangeCallback; + private final Runnable onCancelCallback; /** * Create a new confirmation dialog for tool execution. @@ -60,11 +61,14 @@ public class InvokeToolConfirmationDialog extends Composite { * @param title The title of the confirmation dialog * @param message The message to display * @param input The input object to pass to the tool + * @param onCancelCallback invoked after the dialog is disposed on cancellation, for layout refresh */ - public InvokeToolConfirmationDialog(Composite parent, String title, String message, Object input) { + public InvokeToolConfirmationDialog(Composite parent, String title, String message, Object input, + Runnable onCancelCallback) { super(parent, SWT.BORDER | SWT.WRAP); this.setLayout(new GridLayout(1, false)); this.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + this.onCancelCallback = onCancelCallback; createDialogContent(title, message, input); @@ -242,20 +246,8 @@ public void cancelConfirmation() { new AgentToolCancelLabel(this.getParent(), SWT.NONE, this.cancelMessage); } this.dispose(); - // Check if parent is still valid before using it - if (parent != null && !parent.isDisposed()) { - parent.layout(); - // Walk up to refresh the scroll container's minimum size; without this the panel - // stays expanded at its pre-cancel height because ScrolledComposite.setMinHeight() - // is never updated when no further messages arrive after cancellation. - Composite ancestor = parent.getParent(); - while (ancestor != null && !ancestor.isDisposed()) { - if (ancestor instanceof ChatContentViewer) { - ((ChatContentViewer) ancestor).refreshScrollerLayout(); - break; - } - ancestor = ancestor.getParent(); - } + if (onCancelCallback != null) { + onCancelCallback.run(); } }, this); }