mutter/clutter/clutter-settings.c
Adel Gadllah cfcba18684 clutter-settings: Mark window-scaling-factor as fixed when set by the app
When an application sets the scaling factor manually we should mark it as fixed
and not override it when the xsettings change. This matches GDKs behaviour.

In order for this to work we cannot use the same path when setting the value
internally so introduce a _clutter_settings_set_property_internal and use it
for that.

https://bugzilla.gnome.org/show_bug.cgi?id=735244
2014-08-23 14:02:56 +02:00

891 lines
25 KiB
C

/**
* SECTION:clutter-settings
* @Title: ClutterSettings
* @Short_Description: Settings configuration
*
* Clutter depends on some settings to perform operations like detecting
* multiple button press events, or font options to render text.
*
* Usually, Clutter will strive to use the platform's settings in order
* to be as much integrated as possible. It is, however, possible to
* change these settings on a per-application basis, by using the
* #ClutterSettings singleton object and setting its properties. It is
* also possible, for toolkit developers, to retrieve the settings from
* the #ClutterSettings properties when implementing new UI elements,
* for instance the default font name.
*
* #ClutterSettings is available since Clutter 1.4
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "clutter-settings.h"
#ifdef HAVE_PANGO_FT2
/* for pango_fc_font_map_cache_clear() */
#define PANGO_ENABLE_BACKEND
#include <pango/pangofc-fontmap.h>
#endif /* HAVE_PANGO_FT2 */
#include "clutter-debug.h"
#include "clutter-settings-private.h"
#include "clutter-stage-private.h"
#include "clutter-private.h"
#define DEFAULT_FONT_NAME "Sans 12"
#define CLUTTER_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_SETTINGS, ClutterSettingsClass))
#define CLUTTER_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_SETTINGS))
#define CLUTTER_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_SETTINGS, ClutterSettingsClass))
/**
* ClutterSettings:
*
* <structname>ClutterSettings</structname> is an opaque structure whose
* members cannot be directly accessed.
*
* Since: 1.4
*/
struct _ClutterSettings
{
GObject parent_instance;
ClutterBackend *backend;
gint double_click_time;
gint double_click_distance;
gint dnd_drag_threshold;
gdouble resolution;
gchar *font_name;
gint font_dpi;
gint xft_hinting;
gint xft_antialias;
gchar *xft_hint_style;
gchar *xft_rgba;
gint long_press_duration;
guint last_fontconfig_timestamp;
guint password_hint_time;
gint window_scaling_factor;
gint unscaled_font_dpi;
guint fixed_scaling_factor : 1;
};
struct _ClutterSettingsClass
{
GObjectClass parent_class;
};
enum
{
PROP_0,
PROP_BACKEND,
PROP_DOUBLE_CLICK_TIME,
PROP_DOUBLE_CLICK_DISTANCE,
PROP_DND_DRAG_THRESHOLD,
PROP_FONT_NAME,
PROP_FONT_ANTIALIAS,
PROP_FONT_DPI,
PROP_FONT_HINTING,
PROP_FONT_HINT_STYLE,
PROP_FONT_RGBA,
PROP_LONG_PRESS_DURATION,
PROP_FONTCONFIG_TIMESTAMP,
PROP_PASSWORD_HINT_TIME,
PROP_WINDOW_SCALING_FACTOR,
PROP_UNSCALED_FONT_DPI,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_TYPE (ClutterSettings, clutter_settings, G_TYPE_OBJECT);
static inline void
settings_update_font_options (ClutterSettings *self)
{
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_GRAY;
cairo_subpixel_order_t subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
cairo_font_options_t *options;
if (self->backend == NULL)
return;
options = cairo_font_options_create ();
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
if (self->xft_hinting >= 0 &&
self->xft_hint_style == NULL)
{
hint_style = CAIRO_HINT_STYLE_NONE;
}
else if (self->xft_hint_style != NULL)
{
if (strcmp (self->xft_hint_style, "hintnone") == 0)
hint_style = CAIRO_HINT_STYLE_NONE;
else if (strcmp (self->xft_hint_style, "hintslight") == 0)
hint_style = CAIRO_HINT_STYLE_SLIGHT;
else if (strcmp (self->xft_hint_style, "hintmedium") == 0)
hint_style = CAIRO_HINT_STYLE_MEDIUM;
else if (strcmp (self->xft_hint_style, "hintfull") == 0)
hint_style = CAIRO_HINT_STYLE_FULL;
}
cairo_font_options_set_hint_style (options, hint_style);
if (self->xft_rgba)
{
if (strcmp (self->xft_rgba, "rgb") == 0)
subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
else if (strcmp (self->xft_rgba, "bgr") == 0)
subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
else if (strcmp (self->xft_rgba, "vrgb") == 0)
subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
else if (strcmp (self->xft_rgba, "vbgr") == 0)
subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
}
cairo_font_options_set_subpixel_order (options, subpixel_order);
if (self->xft_antialias >= 0 && !self->xft_antialias)
antialias_mode = CAIRO_ANTIALIAS_NONE;
else if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
antialias_mode = CAIRO_ANTIALIAS_SUBPIXEL;
else if (self->xft_antialias >= 0)
antialias_mode = CAIRO_ANTIALIAS_GRAY;
cairo_font_options_set_antialias (options, antialias_mode);
CLUTTER_NOTE (BACKEND, "New font options:\n"
" - font-name: %s\n"
" - antialias: %d\n"
" - hinting: %d\n"
" - hint-style: %s\n"
" - rgba: %s\n",
self->font_name != NULL ? self->font_name : DEFAULT_FONT_NAME,
self->xft_antialias,
self->xft_hinting,
self->xft_hint_style != NULL ? self->xft_hint_style : "<null>",
self->xft_rgba != NULL ? self->xft_rgba : "<null>");
clutter_backend_set_font_options (self->backend, options);
cairo_font_options_destroy (options);
}
static void
settings_update_font_name (ClutterSettings *self)
{
CLUTTER_NOTE (BACKEND, "New font-name: %s", self->font_name);
if (self->backend != NULL)
g_signal_emit_by_name (self->backend, "font-changed");
}
static void
settings_update_resolution (ClutterSettings *self)
{
const char *scale_env = NULL;
if (self->font_dpi > 0)
self->resolution = (gdouble) self->font_dpi / 1024.0;
else
self->resolution = 96.0;
scale_env = g_getenv ("GDK_DPI_SCALE");
if (scale_env != NULL)
{
double scale = g_ascii_strtod (scale_env, NULL);
if (scale != 0 && self->resolution > 0)
self->resolution *= scale;
}
CLUTTER_NOTE (BACKEND, "New resolution: %.2f (%s)",
self->resolution,
self->unscaled_font_dpi > 0 ? "unscaled" : "scaled");
if (self->backend != NULL)
g_signal_emit_by_name (self->backend, "resolution-changed");
}
static void
settings_update_fontmap (ClutterSettings *self,
guint stamp)
{
if (self->backend == NULL)
return;
#ifdef HAVE_PANGO_FT2
CLUTTER_NOTE (BACKEND, "Update fontmaps (stamp: %d)", stamp);
if (self->last_fontconfig_timestamp != stamp)
{
ClutterMainContext *context;
gboolean update_needed = FALSE;
context = _clutter_context_get_default ();
/* If there is no font map yet then we don't need to do anything
* because the config for fontconfig will be read when it is
* created */
if (context->font_map)
{
PangoFontMap *fontmap = PANGO_FONT_MAP (context->font_map);
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;
}
}
self->last_fontconfig_timestamp = stamp;
if (update_needed)
g_signal_emit_by_name (self->backend, "font-changed");
}
#endif /* HAVE_PANGO_FT2 */
}
static void
clutter_settings_finalize (GObject *gobject)
{
ClutterSettings *self = CLUTTER_SETTINGS (gobject);
g_free (self->font_name);
g_free (self->xft_hint_style);
g_free (self->xft_rgba);
G_OBJECT_CLASS (clutter_settings_parent_class)->finalize (gobject);
}
static void
clutter_settings_set_property (GObject *gobject,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ClutterSettings *self = CLUTTER_SETTINGS (gobject);
switch (prop_id)
{
case PROP_BACKEND:
self->backend = g_value_get_object (value);
break;
case PROP_DOUBLE_CLICK_TIME:
self->double_click_time = g_value_get_int (value);
break;
case PROP_DOUBLE_CLICK_DISTANCE:
self->double_click_distance = g_value_get_int (value);
break;
case PROP_DND_DRAG_THRESHOLD:
self->dnd_drag_threshold = g_value_get_int (value);
break;
case PROP_FONT_NAME:
g_free (self->font_name);
self->font_name = g_value_dup_string (value);
settings_update_font_name (self);
break;
case PROP_FONT_ANTIALIAS:
self->xft_antialias = g_value_get_int (value);
settings_update_font_options (self);
break;
case PROP_FONT_DPI:
self->font_dpi = g_value_get_int (value);
settings_update_resolution (self);
break;
case PROP_FONT_HINTING:
self->xft_hinting = g_value_get_int (value);
settings_update_font_options (self);
break;
case PROP_FONT_HINT_STYLE:
g_free (self->xft_hint_style);
self->xft_hint_style = g_value_dup_string (value);
settings_update_font_options (self);
break;
case PROP_FONT_RGBA:
g_free (self->xft_rgba);
self->xft_rgba = g_value_dup_string (value);
settings_update_font_options (self);
break;
case PROP_LONG_PRESS_DURATION:
self->long_press_duration = g_value_get_int (value);
break;
case PROP_FONTCONFIG_TIMESTAMP:
settings_update_fontmap (self, g_value_get_uint (value));
break;
case PROP_PASSWORD_HINT_TIME:
self->password_hint_time = g_value_get_uint (value);
break;
case PROP_WINDOW_SCALING_FACTOR:
if (!self->fixed_scaling_factor)
{
self->window_scaling_factor = g_value_get_int (value);
self->fixed_scaling_factor = TRUE;
}
break;
case PROP_UNSCALED_FONT_DPI:
self->font_dpi = g_value_get_int (value);
settings_update_resolution (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
void
clutter_settings_set_property_internal (ClutterSettings *self,
const char *property,
GValue *value)
{
property = g_intern_string (property);
if (property == I_("window-scaling-factor") &&
self->fixed_scaling_factor)
return;
g_object_set_property (G_OBJECT (self), property, value);
if (property == I_("window-scaling-factor"))
self->fixed_scaling_factor = FALSE;
}
static void
clutter_settings_get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ClutterSettings *self = CLUTTER_SETTINGS (gobject);
switch (prop_id)
{
case PROP_DOUBLE_CLICK_TIME:
g_value_set_int (value, self->double_click_time);
break;
case PROP_DOUBLE_CLICK_DISTANCE:
g_value_set_int (value, self->double_click_distance);
break;
case PROP_DND_DRAG_THRESHOLD:
g_value_set_int (value, self->dnd_drag_threshold);
break;
case PROP_FONT_NAME:
g_value_set_string (value, self->font_name);
break;
case PROP_FONT_ANTIALIAS:
g_value_set_int (value, self->xft_antialias);
break;
case PROP_FONT_DPI:
g_value_set_int (value, self->resolution * 1024);
break;
case PROP_FONT_HINTING:
g_value_set_int (value, self->xft_hinting);
break;
case PROP_FONT_HINT_STYLE:
g_value_set_string (value, self->xft_hint_style);
break;
case PROP_FONT_RGBA:
g_value_set_string (value, self->xft_rgba);
break;
case PROP_LONG_PRESS_DURATION:
g_value_set_int (value, self->long_press_duration);
break;
case PROP_PASSWORD_HINT_TIME:
g_value_set_uint (value, self->password_hint_time);
break;
case PROP_WINDOW_SCALING_FACTOR:
g_value_set_int (value, self->window_scaling_factor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
}
}
static void
clutter_settings_dispatch_properties_changed (GObject *gobject,
guint n_pspecs,
GParamSpec **pspecs)
{
ClutterSettings *self = CLUTTER_SETTINGS (gobject);
GObjectClass *klass;
/* chain up to emit ::notify */
klass = G_OBJECT_CLASS (clutter_settings_parent_class);
klass->dispatch_properties_changed (gobject, n_pspecs, pspecs);
/* emit settings-changed just once for multiple properties */
if (self->backend != NULL)
g_signal_emit_by_name (self->backend, "settings-changed");
}
static void
clutter_settings_class_init (ClutterSettingsClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
/**
* ClutterSettings:backend:
*
* A back pointer to the #ClutterBackend
*
* Since: 1.4
*
* Deprecated: 1.10
*/
obj_props[PROP_BACKEND] =
g_param_spec_object ("backend",
"Backend",
"A pointer to the backend",
CLUTTER_TYPE_BACKEND,
CLUTTER_PARAM_WRITABLE |
G_PARAM_DEPRECATED |
G_PARAM_CONSTRUCT_ONLY);
/**
* ClutterSettings:double-click-time:
*
* The time, in milliseconds, that should elapse between button-press
* events in order to increase the click count by 1.
*
* Since: 1.4
*/
obj_props[PROP_DOUBLE_CLICK_TIME] =
g_param_spec_int ("double-click-time",
P_("Double Click Time"),
P_("The time between clicks necessary to detect a multiple click"),
0, G_MAXINT,
250,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:double-click-distance:
*
* The maximum distance, in pixels, between button-press events that
* determines whether or not to increase the click count by 1.
*
* Since: 1.4
*/
obj_props[PROP_DOUBLE_CLICK_DISTANCE] =
g_param_spec_int ("double-click-distance",
P_("Double Click Distance"),
P_("The distance between clicks necessary to detect a multiple click"),
0, G_MAXINT,
5,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:dnd-drag-threshold:
*
* The default distance that the cursor of a pointer device
* should travel before a drag operation should start.
*
* Since: 1.8
*/
obj_props[PROP_DND_DRAG_THRESHOLD] =
g_param_spec_int ("dnd-drag-threshold",
P_("Drag Threshold"),
P_("The distance the cursor should travel before starting to drag"),
1, G_MAXINT,
8,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:font-name:
*
* The default font name that should be used by text actors, as
* a string that can be passed to pango_font_description_from_string().
*
* Since: 1.4
*/
obj_props[PROP_FONT_NAME] =
g_param_spec_string ("font-name",
P_("Font Name"),
P_("The description of the default font, as one that could be parsed by Pango"),
NULL,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:font-antialias:
*
* Whether or not to use antialiasing when rendering text; a value
* of 1 enables it unconditionally; a value of 0 disables it
* unconditionally; and -1 will use the system's default.
*
* Since: 1.4
*/
obj_props[PROP_FONT_ANTIALIAS] =
g_param_spec_int ("font-antialias",
P_("Font Antialias"),
P_("Whether to use antialiasing (1 to enable, 0 to disable, and -1 to use the default)"),
-1, 1,
-1,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:font-dpi:
*
* The DPI used when rendering text, as a value of 1024 * dots/inch.
*
* If set to -1, the system's default will be used instead
*
* Since: 1.4
*/
obj_props[PROP_FONT_DPI] =
g_param_spec_int ("font-dpi",
P_("Font DPI"),
P_("The resolution of the font, in 1024 * dots/inch, or -1 to use the default"),
-1, 1024 * 1024,
-1,
CLUTTER_PARAM_READWRITE);
obj_props[PROP_UNSCALED_FONT_DPI] =
g_param_spec_int ("unscaled-font-dpi",
P_("Font DPI"),
P_("The resolution of the font, in 1024 * dots/inch, or -1 to use the default"),
-1, 1024 * 1024,
-1,
CLUTTER_PARAM_WRITABLE);
/**
* ClutterSettings:font-hinting:
*
* Whether or not to use hinting when rendering text; a value of 1
* unconditionally enables it; a value of 0 unconditionally disables
* it; and a value of -1 will use the system's default.
*
* Since: 1.4
*/
obj_props[PROP_FONT_HINTING] =
g_param_spec_int ("font-hinting",
P_("Font Hinting"),
P_("Whether to use hinting (1 to enable, 0 to disable and -1 to use the default)"),
-1, 1,
-1,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:font-hint-style:
*
* The style of the hinting used when rendering text. Valid values
* are:
*
* - hintnone
* - hintslight
* - hintmedium
* - hintfull
*
* Since: 1.4
*/
obj_props[PROP_FONT_HINT_STYLE] =
g_param_spec_string ("font-hint-style",
P_("Font Hint Style"),
P_("The style of hinting (hintnone, hintslight, hintmedium, hintfull)"),
NULL,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:font-subpixel-order:
*
* The type of sub-pixel antialiasing used when rendering text. Valid
* values are:
*
* - none
* - rgb
* - bgr
* - vrgb
* - vbgr
*
* Since: 1.4
*/
obj_props[PROP_FONT_RGBA] =
g_param_spec_string ("font-subpixel-order",
P_("Font Subpixel Order"),
P_("The type of subpixel antialiasing (none, rgb, bgr, vrgb, vbgr)"),
NULL,
CLUTTER_PARAM_READWRITE);
/**
* ClutterSettings:long-press-duration:
*
* Sets the minimum duration for a press to be recognized as a long press
* gesture. The duration is expressed in milliseconds.
*
* See also #ClutterClickAction:long-press-duration.
*
* Since: 1.8
*/
obj_props[PROP_LONG_PRESS_DURATION] =
g_param_spec_int ("long-press-duration",
P_("Long Press Duration"),
P_("The minimum duration for a long press gesture to be recognized"),
0, G_MAXINT,
500,
CLUTTER_PARAM_READWRITE);
obj_props[PROP_WINDOW_SCALING_FACTOR] =
g_param_spec_int ("window-scaling-factor",
P_("Window Scaling Factor"),
P_("The scaling factor to be applied to windows"),
1, G_MAXINT,
1,
CLUTTER_PARAM_READWRITE);
obj_props[PROP_FONTCONFIG_TIMESTAMP] =
g_param_spec_uint ("fontconfig-timestamp",
P_("Fontconfig configuration timestamp"),
P_("Timestamp of the current fontconfig configuration"),
0, G_MAXUINT,
0,
CLUTTER_PARAM_WRITABLE);
/**
* ClutterText:password-hint-time:
*
* How long should Clutter show the last input character in editable
* ClutterText actors. The value is in milliseconds. A value of 0
* disables showing the password hint. 600 is a good value for
* enabling the hint.
*
* Since: 1.10
*/
obj_props[PROP_PASSWORD_HINT_TIME] =
g_param_spec_uint ("password-hint-time",
P_("Password Hint Time"),
P_("How long to show the last input character in hidden entries"),
0, G_MAXUINT,
0,
CLUTTER_PARAM_READWRITE);
gobject_class->set_property = clutter_settings_set_property;
gobject_class->get_property = clutter_settings_get_property;
gobject_class->dispatch_properties_changed =
clutter_settings_dispatch_properties_changed;
gobject_class->finalize = clutter_settings_finalize;
g_object_class_install_properties (gobject_class, PROP_LAST, obj_props);
}
static void
clutter_settings_init (ClutterSettings *self)
{
const char *scale_str;
self->resolution = -1.0;
self->font_dpi = -1;
self->unscaled_font_dpi = -1;
self->double_click_time = 250;
self->double_click_distance = 5;
self->dnd_drag_threshold = 8;
self->font_name = g_strdup (DEFAULT_FONT_NAME);
self->xft_antialias = -1;
self->xft_hinting = -1;
self->xft_hint_style = NULL;
self->xft_rgba = NULL;
self->long_press_duration = 500;
/* if the scaling factor was set by the environment we ignore
* any explicit setting
*/
scale_str = g_getenv ("CLUTTER_SCALE");
if (scale_str != NULL)
{
self->window_scaling_factor = atol (scale_str);
self->fixed_scaling_factor = TRUE;
}
else
self->window_scaling_factor = 1;
}
/**
* clutter_settings_get_default:
*
* Retrieves the singleton instance of #ClutterSettings
*
* Return value: (transfer none): the instance of #ClutterSettings. The
* returned object is owned by Clutter and it should not be unreferenced
* directly
*
* Since: 1.4
*/
ClutterSettings *
clutter_settings_get_default (void)
{
static ClutterSettings *settings = NULL;
if (G_UNLIKELY (settings == NULL))
settings = g_object_new (CLUTTER_TYPE_SETTINGS, NULL);
return settings;
}
void
_clutter_settings_set_backend (ClutterSettings *settings,
ClutterBackend *backend)
{
g_assert (CLUTTER_IS_SETTINGS (settings));
g_assert (CLUTTER_IS_BACKEND (backend));
settings->backend = backend;
}
#define SETTINGS_GROUP "Settings"
void
_clutter_settings_read_from_key_file (ClutterSettings *settings,
GKeyFile *keyfile)
{
GObjectClass *settings_class;
GObject *settings_obj;
GParamSpec **pspecs;
guint n_pspecs, i;
if (!g_key_file_has_group (keyfile, SETTINGS_GROUP))
return;
settings_obj = G_OBJECT (settings);
settings_class = G_OBJECT_GET_CLASS (settings);
pspecs = g_object_class_list_properties (settings_class, &n_pspecs);
for (i = 0; i < n_pspecs; i++)
{
GParamSpec *pspec = pspecs[i];
const gchar *p_name = pspec->name;
GType p_type = G_TYPE_FUNDAMENTAL (pspec->value_type);
GValue value = G_VALUE_INIT;
GError *key_error = NULL;
g_value_init (&value, p_type);
switch (p_type)
{
case G_TYPE_INT:
case G_TYPE_UINT:
{
gint val;
val = g_key_file_get_integer (keyfile,
SETTINGS_GROUP, p_name,
&key_error);
if (p_type == G_TYPE_INT)
g_value_set_int (&value, val);
else
g_value_set_uint (&value, val);
}
break;
case G_TYPE_BOOLEAN:
{
gboolean val;
val = g_key_file_get_boolean (keyfile,
SETTINGS_GROUP, p_name,
&key_error);
g_value_set_boolean (&value, val);
}
break;
case G_TYPE_FLOAT:
case G_TYPE_DOUBLE:
{
gdouble val;
val = g_key_file_get_double (keyfile,
SETTINGS_GROUP, p_name,
&key_error);
if (p_type == G_TYPE_FLOAT)
g_value_set_float (&value, val);
else
g_value_set_double (&value, val);
}
break;
case G_TYPE_STRING:
{
gchar *val;
val = g_key_file_get_string (keyfile,
SETTINGS_GROUP, p_name,
&key_error);
g_value_take_string (&value, val);
}
break;
}
if (key_error != NULL &&
key_error->domain != G_KEY_FILE_ERROR &&
key_error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND)
{
g_critical ("Unable to read the value for setting '%s': %s",
p_name,
key_error->message);
}
if (key_error == NULL)
g_object_set_property (settings_obj, p_name, &value);
else
g_error_free (key_error);
g_value_unset (&value);
}
g_free (pspecs);
}