From 8fc0e69fb57bb9ef0d73a0639eac14c769c2d1b2 Mon Sep 17 00:00:00 2001 From: pbansal Date: Fri, 15 Feb 2019 10:58:57 +0530 Subject: [PATCH] 8218469: JSlider display issue with slider for GTKLookAndFeel 8218470: JScrollBar display issue with GTKLookAndFeel 8218472: JProgressBar display issue with GTKLookAndFeel 8203627: Swing applications with JRadioButton and JCheckbox fail to render correctly when using GTK3 and the GTK L&F Reviewed-by: serb, prr --- .../com/sun/java/swing/plaf/gtk/GTKStyle.java | 15 ++ src/solaris/native/sun/awt/gtk3_interface.c | 180 +++++++++++++----- src/solaris/native/sun/awt/gtk3_interface.h | 15 +- 3 files changed, 160 insertions(+), 50 deletions(-) diff --git a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java index 27bc9d9a7..ba830465e 100644 --- a/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java +++ b/src/share/classes/com/sun/java/swing/plaf/gtk/GTKStyle.java @@ -763,6 +763,14 @@ class GTKStyle extends SynthStyle implements GTKConstants { if (classKey != null) { Object value = getClassSpecificValue(classKey); if (value != null) { + //This is a workaround as the "slider-length" property has been + //deprecated for GtkScale from gtk 3.20, so default value of 31 + //is used and makes redering of slider wrong. Value 14 is being + //used as default value for Slider.thumbHeight is 14 and making + //width 14 as well makes slider thumb render in proper shape + if ("Slider.thumbWidth".equals(key) && value.equals(31)) { + return 14; + } return value; } } @@ -775,8 +783,15 @@ class GTKStyle extends SynthStyle implements GTKConstants { return getColorForState(context, ColorType.FOREGROUND); } else if (key == "ScrollBar.minimumThumbSize") { + //This is a workaround as the "min-slider-length" property has been + //deprecated for GtkScrollBar from gtk 3.20, so default value of 21 + //is used and makes ScrollBar thumb very small. Value 40 is being + //used as this is the value mentioned in css files int len = getClassSpecificIntValue(context, "min-slider-length", 21); + if (len == 21) { + len = 40; + } JScrollBar sb = (JScrollBar)context.getComponent(); if (sb.getOrientation() == JScrollBar.HORIZONTAL) { return new DimensionUIResource(len, 0); diff --git a/src/solaris/native/sun/awt/gtk3_interface.c b/src/solaris/native/sun/awt/gtk3_interface.c index 93b1c0f79..9c53579c4 100644 --- a/src/solaris/native/sun/awt/gtk3_interface.c +++ b/src/solaris/native/sun/awt/gtk3_interface.c @@ -258,6 +258,7 @@ static void empty() {} 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 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name) } 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 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name) "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 @@ static GtkWidget *gtk3_get_widget(WidgetType widget_type) 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 @@ static void gtk3_paint_box(WidgetType widget_type, GtkStateType state_type, */ 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 @@ static void gtk3_paint_box(WidgetType widget_type, GtkStateType state_type, 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_box_gap(WidgetType widget_type, GtkStateType state_type, 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); } @@ -1680,7 +1776,6 @@ static void gtk3_paint_flat_box(WidgetType widget_type, GtkStateType state_type, 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) { @@ -1783,25 +1878,19 @@ static void gtk3_paint_vline(WidgetType widget_type, GtkStateType state_type, 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, @@ -1860,15 +1949,7 @@ static void gtk3_paint_slider(WidgetType widget_type, GtkStateType state_type, 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); @@ -1882,9 +1963,10 @@ static void gtk3_paint_slider(WidgetType widget_type, GtkStateType state_type, 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, diff --git a/src/solaris/native/sun/awt/gtk3_interface.h b/src/solaris/native/sun/awt/gtk3_interface.h index 9ec1c2506..3d6e05360 100644 --- a/src/solaris/native/sun/awt/gtk3_interface.h +++ b/src/solaris/native/sun/awt/gtk3_interface.h @@ -162,6 +162,7 @@ typedef void GtkAdjustment; typedef void GtkRange; typedef void GtkProgressBar; typedef void GtkProgress; +typedef void GtkWidgetPath; /* Some real structures */ typedef struct @@ -238,7 +239,6 @@ typedef struct { GType owner_type; } GParamSpec; - static gchar* (*fp_glib_check_version)(guint required_major, guint required_minor, guint required_micro); @@ -573,5 +573,18 @@ static void (*fp_gtk_arrow_set)(GtkWidget* arrow, static void (*fp_gtk_widget_size_request)(GtkWidget *widget, GtkRequisition *requisition); static GtkAdjustment* (*fp_gtk_range_get_adjustment)(GtkRange* range); +static GtkWidgetPath* (*fp_gtk_widget_path_copy) + (const GtkWidgetPath *path); +static const GtkWidgetPath* (*fp_gtk_style_context_get_path) + (GtkStyleContext *context); +static GtkWidgetPath* (*fp_gtk_widget_path_new) (void); +static gint (*fp_gtk_widget_path_append_type) + (GtkWidgetPath *path, GType type); +static void (*fp_gtk_widget_path_iter_set_object_name) + (GtkWidgetPath *path, gint pos, const char *name); +static void (*fp_gtk_style_context_set_path) + (GtkStyleContext *context, GtkWidgetPath *path); +static void (*fp_gtk_widget_path_unref) (GtkWidgetPath *path); +static GtkStyleContext* (*fp_gtk_style_context_new) (void); #endif /* !_GTK3_INTERFACE_H */ -- GitLab