Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2019-07-24 14:49:48 +0000
committerEric Williams2019-07-31 19:31:29 +0000
commit133ff2c44262645cab8b617b0cf983f04cad10ed (patch)
tree380b55125903d96f51df5dba117543eab3508246
parent007b221587caa5b7cb16ad14189f664a13456262 (diff)
downloadeclipse.platform.swt-133ff2c44262645cab8b617b0cf983f04cad10ed.tar.gz
eclipse.platform.swt-133ff2c44262645cab8b617b0cf983f04cad10ed.tar.xz
eclipse.platform.swt-133ff2c44262645cab8b617b0cf983f04cad10ed.zip
Bug 546490: [GTK] Incorrect Table/Tree size
Address Tree sizing issues. The majority of the issues stem from the fact that GTK reports a 1x1 size for Widgets which are not visible. This afflicts columns in Trees/Tables, and throws of computeSize() values. This patch addresses this by initially setting the column buttons visible whenever doing a pack() or computeSize() operation. Further more, GtkScrolledWindows without scrollbars sometimes do not change their size, likely due to caching. In order to work around, we check if the Tree has an initial computed height equalling the header height, and bump that height by 1px to trigger a resize. Tested on GTK3.24 on X11 and Wayland. No AllNonBrowser JUnit tests fail. Change-Id: I7e6bc4940e9b026a30b81e1993ab09c7d5332753 Signed-off-by: Eric Williams <ericwill@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java34
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java6
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug546490_TreeSizingIssues.java141
3 files changed, 174 insertions, 7 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
index 77975e12c4..7145a599e8 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
@@ -89,6 +89,8 @@ public class Tree extends Composite {
TreeItem currentItem;
ImageList imageList, headerImageList;
boolean firstCustomDraw;
+ /** True iff computeSize has never been called on this Tree */
+ boolean firstCompute = true;
boolean modelChanged;
boolean expandAll;
int drawState, drawFlags;
@@ -600,9 +602,20 @@ Point computeSizeInPixels (int wHint, int hHint, boolean changed) {
checkWidget ();
if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
+ /*
+ * Set all the TreeColumn buttons visible otherwise
+ * gtk_widget_get_preferred_size() will not take their size
+ * into account.
+ */
+ if (firstCompute) {
+ for (int x = 0; x < columns.length; x++) {
+ TreeColumn column = columns[x];
+ if (column != null) GTK.gtk_widget_set_visible(column.buttonHandle, true);
+ }
+ firstCompute = false;
+ }
GTK.gtk_widget_realize(handle);
Point size = computeNativeSize (handle, wHint, hHint, changed);
- if (size.x == 0 && wHint == SWT.DEFAULT) size.x = DEFAULT_WIDTH;
/*
* In GTK 3, computeNativeSize(..) sometimes just returns the header
@@ -616,14 +629,21 @@ Point computeSizeInPixels (int wHint, int hHint, boolean changed) {
size.y = getItemCount() * getItemHeightInPixels() + getHeaderHeight();
}
- /*
- * In case the table doesn't contain any elements,
- * getItemCount returns 0 and size.y will be 0
- * so need to assign default height
- */
- if (size.y == 0 && hHint == SWT.DEFAULT) size.y = DEFAULT_HEIGHT;
Rectangle trim = computeTrimInPixels (0, 0, size.x, size.y);
size.x = trim.width;
+ /*
+ * Feature in GTK: sometimes GtkScrolledWindow's with no scrollbars
+ * won't automatically adjust their size. This happens when a Tree
+ * has a header, and the initial computed height was the height of
+ * the of the header.
+ *
+ * The fix is to increment the height by 1 in order to force a size
+ * update for the parent GtkScrollWindow, otherwise the headers
+ * will not be shown. This only happens once, see bug 546490.
+ */
+ if (size.y == this.headerHeight && this.headerVisible && (style & SWT.NO_SCROLL) != 0) {
+ trim.height = trim.height + 1;
+ }
size.y = trim.height;
return size;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java
index 42b7185fc5..ec30bbe978 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeColumn.java
@@ -447,6 +447,12 @@ public void pack () {
int width = 0;
if (buttonHandle != 0) {
GtkRequisition requisition = new GtkRequisition ();
+ /*
+ * Check if the header button is hidden, otherwise GTK will
+ * return a 1x1 size. See bug 546490.
+ */
+ boolean visible = GTK.gtk_widget_get_visible(buttonHandle);
+ if (!visible) GTK.gtk_widget_set_visible(buttonHandle, !visible);
gtk_widget_get_preferred_size (buttonHandle, requisition);
width = requisition.width;
}
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug546490_TreeSizingIssues.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug546490_TreeSizingIssues.java
new file mode 100644
index 0000000000..90a69c6d23
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug546490_TreeSizingIssues.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Patrick Tasse and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Patrick Tasse - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+public class Bug546490_TreeSizingIssues {
+
+ private static final int NUM_COL = 5;
+ private static final int NUM_ROW = 5;
+
+ public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+
+ shell.setLayout(new RowLayout(SWT.VERTICAL));
+
+ Label label1 = new Label(shell, SWT.NONE);
+ label1.setText("Tree #1 with no items, 5 columns packed");
+ Tree tree1 = new Tree(shell, SWT.NO_SCROLL);
+ tree1.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
+ tree1.setHeaderVisible(true);
+ tree1.setLinesVisible(true);
+ for (int col = 0; col < NUM_COL; col++) {
+ TreeColumn column = new TreeColumn(tree1, SWT.CENTER);
+ column.setText("Column " + col);
+ column.pack();
+ }
+
+ Label label2 = new Label(shell, SWT.NONE);
+ label2.setText("Tree #2 with no items, 5 columns width=0");
+ Tree tree2 = new Tree(shell, SWT.NO_SCROLL);
+ tree2.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
+ tree2.setHeaderVisible(true);
+ tree2.setLinesVisible(true);
+ for (int col = 0; col < NUM_COL; col++) {
+ TreeColumn column = new TreeColumn(tree2, SWT.CENTER);
+ column.setText("Column " + col);
+ column.setWidth(0);
+ }
+
+ Label label3 = new Label(shell, SWT.NONE);
+ label3.setText("Tree #3 with no items, 5 columns width=100");
+ Tree tree3 = new Tree(shell, SWT.NO_SCROLL);
+ tree3.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
+ tree3.setHeaderVisible(true);
+ tree3.setLinesVisible(true);
+ for (int col = 0; col < NUM_COL; col++) {
+ TreeColumn column = new TreeColumn(tree3, SWT.CENTER);
+ column.setText("Column " + col);
+ column.setWidth(100);
+ }
+
+ Label label4 = new Label(shell, SWT.NONE);
+ label4.setText("Tree #4 with 5 items, 5 columns width=100");
+ Tree tree4 = new Tree(shell, SWT.NO_SCROLL);
+ tree4.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
+ tree4.setHeaderVisible(true);
+ tree4.setLinesVisible(true);
+ for (int col = 0; col < NUM_COL; col++) {
+ TreeColumn column = new TreeColumn(tree4, SWT.CENTER);
+ column.setText("Column " + col);
+ column.setWidth(100);
+ }
+ for (int row = 1; row <= NUM_ROW; row++) {
+ TreeItem item = new TreeItem(tree4, SWT.NONE);
+ if (row % 2 == 0) {
+ item.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
+ } else {
+ item.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
+ }
+ for (int col = 0; col < NUM_COL; col++) {
+ item.setText(col, "R" + row + "C" + col);
+ }
+ }
+
+ Label label5 = new Label(shell, SWT.NONE);
+ label5.setText("Tree #5 with 5 items, 5 columns packed");
+ Tree tree5 = new Tree(shell, SWT.NO_SCROLL);
+ tree5.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
+ tree5.setHeaderVisible(true);
+ tree5.setLinesVisible(true);
+ for (int col = 0; col < NUM_COL; col++) {
+ TreeColumn column = new TreeColumn(tree5, SWT.CENTER);
+ column.setText("Column " + col);
+ }
+ for (int row = 1; row <= NUM_ROW; row++) {
+ TreeItem item = new TreeItem(tree5, SWT.NONE);
+ if (row % 2 == 0) {
+ item.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
+ } else {
+ item.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
+ }
+ for (int col = 0; col < NUM_COL; col++) {
+ item.setText(col, "R" + row + "C" + col);
+ }
+ }
+ for (TreeColumn column : tree5.getColumns()) {
+ column.pack();
+ }
+
+ Label label = new Label(shell, SWT.NONE);
+ label.setText("Resize shell to see tree sizes change!");
+
+ shell.setText("Tree, never resized");
+ shell.pack();
+ shell.open();
+ shell.addControlListener(new ControlAdapter() {
+ @Override
+ public void controlResized(ControlEvent e) {
+ shell.setText("Tree, has been resized");
+ }
+ });
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ display.dispose();
+ }
+} \ No newline at end of file

Back to the top