Skip to content

Commit de828cc

Browse files
jdneoCopilotCopilot
authored
fix: consolidate control validation into layoutNow (#340)
* fix: consolidate control validation into layoutNow requestLayout and flushPendingLayoutRequests each filtered out null/ disposed controls via a shared validControls helper before delegating to layoutNow, duplicating the same defensive check at every call site. layoutNow now performs its own null/disposed filtering right where it dereferences the controls (getShell(), shell.layout(...)), so the invariant is enforced in exactly one place instead of trusted by two separate callers. requestLayout becomes a pure dispatcher: it no longer pre-filters, it just forwards the raw controls to pendingLayoutRequests or layoutNow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: repair syntax broken by autofix commit in requestLayout The prior "Potential fix for pull request finding" commit (04e7682) badly spliced a null-check into requestLayout, leaving a dangling duplicate `layoutNow(changed); }` outside the method body and dedenting the whole method. This left invalid Java that failed the Tycho/ECJ compile in CI. Restores correct syntax/indentation while keeping the null-guard around Collections.addAll(pendingLayoutRequests, changed), which is the same defensive check layoutNow already applies to its own `controls` parameter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 073b82a commit de828cc

2 files changed

Lines changed: 82 additions & 5 deletions

File tree

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ChatView.java

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
package com.microsoft.copilot.eclipse.ui.chat;
55

66
import java.util.ArrayList;
7+
import java.util.Collections;
78
import java.util.HashSet;
9+
import java.util.LinkedHashSet;
810
import java.util.List;
911
import java.util.Map;
1012
import java.util.Set;
@@ -32,6 +34,7 @@
3234
import org.eclipse.swt.widgets.Composite;
3335
import org.eclipse.swt.widgets.Control;
3436
import org.eclipse.swt.widgets.Display;
37+
import org.eclipse.swt.widgets.Shell;
3538
import org.eclipse.ui.IPartListener2;
3639
import org.eclipse.ui.IWorkbenchPartReference;
3740
import org.eclipse.ui.PlatformUI;
@@ -164,6 +167,9 @@ public class ChatView extends ViewPart implements ChatProgressListener, MessageL
164167
private IContextActivation chatViewContextActivation;
165168
private IPartListener2 partListener;
166169

170+
/** Controls whose {@link #requestLayout(Control...)} call was suppressed while this view was hidden. */
171+
private final Set<Control> pendingLayoutRequests = new LinkedHashSet<>();
172+
167173
@Override
168174
public void createPartControl(Composite parent) {
169175
this.parent = parent;
@@ -517,7 +523,12 @@ public void partOpened(IWorkbenchPartReference partRef) {
517523

518524
@Override
519525
public void partVisible(IWorkbenchPartReference partRef) {
520-
// No action needed
526+
// Replay layout requests skipped while this view was hidden behind another part in the same
527+
// stack, targeted at just the specific control(s) that changed -- avoids a blind full-tree
528+
// relayout of the (possibly long) chat conversation.
529+
if (partRef.getPart(false) == ChatView.this) {
530+
flushPendingLayoutRequests();
531+
}
521532
}
522533
};
523534

@@ -1702,16 +1713,75 @@ public void dispose() {
17021713
getSite().getPage().removePartListener(this.partListener);
17031714
this.partListener = null;
17041715
}
1716+
pendingLayoutRequests.clear();
17051717
deactivateChatViewContext();
17061718

17071719
super.dispose();
17081720
}
17091721

17101722
/**
1711-
* Layout the view.
1723+
* Request a layout of the given control(s), which must be part of this view's widget tree.
1724+
*
1725+
* <p>Passing every control whose content actually changed (rather than a blind {@code
1726+
* parent.layout(true, true)}) lets SWT flush exactly those controls' cached sizes -- and only the
1727+
* ancestor chains leading to them -- so it never touches unrelated subtrees like the chat
1728+
* conversation history. Passing only a subset of what changed (e.g. a text label but not a
1729+
* sibling icon label that also changed) will leave the omitted control's cached size stale.
1730+
*
1731+
* <p>Skipped while the view isn't visible (e.g. stacked behind another part) to avoid layout cost
1732+
* on every editor switch; {@code changed} is instead remembered and replayed by {@link
1733+
* #flushPendingLayoutRequests()} once the view becomes visible again.
1734+
*
1735+
* @param changed every control whose content/layout data just changed
1736+
*/
1737+
public void requestLayout(Control... changed) {
1738+
if (getSite() == null || getSite().getPage() == null || !getSite().getPage().isPartVisible(this)) {
1739+
if (changed != null) {
1740+
Collections.addAll(pendingLayoutRequests, changed);
1741+
}
1742+
return;
1743+
}
1744+
layoutNow(changed);
1745+
}
1746+
1747+
/**
1748+
* Replays layout requests that were suppressed by {@link #requestLayout(Control...)} while this
1749+
* view was hidden, targeted at just the specific control(s) that changed.
17121750
*/
1713-
public void layout(boolean changed, boolean all) {
1714-
parent.layout(changed, all);
1751+
private void flushPendingLayoutRequests() {
1752+
if (pendingLayoutRequests.isEmpty()) {
1753+
return;
1754+
}
1755+
// Snapshot and clear before replaying: a control's requestLayout() could in principle
1756+
// synchronously trigger a new call back into requestLayout(Control...), which would otherwise
1757+
// mutate pendingLayoutRequests while it's being iterated.
1758+
Set<Control> toFlush = new LinkedHashSet<>(pendingLayoutRequests);
1759+
pendingLayoutRequests.clear();
1760+
layoutNow(toFlush.toArray(new Control[0]));
1761+
}
1762+
1763+
/**
1764+
* Flushes cached sizes for exactly the given controls (and the ancestor chains leading to them)
1765+
* and lays them out, in a single batched pass. Silently ignores {@code null} or disposed
1766+
* controls.
1767+
*/
1768+
private void layoutNow(Control... controls) {
1769+
List<Control> valid = new ArrayList<>();
1770+
if (controls != null) {
1771+
for (Control control : controls) {
1772+
if (control != null && !control.isDisposed()) {
1773+
valid.add(control);
1774+
}
1775+
}
1776+
}
1777+
if (valid.isEmpty()) {
1778+
return;
1779+
}
1780+
Shell shell = valid.get(0).getShell();
1781+
if (shell == null || shell.isDisposed()) {
1782+
return;
1783+
}
1784+
shell.layout(valid.toArray(new Control[0]), SWT.DEFER);
17151785
}
17161786

17171787
/**

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ReferencedFile.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,14 @@ protected void setFile(@Nullable IResource file) {
170170
setLayoutData(layoutData);
171171
ChatView chatView = UiUtils.getView(Constants.CHAT_VIEW_ID, ChatView.class);
172172
if (chatView != null) {
173-
chatView.layout(true, true);
173+
// Pass every child whose content setFile()/setupXDisplay() can touch (icon image, file name
174+
// text/CSS class, close button image) -- not just this composite or a single child. SWT's
175+
// targeted requestLayout() only flushes cached sizes for the exact controls it's given (plus
176+
// their ancestor chains up to cmpFileRef and beyond); passing a subset silently leaves the
177+
// others' cached sizes stale (previously: a clipped icon, and before that a chip that didn't
178+
// shrink). Since all three are descendants of this composite, their ancestor walk-up already
179+
// covers this chip's own RowData/visibility change too -- no need to pass `this` separately.
180+
chatView.requestLayout(lblfileIcon, lblFileName, lblClose);
174181
}
175182
}
176183

0 commit comments

Comments
 (0)