diff options
author | Simeon Andreev | 2018-04-13 08:48:11 +0000 |
---|---|---|
committer | Andrey Loskutov | 2018-04-16 17:47:21 +0000 |
commit | 802688f6202feab16b46f81f6e6b893c37341a30 (patch) | |
tree | e878d49c4b5a1b3668e3d7bcd0593b8b21ad3ae5 | |
parent | 28b870c25e2d6c47b6d9c9bf84183034f8c2535d (diff) | |
download | eclipse.platform.swt-802688f6202feab16b46f81f6e6b893c37341a30.tar.gz eclipse.platform.swt-802688f6202feab16b46f81f6e6b893c37341a30.tar.xz eclipse.platform.swt-802688f6202feab16b46f81f6e6b893c37341a30.zip |
Bug 533533 - [GTK3] Provide a way to disable fix for Control.print()
Bug 531667 reports a defect in Canvas.pring(GC). The fix provided for
531667 exposes a number of problems which were initially fixed for Bug
421127 (while breaking Canvas.pring(GC)). These problems were originally
caused by breaking API change between GTK 3.09 and GTK 3.10.
The known problems were fixed also in the context of Bug 531667. Since
the GTK API change has massive implications for SWT, there may be
further undiscovered defects.
This change provides a switch for the fixes done for Bug 531667, as a
last resort in case of severe defects that cannot be fixed (e.g. due to
a platform which cannot be changed). The fixes can be deactivated by
specifying -Dorg.eclipse.swt.internal.gtk.cairoContextReuse=false in the
command line arguments of Eclipse (e.g. via eclipse.ini).
Change-Id: I7722a1bb4afb4bf54ba2a6a1613c51de867ee0d9
Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
3 files changed, 37 insertions, 14 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index 85386b46e6..ec0375a0c2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -728,6 +728,27 @@ public class OS extends C { } } + /* Fix for Bug 421127 causes regression in Control.print(GC), namely Canvas.print(GC) doesn't work. + * To avoid dealing with breaking API change in GTK 3.10, the fix initializes a new Cairo object for each widget. + * Fixes for Bug 531667 ensures that the print method functions, by propagating the same Cairo object to each widget. + * Since any number of classes can be affected by this change, its not clear whether the present fixes are sufficient. + * We therefore add a kill switch for this patch, which is to be used as last resort + * in case of widget rendering problems due to incomplete fixes. + * + * Use by adding a VM argument: -Dorg.eclipse.swt.internal.gtk.cairoContextReuse=false + * + * For more information see: + * Bug 421127, Bug 531667 + */ + public static final boolean CAIRO_CONTEXT_REUSE; + static { + boolean cairoContextReuse = true; + if ("false".equals(System.getProperty("org.eclipse.swt.internal.gtk.cairoContextReuse"))) { + cairoContextReuse = false; + } + CAIRO_CONTEXT_REUSE = cairoContextReuse; + } + protected static byte [] ascii (String name) { int length = name.length (); char [] chars = new char [length]; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java index 609388db8e..e6c7bff4b1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java @@ -2029,7 +2029,7 @@ Rectangle getClippingInPixels() { /* Intersect visible bounds with clipping */ if (clipRgn != 0) { /* Convert clipping to device space if needed */ - if (data.clippingTransform != null && GTK.GTK_VERSION < OS.VERSION (3, 14, 0)) { + if (data.clippingTransform != null && (GTK.GTK_VERSION < OS.VERSION (3, 14, 0) || !OS.CAIRO_CONTEXT_REUSE)) { clipRgn = convertRgn(clipRgn, data.clippingTransform); GDK.gdk_region_intersect(rgn, clipRgn); GDK.gdk_region_destroy(clipRgn); @@ -2038,7 +2038,7 @@ Rectangle getClippingInPixels() { } } /* Convert to user space */ - if (cairo != 0 && GTK.GTK_VERSION < OS.VERSION (3, 14, 0)) { + if (cairo != 0 && (GTK.GTK_VERSION < OS.VERSION (3, 14, 0) || !OS.CAIRO_CONTEXT_REUSE)) { double[] matrix = new double[6]; Cairo.cairo_get_matrix(cairo, matrix); Cairo.cairo_matrix_invert(matrix); @@ -2087,7 +2087,7 @@ public void getClipping(Region region) { GDK.gdk_region_union_with_rect(clipping, rect); } else { /* Convert clipping to device space if needed */ - if (data.clippingTransform != null && GTK.GTK_VERSION < OS.VERSION (3, 14, 0)) { + if (data.clippingTransform != null && (GTK.GTK_VERSION < OS.VERSION (3, 14, 0) || !OS.CAIRO_CONTEXT_REUSE)) { long /*int*/ rgn = convertRgn(clipRgn, data.clippingTransform); GDK.gdk_region_union(clipping, rgn); GDK.gdk_region_destroy(rgn); @@ -2099,7 +2099,7 @@ public void getClipping(Region region) { GDK.gdk_region_intersect(clipping, data.damageRgn); } /* Convert to user space */ - if (cairo != 0 && GTK.GTK_VERSION < OS.VERSION (3, 14, 0)) { + if (cairo != 0 && (GTK.GTK_VERSION < OS.VERSION (3, 14, 0) || !OS.CAIRO_CONTEXT_REUSE)) { double[] matrix = new double[6]; Cairo.cairo_get_matrix(cairo, matrix); Cairo.cairo_matrix_invert(matrix); @@ -2487,7 +2487,7 @@ public void getTransform(Transform transform) { * They do not want to know about the global coordinates of their widget, which is contained in Cairo.cairo_get_matrix(). * So we return whatever the client specified with setTransform. */ - if (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0)) { + if (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0) && OS.CAIRO_CONTEXT_REUSE) { if (currentTransform != null) { transform.handle = currentTransform.clone(); } else { @@ -2586,7 +2586,7 @@ void init(Drawable drawable, GCData data, long /*int*/ gdkGC) { initCairo(); if ((data.style & SWT.MIRRORED) != 0) { // Don't overwrite the Cairo transformation matrix in GTK 3.14 and above; it contains a translation relative to the parent widget. - if (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0)) { + if (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0) && OS.CAIRO_CONTEXT_REUSE) { int[] w = new int[1], h = new int[1]; getSize(w, h); Cairo.cairo_translate(cairo, w[0], 0); @@ -2595,9 +2595,11 @@ void init(Drawable drawable, GCData data, long /*int*/ gdkGC) { Cairo.cairo_set_matrix(data.cairo, identity()); } } - if (cairoTransformationMatrix == null) cairoTransformationMatrix = new double[6]; - Cairo.cairo_get_matrix(data.cairo, cairoTransformationMatrix); - clipping = getClipping(); + if (OS.CAIRO_CONTEXT_REUSE) { + if (cairoTransformationMatrix == null) cairoTransformationMatrix = new double[6]; + Cairo.cairo_get_matrix(data.cairo, cairoTransformationMatrix); + clipping = getClipping(); + } } void initCairo() { @@ -2916,7 +2918,7 @@ void setCairoClip(long /*int*/ damageRgn, long /*int*/ clipRgn) { * The Cairo handle is shared by all widgets, but GC.setClipping allows global clipping changes. * So we intersect whatever the client sets with the initial GC clipping. */ - if (GTK.GTK_VERSION >= OS.VERSION(3, 14, 0)) { + if (GTK.GTK_VERSION >= OS.VERSION(3, 14, 0) && OS.CAIRO_CONTEXT_REUSE) { limitClipping(clipRgnCopy); } @@ -2992,7 +2994,7 @@ void setClipping(long /*int*/ clipRgn) { if (data.clipRgn == 0) data.clipRgn = GDK.gdk_region_new(); GDK.gdk_region_subtract(data.clipRgn, data.clipRgn); GDK.gdk_region_union(data.clipRgn, clipRgn); - if (GTK.GTK_VERSION < OS.VERSION (3, 14, 0)) { + if (GTK.GTK_VERSION < OS.VERSION (3, 14, 0) || !OS.CAIRO_CONTEXT_REUSE) { if (data.clippingTransform == null) data.clippingTransform = new double[6]; Cairo.cairo_get_matrix(cairo, data.clippingTransform); } @@ -3108,7 +3110,7 @@ void setClippingInPixels(Rectangle rect) { } private void resetClipping() { - if (GTK.GTK_VERSION >= OS.VERSION(3, 14, 0)) { + if (GTK.GTK_VERSION >= OS.VERSION(3, 14, 0) && OS.CAIRO_CONTEXT_REUSE) { /* * Bug 531667: widgets paint over other widgets * @@ -3712,7 +3714,7 @@ public void setTransform(Transform transform) { if (data.cairo == 0 && transform == null) return; initCairo(); long /*int*/ cairo = data.cairo; - if (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0)) { + if (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0) && OS.CAIRO_CONTEXT_REUSE) { // Re-set the original Cairo transformation matrix: it contains a translation relative to the parent widget. if (currentTransform != null) { Cairo.cairo_set_matrix(cairo, cairoTransformationMatrix); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 61a9d0d311..2b42fefd28 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -3583,7 +3583,7 @@ long /*int*/ gtk_draw (long /*int*/ widget, long /*int*/ cairo) { event.setBounds (eventBounds); GCData data = new GCData (); // data.damageRgn = gdkEvent.region; - if (GTK.GTK_VERSION <= OS.VERSION (3, 9, 0) || GTK.GTK_VERSION >= OS.VERSION (3, 14, 0)) { + if (GTK.GTK_VERSION <= OS.VERSION (3, 9, 0) || (GTK.GTK_VERSION >= OS.VERSION (3, 14, 0) && OS.CAIRO_CONTEXT_REUSE)) { data.cairo = cairo; } GC gc = event.gc = GC.gtk_new (this, data); |