Return an appropriate GtkStyle from gtk_rc_get_style_by_paths()

Always returning NULL (no match) from gtk_rc_get_style_by_paths()
means that looking up colors and style properties based on the
GtkStyle will give default values instead of themed values. We can
do better by returning a GtkStyle based on a GtkWidgetPath that we
figure out from the values passed in to get_style_by_paths().

https://bugzilla.gnome.org/show_bug.cgi?id=637520
This commit is contained in:
Owen W. Taylor 2010-12-20 13:48:44 -05:00
parent 928fd84ebf
commit a2dddb1da0
3 changed files with 103 additions and 10 deletions

View File

@ -807,7 +807,83 @@ gtk_rc_get_style_by_paths (GtkSettings *settings,
const char *class_path,
GType type)
{
return NULL;
GtkWidgetPath *path;
GtkStyle *style;
path = gtk_widget_path_new ();
/* For compatibility, we return a GtkStyle based on a GtkStyleContext
* with a GtkWidgetPath appropriate for the supplied information.
*
* GtkWidgetPath is composed of a list of GTypes with optional names;
* In GTK+-2.0, widget_path consisted of the widget names, or
* the class names for unnamed widgets, while class_path had the
* class names always. So, use class_path to determine the GTypes
* and extract widget names from widget_path as applicable.
*/
if (class_path == NULL)
{
gtk_widget_path_append_type (path, type == G_TYPE_NONE ? GTK_TYPE_WIDGET : type);
}
else
{
const gchar *widget_p, *widget_next;
const gchar *class_p, *class_next;
widget_next = widget_path;
class_next = class_path;
while (*class_next)
{
GType component_type;
gchar *component_class;
gchar *component_name;
gint pos;
class_p = class_next;
if (*class_p == '.')
class_p++;
widget_p = widget_next; /* Might be NULL */
if (widget_p && *widget_p == '.')
widget_p++;
class_next = strchr (class_p, '.');
if (class_next == NULL)
class_next = class_p + strlen (class_p);
if (widget_p)
{
widget_next = strchr (widget_p, '.');
if (widget_next == NULL)
widget_next = widget_p + strlen (widget_p);
}
component_class = g_strndup (class_p, class_next - class_p);
if (widget_p && *widget_p)
component_name = g_strndup (widget_p, widget_next - widget_p);
else
component_name = NULL;
component_type = g_type_from_name (component_class);
if (component_type == G_TYPE_INVALID)
component_type = GTK_TYPE_WIDGET;
pos = gtk_widget_path_append_type (path, component_type);
if (component_name != NULL && strcmp (component_name, component_name) != 0)
gtk_widget_path_iter_set_name (path, pos, component_name);
g_free (component_class);
g_free (component_name);
}
}
style = _gtk_style_new_for_path (_gtk_settings_get_screen (settings),
path);
gtk_widget_path_free (path);
return style;
}
/**

View File

@ -798,6 +798,26 @@ gtk_style_copy (GtkStyle *style)
return new_style;
}
GtkStyle*
_gtk_style_new_for_path (GdkScreen *screen,
GtkWidgetPath *path)
{
GtkStyleContext *context;
GtkStyle *style;
context = gtk_style_context_new ();
gtk_style_context_set_screen (context, screen);
gtk_style_context_set_path (context, path);
style = g_object_new (GTK_TYPE_STYLE,
"context", context,
NULL);
g_object_unref (context);
return style;
}
/**
* gtk_style_new:
* @returns: a new #GtkStyle.
@ -809,22 +829,15 @@ gtk_style_copy (GtkStyle *style)
GtkStyle*
gtk_style_new (void)
{
GtkStyleContext *context;
GtkWidgetPath *path;
GtkStyle *style;
context = gtk_style_context_new ();
gtk_style_context_set_screen (context, gdk_screen_get_default ());
path = gtk_widget_path_new ();
gtk_widget_path_append_type (path, GTK_TYPE_WIDGET);
gtk_style_context_set_path (context, path);
style = g_object_new (GTK_TYPE_STYLE,
"context", context,
NULL);
style = _gtk_style_new_for_path (gdk_screen_get_default (),
path);
g_object_unref (context);
gtk_widget_path_free (path);
return style;

View File

@ -34,6 +34,7 @@
#include <gdk/gdk.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkwidgetpath.h>
G_BEGIN_DECLS
@ -634,10 +635,13 @@ void gtk_style_get (GtkStyle *style,
#endif
/* --- private API --- */
GtkStyle* _gtk_style_new_for_path (GdkScreen *screen,
GtkWidgetPath *path);
void _gtk_style_shade (const GdkColor *a,
GdkColor *b,
gdouble k);
void gtk_draw_insertion_cursor (GtkWidget *widget,
cairo_t *cr,
const GdkRectangle *location,