diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java index c55f99be603..7957f7e99d9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java @@ -2361,8 +2361,10 @@ void resizeBounds (int width, int height, boolean notify) { GDK.gdk_window_resize (enableWindow, width, height); } } - int boxWidth = width - 2*border; - int boxHeight = height - 2*border; + // GTK rejects negative allocations; a shell smaller than its own border must not + // leak a negative size into gtk_widget_size_allocate(). + int boxWidth = Math.max (0, width - 2*border); + int boxHeight = Math.max (0, height - 2*border); if ((style & SWT.RESIZE) == 0) { GTK.gtk_widget_set_size_request (vboxHandle, boxWidth, boxHeight); } diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Shell.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Shell.java index d16f1e47ae1..bebbe450e8d 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Shell.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Shell.java @@ -1054,4 +1054,24 @@ public void test_setLocationII() { } super.test_setLocationII(); } + +@Test +public void test_degenerateSizeDoesNotExpandShell() { + // A bordered popup asked for a height of 0 used to be allocated -1, which GTK rejects, + // so it fell back to its natural size with its content never laid out. See issue 3539. + // GTK4 backs these shells with a GtkPopover, which never went through that box maths + // and enforces a minimum height of its own. + assumeTrue(SwtTestUtil.isGTK && !SwtTestUtil.isGTK4()); + Shell popup = new Shell(shell, SWT.TOOL | SWT.ON_TOP); + popup.setLayout(new FillLayout()); + Button child = new Button(popup, SWT.PUSH); + child.setText("some content that is clearly taller than two pixels"); + popup.setSize(228, 0); + popup.setVisible(true); + SwtTestUtil.processEvents(); + Rectangle clientArea = popup.getClientArea(); + popup.dispose(); + assertTrue(clientArea.height >= 0, "negative client area: " + clientArea); + assertTrue(clientArea.height <= 2, "shell expanded to its natural size: " + clientArea); +} }