f2e612a
From daefb444e2757b0fda729cafbeea7c19efa979a3 Mon Sep 17 00:00:00 2001
f2e612a
From: Eric Williams
f2e612a
Date: Thu, 26 Nov 2015 08:46:27 -0500
f2e612a
Subject: Bug 479998: [GTK3] Form/wizard Composites have incorrect background
f2e612a
 colors
f2e612a
f2e612a
As of GTK3.16 gtk_widget_override_background_color() is deprecated.
f2e612a
Unfortunately in GTK3.18 it has started to break the background colors
f2e612a
of SwtFixed containers. This is most notably visible in the workspace
f2e612a
selection and commit dialogs, where some background containers had the
f2e612a
default gray background color when they should have been white.
f2e612a
f2e612a
This fix overrides the draw signal in Composite, which allows for CSS
f2e612a
rendering of the background color using gtk_render_background(), which
f2e612a
is the recommended fix as per the GTK team's changes. This ensures that
f2e612a
every composite is drawn with the correct background color if it is set. 
f2e612a
f2e612a
The only additional side effect is that ToolBar background colors need
f2e612a
to be set with CSS also, since some SwtFixed containers that were
f2e612a
previously being overridden by ToolBar background colors now are
f2e612a
correctly displaying their own background. This means that ToolBars need
f2e612a
to be rendered with CSS as well. This can be accomplished very easily by
f2e612a
overriding the setBackgroundColor() method in ToolBar.java.
f2e612a
f2e612a
This change will only affect SWT using GTK3.16 and upward. Anything
f2e612a
below 3.16 still uses the old function (which works reliably on those
f2e612a
versions).
f2e612a
f2e612a
Change-Id: If9d1037fd24b9739e0c30ff794eb6fed0247d56f
f2e612a
Signed-off-by: Eric Williams <ericwill@redhat.com>
f2e612a
---
f2e612a
 .../Eclipse SWT PI/gtk/library/os.c                | 26 +++++++++++++-
f2e612a
 .../Eclipse SWT PI/gtk/library/os.h                |  1 +
f2e612a
 .../Eclipse SWT PI/gtk/library/os_custom.h         |  1 +
f2e612a
 .../Eclipse SWT PI/gtk/library/os_stats.c          |  1 +
f2e612a
 .../Eclipse SWT PI/gtk/library/os_stats.h          |  1 +
f2e612a
 .../gtk/org/eclipse/swt/internal/gtk/OS.java       | 13 +++++++
f2e612a
 .../gtk/org/eclipse/swt/widgets/Composite.java     | 40 ++++++++++++++++++++++
f2e612a
 .../gtk/org/eclipse/swt/widgets/Control.java       | 29 ++++++++++++----
f2e612a
 .../gtk/org/eclipse/swt/widgets/ToolBar.java       | 10 ++++++
f2e612a
 9 files changed, 115 insertions(+), 7 deletions(-)
f2e612a
f2e612a
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
f2e612a
index 52ade78..2d47a1c 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c	
f2e612a
@@ -7181,6 +7181,30 @@ fail:
f2e612a
 }
f2e612a
 #endif
f2e612a
 
f2e612a
+#ifndef NO__1gdk_1rgba_1to_1string
f2e612a
+JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1rgba_1to_1string)
f2e612a
+	(JNIEnv *env, jclass that, jobject arg0)
f2e612a
+{
f2e612a
+	GdkRGBA _arg0, *lparg0=NULL;
f2e612a
+	jintLong rc = 0;
f2e612a
+	OS_NATIVE_ENTER(env, that, _1gdk_1rgba_1to_1string_FUNC);
f2e612a
+	if (arg0) if ((lparg0 = getGdkRGBAFields(env, arg0, &_arg0)) == NULL) goto fail;
f2e612a
+/*
f2e612a
+	rc = (jintLong)gdk_rgba_to_string((GdkRGBA *)lparg0);
f2e612a
+*/
f2e612a
+	{
f2e612a
+		OS_LOAD_FUNCTION(fp, gdk_rgba_to_string)
f2e612a
+		if (fp) {
f2e612a
+			rc = (jintLong)((jintLong (CALLING_CONVENTION*)(GdkRGBA *))fp)((GdkRGBA *)lparg0);
f2e612a
+		}
f2e612a
+	}
f2e612a
+fail:
f2e612a
+	if (arg0 && lparg0) setGdkRGBAFields(env, arg0, lparg0);
f2e612a
+	OS_NATIVE_EXIT(env, that, _1gdk_1rgba_1to_1string_FUNC);
f2e612a
+	return rc;
f2e612a
+}
f2e612a
+#endif
f2e612a
+
f2e612a
 #ifndef NO__1gdk_1screen_1get_1default
