Blob Blame Raw
From 3dc220718412431322c00e1f820c9ce0168892f5 Mon Sep 17 00:00:00 2001
From: Eric Williams
Date: Mon, 23 Nov 2015 10:37:11 -0500
Subject: Bug 481122: [GTK3.18+] some set/get Background/Foreground color
 methods have no effect

With changes in GTK3.18 and onward, gtk_style_context_get_color()
behaves differently. In order to correctly fetch the color we must first
save the GtkStyleContext, set its state, fetch the color, and then
restore the GtkStyleContext. Failure to do this on GTK3.18+ leads to
failures in the getForegroundColor() method.

The convenience method styleContextGetColor() in Display takes care of
the process.

Tested on GTK 3.18, 3.16, 3.14, 3.8, and 2.24. All foreground color
related tests on GTK3 now pass. GTK2 behaviour remains unchanged.

Change-Id: I6423edab5038dc0ef54afc6dd826f19fc936f987
Signed-off-by: Eric Williams <ericwill@redhat.com>
---
 .../gtk/org/eclipse/swt/widgets/Control.java       |  2 +-
 .../gtk/org/eclipse/swt/widgets/Display.java       | 36 ++++++++++++++--------
 .../gtk/org/eclipse/swt/widgets/Text.java          |  2 +-
 3 files changed, 26 insertions(+), 14 deletions(-)

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 ffd9d11..7061084 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	
@@ -2626,7 +2626,7 @@ GdkColor getContextColor () {
 	long /*int*/ fontHandle = fontHandle ();
 	long /*int*/ context = OS.gtk_widget_get_style_context (fontHandle);
 	GdkRGBA rgba = new GdkRGBA ();
-	OS.gtk_style_context_get_color (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
+	rgba = display.styleContextGetColor (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
 	GdkColor color = new GdkColor ();
 	color.red = (short)(rgba.red * 0xFFFF);
 	color.green = (short)(rgba.green * 0xFFFF);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index 0119882..d7e670c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java	
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java	
@@ -2373,8 +2373,7 @@ void initializeSystemColors () {
 		OS.gtk_style_context_add_class (context, OS.GTK_STYLE_CLASS_TOOLTIP);
 		OS.gtk_style_context_invalidate(context);
 		GdkRGBA rgba = new GdkRGBA();
-		OS.gtk_style_context_get_color (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
-		COLOR_INFO_FOREGROUND = toGdkColor (rgba);
+		COLOR_INFO_FOREGROUND = toGdkColor (styleContextGetColor (context, OS.GTK_STATE_FLAG_NORMAL, rgba));
 		getBackgroundColor (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
 		COLOR_INFO_BACKGROUND = toGdkColor (rgba);
 		OS.gtk_widget_destroy (tooltipShellHandle);
@@ -2387,8 +2386,7 @@ void initializeSystemColors () {
 		COLOR_WIDGET_NORMAL_SHADOW = toGdkColor (rgba, 0.7);
 		COLOR_WIDGET_HIGHLIGHT_SHADOW = toGdkColor (rgba, 1.3);
 
-		OS.gtk_style_context_get_color (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
-		COLOR_WIDGET_FOREGROUND = toGdkColor (rgba);
+		COLOR_WIDGET_FOREGROUND = toGdkColor (styleContextGetColor (context, OS.GTK_STATE_FLAG_NORMAL, rgba));
 		OS.gtk_style_context_get_background_color (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
 		COLOR_WIDGET_BACKGROUND = toGdkColor (rgba);
 
@@ -2396,17 +2394,14 @@ void initializeSystemColors () {
 		OS.gtk_style_context_add_class(context, OS.GTK_STYLE_CLASS_VIEW);
 		OS.gtk_style_context_add_class(context, OS.GTK_STYLE_CLASS_CELL);
 		OS.gtk_style_context_invalidate(context);
-		OS.gtk_style_context_get_color (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
-		COLOR_LIST_FOREGROUND = toGdkColor (rgba);
+		COLOR_LIST_FOREGROUND = toGdkColor (styleContextGetColor (context, OS.GTK_STATE_FLAG_NORMAL, rgba));
 		OS.gtk_style_context_get_background_color (context, OS.GTK_STATE_FLAG_NORMAL, rgba);
 		COLOR_LIST_BACKGROUND = toGdkColor (rgba);
 		OS.gtk_style_context_restore (context);
-		OS.gtk_style_context_get_color (context, OS.GTK_STATE_FLAG_SELECTED, rgba);
-		COLOR_LIST_SELECTION_TEXT = toGdkColor (rgba);
+		COLOR_LIST_SELECTION_TEXT = toGdkColor (styleContextGetColor (context, OS.GTK_STATE_FLAG_SELECTED, rgba));
 		OS.gtk_style_context_get_background_color (context, OS.GTK_STATE_FLAG_SELECTED, rgba);
 		COLOR_LIST_SELECTION = toGdkColor (rgba);
-		OS.gtk_style_context_get_color (context, OS.GTK_STATE_FLAG_ACTIVE, rgba);
-		COLOR_LIST_SELECTION_TEXT_INACTIVE = toGdkColor (rgba);
+		COLOR_LIST_SELECTION_TEXT_INACTIVE = toGdkColor (styleContextGetColor (context, OS.GTK_STATE_FLAG_ACTIVE, rgba));
 		OS.gtk_style_context_get_background_color (context, OS.GTK_STATE_FLAG_ACTIVE, rgba);
 		COLOR_LIST_SELECTION_INACTIVE = toGdkColor (rgba);
 
@@ -2415,8 +2410,7 @@ void initializeSystemColors () {
 		OS.gtk_style_context_get_background_color (context, OS.GTK_STATE_FLAG_SELECTED, rgba);
 		COLOR_TITLE_BACKGROUND_GRADIENT = toGdkColor (rgba, 1.3);
 
-		OS.gtk_style_context_get_color (context, OS.GTK_STATE_FLAG_INSENSITIVE, rgba);
-		COLOR_TITLE_INACTIVE_FOREGROUND = toGdkColor (rgba);
+		COLOR_TITLE_INACTIVE_FOREGROUND = toGdkColor (styleContextGetColor (context, OS.GTK_STATE_FLAG_INSENSITIVE, rgba));
 		OS.gtk_style_context_get_background_color (context, OS.GTK_STATE_FLAG_INSENSITIVE, rgba);
 		COLOR_TITLE_INACTIVE_BACKGROUND = toGdkColor (rgba);
 		COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT = toGdkColor (rgba, 1.3);
@@ -2497,6 +2491,24 @@ void initializeSystemColors () {
 	COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT = gdkColor;
 }
 
+GdkRGBA styleContextGetColor(long /*int*/ context, int flag, GdkRGBA rgba) {
+	/*
+	* Feature in GTK: we need to handle calls to gtk_style_context_get_color()
+	* differently due to changes in GTK3.18+. This solves failing test cases
+	* which started failing after GTK3.16. See Bug 481122 for more info.
+	* Reference: https://blogs.gnome.org/mclasen/2015/11/20/a-gtk-update/
+	*/
+	if (OS.GTK_VERSION >= OS.VERSION(3, 18, 0)) {
+		OS.gtk_style_context_save(context);
+		OS.gtk_style_context_set_state(context, flag);
+		OS.gtk_style_context_get_color (context, flag, rgba);
+		OS.gtk_style_context_restore(context);
+	} else {
+		OS.gtk_style_context_get_color (context, flag, rgba);
+	}
+	return rgba;
+}
+
 /**
  * Returns the single instance of the system taskBar or null
  * when there is no system taskBar available for the platform.
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java
index 2865cd5..6b68b6a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java	
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java	
@@ -1664,7 +1664,7 @@ void drawMessage (long /*int*/ cr) {
 			if (OS.GTK3) {
 				long /*int*/ styleContext = OS.gtk_widget_get_style_context (handle);
 				GdkRGBA rgba = new GdkRGBA ();
-				OS.gtk_style_context_get_color (styleContext, OS.GTK_STATE_FLAG_INSENSITIVE, rgba);
+				rgba = display.styleContextGetColor (styleContext, OS.GTK_STATE_FLAG_INSENSITIVE, rgba);
 				textColor.red = (short)(rgba.red * 0xFFFF);
 				textColor.green = (short)(rgba.green * 0xFFFF);
 				textColor.blue = (short)(rgba.blue * 0xFFFF);
-- 
cgit v0.11.2-4-g4a35