Skip to content

Commit cf9b773

Browse files
committed
fix nested scrolling and full-row table selection
1 parent 9289af0 commit cf9b773

4 files changed

Lines changed: 99 additions & 3 deletions

File tree

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/FileOperationAutoApproveSection.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.eclipse.jface.viewers.TableViewer;
2424
import org.eclipse.jface.viewers.TableViewerColumn;
2525
import org.eclipse.swt.SWT;
26+
import org.eclipse.swt.events.ControlAdapter;
2627
import org.eclipse.swt.graphics.Color;
2728
import org.eclipse.swt.layout.GridData;
2829
import org.eclipse.swt.layout.GridLayout;
@@ -112,13 +113,14 @@ private void createContents() {
112113

113114
private void createTable(Composite parent) {
114115
tableViewer = new TableViewer(parent,
115-
SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE);
116+
SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL);
116117
Table table = tableViewer.getTable();
117118
GridData tableData = new GridData(SWT.FILL, SWT.FILL, true, false);
118119
tableData.heightHint = TABLE_HEIGHT_HINT;
119120
table.setLayoutData(tableData);
120121
table.setHeaderVisible(true);
121122
table.setLinesVisible(true);
123+
SwtUtils.forwardVerticalMouseWheelToParentScrollerAtBoundary(table);
122124

123125
TableViewerColumn patternCol =
124126
new TableViewerColumn(tableViewer, SWT.NONE);
@@ -177,6 +179,17 @@ public Color getForeground(Object element) {
177179
? Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY) : null;
178180
}
179181
});
182+
table.addControlListener(new ControlAdapter() {
183+
@Override
184+
public void controlResized(org.eclipse.swt.events.ControlEvent e) {
185+
int remainingWidth = table.getClientArea().width
186+
- patternCol.getColumn().getWidth()
187+
- descCol.getColumn().getWidth();
188+
if (remainingWidth > 100) {
189+
statusCol.getColumn().setWidth(remainingWidth);
190+
}
191+
}
192+
});
180193

181194
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
182195
tableViewer.addSelectionChangedListener(e -> updateButtonState());

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/McpAutoApproveSection.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,11 @@ private void createContents() {
9090

9191
// Tree viewer for server/tool approval
9292
treeViewer = new CheckboxTreeViewer(group,
93-
SWT.BORDER | SWT.FULL_SELECTION);
93+
SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL);
9494
GridData treeData = new GridData(SWT.FILL, SWT.FILL, true, false);
9595
treeData.heightHint = TREE_HEIGHT_HINT;
9696
treeViewer.getTree().setLayoutData(treeData);
97+
SwtUtils.forwardVerticalMouseWheelToParentScrollerAtBoundary(treeViewer.getTree());
9798

9899
treeViewer.setContentProvider(new McpTreeContentProvider());
99100
treeViewer.setLabelProvider(new McpTreeLabelProvider());

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/preferences/TerminalAutoApproveSection.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.eclipse.jface.viewers.TableViewer;
1919
import org.eclipse.jface.viewers.TableViewerColumn;
2020
import org.eclipse.swt.SWT;
21+
import org.eclipse.swt.events.ControlAdapter;
2122
import org.eclipse.swt.layout.GridData;
2223
import org.eclipse.swt.layout.GridLayout;
2324
import org.eclipse.swt.widgets.Button;
@@ -30,6 +31,7 @@
3031
import com.microsoft.copilot.eclipse.core.CopilotCore;
3132
import com.microsoft.copilot.eclipse.core.chat.TerminalAutoApproveRule;
3233
import com.microsoft.copilot.eclipse.ui.chat.confirmation.TerminalConfirmationHandler;
34+
import com.microsoft.copilot.eclipse.ui.utils.SwtUtils;
3335