f2e612a
 JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1screen_1get_1default)
f2e612a
 	(JNIEnv *env, jclass that)
f2e612a
@@ -18352,7 +18376,7 @@ JNIEXPORT jint JNICALL OS_NATIVE(_1gtk_1widget_1get_1state_1flags)
f2e612a
 	{
f2e612a
 		OS_LOAD_FUNCTION(fp, gtk_widget_get_state_flags)
f2e612a
 		if (fp) {
f2e612a
-			rc = (jint)((jintLong (CALLING_CONVENTION*)(GtkWidget *))fp)((GtkWidget *)arg0);
f2e612a
+			rc = (jint)((jint (CALLING_CONVENTION*)(GtkWidget *))fp)((GtkWidget *)arg0);
f2e612a
 		}
f2e612a
 	}
f2e612a
 	OS_NATIVE_EXIT(env, that, _1gtk_1widget_1get_1state_1flags_FUNC);
f2e612a
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h
f2e612a
index 2ccdca2..90084ea 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.h	
f2e612a
@@ -184,6 +184,7 @@
f2e612a
 #define NO__1gtk_1style_1context_1set_1state
f2e612a
 #define NO__1gtk_1color_1chooser_1get_1rgba
f2e612a
 #define NO__1gtk_1color_1chooser_1set_1rgba
f2e612a
+#define NO__1gdk_1rgba_1to_1string
f2e612a
 
f2e612a
 #define NO__1g_1object_1set__I_3BLorg_eclipse_swt_internal_gtk_GdkRGBA_2I
f2e612a
 #define NO__1g_1object_1set__J_3BLorg_eclipse_swt_internal_gtk_GdkRGBA_2J
f2e612a
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h
f2e612a
index a293df9..6cd4c80 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h	
f2e612a
@@ -307,6 +307,7 @@
f2e612a
 #define gdk_pointer_ungrab_LIB LIB_GDK
f2e612a
 #define gdk_region_polygon_LIB LIB_GDK
f2e612a
 #define gdk_region_get_rectangles_LIB LIB_GDK
f2e612a
+#define gdk_rgba_to_string_LIB LIB_GDK
f2e612a
 #define gdk_screen_get_default_LIB LIB_GDK
f2e612a
 #define gdk_screen_get_monitor_at_point_LIB LIB_GDK
f2e612a
 #define gdk_screen_get_monitor_at_window_LIB LIB_GDK
