--- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c Thu Feb 14 20:20:49 2019 +0000
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c Fri Feb 15 10:58:57 2019 +0530
@@ -258,6 +258,7 @@
static gboolean gtk3_version_3_10 = TRUE;
static gboolean gtk3_version_3_14 = FALSE;
+static gboolean gtk3_version_3_20 = FALSE;
GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
{
@@ -400,6 +401,18 @@
}
gtk3_version_3_14 = !fp_gtk_check_version(3, 14, 0);
+ if (!fp_gtk_check_version(3, 20, 0)) {
+ gtk3_version_3_20 = TRUE;
+ fp_gtk_widget_path_copy = dl_symbol("gtk_widget_path_copy");
+ fp_gtk_widget_path_new = dl_symbol("gtk_widget_path_new");
+ fp_gtk_widget_path_append_type = dl_symbol("gtk_widget_path_append_type");
+ fp_gtk_widget_path_iter_set_object_name = dl_symbol("gtk_widget_path_iter_set_object_name");
+ fp_gtk_style_context_set_path = dl_symbol("gtk_style_context_set_path");
+ fp_gtk_widget_path_unref = dl_symbol("gtk_widget_path_unref");
+ fp_gtk_style_context_get_path = dl_symbol("gtk_style_context_get_path");
+ fp_gtk_style_context_new = dl_symbol("gtk_style_context_new");
+ }
+
fp_gdk_window_create_similar_surface =
dl_symbol("gdk_window_create_similar_surface");
fp_gtk_settings_get_for_screen =
@@ -561,7 +574,6 @@
"gtk_combo_box_new_with_entry");
fp_gtk_separator_tool_item_new = dlsym(gtk3_libhandle,
"gtk_separator_tool_item_new");
-
fp_g_list_append = dl_symbol("g_list_append");
fp_g_list_free = dl_symbol("g_list_free");
fp_g_list_free_full = dl_symbol("g_list_free_full");
@@ -1362,6 +1374,90 @@
return result;
}
+static void append_element (GtkWidgetPath *path, const gchar *selector)
+{
+ fp_gtk_widget_path_append_type (path, G_TYPE_NONE);
+ fp_gtk_widget_path_iter_set_object_name (path, -1, selector);
+}
+
+static GtkWidgetPath* createWidgetPath(const GtkWidgetPath* path) {
+ if (path == NULL) {
+ return fp_gtk_widget_path_new();
+ } else {
+ return fp_gtk_widget_path_copy(path);
+ }
+}
+
+static GtkStyleContext* get_style(WidgetType widget_type, const gchar *detail)
+{
+ if (!gtk3_version_3_20) {
+ gtk3_widget = gtk3_get_widget(widget_type);
+ GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
+ fp_gtk_style_context_save (context);
+ if (detail != 0) {
+ transform_detail_string(detail, context);
+ }
+ return context;
+ } else {
+ gtk3_widget = gtk3_get_widget(widget_type);
+ GtkStyleContext* widget_context = fp_gtk_widget_get_style_context (gtk3_widget);
+ GtkWidgetPath *path = NULL;
+ if (detail != 0) {
+ if (strcmp(detail, "checkbutton") == 0) {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ append_element(path, "check");
+ } else if (strcmp(detail, "radiobutton") == 0) {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ append_element(path, "radio");
+ } else if (strcmp(detail, "vscale") == 0 || strcmp(detail, "hscale") == 0) {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ append_element(path, "slider");
+ } else if (strcmp(detail, "trough") == 0) {
+ //This is a fast solution to the scrollbar trough not being rendered properly
+ if (widget_type == HSCROLL_BAR || widget_type == HSCROLL_BAR_TRACK ||
+ widget_type == VSCROLL_BAR || widget_type == VSCROLL_BAR_TRACK) {
+ path = createWidgetPath (NULL);
+ } else {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ }
+ append_element(path, detail);
+ } else if (strcmp(detail, "bar") == 0) {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ append_element(path, "trough");
+ append_element(path, "progress");
+ } else if (strcmp(detail, "vscrollbar") == 0 || strcmp(detail, "hscrollbar") == 0) {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ append_element(path, "button");
+ } else if (strcmp(detail, "check") == 0) {
+ path = createWidgetPath (NULL);
+ append_element(path, detail);
+ } else if (strcmp(detail, "option") == 0) {
+ path = createWidgetPath (NULL);
+ append_element(path, "radio");
+ } else {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ append_element(path, detail);
+ }
+ } else {
+ path = createWidgetPath (fp_gtk_style_context_get_path (widget_context));
+ }
+
+ GtkStyleContext *context = fp_gtk_style_context_new ();
+ fp_gtk_style_context_set_path (context, path);
+ fp_gtk_widget_path_unref (path);
+ return context;
+ }
+}
+
+static void disposeOrRestoreContext(GtkStyleContext *context)
+{
+ if (!gtk3_version_3_20) {
+ fp_gtk_style_context_restore (context);
+ } else {
+ fp_g_object_unref (context);
+ }
+}
+
static void gtk3_paint_arrow(WidgetType widget_type, GtkStateType state_type,
GtkShadowType shadow_type, const gchar *detail,
gint x, gint y, gint width, gint height,
@@ -1509,13 +1605,9 @@
*/
gtk3_set_direction(gtk3_widget, dir);
- GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
- fp_gtk_style_context_save (context);
-
- transform_detail_string(detail, context);
+ GtkStyleContext* context = get_style(widget_type, detail);
GtkStateFlags flags = get_gtk_flags(state_type);
-
if (shadow_type == GTK_SHADOW_IN && widget_type != COMBO_BOX_ARROW_BUTTON) {
flags |= GTK_STATE_FLAG_ACTIVE;
}
@@ -1532,23 +1624,31 @@
fp_gtk_style_context_add_class (context, "default");
}
+ if (fp_gtk_style_context_has_class(context, "trough")) {
+ flags |= GTK_STATE_FLAG_BACKDROP;
+ }
+
fp_gtk_style_context_set_state (context, flags);
- if (fp_gtk_style_context_has_class(context, "progressbar")) {
- fp_gtk_render_activity (context, cr, x, y, width, height);
- } else {
- fp_gtk_render_background (context, cr, x, y, width, height);
- if (shadow_type != GTK_SHADOW_NONE) {
- fp_gtk_render_frame(context, cr, x, y, width, height);
- }
+ fp_gtk_render_background (context, cr, x, y, width, height);
+ if (shadow_type != GTK_SHADOW_NONE) {
+ fp_gtk_render_frame(context, cr, x, y, width, height);
}
- fp_gtk_style_context_restore (context);
+ disposeOrRestoreContext(context);
+
/*
* Reset the text direction to the default value so that we don't
* accidentally affect other operations and widgets.
*/
gtk3_set_direction(gtk3_widget, GTK_TEXT_DIR_LTR);
+
+ //This is a fast solution to the scrollbar trough not being rendered properly
+ if ((widget_type == HSCROLL_BAR || widget_type == HSCROLL_BAR_TRACK ||
+ widget_type == VSCROLL_BAR || widget_type == VSCROLL_BAR_TRACK) && detail != 0) {
+ gtk3_paint_box(widget_type, state_type, shadow_type, NULL,
+ x, y, width, height, synth_state, dir);
+ }
}
static void gtk3_paint_box_gap(WidgetType widget_type, GtkStateType state_type,
@@ -1580,23 +1680,19 @@
static void gtk3_paint_check(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height)
{
- gtk3_widget = gtk3_get_widget(widget_type);
-
- GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
-
- fp_gtk_style_context_save (context);
+ GtkStyleContext* context = get_style(widget_type, detail);
GtkStateFlags flags = get_gtk_state_flags(synth_state);
if (gtk3_version_3_14 && (synth_state & SELECTED)) {
- flags = GTK_STATE_FLAG_CHECKED;
+ flags &= ~GTK_STATE_FLAG_SELECTED;
+ flags |= GTK_STATE_FLAG_CHECKED;
}
fp_gtk_style_context_set_state(context, flags);
- fp_gtk_style_context_add_class (context, "check");
-
- fp_gtk_render_check (context, cr, x, y, width, height);
-
- fp_gtk_style_context_restore (context);
+ fp_gtk_render_background(context, cr, x, y, width, height);
+ fp_gtk_render_frame(context, cr, x, y, width, height);
+ fp_gtk_render_check(context, cr, x, y, width, height);
+ disposeOrRestoreContext(context);
}
@@ -1684,7 +1780,6 @@
gtk3_widget = gtk3_get_widget(widget_type);
GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
-
fp_gtk_style_context_save (context);
if (detail != 0) {
@@ -1787,25 +1882,19 @@
static void gtk3_paint_option(WidgetType widget_type, gint synth_state,
const gchar *detail, gint x, gint y, gint width, gint height)
{
- gtk3_widget = gtk3_get_widget(widget_type);
-
- GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
-
- fp_gtk_style_context_save (context);
+ GtkStyleContext* context = get_style(widget_type, detail);
GtkStateFlags flags = get_gtk_state_flags(synth_state);
if (gtk3_version_3_14 && (synth_state & SELECTED)) {
- flags = GTK_STATE_FLAG_CHECKED;
+ flags &= ~GTK_STATE_FLAG_SELECTED;
+ flags |= GTK_STATE_FLAG_CHECKED;
}
fp_gtk_style_context_set_state(context, flags);
- if (detail != 0) {
- transform_detail_string(detail, context);
- }
-
+ fp_gtk_render_background(context, cr, x, y, width, height);
+ fp_gtk_render_frame(context, cr, x, y, width, height);
fp_gtk_render_option(context, cr, x, y, width, height);
-
- fp_gtk_style_context_restore (context);
+ disposeOrRestoreContext(context);
}
static void gtk3_paint_shadow(WidgetType widget_type, GtkStateType state_type,
@@ -1864,15 +1953,7 @@
gint x, gint y, gint width, gint height, GtkOrientation orientation,
gboolean has_focus)
{
- gtk3_widget = gtk3_get_widget(widget_type);
-
- GtkStyleContext* context = fp_gtk_widget_get_style_context (gtk3_widget);
-
- fp_gtk_style_context_save (context);
-
- if (detail) {
- transform_detail_string(detail, context);
- }
+ GtkStyleContext *context = get_style(widget_type, detail);
GtkStateFlags flags = get_gtk_flags(state_type);
@@ -1886,9 +1967,10 @@
fp_gtk_style_context_set_state (context, flags);
+ fp_gtk_render_background (context, cr, x, y, width, height);
+ fp_gtk_render_frame(context, cr, x, y, width, height);
(*fp_gtk_render_slider)(context, cr, x, y, width, height, orientation);
-
- fp_gtk_style_context_restore (context);
+ disposeOrRestoreContext(context);
}
static void gtk3_paint_background(WidgetType widget_type,