Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java55
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java75
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535323_ComboSizing.java46
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535657_MultipleComboOverlap.java79
4 files changed, 212 insertions, 43 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
index 4718fa2440..ff043982c2 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java
@@ -662,6 +662,34 @@ long /*int*/ findPopupHandle (long /*int*/ oldList) {
return result;
}
+@Override
+Point resizeCalculationsGTK3 (long /*int*/ widget, int width, int height) {
+ Point sizes = new Point (width, height);
+ /*
+ * Feature in GTK3.20+: size calculations take into account GtkCSSNode
+ * elements which we cannot access. If the to-be-allocated size minus
+ * these elements is < 0, allocate the preferred size instead. See bug 486068.
+ */
+ if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0) && widget == handle) {
+ GtkRequisition minimumSize = new GtkRequisition();
+ GtkRequisition naturalSize = new GtkRequisition();
+ // Use the handle only for READ_ONLY Combos, otherwise use the GtkEntry
+ long /*int*/ preferredSizeHandle = ((style & SWT.READ_ONLY) == 0 && entryHandle != 0) ? entryHandle : handle;
+ GTK.gtk_widget_get_preferred_size(preferredSizeHandle, minimumSize, naturalSize);
+ /*
+ * Use the smallest of the minimum/natural sizes to prevent oversized
+ * widgets.
+ */
+ int smallestWidth = Math.min(minimumSize.width, naturalSize.width);
+ int smallestHeight = Math.min(minimumSize.height, naturalSize.height);
+ sizes.x = (width - (smallestWidth - width)) < 0 ? smallestWidth : width;
+ sizes.y = (height - (smallestHeight - height)) < 0 ? smallestHeight : height;
+ return sizes;
+ } else {
+ return super.resizeCalculationsGTK3(widget, width, height);
+ }
+}
+
long /*int*/ findButtonHandle() {
/*
* Feature in GTK. There is no API to query the button
@@ -1423,25 +1451,30 @@ long /*int*/ gtk_delete_text (long /*int*/ widget, long /*int*/ start_pos, long
@Override
long /*int*/ gtk_draw (long /*int*/ widget, long /*int*/ cairo) {
/*
- * Feature in GTK3.20+: READ_ONLY Combos have their clip unioned
+ * Feature in GTK3.20+: Combos have their clip unioned
* with the parent container (Composite in this case). This causes
* overdrawing into neighbouring widgets and breaks resizing.
*
- * The fix is to adjust the clip and allocation of the Combo and its children
+ * The fix is to adjust the clip and allocation of the Combo (and its children)
* in the parent Composite's draw handler, as it ensures that the draw events
* going to the Combo have the correct geometry specifications. This has to
* happen in the parent Composite since neighouring widgets that share the
* same parent are affected. See bug 500703.
+ *
+ * An additional fix was implemented to support non-READ_ONLY Combos, as well
+ * as the case when one Composite has multiple Combos within it -- see bug 535323.
*/
- if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0) && (style & SWT.READ_ONLY) != 0) {
- if (parent != null && parent.fixClipHandle == 0) {
- long /*int*/ parentHandle = GTK.gtk_widget_get_parent(fixedHandle);
- if (parentHandle != 0) {
- parent.fixClipHandle = parentHandle;
- GTK.gtk_widget_queue_draw(parentHandle);
- long [] /*int*/ array = {fixedHandle, handle, buttonBoxHandle, buttonHandle, cellBoxHandle, cellHandle};
- parent.fixClipHandleChildren = new long /*int*/ [array.length];
- System.arraycopy (array, 0, parent.fixClipHandleChildren, 0, array.length);
+ if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
+ long /*int*/ parentHandle = GTK.gtk_widget_get_parent(fixedHandle);
+ if (parentHandle != 0) {
+ if (parent.fixClipHandle == 0) parent.fixClipHandle = parentHandle;
+ GTK.gtk_widget_queue_draw(parentHandle);
+ if ((style & SWT.READ_ONLY) != 0) {
+ long /*int*/ [] array = {fixedHandle, handle, buttonBoxHandle, buttonHandle, cellBoxHandle, cellHandle};
+ parent.fixClipMap.put(this, array);
+ } else {
+ long /*int*/ [] array = {fixedHandle, handle, entryHandle, buttonBoxHandle, buttonHandle};
+ parent.fixClipMap.put(this, array);
}
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
index ed35e96db8..cf786af88b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java
@@ -11,6 +11,8 @@
package org.eclipse.swt.widgets;
+import java.util.*;
+
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
@@ -72,13 +74,15 @@ public class Composite extends Scrollable {
*/
long /*int*/ fixClipHandle;
/**
- * If fixClipHandle is set, fixClipArray can contain additional child widgets
- * that also need to have their clips adjusted.
+ * If fixClipHandle is set, then the fixClipMap HashMap contains children
+ * of fixClipHandle that also need to have their clips adjusted.
*
- * <p>The array <b>must</b> be ordered by widget hierarchy, as this array will be
- * traversed in-order to adjust the clipping of each element. See bug 500703.</p>
+ * <p>Each key is a Control which needs to have its clip adjusted, and each value
+ * is an array of handles (descendants of the Control) ordered by widget hierarchy.
+ * This array will be traversed in-order to adjust the clipping of each element.
+ * See bug 500703 and 535323.</p>
*/
- long /*int*/ [] fixClipHandleChildren = {};
+ Map<Control, long /*int*/ []> fixClipMap = new HashMap<> ();
static final String NO_INPUT_METHOD = "org.eclipse.swt.internal.gtk.noInputMethod"; //$NON-NLS-1$
@@ -356,41 +360,48 @@ void createHandle (int index, boolean fixed, boolean scrolled) {
* <p>If the array is empty this method just returns. See bug 500703.</p>
*/
void fixChildClippings () {
- if (fixClipHandleChildren == null) {
+ if (fixClipHandle == 0 || fixClipMap.isEmpty()) {
return;
} else {
GtkRequisition minimumSize = new GtkRequisition ();
GtkRequisition naturalSize = new GtkRequisition ();
GtkAllocation clip = new GtkAllocation ();
GtkAllocation allocation = new GtkAllocation ();
- for (long /*int*/ widget : fixClipHandleChildren) {
- GTK.gtk_widget_get_allocation(widget, allocation);
- GTK.gtk_widget_get_clip(widget, clip);
- /*
- * If the clip is negative, add the x coordinate to the width
- * and set the x coordinate to 0.
- */
- if (clip.x < 0) {
- clip.width = clip.width + clip.x;
- clip.x = 0;
- /*
- * Some "transient" widgets like menus get allocations of
- * {-1, -1, 1, 1}. Check to make sure this isn't the case
- * before proceeding.
- */
- if (allocation.x < -1 && (allocation.width > 1 || allocation.height > 1)) {
- // Adjust the allocation just like the clip, if it's negative
- allocation.width = allocation.width + allocation.x;
- allocation.x = 0;
- // Call gtk_widget_get_preferred_size() to prevent warnings
- GTK.gtk_widget_get_preferred_size(widget, minimumSize, naturalSize);
- // Allocate and queue a resize event
- GTK.gtk_widget_size_allocate(widget, allocation);
- GTK.gtk_widget_queue_resize(widget);
+ Control [] children = _getChildren();
+ for (Control child : children) {
+ if (fixClipMap.containsKey(child)) {
+ long /*int*/ [] childHandles = fixClipMap.get(child);
+ for (long /*int*/ widget : childHandles) {
+ GTK.gtk_widget_get_allocation(widget, allocation);
+ GTK.gtk_widget_get_clip(widget, clip);
+ /*
+ * If the clip is negative, add the x coordinate to the width
+ * and set the x coordinate to 0.
+ */
+ if (clip.x < 0) {
+ clip.width = clip.width + clip.x;
+ clip.x = 0;
+ /*
+ * Some "transient" widgets like menus get allocations of
+ * {-1, -1, 1, 1}. Check to make sure this isn't the case
+ * before proceeding.
+ */
+ if (allocation.x < -1 && (allocation.width > 1 || allocation.height > 1)) {
+ // Adjust the allocation just like the clip, if it's negative
+ allocation.width = allocation.width + allocation.x;
+ allocation.x = 0;
+ // Call gtk_widget_get_preferred_size() to prevent warnings
+ GTK.gtk_widget_get_preferred_size(widget, minimumSize, naturalSize);
+ // Allocate and queue a resize event
+ GTK.gtk_widget_size_allocate(widget, allocation);
+ GTK.gtk_widget_queue_resize(widget);
+ }
+ }
+ // Adjust the clip
+ GTK.gtk_widget_set_clip(widget, allocation);
+
}
}
- // Adjust the clip
- GTK.gtk_widget_set_clip(widget, allocation);
}
}
}
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535323_ComboSizing.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535323_ComboSizing.java
new file mode 100644
index 0000000000..374ebecc51
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535323_ComboSizing.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class Bug535323_ComboSizing {
+
+ public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ Rectangle clientArea = shell.getClientArea();
+ Combo combo1 = new Combo(shell, SWT.BORDER);
+ combo1.setItems("Alpha", "Bravo", "Charlie");
+ Point prefSize = combo1.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ combo1.setBounds(clientArea.x, clientArea.y, prefSize.x, prefSize.y);
+ Combo combo2 = new Combo(shell, SWT.BORDER);
+ combo2.setItems("Alpha", "Bravo", "Charlie");
+ combo2.setBounds(clientArea.x, clientArea.y, prefSize.x, prefSize.y);
+ combo2.setBounds(clientArea.x, clientArea.y + prefSize.y, (prefSize.x / 2) - 1, prefSize.y);
+ Combo combo3 = new Combo(shell, SWT.BORDER);
+ combo3.setItems("Alpha", "Bravo", "Charlie");
+ combo3.setBounds(clientArea.x, clientArea.y + prefSize.y * 2, (prefSize.x / 2) + 1, prefSize.y);
+ shell.pack();
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+
+} \ No newline at end of file
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535657_MultipleComboOverlap.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535657_MultipleComboOverlap.java
new file mode 100644
index 0000000000..de17159453
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535657_MultipleComboOverlap.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+public class Bug535657_MultipleComboOverlap {
+
+ public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setSize(400, 200);
+ shell.setText("Bug_odd_combos_on_resize");
+ shell.setLayout(new GridLayout());
+
+ createGroup(shell);
+
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+
+ private static void createGroup(Composite parent) {
+ Group group = new Group(parent, SWT.SHADOW_IN);
+
+ group.setText("some group");
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
+ gridData.horizontalSpan = 2;
+ group.setLayoutData(gridData);
+
+ GridLayout gridLayout = new GridLayout(2, false);
+ group.setLayout(gridLayout);
+
+ class LabelAndText {
+ String labelText;
+ String comboItem;
+
+ LabelAndText(String labelText, String comboItem) {
+ this.labelText = labelText;
+ this.comboItem = comboItem;
+ }
+ }
+
+ LabelAndText[] texts = {
+ new LabelAndText("Some label text: ", "some text"),
+ new LabelAndText("Some label text: ", "some long combo text"),
+ new LabelAndText("Some label text: ", "some text"),
+ };
+
+ for (LabelAndText text : texts) {
+ Label label = new Label(group, SWT.NONE);
+ label.setText(text.labelText);
+ Combo combo = new Combo(group, SWT.READ_ONLY | SWT.DROP_DOWN);
+ GridData comboGridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
+ combo.setLayoutData(comboGridData);
+ combo.add(text.comboItem);
+ }
+ }
+} \ No newline at end of file

Back to the top