f2e612a
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
f2e612a
index bd9d7b5..ad9f01d 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c	
f2e612a
@@ -554,6 +554,7 @@ char * OS_nativeFunctionNames[] = {
f2e612a
 	"_1gdk_1region_1subtract",
f2e612a
 	"_1gdk_1region_1union",
f2e612a
 	"_1gdk_1region_1union_1with_1rect",
f2e612a
+	"_1gdk_1rgba_1to_1string",
f2e612a
 	"_1gdk_1screen_1get_1default",
f2e612a
 	"_1gdk_1screen_1get_1monitor_1at_1point",
f2e612a
 	"_1gdk_1screen_1get_1monitor_1at_1window",
f2e612a
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
f2e612a
index 016b472..cb21fb3 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h	
f2e612a
@@ -564,6 +564,7 @@ typedef enum {
f2e612a
 	_1gdk_1region_1subtract_FUNC,
f2e612a
 	_1gdk_1region_1union_FUNC,
f2e612a
 	_1gdk_1region_1union_1with_1rect_FUNC,
f2e612a
+	_1gdk_1rgba_1to_1string_FUNC,
f2e612a
 	_1gdk_1screen_1get_1default_FUNC,
f2e612a
 	_1gdk_1screen_1get_1monitor_1at_1point_FUNC,
f2e612a
 	_1gdk_1screen_1get_1monitor_1at_1window_FUNC,
f2e612a
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
f2e612a
index a7fb6fe..a1795dd 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java	
f2e612a
@@ -5492,6 +5492,19 @@ public static final void gdk_region_union_with_rect(long /*int*/ region, GdkRect
f2e612a
 		lock.unlock();
f2e612a
 	}
f2e612a
 }
f2e612a
+/** 
f2e612a
+ * @method flags=dynamic
f2e612a
+ * @param rgba cast=(GdkRGBA *) 
f2e612a
+ */
f2e612a
+public static final native long /*int*/ _gdk_rgba_to_string(GdkRGBA rgba);
f2e612a
+public static final long /*int*/ gdk_rgba_to_string(GdkRGBA rgba) {
f2e612a
+	lock.lock();
f2e612a
+	try {
f2e612a
+		return _gdk_rgba_to_string(rgba);
f2e612a
+	} finally {
f2e612a
+		lock.unlock();
f2e612a
+	}
f2e612a
+}
f2e612a
 /** @method flags=dynamic */
f2e612a
 public static final native long /*int*/ _gdk_screen_get_default();
f2e612a
 public static final long /*int*/ gdk_screen_get_default() {
f2e612a
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
f2e612a
index 4c4b557..e0f4782 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java	
f2e612a
@@ -64,6 +64,7 @@ public class Composite extends Scrollable {
f2e612a
 	Layout layout;
f2e612a
 	Control[] tabList;
f2e612a
 	int layoutCount, backgroundMode;
f2e612a
+	GdkRGBA background;
f2e612a
 
f2e612a
 	static final String NO_INPUT_METHOD = "org.eclipse.swt.internal.gtk.noInputMethod"; //$NON-NLS-1$
f2e612a
 
f2e612a
@@ -352,6 +353,16 @@ void createHandle (int index, boolean fixed, boolean scrolled) {
f2e612a
 }
f2e612a
 
f2e612a
 @Override
f2e612a
+long /*int*/ gtk_draw (long /*int*/ widget, long /*int*/ cairo) {
f2e612a
+	if (OS.GTK_VERSION >= OS.VERSION(3, 16, 0)) {
f2e612a
+		Rectangle area = getClientArea();
f2e612a
+		long /*int*/ context = OS.gtk_widget_get_style_context(widget);
f2e612a
+		OS.gtk_render_background(context, cairo, area.x, area.y, area.width, area.height);
f2e612a
+	}
f2e612a
+	return super.gtk_draw(widget, cairo);
f2e612a
+}
f2e612a
+
f2e612a
+@Override
f2e612a
 void deregister () {
f2e612a
 	super.deregister ();
f2e612a
 	if (socketHandle != 0) display.removeWidget (socketHandle);
f2e612a
@@ -650,6 +661,23 @@ public Rectangle getClientArea () {
f2e612a
 	return super.getClientArea();
f2e612a
 }
f2e612a
 
f2e612a
+@Override
f2e612a
+GdkColor getContextBackground () {
f2e612a
+	if (OS.GTK_VERSION >= OS.VERSION(3, 16, 0)) {
f2e612a
+		if (background != null) {
f2e612a
+			GdkColor color = new GdkColor ();
f2e612a
+			color.red = (short)(background.red * 0xFFFF);
f2e612a
+			color.green = (short)(background.green * 0xFFFF);
f2e612a
+			color.blue = (short)(background.blue * 0xFFFF);
f2e612a
+			return color;
f2e612a
+		} else {
f2e612a
+			return display.COLOR_WIDGET_BACKGROUND;
f2e612a
+		}
f2e612a
+	} else {
f2e612a
+		return super.getContextBackground();
f2e612a
+	}
f2e612a
+}
f2e612a
+
f2e612a
 /**
f2e612a
  * Returns layout which is associated with the receiver, or
f2e612a
  * null if one has not been set.
f2e612a
@@ -1438,6 +1466,18 @@ public void setBackgroundMode (int mode) {
f2e612a
 }
f2e612a
 
f2e612a
 @Override
f2e612a
+void setBackgroundColor (long /*int*/ context, long /*int*/ handle, GdkRGBA rgba) {
f2e612a
+	if (OS.GTK_VERSION >= OS.VERSION(3, 16, 0)) {
f2e612a
+		background = rgba;
f2e612a
+		String color = gtk_rgba_to_css_string(background);
f2e612a
+		String css = "SwtFixed {background-color: " + color + "}";
f2e612a
+		gtk_css_provider_load_from_css(context, css);
f2e612a
+	} else {
f2e612a
+		super.setBackgroundColor(context, handle, rgba);
f2e612a
+	}
f2e612a
+}
f2e612a
+
f2e612a
+@Override
f2e612a
 int setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
f2e612a
 	int result = super.setBounds (x, y, width, height, move, resize);
f2e612a
 	if ((result & RESIZED) != 0 && layout != null) {
f2e612a
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
f2e612a
index ecf2da0..f297659 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java	
f2e612a
@@ -4096,13 +4096,30 @@ void gtk_css_provider_load_from_css (long /*int*/ context, String css) {
f2e612a
 
f2e612a
 String gtk_rgba_to_css_string (GdkRGBA rgba) {
f2e612a
 	/*
f2e612a
-	 * In GdkRGBA, values are a double between 0-1.
f2e612a
-     * In CSS, values are typically integers between 0-255.
f2e612a
-     * I.e, note, there is a slight loss of precision.
f2e612a
-     * Thus setting/getting color *might* return slight differences.
f2e612a
+	 * In GdkRGBA, values are a double between 0-1.
f2e612a
+	 * In CSS, values are integers between 0-255 for r, g, and b.
f2e612a
+	 * Alpha is still a double between 0-1.
f2e612a
+	 * The final CSS format is: rgba(int, int, int, double)
f2e612a
+	 * Due to this, there is a slight loss of precision.
f2e612a
+	 * Setting/getting with CSS *might* yield slight differences.
f2e612a
 	 */
f2e612a
-	String color = "rgba(" + (int)(rgba.red * 255) + "," + (int)(rgba.green * 255) + "," + (int)(rgba.blue * 255) + "," + (int)(rgba.alpha * 255) + ")";
f2e612a
-	return color;
f2e612a
+	GdkRGBA toConvert;
f2e612a
+	if (rgba != null) {
f2e612a
+		toConvert = rgba;
f2e612a
+	} else {
f2e612a
+		// If we have a null RGBA, set it to the default COLOR_WIDGET_BACKGROUND.
f2e612a
+		GdkColor defaultGdkColor = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).handle; 
f2e612a
+		toConvert = new GdkRGBA ();
f2e612a
+		toConvert.alpha = 1.0;
f2e612a
+		toConvert.red = (defaultGdkColor.red & 0xFFFF) / (float)0xFFFF;
f2e612a
+		toConvert.green = (defaultGdkColor.green & 0xFFFF) / (float)0xFFFF;
f2e612a
+		toConvert.blue = (defaultGdkColor.blue & 0xFFFF) / (float)0xFFFF;
f2e612a
+	}
f2e612a
+	long /*int*/ str = OS.gdk_rgba_to_string (toConvert);
f2e612a
+	int length = OS.strlen (str);
f2e612a
+	byte [] buffer = new byte [length];
f2e612a
+	OS.memmove (buffer, str, length);
f2e612a
+	return new String (Converter.mbcsToWcs (null, buffer));
f2e612a
 }
f2e612a
 
f2e612a
 void setBackgroundColor (long /*int*/ handle, GdkColor color) {
f2e612a
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java
f2e612a
index 8f6d149..d69f1d6 100644
f2e612a
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java	
f2e612a
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java	
f2e612a
@@ -600,6 +600,16 @@ int setBounds (int x, int y, int width, int height, boolean move, boolean resize
f2e612a
 }
f2e612a
 
f2e612a
 @Override
f2e612a
+void setBackgroundColor (long /*int*/ context, long /*int*/ handle, GdkRGBA rgba) {
f2e612a
+	if (OS.GTK_VERSION >= OS.VERSION(3, 16, 0)) {
f2e612a
+		String css = "GtkToolbar {background-color: " + gtk_rgba_to_css_string(rgba) + "}";
f2e612a
+		gtk_css_provider_load_from_css(context, css);
f2e612a
+	} else {
f2e612a
+		super.setBackgroundColor(context, handle, rgba);
f2e612a
+	}
f2e612a
+}
f2e612a
+
f2e612a
+@Override
f2e612a
 void setFontDescription (long /*int*/ font) {
f2e612a
 	super.setFontDescription (font);
f2e612a
 	ToolItem [] items = getItems ();
f2e612a
-- 
f2e612a
cgit v0.11.2-4-g4a35
f2e612a
f2e612a