3436
/**
3537
* Terminal auto-approve section with a rule table, action buttons, and
@@ -90,13 +92,14 @@ private void createContents() {
9092

9193
private void createTable(Composite parent) {
9294
tableViewer = new TableViewer(parent,
93-
SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE);
95+
SWT.BORDER | SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL);
9496
Table table = tableViewer.getTable();
9597
GridData tableData = new GridData(SWT.FILL, SWT.FILL, true, false);
9698
tableData.heightHint = TABLE_HEIGHT_HINT;
9799
table.setLayoutData(tableData);
98100
table.setHeaderVisible(true);
99101
table.setLinesVisible(true);
102+
SwtUtils.forwardVerticalMouseWheelToParentScrollerAtBoundary(table);
100103

101104
TableViewerColumn commandCol =
102105
new TableViewerColumn(tableViewer, SWT.NONE);
@@ -123,6 +126,16 @@ public String getText(Object element) {
123126
: Messages.preferences_page_auto_approve_deny;
124127
}
125128
});
129+
table.addControlListener(new ControlAdapter() {
130+
@Override
131+
public void controlResized(org.eclipse.swt.events.ControlEvent e) {
132+
int remainingWidth = table.getClientArea().width
133+
- commandCol.getColumn().getWidth();
134+
if (remainingWidth > 100) {
135+
statusCol.getColumn().setWidth(remainingWidth);
136+
}
137+
}
138+
});
126139

127140
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
128141
tableViewer.addSelectionChangedListener(e -> updateButtonState());

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/utils/SwtUtils.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@
1212
import org.eclipse.jface.resource.ColorRegistry;
1313
import org.eclipse.jface.resource.JFaceResources;
1414
import org.eclipse.jface.text.ITextViewer;
15+
import org.eclipse.swt.SWT;
16+
import org.eclipse.swt.custom.ScrolledComposite;
1517
import org.eclipse.swt.custom.StyledText;
1618
import org.eclipse.swt.dnd.Clipboard;
1719
import org.eclipse.swt.dnd.TextTransfer;
1820
import org.eclipse.swt.dnd.Transfer;
1921
import org.eclipse.swt.graphics.Color;
22+
import org.eclipse.swt.graphics.Point;
2023
import org.eclipse.swt.graphics.RGB;
24+
import org.eclipse.swt.widgets.Composite;
2125
import org.eclipse.swt.widgets.Control;
2226
import org.eclipse.swt.widgets.Display;
27+
import org.eclipse.swt.widgets.ScrollBar;
28+
import org.eclipse.swt.widgets.Scrollable;
2329
import org.eclipse.swt.widgets.Shell;
2430
import org.eclipse.ui.IEditorPart;
2531
import org.eclipse.ui.IWorkbench;
@@ -272,6 +278,69 @@ public static Color getDefaultGhostTextColor(Display display) {
272278
return new Color(display, new RGB(DEFAULT_GHOST_TEXT_SCALE, DEFAULT_GHOST_TEXT_SCALE, DEFAULT_GHOST_TEXT_SCALE));
273279
}
274280

281+
/**
282+
* Forwards vertical mouse wheel scrolling from a nested scrollable to its nearest parent scroller when the nested
283+
* control is already at the scroll boundary.
284+
*/
285+
public static void forwardVerticalMouseWheelToParentScrollerAtBoundary(Scrollable scrollable) {
286+
scrollable.addListener(SWT.MouseWheel, event -> {
287+
if (event.count == 0 || scrollable.isDisposed()
288+
|| canScrollVertically(scrollable.getVerticalBar(), event.count)) {
289+
return;
290+
}
291+
292+
ScrolledComposite parentScroller = findParentScroller(scrollable);
293+
if (parentScroller != null
294+
&& canScrollVertically(parentScroller.getVerticalBar(), event.count)) {
295+
event.doit = false;
296+
scrollParentVertically(parentScroller, event.count);
297+
}
298+
});
299+
}
300+
301+
private static ScrolledComposite findParentScroller(Scrollable scrollable) {
302+
Composite parent = scrollable.getParent();
303+
while (parent != null) {
304+
if (parent instanceof ScrolledComposite scrolledComposite) {
305+
return scrolledComposite;
306+
}
307+
parent = parent.getParent();
308+
}
309+
return null;
310+
}
311+
312+
private static void scrollParentVertically(ScrolledComposite scrolledComposite, int wheelCount) {
313+
ScrollBar verticalBar = scrolledComposite.getVerticalBar();
314+
if (verticalBar == null || verticalBar.isDisposed()) {
315+
return;
316+
}
317+
318+
Point origin = scrolledComposite.getOrigin();
319+
int minimum = verticalBar.getMinimum();
320+
int maximum = Math.max(minimum,
321+
verticalBar.getMaximum() - verticalBar.getThumb());
322+
int delta = -wheelCount * Math.max(1, verticalBar.getIncrement());
323+
int nextY = Math.max(minimum, Math.min(maximum, origin.y + delta));
324+
scrolledComposite.setOrigin(origin.x, nextY);
325+
}
326+
327+
private static boolean canScrollVertically(ScrollBar verticalBar, int wheelCount) {
328+
if (verticalBar == null || verticalBar.isDisposed()
329+
|| !verticalBar.getEnabled()) {
330+
return false;
331+
}
332+
333+
int minimum = verticalBar.getMinimum();
334+
int maximum = Math.max(minimum,
335+
verticalBar.getMaximum() - verticalBar.getThumb());
336+
int selection = Math.max(minimum,
337+
Math.min(maximum, verticalBar.getSelection()));
338+
if (wheelCount > 0) {
339+
return selection > minimum;
340+
}
341+
return selection < maximum;
342+
}
343+
275344
/**
276345
* Copy the given text to the clipboard.
277346
*/

0 commit comments

Comments
 (0)