Skip to content

Commit 05ec74d

Browse files
vogellaclaude
andcommitted
[GTK3] Remove show_arrow toggle workaround in ToolBar.computeSize
Remove the gtk_toolbar_set_show_arrow toggle in computeSizeInPixels that was added in 2012 (Bug 46025) to work around a GTK3 sizing bug where the toolbar reported only the overflow arrow width. This workaround causes two GTK state transitions per measurement, each triggering gtk_widget_queue_resize -> gtk_widget_queue_draw -> gdk_window_invalidate_region. When a SWT.WRAP ToolBar sits inside a frequently-measured parent (e.g. CTabFolder.setTopRight), this creates a self-sustaining ~60 Hz repaint loop that burns 10-25% CPU while idle. The original GTK3 sizing bug dates from GTK 3.4 era. Modern GTK 3.24 computes preferred size correctly without the show_arrow dance. Also adds Snippet394 to verify ToolBar.computeSize with SWT.WRAP returns correct dimensions without the workaround. Fixes #3236 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d40a72f commit 05ec74d

2 files changed

Lines changed: 93 additions & 17 deletions

File tree

  • bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets
  • examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -177,23 +177,7 @@ Point computeSizeInPixels (int wHint, int hHint, boolean changed) {
177177
if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
178178
if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
179179

180-
Point size = null;
181-
182-
if (GTK.GTK4) {
183-
size = computeNativeSize (handle, wHint, hHint, changed);
184-
} else {
185-
/*
186-
* Feature in GTK. Size of toolbar is calculated incorrectly
187-
* and appears as just the overflow arrow, if the arrow is enabled
188-
* to display. The fix is to disable it before the computation of
189-
* size and enable it if WRAP style is set.
190-
*/
191-
GTK3.gtk_toolbar_set_show_arrow (handle, false);
192-
size = computeNativeSize (handle, wHint, hHint, changed);
193-
if ((style & SWT.WRAP) != 0) GTK3.gtk_toolbar_set_show_arrow (handle, true);
194-
}
195-
196-
return size;
180+
return computeNativeSize (handle, wHint, hHint, changed);
197181
}
198182

199183
@Override
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Eclipse Foundation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Eclipse Foundation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.swt.snippets;
15+
16+
import org.eclipse.swt.*;
17+
import org.eclipse.swt.graphics.*;
18+
import org.eclipse.swt.layout.*;
19+
import org.eclipse.swt.widgets.*;
20+
21+
/**
22+
* ToolBar computeSize test: verify whether the GTK3 toolbar sizing bug
23+
* (toolbar reports only the overflow arrow width when show_arrow is enabled)
24+
* is still present.
25+
*
26+
* <p>This snippet creates a ToolBar with several items and compares the
27+
* computed size with and without the SWT.WRAP style. If the GTK bug is fixed,
28+
* both sizes should be similar. If the bug is still present, the WRAP toolbar
29+
* will report a much smaller width (just the arrow).
30+
*
31+
* <p>See https://github.com/eclipse-platform/eclipse.platform.swt/issues/3236
32+
*
33+
* <p>For a list of all SWT example snippets see
34+
* https://eclipse.dev/eclipse/swt/snippets/
35+
*/
36+
public class Snippet394 {
37+
38+
public static void main(String[] args) {
39+
Display display = new Display();
40+
Shell shell = new Shell(display);
41+
shell.setText("Snippet 394 - ToolBar computeSize with WRAP");
42+
shell.setLayout(new GridLayout(1, false));
43+
44+
// Create a toolbar WITHOUT SWT.WRAP
45+
ToolBar toolBarNoWrap = new ToolBar(shell, SWT.FLAT | SWT.RIGHT);
46+
addItems(toolBarNoWrap);
47+
48+
// Create a toolbar WITH SWT.WRAP
49+
ToolBar toolBarWrap = new ToolBar(shell, SWT.FLAT | SWT.RIGHT | SWT.WRAP);
50+
addItems(toolBarWrap);
51+
52+
// Compute sizes
53+
Point sizeNoWrap = toolBarNoWrap.computeSize(SWT.DEFAULT, SWT.DEFAULT);
54+
Point sizeWrap = toolBarWrap.computeSize(SWT.DEFAULT, SWT.DEFAULT);
55+
56+
// Display results
57+
Label resultLabel = new Label(shell, SWT.WRAP);
58+
resultLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
59+
StringBuilder sb = new StringBuilder();
60+
sb.append("ToolBar without WRAP: " + sizeNoWrap.x + " x " + sizeNoWrap.y + "\n");
61+
sb.append("ToolBar with WRAP: " + sizeWrap.x + " x " + sizeWrap.y + "\n\n");
62+
63+
int widthDiff = Math.abs(sizeNoWrap.x - sizeWrap.x);
64+
if (widthDiff > sizeNoWrap.x / 2) {
65+
sb.append("RESULT: Large width difference (" + widthDiff + "px). "
66+
+ "The GTK sizing bug may still be present.\n"
67+
+ "The WRAP toolbar is likely reporting only the arrow width.");
68+
} else {
69+
sb.append("RESULT: Widths are similar (diff=" + widthDiff + "px). "
70+
+ "The GTK sizing bug appears to be fixed.");
71+
}
72+
resultLabel.setText(sb.toString());
73+
74+
// Also print to console
75+
System.out.println(sb);
76+
77+
shell.pack();
78+
shell.open();
79+
while (!shell.isDisposed()) {
80+
if (!display.readAndDispatch()) display.sleep();
81+
}
82+
display.dispose();
83+
}
84+
85+
private static void addItems(ToolBar toolBar) {
86+
for (int i = 0; i < 5; i++) {
87+
ToolItem item = new ToolItem(toolBar, SWT.PUSH);
88+
item.setText("Action " + (i + 1));
89+
}
90+
}
91+
92+
}

0 commit comments

Comments
 (0)