X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtksettings.c;h=3c9036c434830ae067631f653bee701a5a50d175;hb=1074aa0c49f647ed4b2a969618051c59da5aad01;hp=f84bc9b28338d488d48f89b29253db264ad1af5b;hpb=3b3307b946ed3fb7e3669ed98ec154d4b161bb1d;p=~andy%2Fgtk diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index f84bc9b28..3c9036c43 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -12,8 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library. If not, see .Free */ @@ -23,15 +22,17 @@ #include -#include "gtkmodules.h" #include "gtksettings.h" -#include "gtkrc.h" + +#include "gtkmodules.h" +#include "gtkmodulesprivate.h" +#include "gtksettingsprivate.h" #include "gtkintl.h" #include "gtkwidget.h" -#include "gtktypeutils.h" #include "gtkprivate.h" -#include "gtkcssprovider.h" -#include "gtksymboliccolor.h" +#include "gtkcssproviderprivate.h" +#include "gtkstyleproviderprivate.h" +#include "gtktypebuiltins.h" #include "gtkversion.h" #ifdef GDK_WINDOWING_X11 @@ -39,25 +40,50 @@ #include #endif +#ifdef GDK_WINDOWING_QUARTZ +#include "quartz/gdkquartz.h" +#endif + +#ifdef G_OS_WIN32 +#include "gtkwin32themeprivate.h" +#endif + +#undef GDK_DEPRECATED +#undef GDK_DEPRECATED_FOR +#define GDK_DEPRECATED +#define GDK_DEPRECATED_FOR(f) + +#include "deprecated/gtkrc.h" + /** * SECTION:gtksettings * @Short_description: Sharing settings between applications * @Title: Settings * - * GtkSettings provide a mechanism to share global settings between applications. + * GtkSettings provide a mechanism to share global settings between + * applications. + * * On the X window system, this sharing is realized by an * XSettings - * manager that is usually part of the desktop environment, along with utilities - * that let the user change these settings. In the absence of an Xsettings manager, - * settings can also be specified in RC files. + * manager that is usually part of the desktop environment, along with + * utilities that let the user change these settings. In the absence of + * an Xsettings manager, GTK+ reads default values for settings from + * settings.ini files in + * /etc/gtk-3.0, $XDG_CONFIG_DIRS/gtk-3.0 + * and $XDG_CONFIG_HOME/gtk-3.0. + * These files must be valid key files (see #GKeyFile), and have + * a section called Settings. Themes can also provide default values + * for settings by installing a settings.ini file + * next to their gtk.css file. * - * Applications can override system-wide settings with gtk_settings_set_string_property(), - * gtk_settings_set_long_property(), etc. This should be restricted to special - * cases though; GtkSettings are not meant as an application configuration - * facility. When doing so, you need to be aware that settings that are specific - * to individual widgets may not be available before the widget type has been - * realized at least once. The following example demonstrates a way to do this: + * Applications can override system-wide settings with + * gtk_settings_set_string_property(), gtk_settings_set_long_property(), + * etc. This should be restricted to special cases though; GtkSettings are + * not meant as an application configuration facility. When doing so, you + * need to be aware that settings that are specific to individual widgets + * may not be available before the widget type has been realized at least + * once. The following example demonstrates a way to do this: * * gtk_init (&argc, &argv); * @@ -74,22 +100,26 @@ */ -#ifdef GDK_WINDOWING_QUARTZ -#define DEFAULT_KEY_THEME "Mac" -#else -#define DEFAULT_KEY_THEME NULL -#endif - #define DEFAULT_TIMEOUT_INITIAL 200 #define DEFAULT_TIMEOUT_REPEAT 20 #define DEFAULT_TIMEOUT_EXPAND 500 +typedef struct _GtkSettingsPropertyValue GtkSettingsPropertyValue; typedef struct _GtkSettingsValuePrivate GtkSettingsValuePrivate; +struct _GtkSettingsPrivate +{ + GData *queued_settings; /* of type GtkSettingsValue* */ + GtkSettingsPropertyValue *property_values; + GdkScreen *screen; + GtkCssProvider *theme_provider; + GtkCssProvider *key_theme_provider; +}; + typedef enum { GTK_SETTINGS_SOURCE_DEFAULT, - GTK_SETTINGS_SOURCE_RC_FILE, + GTK_SETTINGS_SOURCE_THEME, GTK_SETTINGS_SOURCE_XSETTING, GTK_SETTINGS_SOURCE_APPLICATION } GtkSettingsSource; @@ -123,7 +153,6 @@ enum { PROP_FONT_NAME, PROP_ICON_SIZES, PROP_MODULES, -#ifdef GDK_WINDOWING_X11 PROP_XFT_ANTIALIAS, PROP_XFT_HINTING, PROP_XFT_HINTSTYLE, @@ -131,7 +160,6 @@ enum { PROP_XFT_DPI, PROP_CURSOR_THEME_NAME, PROP_CURSOR_THEME_SIZE, -#endif PROP_ALTERNATIVE_BUTTON_ORDER, PROP_ALTERNATIVE_SORT_ARROWS, PROP_SHOW_INPUT_METHOD_MENU, @@ -165,6 +193,8 @@ enum { PROP_TOOLBAR_STYLE, PROP_TOOLBAR_ICON_SIZE, PROP_AUTO_MNEMONICS, + PROP_PRIMARY_BUTTON_WARPS_SLIDER, + PROP_VISIBLE_FOCUS, PROP_APPLICATION_PREFER_DARK_THEME, PROP_BUTTON_IMAGES, PROP_ENTRY_SELECT_ON_FOCUS, @@ -178,43 +208,47 @@ enum { PROP_LABEL_SELECT_ON_FOCUS, PROP_COLOR_PALETTE, PROP_IM_PREEDIT_STYLE, - PROP_IM_STATUS_STYLE + PROP_IM_STATUS_STYLE, + PROP_SHELL_SHOWS_APP_MENU, + PROP_SHELL_SHOWS_MENUBAR, + PROP_ENABLE_PRIMARY_PASTE, + PROP_RECENT_FILES_ENABLED }; /* --- prototypes --- */ static void gtk_settings_provider_iface_init (GtkStyleProviderIface *iface); - -static void gtk_settings_finalize (GObject *object); -static void gtk_settings_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); -static void gtk_settings_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_settings_notify (GObject *object, - GParamSpec *pspec); -static guint settings_install_property_parser (GtkSettingsClass *class, - GParamSpec *pspec, - GtkRcPropertyParser parser); +static void gtk_settings_provider_private_init (GtkStyleProviderPrivateInterface *iface); + +static void gtk_settings_finalize (GObject *object); +static void gtk_settings_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void gtk_settings_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_settings_notify (GObject *object, + GParamSpec *pspec); +static guint settings_install_property_parser (GtkSettingsClass *class, + GParamSpec *pspec, + GtkRcPropertyParser parser); static void settings_update_double_click (GtkSettings *settings); static void settings_update_modules (GtkSettings *settings); -#ifdef GDK_WINDOWING_X11 static void settings_update_cursor_theme (GtkSettings *settings); static void settings_update_resolution (GtkSettings *settings); static void settings_update_font_options (GtkSettings *settings); static gboolean settings_update_fontconfig (GtkSettings *settings); -#endif -static void settings_update_color_scheme (GtkSettings *settings); static void settings_update_theme (GtkSettings *settings); +static void settings_update_key_theme (GtkSettings *settings); -static void merge_color_scheme (GtkSettings *settings, - const GValue *value, - GtkSettingsSource source); -static gchar *get_color_scheme (GtkSettings *settings); -static GHashTable *get_color_hash (GtkSettings *settings); +static void gtk_settings_load_from_key_file (GtkSettings *settings, + const gchar *path, + GtkSettingsSource source); +static void settings_update_provider (GdkScreen *screen, + GtkCssProvider **old, + GtkCssProvider *new); /* the default palette for GtkColorSelelection */ static const gchar default_color_palette[] = @@ -222,25 +256,38 @@ static const gchar default_color_palette[] = "lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90"; /* --- variables --- */ -static GQuark quark_property_parser = 0; +static GQuark quark_property_parser = 0; static GSList *object_list = NULL; -static guint class_n_properties = 0; +static guint class_n_properties = 0; G_DEFINE_TYPE_EXTENDED (GtkSettings, gtk_settings, G_TYPE_OBJECT, 0, G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLE_PROVIDER, - gtk_settings_provider_iface_init)); + gtk_settings_provider_iface_init) + G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLE_PROVIDER_PRIVATE, + gtk_settings_provider_private_init)); /* --- functions --- */ static void gtk_settings_init (GtkSettings *settings) { + GtkSettingsPrivate *priv; GParamSpec **pspecs, **p; guint i = 0; - - g_datalist_init (&settings->queued_settings); + gchar *path; + const gchar * const *config_dirs; + const gchar *config_dir; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (settings, + GTK_TYPE_SETTINGS, + GtkSettingsPrivate); + + settings->priv = priv; + g_datalist_init (&priv->queued_settings); object_list = g_slist_prepend (object_list, settings); + priv->theme_provider = gtk_css_provider_new (); + /* build up property array for all yet existing properties and queue * notification for them (at least notification for internal properties * will instantly be caught) @@ -249,23 +296,46 @@ gtk_settings_init (GtkSettings *settings) for (p = pspecs; *p; p++) if ((*p)->owner_type == G_OBJECT_TYPE (settings)) i++; - settings->property_values = g_new0 (GtkSettingsPropertyValue, i); + priv->property_values = g_new0 (GtkSettingsPropertyValue, i); i = 0; g_object_freeze_notify (G_OBJECT (settings)); + for (p = pspecs; *p; p++) { GParamSpec *pspec = *p; + GType value_type = G_PARAM_SPEC_VALUE_TYPE (pspec); if (pspec->owner_type != G_OBJECT_TYPE (settings)) - continue; - g_value_init (&settings->property_values[i].value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_param_value_set_default (pspec, &settings->property_values[i].value); + continue; + g_value_init (&priv->property_values[i].value, value_type); + g_param_value_set_default (pspec, &priv->property_values[i].value); + g_object_notify (G_OBJECT (settings), pspec->name); - settings->property_values[i].source = GTK_SETTINGS_SOURCE_DEFAULT; + priv->property_values[i].source = GTK_SETTINGS_SOURCE_DEFAULT; i++; } - g_object_thaw_notify (G_OBJECT (settings)); g_free (pspecs); + + path = g_build_filename (_gtk_get_sysconfdir (), "gtk-3.0", "settings.ini", NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS)) + gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT); + g_free (path); + + config_dirs = g_get_system_config_dirs (); + for (config_dir = *config_dirs; *config_dirs != NULL; config_dirs++) + { + path = g_build_filename (config_dir, "gtk-3.0", "settings.ini", NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS)) + gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT); + g_free (path); + } + + path = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "settings.ini", NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS)) + gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_DEFAULT); + g_free (path); + + g_object_thaw_notify (G_OBJECT (settings)); } static void @@ -273,7 +343,7 @@ gtk_settings_class_init (GtkSettingsClass *class) { GObjectClass *gobject_class = G_OBJECT_CLASS (class); guint result; - + gobject_class->finalize = gtk_settings_finalize; gobject_class->get_property = gtk_settings_get_property; gobject_class->set_property = gtk_settings_set_property; @@ -300,18 +370,18 @@ gtk_settings_class_init (GtkSettingsClass *class) /** * GtkSettings:gtk-cursor-blink: * - * Whether the cursor should blink. + * Whether the cursor should blink. * - * Also see the #GtkSettings:gtk-cursor-blink-timeout setting, + * Also see the #GtkSettings:gtk-cursor-blink-timeout setting, * which allows more flexible control over cursor blinking. */ result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-cursor-blink", - P_("Cursor Blink"), - P_("Whether the cursor should blink"), - TRUE, - GTK_PARAM_READWRITE), - NULL); + P_("Cursor Blink"), + P_("Whether the cursor should blink"), + TRUE, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_CURSOR_BLINK); result = settings_install_property_parser (class, g_param_spec_int ("gtk-cursor-blink-time", @@ -321,7 +391,7 @@ gtk_settings_class_init (GtkSettingsClass *class) GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_CURSOR_BLINK_TIME); - + /** * GtkSettings:gtk-cursor-blink-timeout: * @@ -329,7 +399,7 @@ gtk_settings_class_init (GtkSettingsClass *class) * The timer is reset after each user interaction. * * Setting this to zero has the same effect as setting - * #GtkSettings:gtk-cursor-blink to %FALSE. + * #GtkSettings:gtk-cursor-blink to %FALSE. * * Since: 2.12 */ @@ -343,47 +413,51 @@ gtk_settings_class_init (GtkSettingsClass *class) g_assert (result == PROP_CURSOR_BLINK_TIMEOUT); result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-split-cursor", - P_("Split Cursor"), - P_("Whether two cursors should be displayed for mixed left-to-right and right-to-left text"), - TRUE, - GTK_PARAM_READWRITE), + P_("Split Cursor"), + P_("Whether two cursors should be displayed for mixed left-to-right and right-to-left text"), + TRUE, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_SPLIT_CURSOR); result = settings_install_property_parser (class, g_param_spec_string ("gtk-theme-name", - P_("Theme Name"), - P_("Name of theme RC file to load"), - "Raleigh", - GTK_PARAM_READWRITE), + P_("Theme Name"), + P_("Name of theme to load"), +#ifdef G_OS_WIN32 + _gtk_win32_theme_get_default (), +#else + "Raleigh", +#endif + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_THEME_NAME); result = settings_install_property_parser (class, g_param_spec_string ("gtk-icon-theme-name", - P_("Icon Theme Name"), - P_("Name of icon theme to use"), - "hicolor", - GTK_PARAM_READWRITE), + P_("Icon Theme Name"), + P_("Name of icon theme to use"), + "hicolor", + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_ICON_THEME_NAME); result = settings_install_property_parser (class, g_param_spec_string ("gtk-fallback-icon-theme", - P_("Fallback Icon Theme Name"), - P_("Name of a icon theme to fall back to"), - NULL, - GTK_PARAM_READWRITE), + P_("Fallback Icon Theme Name"), + P_("Name of a icon theme to fall back to"), + NULL, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_FALLBACK_ICON_THEME); - + result = settings_install_property_parser (class, g_param_spec_string ("gtk-key-theme-name", - P_("Key Theme Name"), - P_("Name of key theme RC file to load"), - DEFAULT_KEY_THEME, - GTK_PARAM_READWRITE), + P_("Key Theme Name"), + P_("Name of key theme to load"), + NULL, + GTK_PARAM_READWRITE), NULL); - g_assert (result == PROP_KEY_THEME_NAME); + g_assert (result == PROP_KEY_THEME_NAME); result = settings_install_property_parser (class, g_param_spec_string ("gtk-menu-bar-accel", @@ -395,20 +469,20 @@ gtk_settings_class_init (GtkSettingsClass *class) g_assert (result == PROP_MENU_BAR_ACCEL); result = settings_install_property_parser (class, - g_param_spec_int ("gtk-dnd-drag-threshold", - P_("Drag threshold"), - P_("Number of pixels the cursor can move before dragging"), - 1, G_MAXINT, 8, + g_param_spec_int ("gtk-dnd-drag-threshold", + P_("Drag threshold"), + P_("Number of pixels the cursor can move before dragging"), + 1, G_MAXINT, 8, GTK_PARAM_READWRITE), - NULL); + NULL); g_assert (result == PROP_DND_DRAG_THRESHOLD); result = settings_install_property_parser (class, g_param_spec_string ("gtk-font-name", - P_("Font Name"), - P_("Name of default font to use"), - "Sans 10", - GTK_PARAM_READWRITE), + P_("Font Name"), + P_("Name of default font to use"), + "Sans 10", + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_FONT_NAME); @@ -420,107 +494,105 @@ gtk_settings_class_init (GtkSettingsClass *class) * * size-name = width , height * - * E.g. "gtk-menu=16,16:gtk-button=20,20:gtk-dialog=48,48". - * GTK+ itself use the following named icon sizes: gtk-menu, - * gtk-button, gtk-small-toolbar, gtk-large-toolbar, gtk-dnd, - * gtk-dialog. Applications can register their own named icon + * E.g. "gtk-menu=16,16:gtk-button=20,20:gtk-dialog=48,48". + * GTK+ itself use the following named icon sizes: gtk-menu, + * gtk-button, gtk-small-toolbar, gtk-large-toolbar, gtk-dnd, + * gtk-dialog. Applications can register their own named icon * sizes with gtk_icon_size_register(). */ result = settings_install_property_parser (class, g_param_spec_string ("gtk-icon-sizes", - P_("Icon Sizes"), - P_("List of icon sizes (gtk-menu=16,16:gtk-button=20,20..."), - NULL, - GTK_PARAM_READWRITE), + P_("Icon Sizes"), + P_("List of icon sizes (gtk-menu=16,16:gtk-button=20,20..."), + NULL, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_ICON_SIZES); result = settings_install_property_parser (class, g_param_spec_string ("gtk-modules", - P_("GTK Modules"), - P_("List of currently active GTK modules"), - NULL, - GTK_PARAM_READWRITE), + P_("GTK Modules"), + P_("List of currently active GTK modules"), + NULL, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_MODULES); -#ifdef GDK_WINDOWING_X11 result = settings_install_property_parser (class, - g_param_spec_int ("gtk-xft-antialias", - P_("Xft Antialias"), - P_("Whether to antialias Xft fonts; 0=no, 1=yes, -1=default"), - -1, 1, -1, - GTK_PARAM_READWRITE), - NULL); - + g_param_spec_int ("gtk-xft-antialias", + P_("Xft Antialias"), + P_("Whether to antialias Xft fonts; 0=no, 1=yes, -1=default"), + -1, 1, -1, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_XFT_ANTIALIAS); - + result = settings_install_property_parser (class, - g_param_spec_int ("gtk-xft-hinting", - P_("Xft Hinting"), - P_("Whether to hint Xft fonts; 0=no, 1=yes, -1=default"), - -1, 1, -1, - GTK_PARAM_READWRITE), - NULL); - + g_param_spec_int ("gtk-xft-hinting", + P_("Xft Hinting"), + P_("Whether to hint Xft fonts; 0=no, 1=yes, -1=default"), + -1, 1, -1, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_XFT_HINTING); - + result = settings_install_property_parser (class, - g_param_spec_string ("gtk-xft-hintstyle", - P_("Xft Hint Style"), - P_("What degree of hinting to use; hintnone, hintslight, hintmedium, or hintfull"), - NULL, - GTK_PARAM_READWRITE), + g_param_spec_string ("gtk-xft-hintstyle", + P_("Xft Hint Style"), + P_("What degree of hinting to use; hintnone, hintslight, hintmedium, or hintfull"), + NULL, + GTK_PARAM_READWRITE), NULL); - + g_assert (result == PROP_XFT_HINTSTYLE); - + result = settings_install_property_parser (class, - g_param_spec_string ("gtk-xft-rgba", - P_("Xft RGBA"), - P_("Type of subpixel antialiasing; none, rgb, bgr, vrgb, vbgr"), - NULL, - GTK_PARAM_READWRITE), - NULL); - + g_param_spec_string ("gtk-xft-rgba", + P_("Xft RGBA"), + P_("Type of subpixel antialiasing; none, rgb, bgr, vrgb, vbgr"), + NULL, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_XFT_RGBA); - + result = settings_install_property_parser (class, - g_param_spec_int ("gtk-xft-dpi", - P_("Xft DPI"), - P_("Resolution for Xft, in 1024 * dots/inch. -1 to use default value"), - -1, 1024*1024, -1, - GTK_PARAM_READWRITE), - NULL); - + g_param_spec_int ("gtk-xft-dpi", + P_("Xft DPI"), + P_("Resolution for Xft, in 1024 * dots/inch. -1 to use default value"), + -1, 1024*1024, -1, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_XFT_DPI); result = settings_install_property_parser (class, g_param_spec_string ("gtk-cursor-theme-name", - P_("Cursor theme name"), - P_("Name of the cursor theme to use, or NULL to use the default theme"), - NULL, - GTK_PARAM_READWRITE), + P_("Cursor theme name"), + P_("Name of the cursor theme to use, or NULL to use the default theme"), + NULL, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_CURSOR_THEME_NAME); result = settings_install_property_parser (class, - g_param_spec_int ("gtk-cursor-theme-size", - P_("Cursor theme size"), - P_("Size to use for cursors, or 0 to use the default size"), - 0, 128, 0, - GTK_PARAM_READWRITE), - NULL); - + g_param_spec_int ("gtk-cursor-theme-size", + P_("Cursor theme size"), + P_("Size to use for cursors, or 0 to use the default size"), + 0, 128, 0, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_CURSOR_THEME_SIZE); -#endif /* GDK_WINDOWING_X11 */ result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-alternative-button-order", - P_("Alternative button order"), - P_("Whether buttons in dialogs should use the alternative button order"), - FALSE, - GTK_PARAM_READWRITE), + P_("Alternative button order"), + P_("Whether buttons in dialogs should use the alternative button order"), + FALSE, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_ALTERNATIVE_BUTTON_ORDER); @@ -535,58 +607,58 @@ gtk_settings_class_init (GtkSettingsClass *class) */ result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-alternative-sort-arrows", - P_("Alternative sort indicator direction"), - P_("Whether the direction of the sort indicators in list and tree views is inverted compared to the default (where down means ascending)"), - FALSE, - GTK_PARAM_READWRITE), + P_("Alternative sort indicator direction"), + P_("Whether the direction of the sort indicators in list and tree views is inverted compared to the default (where down means ascending)"), + FALSE, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_ALTERNATIVE_SORT_ARROWS); result = settings_install_property_parser (class, - g_param_spec_boolean ("gtk-show-input-method-menu", - P_("Show the 'Input Methods' menu"), - P_("Whether the context menus of entries and text views should offer to change the input method"), - TRUE, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_boolean ("gtk-show-input-method-menu", + P_("Show the 'Input Methods' menu"), + P_("Whether the context menus of entries and text views should offer to change the input method"), + TRUE, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_SHOW_INPUT_METHOD_MENU); result = settings_install_property_parser (class, - g_param_spec_boolean ("gtk-show-unicode-menu", - P_("Show the 'Insert Unicode Control Character' menu"), - P_("Whether the context menus of entries and text views should offer to insert control characters"), - TRUE, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_boolean ("gtk-show-unicode-menu", + P_("Show the 'Insert Unicode Control Character' menu"), + P_("Whether the context menus of entries and text views should offer to insert control characters"), + TRUE, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_SHOW_UNICODE_MENU); result = settings_install_property_parser (class, - g_param_spec_int ("gtk-timeout-initial", - P_("Start timeout"), - P_("Starting value for timeouts, when button is pressed"), - 0, G_MAXINT, DEFAULT_TIMEOUT_INITIAL, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-timeout-initial", + P_("Start timeout"), + P_("Starting value for timeouts, when button is pressed"), + 0, G_MAXINT, DEFAULT_TIMEOUT_INITIAL, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_TIMEOUT_INITIAL); result = settings_install_property_parser (class, - g_param_spec_int ("gtk-timeout-repeat", - P_("Repeat timeout"), - P_("Repeat value for timeouts, when button is pressed"), - 0, G_MAXINT, DEFAULT_TIMEOUT_REPEAT, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-timeout-repeat", + P_("Repeat timeout"), + P_("Repeat value for timeouts, when button is pressed"), + 0, G_MAXINT, DEFAULT_TIMEOUT_REPEAT, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_TIMEOUT_REPEAT); result = settings_install_property_parser (class, - g_param_spec_int ("gtk-timeout-expand", - P_("Expand timeout"), - P_("Expand value for timeouts, when a widget is expanding a new region"), - 0, G_MAXINT, DEFAULT_TIMEOUT_EXPAND, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-timeout-expand", + P_("Expand timeout"), + P_("Expand value for timeouts, when a widget is expanding a new region"), + 0, G_MAXINT, DEFAULT_TIMEOUT_EXPAND, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_TIMEOUT_EXPAND); @@ -599,11 +671,11 @@ gtk_settings_class_init (GtkSettingsClass *class) * name2: color2 * ... * - * Color names must be acceptable as identifiers in the + * Color names must be acceptable as identifiers in the * gtkrc syntax, and * color specifications must be in the format accepted by * gdk_color_parse(). - * + * * Note that due to the way the color tables from different sources are * merged, color specifications will be converted to hexadecimal form * when getting this property. @@ -615,14 +687,17 @@ gtk_settings_class_init (GtkSettingsClass *class) * * * Since: 2.10 + * + * Deprecated: 3.8: Color scheme support was dropped and is no longer supported. + * You can still set this property, but it will be ignored. */ result = settings_install_property_parser (class, - g_param_spec_string ("gtk-color-scheme", - P_("Color scheme"), - P_("A palette of named colors for use in themes"), - "", - GTK_PARAM_READWRITE), - NULL); + g_param_spec_string ("gtk-color-scheme", + P_("Color scheme"), + P_("A palette of named colors for use in themes"), + "", + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_COLOR_SCHEME); @@ -644,13 +719,16 @@ gtk_settings_class_init (GtkSettingsClass *class) * functionality. * * Since: 2.10 + * + * Deprecated: 3.4. Generally, the behavior for touchscreen input should be + * performed dynamically based on gdk_event_get_source_device(). */ result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-touchscreen-mode", P_("Enable Touchscreen Mode"), P_("When TRUE, there are no motion notify events delivered on this screen"), FALSE, - GTK_PARAM_READWRITE), + GTK_PARAM_READWRITE | G_PARAM_DEPRECATED), NULL); g_assert (result == PROP_TOUCHSCREEN_MODE); @@ -664,13 +742,13 @@ gtk_settings_class_init (GtkSettingsClass *class) * Since: 2.12 */ result = settings_install_property_parser (class, - g_param_spec_int ("gtk-tooltip-timeout", - P_("Tooltip timeout"), - P_("Timeout before tooltip is shown"), - 0, G_MAXINT, - 500, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-tooltip-timeout", + P_("Tooltip timeout"), + P_("Timeout before tooltip is shown"), + 0, G_MAXINT, + 500, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_TOOLTIP_TIMEOUT); @@ -683,20 +761,20 @@ gtk_settings_class_init (GtkSettingsClass *class) * Browse mode is enabled when the mouse pointer moves off an object * where a tooltip was currently being displayed. If the mouse pointer * hits another object before the browse mode timeout expires (see - * #GtkSettings:gtk-tooltip-browse-mode-timeout), it will take the + * #GtkSettings:gtk-tooltip-browse-mode-timeout), it will take the * amount of milliseconds specified by this setting to popup the tooltip * for the new object. * * Since: 2.12 */ result = settings_install_property_parser (class, - g_param_spec_int ("gtk-tooltip-browse-timeout", - P_("Tooltip browse timeout"), - P_("Timeout before tooltip is shown when browse mode is enabled"), - 0, G_MAXINT, - 60, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-tooltip-browse-timeout", + P_("Tooltip browse timeout"), + P_("Timeout before tooltip is shown when browse mode is enabled"), + 0, G_MAXINT, + 60, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_TOOLTIP_BROWSE_TIMEOUT); @@ -712,13 +790,13 @@ gtk_settings_class_init (GtkSettingsClass *class) * Since: 2.12 */ result = settings_install_property_parser (class, - g_param_spec_int ("gtk-tooltip-browse-mode-timeout", - P_("Tooltip browse mode timeout"), - P_("Timeout after which browse mode is disabled"), - 0, G_MAXINT, - 500, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-tooltip-browse-mode-timeout", + P_("Tooltip browse mode timeout"), + P_("Timeout after which browse mode is disabled"), + 0, G_MAXINT, + 500, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_TOOLTIP_BROWSE_MODE_TIMEOUT); @@ -783,12 +861,14 @@ gtk_settings_class_init (GtkSettingsClass *class) /** * GtkSettings:color-hash: * - * Holds a hash table representation of the #GtkSettings:gtk-color-scheme - * setting, mapping color names to #GdkColors. + * Holds a hash table representation of the #GtkSettings:gtk-color-scheme + * setting, mapping color names to #GdkColors. * * Since: 2.10 + * + * Deprecated: 3.8: Will always return an empty hash table. */ - result = settings_install_property_parser (class, + result = settings_install_property_parser (class, g_param_spec_boxed ("color-hash", P_("Color Hash"), P_("A hash table representation of the color scheme."), @@ -797,7 +877,7 @@ gtk_settings_class_init (GtkSettingsClass *class) NULL); g_assert (result == PROP_COLOR_HASH); - result = settings_install_property_parser (class, + result = settings_install_property_parser (class, g_param_spec_string ("gtk-file-chooser-backend", P_("Default file chooser backend"), P_("Name of the GtkFileChooser backend to use by default"), @@ -831,7 +911,7 @@ gtk_settings_class_init (GtkSettingsClass *class) * should contain a %f placeholder, which will get replaced by * the path to the pdf file. The command may also contain a %s * placeholder, which will get replaced by the path to a file - * containing the print settings in the format produced by + * containing the print settings in the format produced by * gtk_print_settings_to_file(). * * The preview application is responsible for removing the pdf file @@ -845,7 +925,7 @@ gtk_settings_class_init (GtkSettingsClass *class) P_("Command to run when displaying a print preview"), GTK_PRINT_PREVIEW_COMMAND, GTK_PARAM_READWRITE), - NULL); + NULL); g_assert (result == PROP_PRINT_PREVIEW_COMMAND); /** @@ -892,31 +972,33 @@ gtk_settings_class_init (GtkSettingsClass *class) * Since: 2.12 */ result = settings_install_property_parser (class, - g_param_spec_int ("gtk-recent-files-limit", - P_("Recent Files Limit"), - P_("Number of recently used files"), - -1, G_MAXINT, - 50, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-recent-files-limit", + P_("Recent Files Limit"), + P_("Number of recently used files"), + -1, G_MAXINT, + 50, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_RECENT_FILES_LIMIT); /** * GtkSettings:gtk-im-module: * - * Which IM (input method) module should be used by default. This is the - * input method that will be used if the user has not explicitly chosen - * another input method from the IM context menu. + * Which IM (input method) module should be used by default. This is the + * input method that will be used if the user has not explicitly chosen + * another input method from the IM context menu. + * This also can be a colon-separated list of input methods, which GTK+ + * will try in turn until it finds one available on the system. * * See #GtkIMContext and see the #GtkSettings:gtk-show-input-method-menu property. */ result = settings_install_property_parser (class, - g_param_spec_string ("gtk-im-module", - P_("Default IM module"), - P_("Which IM module should be used by default"), - NULL, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_string ("gtk-im-module", + P_("Default IM module"), + P_("Which IM module should be used by default"), + NULL, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_IM_MODULE); /** @@ -930,23 +1012,23 @@ gtk_settings_class_init (GtkSettingsClass *class) * Since: 2.14 */ result = settings_install_property_parser (class, - g_param_spec_int ("gtk-recent-files-max-age", - P_("Recent Files Max Age"), - P_("Maximum age of recently used files, in days"), - -1, G_MAXINT, - 30, - GTK_PARAM_READWRITE), - NULL); + g_param_spec_int ("gtk-recent-files-max-age", + P_("Recent Files Max Age"), + P_("Maximum age of recently used files, in days"), + -1, G_MAXINT, + 30, + GTK_PARAM_READWRITE), + NULL); g_assert (result == PROP_RECENT_FILES_MAX_AGE); result = settings_install_property_parser (class, - g_param_spec_uint ("gtk-fontconfig-timestamp", - P_("Fontconfig configuration timestamp"), - P_("Timestamp of current fontconfig configuration"), - 0, G_MAXUINT, 0, - GTK_PARAM_READWRITE), - NULL); - + g_param_spec_uint ("gtk-fontconfig-timestamp", + P_("Fontconfig configuration timestamp"), + P_("Timestamp of current fontconfig configuration"), + 0, G_MAXUINT, 0, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_FONTCONFIG_TIMESTAMP); /** @@ -954,10 +1036,10 @@ gtk_settings_class_init (GtkSettingsClass *class) * * The XDG sound theme to use for event sounds. * - * See the Sound Theme spec + * See the Sound Theme spec * for more information on event sounds and sound themes. * - * GTK+ itself does not support event sounds, you have to use a loadable + * GTK+ itself does not support event sounds, you have to use a loadable * module like the one that comes with libcanberra. * * Since: 2.14 @@ -976,10 +1058,10 @@ gtk_settings_class_init (GtkSettingsClass *class) * * Whether to play event sounds as feedback to user input. * - * See the Sound Theme spec + * See the Sound Theme spec * for more information on event sounds and sound themes. * - * GTK+ itself does not support event sounds, you have to use a loadable + * GTK+ itself does not support event sounds, you have to use a loadable * module like the one that comes with libcanberra. * * Since: 2.14 @@ -987,10 +1069,10 @@ gtk_settings_class_init (GtkSettingsClass *class) result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-enable-input-feedback-sounds", /* Translators: this means sounds that are played as feedback to user input */ - P_("Audible Input Feedback"), - P_("Whether to play event sounds as feedback to user input"), - TRUE, - GTK_PARAM_READWRITE), + P_("Audible Input Feedback"), + P_("Whether to play event sounds as feedback to user input"), + TRUE, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_ENABLE_INPUT_FEEDBACK_SOUNDS); @@ -999,20 +1081,20 @@ gtk_settings_class_init (GtkSettingsClass *class) * * Whether to play any event sounds at all. * - * See the Sound Theme spec + * See the Sound Theme spec * for more information on event sounds and sound themes. * - * GTK+ itself does not support event sounds, you have to use a loadable + * GTK+ itself does not support event sounds, you have to use a loadable * module like the one that comes with libcanberra. * * Since: 2.14 */ result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-enable-event-sounds", - P_("Enable Event Sounds"), - P_("Whether to play any event sounds at all"), - TRUE, - GTK_PARAM_READWRITE), + P_("Enable Event Sounds"), + P_("Whether to play any event sounds at all"), + TRUE, + GTK_PARAM_READWRITE), NULL); g_assert (result == PROP_ENABLE_EVENT_SOUNDS); @@ -1033,7 +1115,7 @@ gtk_settings_class_init (GtkSettingsClass *class) g_assert (result == PROP_ENABLE_TOOLTIPS); /** - * GtkSettings:toolbar-style: + * GtkSettings:gtk-toolbar-style: * * The size of icons in default toolbars. */ @@ -1048,7 +1130,7 @@ gtk_settings_class_init (GtkSettingsClass *class) g_assert (result == PROP_TOOLBAR_STYLE); /** - * GtkSettings:toolbar-icon-size: + * GtkSettings:gtk-toolbar-icon-size: * * The size of icons in default toolbars. */ @@ -1079,6 +1161,41 @@ gtk_settings_class_init (GtkSettingsClass *class) NULL); g_assert (result == PROP_AUTO_MNEMONICS); + /** + * GtkSettings:gtk-primary-button-warps-slider: + * + * Whether a click in a #GtkRange trough should scroll to the click position or + * scroll by a single page in the respective direction. + * + * Since: 3.6 + */ + result = settings_install_property_parser (class, + g_param_spec_boolean ("gtk-primary-button-warps-slider", + P_("Primary button warps slider"), + P_("Whether a primary click on the trough should warp the slider into position"), + TRUE, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_PRIMARY_BUTTON_WARPS_SLIDER); + + /** + * GtkSettings:gtk-visible-focus: + * + * Whether 'focus rectangles' should be always visible, never visible, + * or hidden until the user starts to use the keyboard. + * + * Since: 3.2 + */ + result = settings_install_property_parser (class, + g_param_spec_enum ("gtk-visible-focus", + P_("Visible Focus"), + P_("Whether 'focus rectangles' should be hidden until the user starts to use the keyboard."), + GTK_TYPE_POLICY_TYPE, + GTK_POLICY_ALWAYS, + GTK_PARAM_READWRITE), + gtk_rc_property_parse_enum); + g_assert (result == PROP_VISIBLE_FOCUS); + /** * GtkSettings:gtk-application-prefer-dark-theme: * @@ -1094,7 +1211,7 @@ gtk_settings_class_init (GtkSettingsClass *class) * Dark themes should not be used for documents, where large spaces are white/light * and the dark chrome creates too much contrast (web browser, text editor...). * - * Since: 2.22 + * Since: 3.0 */ result = settings_install_property_parser (class, g_param_spec_boolean ("gtk-application-prefer-dark-theme", @@ -1171,7 +1288,7 @@ gtk_settings_class_init (GtkSettingsClass *class) /** * GtkSettings:gtk-scrolled-window-placement: * - * Where the contents of scrolled windows are located with respect to the + * Where the contents of scrolled windows are located with respect to the * scrollbars, if not overridden by the scrolled window's own placement. * * Since: 2.10 @@ -1252,95 +1369,107 @@ gtk_settings_class_init (GtkSettingsClass *class) GTK_PARAM_READWRITE), gtk_rc_property_parse_enum); g_assert (result == PROP_IM_STATUS_STYLE); -} - -static GtkStyleProperties * -gtk_settings_get_style (GtkStyleProvider *provider, - GtkWidgetPath *path) -{ - PangoFontDescription *font_desc; - gchar *font_name, *color_scheme; - GtkSettings *settings; - GtkStyleProperties *props; - gchar **colors; - guint i; - - settings = GTK_SETTINGS (provider); - props = gtk_style_properties_new (); - - g_object_get (settings, - "gtk-font-name", &font_name, - "gtk-color-scheme", &color_scheme, - NULL); - - colors = g_strsplit_set (color_scheme, "\n;", -1); - - for (i = 0; colors[i]; i++) - { - GtkSymbolicColor *color; - gchar *name, *pos; - GdkRGBA col; - if (!*colors[i]) - continue; - - name = colors[i]; - pos = strchr (colors[i], ':'); - - if (!pos) - continue; + result = settings_install_property_parser (class, + g_param_spec_boolean ("gtk-shell-shows-app-menu", + P_("Desktop shell shows app menu"), + P_("Set to TRUE if the desktop environment " + "is displaying the app menu, FALSE if " + "the app should display it itself."), + FALSE, GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_SHELL_SHOWS_APP_MENU); - /* Set NUL after color name */ - *pos = '\0'; - pos++; + result = settings_install_property_parser (class, + g_param_spec_boolean ("gtk-shell-shows-menubar", + P_("Desktop shell shows the menubar"), + P_("Set to TRUE if the desktop environment " + "is displaying the menubar, FALSE if " + "the app should display it itself."), + FALSE, GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_SHELL_SHOWS_MENUBAR); - /* Find start of color string */ - while (*pos == ' ') - pos++; + /** + * GtkSettings:gtk-enable-primary-paste: + * + * Whether a middle click on a mouse should paste the + * 'PRIMARY' clipboard content at the cursor location. + * + * Since: 3.4 + */ + result = settings_install_property_parser (class, + g_param_spec_boolean ("gtk-enable-primary-paste", + P_("Enable primary paste"), + P_("Whether a middle click on a mouse should paste the 'PRIMARY' clipboard content at the cursor location."), + TRUE, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_ENABLE_PRIMARY_PASTE); - if (!*pos || !gdk_rgba_parse (&col, pos)) - continue; + /** + * GtkSettings:gtk-recent-files-enabled: + * + * Whether GTK+ should keep track of items inside the recently used + * resources list. If set to %FALSE, the list will always be empty. + * + * Since: 3.8 + */ + result = settings_install_property_parser (class, + g_param_spec_boolean ("gtk-recent-files-enabled", + P_("Recent Files Enabled"), + P_("Whether GTK+ remembers recent files"), + TRUE, + GTK_PARAM_READWRITE), + NULL); + g_assert (result == PROP_RECENT_FILES_ENABLED); - color = gtk_symbolic_color_new_literal (&col); - gtk_style_properties_map_color (props, name, color); - gtk_symbolic_color_unref (color); - } + g_type_class_add_private (class, sizeof (GtkSettingsPrivate)); +} - font_desc = pango_font_description_from_string (font_name); +static void +gtk_settings_provider_iface_init (GtkStyleProviderIface *iface) +{ +} - gtk_style_properties_set (props, 0, - "font", font_desc, - NULL); +static GtkCssChange +gtk_settings_style_provider_get_change (GtkStyleProviderPrivate *provider, + const GtkCssMatcher *matcher) +{ + return 0; +} - pango_font_description_free (font_desc); - g_strfreev (colors); - g_free (color_scheme); - g_free (font_name); - return props; +static GtkSettings * +gtk_settings_style_provider_get_settings (GtkStyleProviderPrivate *provider) +{ + return GTK_SETTINGS (provider); } static void -gtk_settings_provider_iface_init (GtkStyleProviderIface *iface) +gtk_settings_provider_private_init (GtkStyleProviderPrivateInterface *iface) { - iface->get_style = gtk_settings_get_style; + iface->get_settings = gtk_settings_style_provider_get_settings; + iface->get_change = gtk_settings_style_provider_get_change; } static void gtk_settings_finalize (GObject *object) { GtkSettings *settings = GTK_SETTINGS (object); + GtkSettingsPrivate *priv = settings->priv; guint i; object_list = g_slist_remove (object_list, settings); - _gtk_rc_context_destroy (settings); - for (i = 0; i < class_n_properties; i++) - g_value_unset (&settings->property_values[i].value); - g_free (settings->property_values); - - g_datalist_clear (&settings->queued_settings); + g_value_unset (&priv->property_values[i].value); + g_free (priv->property_values); + + g_datalist_clear (&priv->queued_settings); + + settings_update_provider (priv->screen, &priv->theme_provider, NULL); + settings_update_provider (priv->screen, &priv->key_theme_provider, NULL); G_OBJECT_CLASS (gtk_settings_parent_class)->finalize (object); } @@ -1349,7 +1478,8 @@ static void settings_init_style (GtkSettings *settings) { static GtkCssProvider *css_provider = NULL; - GtkCssProvider *default_provider; + + GdkScreen *screen = settings->priv->screen; /* Add provider for user file */ if (G_UNLIKELY (!css_provider)) @@ -1369,20 +1499,20 @@ settings_init_style (GtkSettings *settings) g_free (css_path); } - gtk_style_context_add_provider_for_screen (settings->screen, + gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); - default_provider = gtk_css_provider_get_default (); - gtk_style_context_add_provider_for_screen (settings->screen, - GTK_STYLE_PROVIDER (default_provider), - GTK_STYLE_PROVIDER_PRIORITY_FALLBACK); - - gtk_style_context_add_provider_for_screen (settings->screen, + gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (settings), GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); + gtk_style_context_add_provider_for_screen (screen, + GTK_STYLE_PROVIDER (settings->priv->theme_provider), + GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); + settings_update_theme (settings); + settings_update_key_theme (settings); } /** @@ -1405,27 +1535,33 @@ gtk_settings_get_for_screen (GdkScreen *screen) settings = g_object_get_data (G_OBJECT (screen), "gtk-settings"); if (!settings) { - settings = g_object_new (GTK_TYPE_SETTINGS, NULL); - settings->screen = screen; - g_object_set_data_full (G_OBJECT (screen), I_("gtk-settings"), - settings, g_object_unref); +#ifdef GDK_WINDOWING_QUARTZ + if (GDK_IS_QUARTZ_SCREEN (screen)) + settings = g_object_new (GTK_TYPE_SETTINGS, + "gtk-key-theme-name", "Mac", + "gtk-shell-shows-app-menu", TRUE, + "gtk-shell-shows-menubar", TRUE, + NULL); + else +#endif + settings = g_object_new (GTK_TYPE_SETTINGS, NULL); + settings->priv->screen = screen; + g_object_set_data_full (G_OBJECT (screen), I_("gtk-settings"), + settings, g_object_unref); settings_init_style (settings); settings_update_double_click (settings); -#ifdef GDK_WINDOWING_X11 settings_update_cursor_theme (settings); settings_update_resolution (settings); settings_update_font_options (settings); -#endif - settings_update_color_scheme (settings); } - + return settings; } /** * gtk_settings_get_default: - * + * * Gets the #GtkSettings object for the default GDK screen, creating * it if necessary. See gtk_settings_get_for_screen(). * @@ -1445,26 +1581,25 @@ gtk_settings_get_default (void) static void gtk_settings_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) + guint property_id, + const GValue *value, + GParamSpec *pspec) { GtkSettings *settings = GTK_SETTINGS (object); + GtkSettingsPrivate *priv = settings->priv; - g_value_copy (value, &settings->property_values[property_id - 1].value); - settings->property_values[property_id - 1].source = GTK_SETTINGS_SOURCE_APPLICATION; - - if (pspec->param_id == PROP_COLOR_SCHEME) - merge_color_scheme (settings, value, GTK_SETTINGS_SOURCE_APPLICATION); + g_value_copy (value, &priv->property_values[property_id - 1].value); + priv->property_values[property_id - 1].source = GTK_SETTINGS_SOURCE_APPLICATION; } static void gtk_settings_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) + guint property_id, + GValue *value, + GParamSpec *pspec) { GtkSettings *settings = GTK_SETTINGS (object); + GtkSettingsPrivate *priv = settings->priv; GType value_type = G_VALUE_TYPE (value); GType fundamental_type = G_TYPE_FUNDAMENTAL (value_type); @@ -1472,10 +1607,9 @@ gtk_settings_get_property (GObject *object, switch (property_id) { case PROP_COLOR_HASH: - g_value_set_boxed (value, get_color_hash (settings)); - return; - case PROP_COLOR_SCHEME: - g_value_take_string (value, get_color_scheme (settings)); + g_value_take_boxed (value, + g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) gdk_color_free)); return; default: ; } @@ -1489,31 +1623,31 @@ gtk_settings_get_property (GObject *object, g_value_type_transformable (G_TYPE_STRING, G_VALUE_TYPE (value)) || g_value_type_transformable (GDK_TYPE_COLOR, G_VALUE_TYPE (value))) { - if (settings->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION || - !gdk_screen_get_setting (settings->screen, pspec->name, value)) - g_value_copy (&settings->property_values[property_id - 1].value, value); - else + if (priv->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION || + !gdk_screen_get_setting (priv->screen, pspec->name, value)) + g_value_copy (&priv->property_values[property_id - 1].value, value); + else g_param_value_validate (pspec, value); } else { - GValue val = { 0, }; + GValue val = G_VALUE_INIT; /* Try to get xsetting as a string and parse it. */ - + g_value_init (&val, G_TYPE_STRING); - if (settings->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION || - !gdk_screen_get_setting (settings->screen, pspec->name, &val)) + if (priv->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION || + !gdk_screen_get_setting (priv->screen, pspec->name, &val)) { - g_value_copy (&settings->property_values[property_id - 1].value, value); + g_value_copy (&priv->property_values[property_id - 1].value, value); } else { - GValue tmp_value = { 0, }; - GValue gstring_value = { 0, }; + GValue tmp_value = G_VALUE_INIT; + GValue gstring_value = G_VALUE_INIT; GtkRcPropertyParser parser = (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser); - + g_value_init (&gstring_value, G_TYPE_GSTRING); g_value_take_boxed (&gstring_value, g_string_new (g_value_get_string (&val))); @@ -1528,7 +1662,7 @@ gtk_settings_get_property (GObject *object, } else { - g_value_copy (&settings->property_values[property_id - 1].value, value); + g_value_copy (&priv->property_values[property_id - 1].value, value); } g_value_unset (&gstring_value); @@ -1539,14 +1673,21 @@ gtk_settings_get_property (GObject *object, } } +static void +settings_invalidate_style (GtkSettings *settings) +{ + _gtk_style_provider_private_changed (GTK_STYLE_PROVIDER_PRIVATE (settings)); +} + static void gtk_settings_notify (GObject *object, - GParamSpec *pspec) + GParamSpec *pspec) { GtkSettings *settings = GTK_SETTINGS (object); + GtkSettingsPrivate *priv = settings->priv; guint property_id = pspec->param_id; - if (settings->screen == NULL) /* initialization */ + if (priv->screen == NULL) /* initialization */ return; switch (property_id) @@ -1558,46 +1699,51 @@ gtk_settings_notify (GObject *object, case PROP_DOUBLE_CLICK_DISTANCE: settings_update_double_click (settings); break; - case PROP_COLOR_SCHEME: - settings_update_color_scheme (settings); - gtk_style_context_reset_widgets (settings->screen); + case PROP_FONT_NAME: + settings_invalidate_style (settings); + gtk_style_context_reset_widgets (priv->screen); + break; + case PROP_KEY_THEME_NAME: + settings_update_key_theme (settings); break; case PROP_THEME_NAME: + case PROP_APPLICATION_PREFER_DARK_THEME: settings_update_theme (settings); break; -#ifdef GDK_WINDOWING_X11 case PROP_XFT_DPI: settings_update_resolution (settings); /* This is a hack because with gtk_rc_reset_styles() doesn't get * widgets with gtk_widget_style_set(), and also causes more * recomputation than necessary. */ - gtk_style_context_reset_widgets (settings->screen); + gtk_style_context_reset_widgets (priv->screen); break; case PROP_XFT_ANTIALIAS: case PROP_XFT_HINTING: case PROP_XFT_HINTSTYLE: case PROP_XFT_RGBA: settings_update_font_options (settings); - gtk_style_context_reset_widgets (settings->screen); + gtk_style_context_reset_widgets (priv->screen); break; case PROP_FONTCONFIG_TIMESTAMP: if (settings_update_fontconfig (settings)) - gtk_style_context_reset_widgets (settings->screen); + gtk_style_context_reset_widgets (priv->screen); + break; + case PROP_ENABLE_ANIMATIONS: + gtk_style_context_reset_widgets (priv->screen); break; case PROP_CURSOR_THEME_NAME: case PROP_CURSOR_THEME_SIZE: settings_update_cursor_theme (settings); break; -#endif /* GDK_WINDOWING_X11 */ } } gboolean _gtk_settings_parse_convert (GtkRcPropertyParser parser, - const GValue *src_value, - GParamSpec *pspec, - GValue *dest_value) + const GValue *src_value, + GParamSpec *pspec, + GValue *dest_value) { gboolean success = FALSE; @@ -1607,52 +1753,53 @@ _gtk_settings_parse_convert (GtkRcPropertyParser parser, { GString *gstring; gboolean free_gstring = TRUE; - + if (G_VALUE_HOLDS (src_value, G_TYPE_GSTRING)) - { - gstring = g_value_get_boxed (src_value); - free_gstring = FALSE; - } + { + gstring = g_value_get_boxed (src_value); + free_gstring = FALSE; + } else if (G_VALUE_HOLDS_LONG (src_value)) - { - gstring = g_string_new (NULL); - g_string_append_printf (gstring, "%ld", g_value_get_long (src_value)); - } + { + gstring = g_string_new (NULL); + g_string_append_printf (gstring, "%ld", g_value_get_long (src_value)); + } else if (G_VALUE_HOLDS_DOUBLE (src_value)) - { - gstring = g_string_new (NULL); - g_string_append_printf (gstring, "%f", g_value_get_double (src_value)); - } + { + gstring = g_string_new (NULL); + g_string_append_printf (gstring, "%f", g_value_get_double (src_value)); + } else if (G_VALUE_HOLDS_STRING (src_value)) - { - gchar *tstr = g_strescape (g_value_get_string (src_value), NULL); - - gstring = g_string_new ("\""); - g_string_append (gstring, tstr); - g_string_append_c (gstring, '\"'); - g_free (tstr); - } + { + gchar *tstr = g_strescape (g_value_get_string (src_value), NULL); + + gstring = g_string_new (NULL); + g_string_append_c (gstring, '\"'); + g_string_append (gstring, tstr); + g_string_append_c (gstring, '\"'); + g_free (tstr); + } else - { - g_return_val_if_fail (G_VALUE_HOLDS (src_value, G_TYPE_GSTRING), FALSE); - gstring = NULL; /* silence compiler */ - } + { + g_return_val_if_fail (G_VALUE_HOLDS (src_value, G_TYPE_GSTRING), FALSE); + gstring = NULL; /* silence compiler */ + } success = (parser (pspec, gstring, dest_value) && - !g_param_value_validate (pspec, dest_value)); + !g_param_value_validate (pspec, dest_value)); if (free_gstring) - g_string_free (gstring, TRUE); + g_string_free (gstring, TRUE); } else if (G_VALUE_HOLDS (src_value, G_TYPE_GSTRING)) { if (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)) - { - GString *gstring = g_value_get_boxed (src_value); + { + GString *gstring = g_value_get_boxed (src_value); - g_value_set_string (dest_value, gstring ? gstring->str : NULL); - success = !g_param_value_validate (pspec, dest_value); - } + g_value_set_string (dest_value, gstring ? gstring->str : NULL); + success = !g_param_value_validate (pspec, dest_value); + } } else if (g_value_type_transformable (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value))) success = g_param_value_convert (pspec, src_value, dest_value, TRUE); @@ -1661,38 +1808,36 @@ _gtk_settings_parse_convert (GtkRcPropertyParser parser, } static void -apply_queued_setting (GtkSettings *data, - GParamSpec *pspec, - GtkSettingsValuePrivate *qvalue) +apply_queued_setting (GtkSettings *settings, + GParamSpec *pspec, + GtkSettingsValuePrivate *qvalue) { - GValue tmp_value = { 0, }; + GtkSettingsPrivate *priv = settings->priv; + GValue tmp_value = G_VALUE_INIT; GtkRcPropertyParser parser = (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser); g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); if (_gtk_settings_parse_convert (parser, &qvalue->public.value, - pspec, &tmp_value)) + pspec, &tmp_value)) { - if (pspec->param_id == PROP_COLOR_SCHEME) - merge_color_scheme (data, &tmp_value, qvalue->source); - - if (data->property_values[pspec->param_id - 1].source <= qvalue->source) - { - g_value_copy (&tmp_value, &data->property_values[pspec->param_id - 1].value); - data->property_values[pspec->param_id - 1].source = qvalue->source; - g_object_notify (G_OBJECT (data), g_param_spec_get_name (pspec)); - } + if (priv->property_values[pspec->param_id - 1].source <= qvalue->source) + { + g_value_copy (&tmp_value, &priv->property_values[pspec->param_id - 1].value); + priv->property_values[pspec->param_id - 1].source = qvalue->source; + g_object_notify (G_OBJECT (settings), g_param_spec_get_name (pspec)); + } } else { gchar *debug = g_strdup_value_contents (&qvalue->public.value); - + g_message ("%s: failed to retrieve property `%s' of type `%s' from rc file value \"%s\" of type `%s'", - qvalue->public.origin ? qvalue->public.origin : "(for origin information, set GTK_DEBUG)", - pspec->name, - g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), - debug, - G_VALUE_TYPE_NAME (&tmp_value)); + qvalue->public.origin ? qvalue->public.origin : "(for origin information, set GTK_DEBUG)", + pspec->name, + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), + debug, + G_VALUE_TYPE_NAME (&tmp_value)); g_free (debug); } g_value_unset (&tmp_value); @@ -1700,8 +1845,8 @@ apply_queued_setting (GtkSettings *data, static guint settings_install_property_parser (GtkSettingsClass *class, - GParamSpec *pspec, - GtkRcPropertyParser parser) + GParamSpec *pspec, + GtkRcPropertyParser parser) { GSList *node, *next; @@ -1736,10 +1881,10 @@ settings_install_property_parser (GtkSettingsClass *class, if (g_object_class_find_property (G_OBJECT_CLASS (class), pspec->name)) { g_warning (G_STRLOC ": an rc-data property \"%s\" already exists", - pspec->name); + pspec->name); return 0; } - + for (node = object_list; node; node = node->next) g_object_freeze_notify (node->data); @@ -1749,18 +1894,19 @@ settings_install_property_parser (GtkSettingsClass *class, for (node = object_list; node; node = node->next) { GtkSettings *settings = node->data; + GtkSettingsPrivate *priv = settings->priv; GtkSettingsValuePrivate *qvalue; - - settings->property_values = g_renew (GtkSettingsPropertyValue, settings->property_values, class_n_properties); - settings->property_values[class_n_properties - 1].value.g_type = 0; - g_value_init (&settings->property_values[class_n_properties - 1].value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_param_value_set_default (pspec, &settings->property_values[class_n_properties - 1].value); - settings->property_values[class_n_properties - 1].source = GTK_SETTINGS_SOURCE_DEFAULT; + + priv->property_values = g_renew (GtkSettingsPropertyValue, priv->property_values, class_n_properties); + priv->property_values[class_n_properties - 1].value.g_type = 0; + g_value_init (&priv->property_values[class_n_properties - 1].value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_param_value_set_default (pspec, &priv->property_values[class_n_properties - 1].value); + priv->property_values[class_n_properties - 1].source = GTK_SETTINGS_SOURCE_DEFAULT; g_object_notify (G_OBJECT (settings), pspec->name); - - qvalue = g_datalist_get_data (&settings->queued_settings, pspec->name); + + qvalue = g_datalist_get_data (&priv->queued_settings, pspec->name); if (qvalue) - apply_queued_setting (settings, pspec, qvalue); + apply_queued_setting (settings, pspec, qvalue); } for (node = object_list; node; node = next) @@ -1806,9 +1952,14 @@ gtk_settings_install_property (GParamSpec *pspec) settings_install_property_parser (klass, pspec, parser); } +/** + * gtk_settings_install_property_parser: + * @pspec: + * @parser: (scope call): + */ void gtk_settings_install_property_parser (GParamSpec *pspec, - GtkRcPropertyParser parser) + GtkRcPropertyParser parser) { static GtkSettingsClass *klass = NULL; @@ -1825,7 +1976,7 @@ static void free_value (gpointer data) { GtkSettingsValuePrivate *qvalue = data; - + g_value_unset (&qvalue->public.value); g_free (qvalue->public.origin); g_slice_free (GtkSettingsValuePrivate, qvalue); @@ -1833,10 +1984,11 @@ free_value (gpointer data) static void gtk_settings_set_property_value_internal (GtkSettings *settings, - const gchar *prop_name, - const GtkSettingsValue *new_value, - GtkSettingsSource source) + const gchar *prop_name, + const GtkSettingsValue *new_value, + GtkSettingsSource source) { + GtkSettingsPrivate *priv = settings->priv; GtkSettingsValuePrivate *qvalue; GParamSpec *pspec; gchar *name; @@ -1847,20 +1999,20 @@ gtk_settings_set_property_value_internal (GtkSettings *settings, !G_VALUE_HOLDS_STRING (&new_value->value) && !G_VALUE_HOLDS (&new_value->value, G_TYPE_GSTRING)) { - g_warning (G_STRLOC ": value type invalid"); + g_warning (G_STRLOC ": value type invalid (%s)", g_type_name (G_VALUE_TYPE (&new_value->value))); return; } - + name = g_strdup (prop_name); g_strcanon (name, G_CSET_DIGITS "-" G_CSET_a_2_z G_CSET_A_2_Z, '-'); name_quark = g_quark_from_string (name); g_free (name); - qvalue = g_datalist_id_get_data (&settings->queued_settings, name_quark); + qvalue = g_datalist_id_get_data (&priv->queued_settings, name_quark); if (!qvalue) { qvalue = g_slice_new0 (GtkSettingsValuePrivate); - g_datalist_id_set_data_full (&settings->queued_settings, name_quark, qvalue, free_value); + g_datalist_id_set_data_full (&priv->queued_settings, name_quark, qvalue, free_value); } else { @@ -1878,35 +2030,35 @@ gtk_settings_set_property_value_internal (GtkSettings *settings, void gtk_settings_set_property_value (GtkSettings *settings, - const gchar *prop_name, - const GtkSettingsValue *new_value) + const gchar *prop_name, + const GtkSettingsValue *new_value) { g_return_if_fail (GTK_SETTINGS (settings)); g_return_if_fail (prop_name != NULL); g_return_if_fail (new_value != NULL); gtk_settings_set_property_value_internal (settings, prop_name, new_value, - GTK_SETTINGS_SOURCE_APPLICATION); + GTK_SETTINGS_SOURCE_APPLICATION); } void _gtk_settings_set_property_value_from_rc (GtkSettings *settings, - const gchar *prop_name, - const GtkSettingsValue *new_value) + const gchar *prop_name, + const GtkSettingsValue *new_value) { g_return_if_fail (GTK_SETTINGS (settings)); g_return_if_fail (prop_name != NULL); g_return_if_fail (new_value != NULL); gtk_settings_set_property_value_internal (settings, prop_name, new_value, - GTK_SETTINGS_SOURCE_RC_FILE); + GTK_SETTINGS_SOURCE_THEME); } void gtk_settings_set_string_property (GtkSettings *settings, - const gchar *name, - const gchar *v_string, - const gchar *origin) + const gchar *name, + const gchar *v_string, + const gchar *origin) { GtkSettingsValue svalue = { NULL, { 0, }, }; @@ -1923,12 +2075,12 @@ gtk_settings_set_string_property (GtkSettings *settings, void gtk_settings_set_long_property (GtkSettings *settings, - const gchar *name, - glong v_long, - const gchar *origin) + const gchar *name, + glong v_long, + const gchar *origin) { GtkSettingsValue svalue = { NULL, { 0, }, }; - + g_return_if_fail (GTK_SETTINGS (settings)); g_return_if_fail (name != NULL); @@ -1941,9 +2093,9 @@ gtk_settings_set_long_property (GtkSettings *settings, void gtk_settings_set_double_property (GtkSettings *settings, - const gchar *name, - gdouble v_double, - const gchar *origin) + const gchar *name, + gdouble v_double, + const gchar *origin) { GtkSettingsValue svalue = { NULL, { 0, }, }; @@ -1962,21 +2114,21 @@ gtk_settings_set_double_property (GtkSettings *settings, * @pspec: a #GParamSpec * @gstring: the #GString to be parsed * @property_value: a #GValue which must hold #GdkColor values. - * + * * A #GtkRcPropertyParser for use with gtk_settings_install_property_parser() * or gtk_widget_class_install_style_property_parser() which parses a - * color given either by its name or in the form + * color given either by its name or in the form * { red, green, blue } where %red, %green and * %blue are integers between 0 and 65535 or floating-point numbers * between 0 and 1. - * + * * Return value: %TRUE if @gstring could be parsed and @property_value * has been set to the resulting #GdkColor. **/ gboolean gtk_rc_property_parse_color (const GParamSpec *pspec, - const GString *gstring, - GValue *property_value) + const GString *gstring, + GValue *property_value) { GdkColor color = { 0, 0, 0, 0, }; GScanner *scanner; @@ -2005,7 +2157,7 @@ gtk_rc_property_parse_color (const GParamSpec *pspec, * @pspec: a #GParamSpec * @gstring: the #GString to be parsed * @property_value: a #GValue which must hold enum values. - * + * * A #GtkRcPropertyParser for use with gtk_settings_install_property_parser() * or gtk_widget_class_install_style_property_parser() which parses a single * enumeration value. @@ -2013,14 +2165,14 @@ gtk_rc_property_parse_color (const GParamSpec *pspec, * The enumeration value can be specified by its name, its nickname or * its numeric value. For consistency with flags parsing, the value * may be surrounded by parentheses. - * + * * Return value: %TRUE if @gstring could be parsed and @property_value * has been set to the resulting #GEnumValue. **/ gboolean gtk_rc_property_parse_enum (const GParamSpec *pspec, - const GString *gstring, - GValue *property_value) + const GString *gstring, + GValue *property_value) { gboolean need_closing_brace = FALSE, success = FALSE; GScanner *scanner; @@ -2044,15 +2196,15 @@ gtk_rc_property_parse_enum (const GParamSpec *pspec, if (scanner->token == G_TOKEN_IDENTIFIER) { GEnumClass *class = G_PARAM_SPEC_ENUM (pspec)->enum_class; - + enum_value = g_enum_get_value_by_name (class, scanner->value.v_identifier); if (!enum_value) - enum_value = g_enum_get_value_by_nick (class, scanner->value.v_identifier); + enum_value = g_enum_get_value_by_nick (class, scanner->value.v_identifier); if (enum_value) - { - g_value_set_enum (property_value, enum_value->value); - success = TRUE; - } + { + g_value_set_enum (property_value, enum_value->value); + success = TRUE; + } } else if (scanner->token == G_TOKEN_INT) { @@ -2071,8 +2223,8 @@ gtk_rc_property_parse_enum (const GParamSpec *pspec, static guint parse_flags_value (GScanner *scanner, - GFlagsClass *class, - guint *number) + GFlagsClass *class, + guint *number) { g_scanner_get_next_token (scanner); if (scanner->token == G_TOKEN_IDENTIFIER) @@ -2081,12 +2233,12 @@ parse_flags_value (GScanner *scanner, flags_value = g_flags_get_value_by_name (class, scanner->value.v_identifier); if (!flags_value) - flags_value = g_flags_get_value_by_nick (class, scanner->value.v_identifier); + flags_value = g_flags_get_value_by_nick (class, scanner->value.v_identifier); if (flags_value) - { - *number |= flags_value->value; - return G_TOKEN_NONE; - } + { + *number |= flags_value->value; + return G_TOKEN_NONE; + } } else if (scanner->token == G_TOKEN_INT) { @@ -2101,21 +2253,21 @@ parse_flags_value (GScanner *scanner, * @pspec: a #GParamSpec * @gstring: the #GString to be parsed * @property_value: a #GValue which must hold flags values. - * + * * A #GtkRcPropertyParser for use with gtk_settings_install_property_parser() - * or gtk_widget_class_install_style_property_parser() which parses flags. - * + * or gtk_widget_class_install_style_property_parser() which parses flags. + * * Flags can be specified by their name, their nickname or - * numerically. Multiple flags can be specified in the form + * numerically. Multiple flags can be specified in the form * "( flag1 | flag2 | ... )". - * + * * Return value: %TRUE if @gstring could be parsed and @property_value * has been set to the resulting flags value. **/ gboolean gtk_rc_property_parse_flags (const GParamSpec *pspec, - const GString *gstring, - GValue *property_value) + const GString *gstring, + GValue *property_value) { GFlagsClass *class; gboolean success = FALSE; @@ -2133,15 +2285,15 @@ gtk_rc_property_parse_flags (const GParamSpec *pspec, scanner->next_token == G_TOKEN_INT) { guint token, flags_value = 0; - + token = parse_flags_value (scanner, class, &flags_value); if (token == G_TOKEN_NONE && g_scanner_peek_next_token (scanner) == G_TOKEN_EOF) - { - success = TRUE; - g_value_set_flags (property_value, flags_value); - } - + { + success = TRUE; + g_value_set_flags (property_value, flags_value); + } + } else if (g_scanner_get_next_token (scanner) == '(') { @@ -2152,15 +2304,15 @@ gtk_rc_property_parse_flags (const GParamSpec *pspec, /* parse nth values, preceeded by '|' */ while (token == G_TOKEN_NONE && g_scanner_get_next_token (scanner) == '|') - token = parse_flags_value (scanner, class, &flags_value); + token = parse_flags_value (scanner, class, &flags_value); /* done, last token must have closed expression */ if (token == G_TOKEN_NONE && scanner->token == ')' && - g_scanner_peek_next_token (scanner) == G_TOKEN_EOF) - { - g_value_set_flags (property_value, flags_value); - success = TRUE; - } + g_scanner_peek_next_token (scanner) == G_TOKEN_EOF) + { + g_value_set_flags (property_value, flags_value); + success = TRUE; + } } g_scanner_destroy (scanner); @@ -2169,15 +2321,15 @@ gtk_rc_property_parse_flags (const GParamSpec *pspec, static gboolean get_braced_int (GScanner *scanner, - gboolean first, - gboolean last, - gint *value) + gboolean first, + gboolean last, + gint *value) { if (first) { g_scanner_get_next_token (scanner); if (scanner->token != '{') - return FALSE; + return FALSE; } g_scanner_get_next_token (scanner); @@ -2190,13 +2342,13 @@ get_braced_int (GScanner *scanner, { g_scanner_get_next_token (scanner); if (scanner->token != '}') - return FALSE; + return FALSE; } else { g_scanner_get_next_token (scanner); if (scanner->token != ',') - return FALSE; + return FALSE; } return TRUE; @@ -2207,19 +2359,19 @@ get_braced_int (GScanner *scanner, * @pspec: a #GParamSpec * @gstring: the #GString to be parsed * @property_value: a #GValue which must hold boxed values. - * + * * A #GtkRcPropertyParser for use with gtk_settings_install_property_parser() * or gtk_widget_class_install_style_property_parser() which parses a - * requisition in the form + * requisition in the form * "{ width, height }" for integers %width and %height. - * + * * Return value: %TRUE if @gstring could be parsed and @property_value * has been set to the resulting #GtkRequisition. **/ gboolean gtk_rc_property_parse_requisition (const GParamSpec *pspec, - const GString *gstring, - GValue *property_value) + const GString *gstring, + GValue *property_value) { GtkRequisition requisition; GScanner *scanner; @@ -2248,20 +2400,20 @@ gtk_rc_property_parse_requisition (const GParamSpec *pspec, * @pspec: a #GParamSpec * @gstring: the #GString to be parsed * @property_value: a #GValue which must hold boxed values. - * + * * A #GtkRcPropertyParser for use with gtk_settings_install_property_parser() * or gtk_widget_class_install_style_property_parser() which parses - * borders in the form - * "{ left, right, top, bottom }" for integers + * borders in the form + * "{ left, right, top, bottom }" for integers * %left, %right, %top and %bottom. - * + * * Return value: %TRUE if @gstring could be parsed and @property_value * has been set to the resulting #GtkBorder. **/ gboolean gtk_rc_property_parse_border (const GParamSpec *pspec, - const GString *gstring, - GValue *property_value) + const GString *gstring, + GValue *property_value) { GtkBorder border; GScanner *scanner; @@ -2295,61 +2447,48 @@ gtk_rc_property_parse_border (const GParamSpec *pspec, void _gtk_settings_handle_event (GdkEventSetting *event) { + GdkScreen *screen; GtkSettings *settings; GParamSpec *pspec; - guint property_id; - settings = gtk_settings_get_for_screen (gdk_window_get_screen (event->window)); + screen = gdk_window_get_screen (event->window); + settings = gtk_settings_get_for_screen (screen); pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (settings), event->name); - - if (pspec) - { - property_id = pspec->param_id; - if (property_id == PROP_COLOR_SCHEME) - { - GValue value = { 0, }; - - g_value_init (&value, G_TYPE_STRING); - if (!gdk_screen_get_setting (settings->screen, pspec->name, &value)) - g_value_set_static_string (&value, ""); - merge_color_scheme (settings, &value, GTK_SETTINGS_SOURCE_XSETTING); - g_value_unset (&value); - } - g_object_notify (G_OBJECT (settings), pspec->name); - } + if (pspec) + g_object_notify (G_OBJECT (settings), pspec->name); } static void -reset_rc_values_foreach (GQuark key_id, - gpointer data, - gpointer user_data) +reset_rc_values_foreach (GQuark key_id, + gpointer data, + gpointer user_data) { GtkSettingsValuePrivate *qvalue = data; GSList **to_reset = user_data; - if (qvalue->source == GTK_SETTINGS_SOURCE_RC_FILE) + if (qvalue->source == GTK_SETTINGS_SOURCE_THEME) *to_reset = g_slist_prepend (*to_reset, GUINT_TO_POINTER (key_id)); } void _gtk_settings_reset_rc_values (GtkSettings *settings) { + GtkSettingsPrivate *priv = settings->priv; GSList *to_reset = NULL; GSList *tmp_list; GParamSpec **pspecs, **p; gint i; - /* Remove any queued settings - */ - g_datalist_foreach (&settings->queued_settings, - reset_rc_values_foreach, - &to_reset); + /* Remove any queued settings */ + g_datalist_foreach (&priv->queued_settings, + reset_rc_values_foreach, + &to_reset); for (tmp_list = to_reset; tmp_list; tmp_list = tmp_list->next) { GQuark key_id = GPOINTER_TO_UINT (tmp_list->data); - g_datalist_id_remove_data (&settings->queued_settings, key_id); + g_datalist_id_remove_data (&priv->queued_settings, key_id); } g_slist_free (to_reset); @@ -2362,13 +2501,13 @@ _gtk_settings_reset_rc_values (GtkSettings *settings) g_object_freeze_notify (G_OBJECT (settings)); for (p = pspecs; *p; p++) { - if (settings->property_values[i].source == GTK_SETTINGS_SOURCE_RC_FILE) - { - GParamSpec *pspec = *p; + if (priv->property_values[i].source == GTK_SETTINGS_SOURCE_THEME) + { + GParamSpec *pspec = *p; - g_param_value_set_default (pspec, &settings->property_values[i].value); - g_object_notify (G_OBJECT (settings), pspec->name); - } + g_param_value_set_default (pspec, &priv->property_values[i].value); + g_object_notify (G_OBJECT (settings), pspec->name); + } i++; } g_object_thaw_notify (G_OBJECT (settings)); @@ -2378,17 +2517,19 @@ _gtk_settings_reset_rc_values (GtkSettings *settings) static void settings_update_double_click (GtkSettings *settings) { - if (gdk_screen_get_number (settings->screen) == 0) + GtkSettingsPrivate *priv = settings->priv; + + if (gdk_screen_get_number (priv->screen) == 0) { - GdkDisplay *display = gdk_screen_get_display (settings->screen); + GdkDisplay *display = gdk_screen_get_display (priv->screen); gint double_click_time; gint double_click_distance; - - g_object_get (settings, - "gtk-double-click-time", &double_click_time, - "gtk-double-click-distance", &double_click_distance, - NULL); - + + g_object_get (settings, + "gtk-double-click-time", &double_click_time, + "gtk-double-click-distance", &double_click_distance, + NULL); + gdk_display_set_double_click_time (display, double_click_time); gdk_display_set_double_click_distance (display, double_click_distance); } @@ -2398,37 +2539,42 @@ static void settings_update_modules (GtkSettings *settings) { gchar *modules; - - g_object_get (settings, - "gtk-modules", &modules, - NULL); - + + g_object_get (settings, + "gtk-modules", &modules, + NULL); + _gtk_modules_settings_changed (settings, modules); - + g_free (modules); } -#ifdef GDK_WINDOWING_X11 static void settings_update_cursor_theme (GtkSettings *settings) { - GdkDisplay *display = gdk_screen_get_display (settings->screen); +#ifdef GDK_WINDOWING_X11 + GdkDisplay *display = gdk_screen_get_display (settings->priv->screen); gchar *theme = NULL; gint size = 0; - - g_object_get (settings, - "gtk-cursor-theme-name", &theme, - "gtk-cursor-theme-size", &size, - NULL); - - gdk_x11_display_set_cursor_theme (display, theme, size); - g_free (theme); + if (GDK_IS_X11_DISPLAY (display)) + { + g_object_get (settings, + "gtk-cursor-theme-name", &theme, + "gtk-cursor-theme-size", &size, + NULL); + + gdk_x11_display_set_cursor_theme (display, theme, size); + + g_free (theme); + } +#endif } static void settings_update_font_options (GtkSettings *settings) { + GtkSettingsPrivate *priv = settings->priv; gint hinting; gchar *hint_style_str; cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE; @@ -2437,18 +2583,18 @@ settings_update_font_options (GtkSettings *settings) gchar *rgba_str; cairo_subpixel_order_t subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; cairo_font_options_t *options; - + g_object_get (settings, - "gtk-xft-antialias", &antialias, - "gtk-xft-hinting", &hinting, - "gtk-xft-hintstyle", &hint_style_str, - "gtk-xft-rgba", &rgba_str, - NULL); + "gtk-xft-antialias", &antialias, + "gtk-xft-hinting", &hinting, + "gtk-xft-hintstyle", &hint_style_str, + "gtk-xft-rgba", &rgba_str, + NULL); options = cairo_font_options_create (); cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON); - + if (hinting >= 0 && !hinting) { hint_style = CAIRO_HINT_STYLE_NONE; @@ -2456,13 +2602,13 @@ settings_update_font_options (GtkSettings *settings) else if (hint_style_str) { if (strcmp (hint_style_str, "hintnone") == 0) - hint_style = CAIRO_HINT_STYLE_NONE; + hint_style = CAIRO_HINT_STYLE_NONE; else if (strcmp (hint_style_str, "hintslight") == 0) - hint_style = CAIRO_HINT_STYLE_SLIGHT; + hint_style = CAIRO_HINT_STYLE_SLIGHT; else if (strcmp (hint_style_str, "hintmedium") == 0) - hint_style = CAIRO_HINT_STYLE_MEDIUM; + hint_style = CAIRO_HINT_STYLE_MEDIUM; else if (strcmp (hint_style_str, "hintfull") == 0) - hint_style = CAIRO_HINT_STYLE_FULL; + hint_style = CAIRO_HINT_STYLE_FULL; } g_free (hint_style_str); @@ -2472,45 +2618,45 @@ settings_update_font_options (GtkSettings *settings) if (rgba_str) { if (strcmp (rgba_str, "rgb") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; + subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; else if (strcmp (rgba_str, "bgr") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; + subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; else if (strcmp (rgba_str, "vrgb") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; + subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; else if (strcmp (rgba_str, "vbgr") == 0) - subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; + subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; g_free (rgba_str); } cairo_font_options_set_subpixel_order (options, subpixel_order); - + if (antialias >= 0 && !antialias) antialias_mode = CAIRO_ANTIALIAS_NONE; else if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) antialias_mode = CAIRO_ANTIALIAS_SUBPIXEL; else if (antialias >= 0) antialias_mode = CAIRO_ANTIALIAS_GRAY; - + cairo_font_options_set_antialias (options, antialias_mode); - gdk_screen_set_font_options (settings->screen, options); - + gdk_screen_set_font_options (priv->screen, options); + cairo_font_options_destroy (options); } -#ifdef GDK_WINDOWING_X11 static gboolean settings_update_fontconfig (GtkSettings *settings) { +#ifdef GDK_WINDOWING_X11 static guint last_update_timestamp; static gboolean last_update_needed; guint timestamp; g_object_get (settings, - "gtk-fontconfig-timestamp", ×tamp, - NULL); + "gtk-fontconfig-timestamp", ×tamp, + NULL); /* if timestamp is the same as last_update_timestamp, we already have * updated fontconig on this timestamp (another screen requested it perhaps?), @@ -2523,366 +2669,248 @@ settings_update_fontconfig (GtkSettings *settings) /* bug 547680 */ if (PANGO_IS_FC_FONT_MAP (fontmap) && !FcConfigUptoDate (NULL)) - { - pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (fontmap)); - if (FcInitReinitialize ()) - update_needed = TRUE; - } + { + pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (fontmap)); + if (FcInitReinitialize ()) + update_needed = TRUE; + } last_update_timestamp = timestamp; last_update_needed = update_needed; } return last_update_needed; -} +#else + return FALSE; #endif /* GDK_WINDOWING_X11 */ +} static void settings_update_resolution (GtkSettings *settings) { + GtkSettingsPrivate *priv = settings->priv; gint dpi_int; - double dpi; - + gdouble dpi; + g_object_get (settings, - "gtk-xft-dpi", &dpi_int, - NULL); + "gtk-xft-dpi", &dpi_int, + NULL); if (dpi_int > 0) dpi = dpi_int / 1024.; else dpi = -1.; - gdk_screen_set_resolution (settings->screen, dpi); + gdk_screen_set_resolution (priv->screen, dpi); } -#endif - -typedef struct { - GHashTable *color_hash; - GHashTable *tables[GTK_SETTINGS_SOURCE_APPLICATION + 1]; - gchar *lastentry[GTK_SETTINGS_SOURCE_APPLICATION + 1]; -} ColorSchemeData; static void -color_scheme_data_free (ColorSchemeData *data) +settings_update_provider (GdkScreen *screen, + GtkCssProvider **old, + GtkCssProvider *new) { - gint i; - - g_hash_table_unref (data->color_hash); - - for (i = 0; i <= GTK_SETTINGS_SOURCE_APPLICATION; i++) + if (*old != new) { - if (data->tables[i]) - g_hash_table_unref (data->tables[i]); - g_free (data->lastentry[i]); - } - - g_slice_free (ColorSchemeData, data); -} - -static void -settings_update_color_scheme (GtkSettings *settings) -{ - if (!g_object_get_data (G_OBJECT (settings), "gtk-color-scheme")) - { - ColorSchemeData *data; - GValue value = { 0, }; - - data = g_slice_new0 (ColorSchemeData); - data->color_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, - (GDestroyNotify) gdk_color_free); - g_object_set_data_full (G_OBJECT (settings), "gtk-color-scheme", - data, (GDestroyNotify) color_scheme_data_free); + if (*old) + { + gtk_style_context_remove_provider_for_screen (screen, + GTK_STYLE_PROVIDER (*old)); + g_object_unref (*old); + *old = NULL; + } - g_value_init (&value, G_TYPE_STRING); - if (gdk_screen_get_setting (settings->screen, "gtk-color-scheme", &value)) + if (new) { - merge_color_scheme (settings, &value, GTK_SETTINGS_SOURCE_XSETTING); - g_value_unset (&value); + gtk_style_context_add_provider_for_screen (screen, + GTK_STYLE_PROVIDER (new), + GTK_STYLE_PROVIDER_PRIORITY_THEME); + *old = g_object_ref (new); } - } + } } static void settings_update_theme (GtkSettings *settings) { - static GQuark quark_theme_name = 0; - GtkCssProvider *provider, *new_provider = NULL; + GtkSettingsPrivate *priv = settings->priv; gboolean prefer_dark_theme; gchar *theme_name; - if (G_UNLIKELY (!quark_theme_name)) - quark_theme_name = g_quark_from_static_string ("gtk-settings-theme-name"); - - provider = g_object_get_qdata (G_OBJECT (settings), quark_theme_name); - g_object_get (settings, "gtk-theme-name", &theme_name, "gtk-application-prefer-dark-theme", &prefer_dark_theme, NULL); - if (theme_name && *theme_name) + if (!theme_name || !*theme_name) { - gchar *variant = NULL; - - if (prefer_dark_theme) - variant = "dark"; - - new_provider = gtk_css_provider_get_named (theme_name, variant); g_free (theme_name); + theme_name = g_strdup ("Raleigh"); } + + _gtk_css_provider_load_named (priv->theme_provider, + theme_name, + prefer_dark_theme ? "dark" : NULL); - if (new_provider != provider) + if (theme_name && *theme_name) { - if (provider) - gtk_style_context_remove_provider_for_screen (settings->screen, - GTK_STYLE_PROVIDER (provider)); + gchar *theme_dir; + gchar *path; - if (new_provider) - { - gtk_style_context_add_provider_for_screen (settings->screen, - GTK_STYLE_PROVIDER (new_provider), - GTK_STYLE_PROVIDER_PRIORITY_THEME); - g_object_ref (new_provider); - } + /* reload per-theme settings */ + theme_dir = _gtk_css_provider_get_theme_dir (); + path = g_build_filename (theme_dir, theme_name, "gtk-3.0", "settings.ini", NULL); + + if (g_file_test (path, G_FILE_TEST_EXISTS)) + gtk_settings_load_from_key_file (settings, path, GTK_SETTINGS_SOURCE_THEME); - g_object_set_qdata_full (G_OBJECT (settings), quark_theme_name, - new_provider, (GDestroyNotify) g_object_unref); + g_free (theme_dir); + g_free (path); } + + g_free (theme_name); } -static gboolean -add_color_to_hash (gchar *name, - GdkColor *color, - GHashTable *target) +static void +settings_update_key_theme (GtkSettings *settings) { - GdkColor *old; + GtkSettingsPrivate *priv = settings->priv; + GtkCssProvider *provider = NULL; + gchar *key_theme_name; - old = g_hash_table_lookup (target, name); - if (!old || !gdk_color_equal (old, color)) - { - g_hash_table_insert (target, g_strdup (name), gdk_color_copy (color)); + g_object_get (settings, + "gtk-key-theme-name", &key_theme_name, + NULL); - return TRUE; - } + if (key_theme_name && *key_theme_name) + provider = gtk_css_provider_get_named (key_theme_name, "keys"); - return FALSE; + settings_update_provider (priv->screen, &priv->key_theme_provider, provider); + g_free (key_theme_name); } -static gboolean -add_colors_to_hash_from_string (GHashTable *hash, - const gchar *colors) -{ - gchar *s, *p, *name; - GdkColor color; - gboolean changed = FALSE; - gchar *copy; - - copy = g_strdup (colors); - s = copy; - while (s && *s) - { - name = s; - p = strchr (s, ':'); - if (p) - { - *p = '\0'; - p++; - } - else - break; - - while (*p == ' ') - p++; - - s = p; - while (*s) - { - if (*s == '\n' || *s == ';') - { - *s = '\0'; - s++; - break; - } - s++; - } - - if (gdk_color_parse (p, &color)) - changed |= add_color_to_hash (name, &color, hash); - } - - g_free (copy); - return changed; +GdkScreen * +_gtk_settings_get_screen (GtkSettings *settings) +{ + return settings->priv->screen; } -static gboolean -update_color_hash (ColorSchemeData *data, - const gchar *str, - GtkSettingsSource source) + +static void +gtk_settings_load_from_key_file (GtkSettings *settings, + const gchar *path, + GtkSettingsSource source) { - gboolean changed = FALSE; + GError *error; + GKeyFile *keyfile; + gchar **keys; + gsize n_keys; gint i; - GHashTable *old_hash; - GHashTableIter iter; - gpointer name; - gpointer color; - if ((str == NULL || *str == '\0') && - (data->lastentry[source] == NULL || data->lastentry[source][0] == '\0')) - return FALSE; + error = NULL; + keys = NULL; - if (str && data->lastentry[source] && strcmp (str, data->lastentry[source]) == 0) - return FALSE; + keyfile = g_key_file_new (); - /* For the RC_FILE source we merge the values rather than over-writing - * them, since multiple rc files might define independent sets of colors - */ - if ((source != GTK_SETTINGS_SOURCE_RC_FILE) && - data->tables[source] && g_hash_table_size (data->tables[source]) > 0) + if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &error)) { - g_hash_table_unref (data->tables[source]); - data->tables[source] = NULL; - changed = TRUE; /* We can't rely on the code below since str might be "" */ - } - - if (data->tables[source] == NULL) - data->tables[source] = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, - (GDestroyNotify) gdk_color_free); - - g_free (data->lastentry[source]); - data->lastentry[source] = g_strdup (str); + g_warning ("Failed to parse %s: %s", path, error->message); - changed |= add_colors_to_hash_from_string (data->tables[source], str); + g_error_free (error); - if (!changed) - return FALSE; + goto out; + } - /* Rebuild the merged hash table. */ - if (data->color_hash) + keys = g_key_file_get_keys (keyfile, "Settings", &n_keys, &error); + if (error) { - old_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, - (GDestroyNotify) gdk_color_free); + g_warning ("Failed to parse %s: %s", path, error->message); + g_error_free (error); + goto out; + } - g_hash_table_iter_init (&iter, data->color_hash); - while (g_hash_table_iter_next (&iter, &name, &color)) + for (i = 0; i < n_keys; i++) + { + gchar *key; + GParamSpec *pspec; + GType value_type; + GtkSettingsValue svalue = { NULL, { 0, }, }; + + key = keys[i]; + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (settings), key); + if (!pspec) { - g_hash_table_insert (old_hash, name, color); - g_hash_table_iter_steal (&iter); + g_warning ("Unknown key %s in %s", key, path); + continue; } - } - else - { - old_hash = NULL; - } - for (i = 0; i <= GTK_SETTINGS_SOURCE_APPLICATION; i++) - { - if (data->tables[i]) - g_hash_table_foreach (data->tables[i], (GHFunc) add_color_to_hash, - data->color_hash); - } + if (pspec->owner_type != G_OBJECT_TYPE (settings)) + continue; - if (old_hash) - { - /* now check if the merged hash has changed */ - changed = FALSE; - if (g_hash_table_size (old_hash) != g_hash_table_size (data->color_hash)) - changed = TRUE; + value_type = G_PARAM_SPEC_VALUE_TYPE (pspec); + switch (value_type) + { + case G_TYPE_BOOLEAN: + { + gboolean b_val; + + g_value_init (&svalue.value, G_TYPE_LONG); + b_val = g_key_file_get_boolean (keyfile, "Settings", key, &error); + if (!error) + g_value_set_long (&svalue.value, b_val); + break; + } + + case G_TYPE_INT: + { + gint i_val; + + g_value_init (&svalue.value, G_TYPE_LONG); + i_val = g_key_file_get_integer (keyfile, "Settings", key, &error); + if (!error) + g_value_set_long (&svalue.value, i_val); + break; + } + + case G_TYPE_DOUBLE: + { + gdouble d_val; + + g_value_init (&svalue.value, G_TYPE_DOUBLE); + d_val = g_key_file_get_double (keyfile, "Settings", key, &error); + if (!error) + g_value_set_double (&svalue.value, d_val); + break; + } + + default: + { + gchar *s_val; + + g_value_init (&svalue.value, G_TYPE_GSTRING); + s_val = g_key_file_get_string (keyfile, "Settings", key, &error); + if (!error) + g_value_take_boxed (&svalue.value, g_string_new (s_val)); + g_free (s_val); + break; + } + } + if (error) + { + g_warning ("Error setting %s in %s: %s", key, path, error->message); + g_error_free (error); + error = NULL; + } else { - GHashTableIter iter; - gpointer key, value, new_value; - - g_hash_table_iter_init (&iter, old_hash); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - new_value = g_hash_table_lookup (data->color_hash, key); - if (!new_value || !gdk_color_equal (value, new_value)) - { - changed = TRUE; - break; - } - } + if (g_getenv ("GTK_DEBUG")) + svalue.origin = (gchar *)path; + gtk_settings_set_property_value_internal (settings, key, &svalue, source); + g_value_unset (&svalue.value); } - - g_hash_table_unref (old_hash); } - else - changed = TRUE; - - return changed; -} - -static void -merge_color_scheme (GtkSettings *settings, - const GValue *value, - GtkSettingsSource source) -{ - ColorSchemeData *data; - const gchar *colors; - - g_object_freeze_notify (G_OBJECT (settings)); - colors = g_value_get_string (value); - - settings_update_color_scheme (settings); - - data = (ColorSchemeData *) g_object_get_data (G_OBJECT (settings), - "gtk-color-scheme"); - - if (update_color_hash (data, colors, source)) - g_object_notify (G_OBJECT (settings), "color-hash"); - - g_object_thaw_notify (G_OBJECT (settings)); -} - -static GHashTable * -get_color_hash (GtkSettings *settings) -{ - ColorSchemeData *data; - - settings_update_color_scheme (settings); - - data = (ColorSchemeData *)g_object_get_data (G_OBJECT (settings), - "gtk-color-scheme"); - - return data->color_hash; -} - -static void -append_color_scheme (gpointer key, - gpointer value, - gpointer data) -{ - gchar *name = (gchar *)key; - GdkColor *color = (GdkColor *)value; - GString *string = (GString *)data; - - g_string_append_printf (string, "%s: #%04x%04x%04x\n", - name, color->red, color->green, color->blue); -} - -static gchar * -get_color_scheme (GtkSettings *settings) -{ - ColorSchemeData *data; - GString *string; - - settings_update_color_scheme (settings); - - data = (ColorSchemeData *) g_object_get_data (G_OBJECT (settings), - "gtk-color-scheme"); - - string = g_string_new (""); - - g_hash_table_foreach (data->color_hash, append_color_scheme, string); - - return g_string_free (string, FALSE); -} - -GdkScreen * -_gtk_settings_get_screen (GtkSettings *settings) -{ - return settings->screen; + out: + g_strfreev (keys); + g_key_file_free (keyfile); }