diff options
author | Eric Williams | 2018-06-14 16:16:46 +0000 |
---|---|---|
committer | Eric Williams | 2018-06-20 17:38:10 +0000 |
commit | 265c4b7facd5e415064af4d73f364f15b6fb10cd (patch) | |
tree | 59a8fc01dabceaa7ec692faf416befd9c1459b44 | |
parent | 3f113f62ad723f939fc4b4f97642cff8c2a814c6 (diff) | |
download | eclipse.platform.swt-265c4b7facd5e415064af4d73f364f15b6fb10cd.tar.gz eclipse.platform.swt-265c4b7facd5e415064af4d73f364f15b6fb10cd.tar.xz eclipse.platform.swt-265c4b7facd5e415064af4d73f364f15b6fb10cd.zip |
Bug 535124: CSS tree selection issue on Linux only
This patch reverts some changes made to custom drawn Trees which fixed
bugs on lower versions of GTK3 (3.14 and below). Unfortunately these
changes broke some basic Tree selection background/foreground drawing.
On GTK3 we need to use the clipping from the cairo context provided by
the gtk_cell_renderer_render() function. It provides the x and width
values. The y and height values can continue to be fetched via
gtk_tree_view_get_background_area().
Tested on GTK3.22 with the sample project provided in the bug report,
and the snippet attached to this patch. Testing in a child Eclipse shows
no ill effects in the call hierarchy, open type dialog, package
explorer, etc. No AllNonBrowser JUnit tests fail.
Change-Id: I57933468313376f6d3735644fc9a5eb19fee3c99
Signed-off-by: Eric Williams <ericwill@redhat.com>
2 files changed, 76 insertions, 15 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 6d05e95570..4de1357b69 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 @@ -3004,8 +3004,8 @@ void rendererRender (long /*int*/ cell, long /*int*/ cr, long /*int*/ window, lo long /*int*/ path = GTK.gtk_tree_model_get_path (modelHandle, iter); GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect); GTK.gtk_tree_path_free (path); - // A workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=459117 - if (cr != 0 && GTK.GTK_VERSION > OS.VERSION(3, 9, 0) && GTK.GTK_VERSION <= OS.VERSION(3, 14, 8)) { + // Use the x and width information from the Cairo context. See bug 535124. + if (cr != 0 && GTK.GTK3) { GdkRectangle r2 = new GdkRectangle (); GDK.gdk_cairo_get_clip_rectangle (cr, r2); rect.x = r2.x; @@ -3065,15 +3065,11 @@ void rendererRender (long /*int*/ cell, long /*int*/ cr, long /*int*/ window, lo gc.setFont (item.getFont (columnIndex)); if ((style & SWT.MIRRORED) != 0) rect.x = getClientWidth () - rect.width - rect.x; - if (GTK.GTK_VERSION >= OS.VERSION(3, 9, 0) && cr != 0) { - GdkRectangle r = new GdkRectangle(); - GDK.gdk_cairo_get_clip_rectangle(cr, r); - Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, r.y, r.width, r.height)); - // Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075 + if (GTK.GTK3 && cr != 0) { + // Use the original rectangle, not the Cairo clipping for the y, width, and height values. + // See bug 535124. + Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height)); gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height); - if (GTK.GTK_VERSION <= OS.VERSION(3, 14, 8)) { - rect.width = r.width; - } } else { Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height)); // Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075 @@ -3148,8 +3144,8 @@ void rendererRender (long /*int*/ cell, long /*int*/ cr, long /*int*/ window, lo long /*int*/ path = GTK.gtk_tree_model_get_path (modelHandle, iter); GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect); GTK.gtk_tree_path_free (path); - // A workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=459117 - if (cr != 0 && GTK.GTK_VERSION > OS.VERSION(3, 9, 0) && GTK.GTK_VERSION <= OS.VERSION(3, 14, 8)) { + // Use the x and width information from the Cairo context. See bug 535124. + if (cr != 0 && GTK.GTK3) { GdkRectangle r2 = new GdkRectangle (); GDK.gdk_cairo_get_clip_rectangle (cr, r2); rect.x = r2.x; @@ -3166,9 +3162,8 @@ void rendererRender (long /*int*/ cell, long /*int*/ cr, long /*int*/ window, lo Rectangle bounds = image.getBounds (); imageWidth = bounds.width; } - // On gtk >3.9 and <3.14.8 the clip rectangle does not have image area into clip rectangle - // need to adjust clip rectangle with image width - if (cr != 0 && GTK.GTK_VERSION > OS.VERSION(3, 9, 0) && GTK.GTK_VERSION <= OS.VERSION(3, 14, 8)) { + // Account for the image width on GTK3, see bug 535124. + if (cr != 0 && GTK.GTK3) { rect.x -= imageWidth; rect.width +=imageWidth; } diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535124_TreeSelection.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535124_TreeSelection.java new file mode 100644 index 0000000000..cea0224be5 --- /dev/null +++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug535124_TreeSelection.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.widgets.Display; +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 Bug535124_TreeSelection { + + public static void main(String[] args) { + Display display = new Display (); + Shell shell = new Shell(display); + final Color red = display.getSystemColor(SWT.COLOR_RED); + final Color yellow = display.getSystemColor(SWT.COLOR_YELLOW); + final Tree tree = new Tree(shell, SWT.FULL_SELECTION); + tree.setHeaderVisible(true); + new TreeColumn(tree, SWT.NONE).setWidth(100); + new TreeColumn(tree, SWT.NONE).setWidth(100); + new TreeColumn(tree, SWT.NONE).setWidth(100); + for (int i = 0; i < 5; i++) { + TreeItem item = new TreeItem(tree, SWT.NONE); + item.setText(0, "item " + i + " col 0"); + item.setText(1, "item " + i + " col 1"); + item.setText(2, "item " + i + " col 2"); + } + tree.pack(); + tree.addListener(SWT.EraseItem, event -> { + event.detail &= ~SWT.HOT; + if ((event.detail & SWT.SELECTED) == 0) { + return; /* item not selected */ + } + int clientWidth = tree.getClientArea().width; + GC gc = event.gc; + Color oldForeground = gc.getForeground(); + Color oldBackground = gc.getBackground(); + gc.setForeground(red); + gc.setBackground(yellow); + gc.fillGradientRectangle(0, event.y, clientWidth, event.height, false); + gc.setForeground(oldForeground); + gc.setBackground(oldBackground); + event.detail &= ~SWT.SELECTED; + }); + shell.pack(); + shell.open(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + display.dispose(); + } + +}
\ No newline at end of file |