* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <config.h>
+#include "gtkmodules.h"
#include "gtksettings.h"
#include "gtkrc.h"
#include "gtkintl.h"
#include "gtkwidget.h"
+#include "gtkprivate.h"
+#include "gtkalias.h"
+
+#ifdef GDK_WINDOWING_X11
+#include "x11/gdkx.h"
+#endif
+
+#if 0
+#include <pango/pangoxft.h>
+#endif
+
+typedef struct _GtkSettingsValuePrivate GtkSettingsValuePrivate;
+
+typedef enum
+{
+ GTK_SETTINGS_SOURCE_DEFAULT,
+ GTK_SETTINGS_SOURCE_RC_FILE,
+ GTK_SETTINGS_SOURCE_APPLICATION
+} GtkSettingsSource;
+
+struct _GtkSettingsValuePrivate
+{
+ GtkSettingsValue public;
+ GtkSettingsSource source;
+};
+
+struct _GtkSettingsPropertyValue
+{
+ GValue value;
+ GtkSettingsSource source;
+};
enum {
PROP_0,
PROP_DOUBLE_CLICK_TIME,
+ PROP_DOUBLE_CLICK_DISTANCE,
PROP_CURSOR_BLINK,
PROP_CURSOR_BLINK_TIME,
PROP_SPLIT_CURSOR,
PROP_THEME_NAME,
+ PROP_ICON_THEME_NAME,
PROP_KEY_THEME_NAME,
- PROP_MENU_BAR_ACCEL
+ PROP_MENU_BAR_ACCEL,
+ PROP_DND_DRAG_THRESHOLD,
+ PROP_FONT_NAME,
+ PROP_ICON_SIZES,
+ PROP_MODULES,
+#ifdef GDK_WINDOWING_X11
+ PROP_XFT_ANTIALIAS,
+ PROP_XFT_HINTING,
+ PROP_XFT_HINTSTYLE,
+ PROP_XFT_RGBA,
+ PROP_XFT_DPI,
+ PROP_CURSOR_THEME_NAME,
+ PROP_CURSOR_THEME_SIZE,
+#endif
+ PROP_ALTERNATIVE_BUTTON_ORDER
};
static void gtk_settings_init (GtkSettings *settings);
static void gtk_settings_class_init (GtkSettingsClass *class);
static void gtk_settings_finalize (GObject *object);
-static GObject* gtk_settings_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties);
static void gtk_settings_get_property (GObject *object,
guint property_id,
GValue *value,
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);
+#endif
+
/* --- variables --- */
static gpointer parent_class = NULL;
-static GtkSettings *the_singleton = NULL;
static GQuark quark_property_parser = 0;
static GSList *object_list = NULL;
static guint class_n_properties = 0;
(GInstanceInitFunc) gtk_settings_init,
};
- settings_type = g_type_register_static (G_TYPE_OBJECT, "GtkSettings", &settings_info, 0);
+ settings_type = g_type_register_static (G_TYPE_OBJECT, "GtkSettings",
+ &settings_info, 0);
}
return settings_type;
for (p = pspecs; *p; p++)
if ((*p)->owner_type == G_OBJECT_TYPE (settings))
i++;
- settings->property_values = g_new0 (GValue, i);
+ settings->property_values = g_new0 (GtkSettingsPropertyValue, i);
i = 0;
g_object_freeze_notify (G_OBJECT (settings));
for (p = pspecs; *p; p++)
if (pspec->owner_type != G_OBJECT_TYPE (settings))
continue;
- g_value_init (settings->property_values + i, G_PARAM_SPEC_VALUE_TYPE (pspec));
- g_param_value_set_default (pspec, settings->property_values + i);
+ 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);
g_object_notify (G_OBJECT (settings), pspec->name);
+ settings->property_values[i].source = GTK_SETTINGS_SOURCE_DEFAULT;
i++;
}
g_object_thaw_notify (G_OBJECT (settings));
parent_class = g_type_class_peek_parent (class);
- gobject_class->constructor = gtk_settings_constructor;
gobject_class->finalize = gtk_settings_finalize;
gobject_class->get_property = gtk_settings_get_property;
gobject_class->set_property = gtk_settings_set_property;
result = settings_install_property_parser (class,
g_param_spec_int ("gtk-double-click-time",
- _("Double Click Time"),
- _("Maximum time allowed between two clicks for them to be considered a double click (in milliseconds)"),
+ P_("Double Click Time"),
+ P_("Maximum time allowed between two clicks for them to be considered a double click (in milliseconds)"),
0, G_MAXINT, 250,
- G_PARAM_READWRITE),
+ GTK_PARAM_READWRITE),
NULL);
g_assert (result == PROP_DOUBLE_CLICK_TIME);
+ result = settings_install_property_parser (class,
+ g_param_spec_int ("gtk-double-click-distance",
+ P_("Double Click Distance"),
+ P_("Maximum distance allowed between two clicks for them to be considered a double click (in pixels)"),
+ 0, G_MAXINT, 5,
+ GTK_PARAM_READWRITE),
+ NULL);
+ g_assert (result == PROP_DOUBLE_CLICK_DISTANCE);
result = settings_install_property_parser (class,
g_param_spec_boolean ("gtk-cursor-blink",
- _("Cursor Blink"),
- _("Whether the cursor should blink"),
+ P_("Cursor Blink"),
+ P_("Whether the cursor should blink"),
TRUE,
- G_PARAM_READWRITE),
+ GTK_PARAM_READWRITE),
NULL);
g_assert (result == PROP_CURSOR_BLINK);
result = settings_install_property_parser (class,
g_param_spec_int ("gtk-cursor-blink-time",
- _("Cursor Blink Time"),
- _("Length of the cursor blink cycle, in milleseconds"),
+ P_("Cursor Blink Time"),
+ P_("Length of the cursor blink cycle, in milleseconds"),
100, G_MAXINT, 1200,
- G_PARAM_READWRITE),
+ GTK_PARAM_READWRITE),
NULL);
g_assert (result == PROP_CURSOR_BLINK_TIME);
result = settings_install_property_parser (class,
g_param_spec_boolean ("gtk-split-cursor",
- _("Split Cursor"),
- _("Whether two cursors should be displayed for mixed left-to-right and right-to-left text"),
+ P_("Split Cursor"),
+ P_("Whether two cursors should be displayed for mixed left-to-right and right-to-left text"),
TRUE,
- G_PARAM_READWRITE),
+ GTK_PARAM_READWRITE),
NULL);
g_assert (result == PROP_SPLIT_CURSOR);
result = settings_install_property_parser (class,
g_param_spec_string ("gtk-theme-name",
- _("Theme Name"),
- _("Name of theme RC file to load"),
- NULL,
- G_PARAM_READWRITE),
+ P_("Theme Name"),
+ P_("Name of theme RC file to load"),
+ "Raleigh",
+ 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),
+ NULL);
+ g_assert (result == PROP_ICON_THEME_NAME);
+
result = settings_install_property_parser (class,
g_param_spec_string ("gtk-key-theme-name",
- _("Key Theme Name"),
- _("Name of key theme RC file to load"),
+ P_("Key Theme Name"),
+ P_("Name of key theme RC file to load"),
NULL,
- G_PARAM_READWRITE),
+ GTK_PARAM_READWRITE),
NULL);
g_assert (result == PROP_KEY_THEME_NAME);
result = settings_install_property_parser (class,
g_param_spec_string ("gtk-menu-bar-accel",
- _("Menu bar accelerator"),
- _("Keybinding to activate the menu bar"),
+ P_("Menu bar accelerator"),
+ P_("Keybinding to activate the menu bar"),
"F10",
- G_PARAM_READWRITE),
+ GTK_PARAM_READWRITE),
NULL);
-
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,
+ GTK_PARAM_READWRITE),
+ 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),
+ NULL);
+ g_assert (result == PROP_FONT_NAME);
+
+ 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),
+ 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),
+ 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_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_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),
+ 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_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_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"),
+ 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"),
+ 0, 128, 24,
+ 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),
+ NULL);
+ g_assert (result == PROP_ALTERNATIVE_BUTTON_ORDER);
}
static void
object_list = g_slist_remove (object_list, settings);
for (i = 0; i < class_n_properties; i++)
- g_value_unset (settings->property_values + i);
+ g_value_unset (&settings->property_values[i].value);
g_free (settings->property_values);
g_datalist_clear (&settings->queued_settings);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-static GObject*
-gtk_settings_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
+/**
+ * gtk_settings_get_for_screen:
+ * @screen : a #GdkScreen.
+ *
+ * Gets the #GtkSettings object for @screen, creating it if necessary.
+ *
+ * Return value: a #GtkSettings object.
+ *
+ * Since: 2.2
+ */
+GtkSettings*
+gtk_settings_get_for_screen (GdkScreen *screen)
{
- GObject *object;
-
- /* currently we're a singleton, that might change with multiple display support though */
- if (!the_singleton)
+ GtkSettings *settings;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ settings = g_object_get_data (G_OBJECT (screen), "gtk-settings");
+ if (!settings)
{
- object = G_OBJECT_CLASS (parent_class)->constructor (type,
- n_construct_properties,
- construct_properties);
- the_singleton = GTK_SETTINGS (g_object_ref (object));
- }
- else
- object = g_object_ref (G_OBJECT (the_singleton));
+ settings = g_object_new (GTK_TYPE_SETTINGS, NULL);
+ settings->screen = screen;
+ g_object_set_data (G_OBJECT (screen), "gtk-settings", settings);
- return object;
+ gtk_rc_reparse_all_for_settings (settings, TRUE);
+ settings_update_double_click (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().
+ *
+ * Return value: a #GtkSettings object. If there is no default
+ * screen, then returns %NULL.
+ **/
GtkSettings*
gtk_settings_get_default (void)
{
- if (!the_singleton)
- g_object_new (GTK_TYPE_SETTINGS, NULL);
-
- return the_singleton; /* we don't add a reference count here, we'd be settings_ref_global() if we did */
+ GdkScreen *screen = gdk_screen_get_default ();
+
+ if (screen)
+ return gtk_settings_get_for_screen (screen);
+ else
+ return NULL;
}
static void
GParamSpec *pspec)
{
GtkSettings *settings = GTK_SETTINGS (object);
-
- g_value_copy (value, settings->property_values + property_id - 1);
+
+ g_value_copy (value, &settings->property_values[property_id - 1].value);
+ settings->property_values[property_id - 1].source = GTK_SETTINGS_SOURCE_APPLICATION;
}
static void
GParamSpec *pspec)
{
GtkSettings *settings = GTK_SETTINGS (object);
+ GType value_type = G_VALUE_TYPE (value);
+ GType fundamental_type = G_TYPE_FUNDAMENTAL (value_type);
- if (g_value_type_transformable (G_TYPE_INT, G_VALUE_TYPE (value)) ||
+ /* For enums and strings, we need to get the value as a string,
+ * not as an int, since we support using names/nicks as the setting
+ * value.
+ */
+ if ((g_value_type_transformable (G_TYPE_INT, value_type) &&
+ !(fundamental_type == G_TYPE_ENUM || fundamental_type == G_TYPE_FLAGS)) ||
g_value_type_transformable (G_TYPE_STRING, G_VALUE_TYPE (value)) ||
g_value_type_transformable (GDK_TYPE_COLOR, G_VALUE_TYPE (value)))
{
- if (gdk_setting_get (pspec->name, value))
- g_param_value_validate (pspec, 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
- g_value_copy (settings->property_values + property_id - 1, value);
+ g_param_value_validate (pspec, value);
}
else
{
g_value_init (&val, G_TYPE_STRING);
- if (!gdk_setting_get (pspec->name, &val))
+ if (settings->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION ||
+ !gdk_screen_get_setting (settings->screen, pspec->name, &val))
{
- g_value_copy (settings->property_values + property_id - 1, value);
+ g_value_copy (&settings->property_values[property_id - 1].value, value);
}
else
{
GValue tmp_value = { 0, };
GValue gstring_value = { 0, };
- GtkRcPropertyParser parser = g_param_spec_get_qdata (pspec,
- quark_property_parser);
+ GtkRcPropertyParser parser = (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser);
g_value_init (&gstring_value, G_TYPE_GSTRING);
- g_value_set_boxed (&gstring_value,
- g_string_new (g_value_get_string (&val)));
+ g_value_take_boxed (&gstring_value,
+ g_string_new (g_value_get_string (&val)));
g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
}
else
{
- g_value_copy (settings->property_values + property_id - 1, value);
+ g_value_copy (&settings->property_values[property_id - 1].value, value);
}
g_value_unset (&gstring_value);
gtk_settings_notify (GObject *object,
GParamSpec *pspec)
{
+ GtkSettings *settings = GTK_SETTINGS (object);
guint property_id = pspec->param_id;
- gint double_click_time;
-
-#if 1
- GValue tmp_value = { 0, };
- gchar *contents;
- g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
- g_object_get_property (object, pspec->name, &tmp_value);
- contents = g_strdup_value_contents (&tmp_value);
+
+ if (settings->screen == NULL) /* initialization */
+ return;
switch (property_id)
{
+ case PROP_MODULES:
+ settings_update_modules (settings);
+ break;
case PROP_DOUBLE_CLICK_TIME:
- g_object_get (object, pspec->name, &double_click_time, NULL);
- gdk_set_double_click_time (double_click_time);
+ case PROP_DOUBLE_CLICK_DISTANCE:
+ settings_update_double_click (settings);
+ break;
+#ifdef GDK_WINDOWING_X11
+ case PROP_XFT_DPI:
+ case PROP_XFT_ANTIALIAS:
+ case PROP_XFT_HINTING:
+ case PROP_XFT_HINTSTYLE:
+ case PROP_XFT_RGBA:
+ /* 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_rc_reset_styles (GTK_SETTINGS (object));
+ break;
+ case PROP_CURSOR_THEME_NAME:
+ case PROP_CURSOR_THEME_SIZE:
+ settings_update_cursor_theme (settings);
break;
+#endif /* GDK_WINDOWING_X11 */
}
-
- g_free (contents);
- g_value_unset (&tmp_value);
-#endif
}
gboolean
}
else if (G_VALUE_HOLDS_LONG (src_value))
{
- gstring = g_string_new ("");
+ 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 ("");
+ 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))
}
static void
-apply_queued_setting (GtkSettings *data,
- GParamSpec *pspec,
- GtkSettingsValue *qvalue)
+apply_queued_setting (GtkSettings *data,
+ GParamSpec *pspec,
+ GtkSettingsValuePrivate *qvalue)
{
GValue tmp_value = { 0, };
- GtkRcPropertyParser parser = g_param_spec_get_qdata (pspec, quark_property_parser);
+ 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->value,
+ if (_gtk_settings_parse_convert (parser, &qvalue->public.value,
pspec, &tmp_value))
- g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
+ {
+ if (data->property_values[pspec->param_id - 1].source <= qvalue->source)
+ {
+ g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
+ data->property_values[pspec->param_id - 1].source = qvalue->source;
+ }
+ }
else
{
- gchar *debug = g_strdup_value_contents (&qvalue->value);
+ 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->origin,
+ qvalue->public.origin,
pspec->name,
g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
debug,
g_object_freeze_notify (node->data);
g_object_class_install_property (G_OBJECT_CLASS (class), ++class_n_properties, pspec);
- g_param_spec_set_qdata (pspec, quark_property_parser, parser);
+ g_param_spec_set_qdata (pspec, quark_property_parser, (gpointer) parser);
for (node = object_list; node; node = node->next)
{
GtkSettings *settings = node->data;
- GtkSettingsValue *qvalue;
+ GtkSettingsValuePrivate *qvalue;
- settings->property_values = g_renew (GValue, settings->property_values, class_n_properties);
- settings->property_values[class_n_properties - 1].g_type = 0;
- g_value_init (settings->property_values + class_n_properties - 1, G_PARAM_SPEC_VALUE_TYPE (pspec));
- g_param_value_set_default (pspec, settings->property_values + class_n_properties - 1);
+ 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;
g_object_notify (G_OBJECT (settings), pspec->name);
qvalue = g_datalist_get_data (&settings->queued_settings, pspec->name);
}
void
-gtk_settings_install_property (GParamSpec *pspec)
+gtk_settings_install_property (GParamSpec *pspec)
{
GtkRcPropertyParser parser;
}
void
-gtk_settings_install_property_parser (GParamSpec *pspec,
- GtkRcPropertyParser parser)
+gtk_settings_install_property_parser (GParamSpec *pspec,
+ GtkRcPropertyParser parser)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
g_return_if_fail (parser != NULL);
static void
free_value (gpointer data)
{
- GtkSettingsValue *qvalue = data;
+ GtkSettingsValuePrivate *qvalue = data;
- g_value_unset (&qvalue->value);
- g_free (qvalue->origin);
+ g_value_unset (&qvalue->public.value);
+ g_free (qvalue->public.origin);
g_free (qvalue);
}
-void
-gtk_settings_set_property_value (GtkSettings *settings,
- const gchar *prop_name,
- const GtkSettingsValue *new_value)
+static void
+gtk_settings_set_property_value_internal (GtkSettings *settings,
+ const gchar *prop_name,
+ const GtkSettingsValue *new_value,
+ GtkSettingsSource source)
{
- GtkSettingsValue *qvalue;
+ GtkSettingsValuePrivate *qvalue;
GParamSpec *pspec;
gchar *name;
GQuark name_quark;
- g_return_if_fail (GTK_SETTINGS (settings));
- g_return_if_fail (prop_name != NULL);
- g_return_if_fail (new_value != NULL);
- g_return_if_fail (new_value->origin != NULL);
-
if (!G_VALUE_HOLDS_LONG (&new_value->value) &&
!G_VALUE_HOLDS_DOUBLE (&new_value->value) &&
!G_VALUE_HOLDS_STRING (&new_value->value) &&
name = g_strdup (prop_name);
g_strcanon (name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
- name_quark = g_quark_try_string (name);
- if (name_quark)
- g_free (name);
- else
- name_quark = g_quark_from_string (name);
+ name_quark = g_quark_from_string (name);
+ g_free (name);
qvalue = g_datalist_id_get_data (&settings->queued_settings, name_quark);
if (!qvalue)
{
- qvalue = g_new0 (GtkSettingsValue, 1);
+ qvalue = g_new0 (GtkSettingsValuePrivate, 1);
g_datalist_id_set_data_full (&settings->queued_settings, name_quark, qvalue, free_value);
}
else
{
- g_free (qvalue->origin);
- g_value_unset (&qvalue->value);
+ g_free (qvalue->public.origin);
+ g_value_unset (&qvalue->public.value);
}
- qvalue->origin = g_strdup (new_value->origin);
- g_value_init (&qvalue->value, G_VALUE_TYPE (&new_value->value));
- g_value_copy (&new_value->value, &qvalue->value);
+ qvalue->public.origin = g_strdup (new_value->origin);
+ g_value_init (&qvalue->public.value, G_VALUE_TYPE (&new_value->value));
+ g_value_copy (&new_value->value, &qvalue->public.value);
+ qvalue->source = source;
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (settings), g_quark_to_string (name_quark));
if (pspec)
apply_queued_setting (settings, pspec, qvalue);
}
+void
+gtk_settings_set_property_value (GtkSettings *settings,
+ 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);
+ g_return_if_fail (new_value->origin != NULL);
+
+ gtk_settings_set_property_value_internal (settings, prop_name, new_value,
+ GTK_SETTINGS_SOURCE_APPLICATION);
+}
+
+void
+_gtk_settings_set_property_value_from_rc (GtkSettings *settings,
+ 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);
+ g_return_if_fail (new_value->origin != NULL);
+
+ gtk_settings_set_property_value_internal (settings, prop_name, new_value,
+ GTK_SETTINGS_SOURCE_RC_FILE);
+}
+
void
gtk_settings_set_string_property (GtkSettings *settings,
const gchar *name,
g_value_unset (&svalue.value);
}
+/**
+ * gtk_rc_property_parse_color:
+ * @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
+ * <literal>{ red, green, blue }</literal> 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,
return success;
}
+/**
+ * gtk_rc_property_parse_enum:
+ * @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.
+ *
+ * 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,
g_scanner_input_text (scanner, gstring->str, gstring->len);
/* we just want to parse _one_ value, but for consistency with flags parsing
- * we support optional paranthesis
+ * we support optional parenthesis
*/
g_scanner_get_next_token (scanner);
if (scanner->token == '(')
return G_TOKEN_IDENTIFIER;
}
+/**
+ * gtk_rc_property_parse_flags:
+ * @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.
+ *
+ * Flags can be specified by their name, their nickname or
+ * numerically. Multiple flags can be specified in the form
+ * <literal>"( flag1 | flag2 | ... )"</literal>.
+ *
+ * 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)
{
GFlagsClass *class;
- gboolean success = FALSE;
+ gboolean success = FALSE;
GScanner *scanner;
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE);
return TRUE;
}
+/**
+ * gtk_rc_property_parse_requisition:
+ * @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
+ * <literal>"{ width, height }"</literal> 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,
return success;
}
+/**
+ * gtk_rc_property_parse_border:
+ * @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
+ * <literal>"{ left, right, top, bottom }"</literal> 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,
void
_gtk_settings_handle_event (GdkEventSetting *event)
{
- GtkSettings *settings = gtk_settings_get_default ();
+ GtkSettings *settings = gtk_settings_get_for_screen (gdk_drawable_get_screen (event->window));
if (g_object_class_find_property (G_OBJECT_GET_CLASS (settings), event->name))
g_object_notify (G_OBJECT (settings), event->name);
}
+
+static void
+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)
+ *to_reset = g_slist_prepend (*to_reset, GUINT_TO_POINTER (key_id));
+}
+
+void
+_gtk_settings_reset_rc_values (GtkSettings *settings)
+{
+ 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);
+
+ 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);
+ }
+
+ /* Now reset the active settings
+ */
+ pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), NULL);
+ i = 0;
+
+ 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;
+
+ g_param_value_set_default (pspec, &settings->property_values[i].value);
+ g_object_notify (G_OBJECT (settings), pspec->name);
+ }
+ i++;
+ }
+ g_object_thaw_notify (G_OBJECT (settings));
+ g_free (pspecs);
+}
+
+static void
+settings_update_double_click (GtkSettings *settings)
+{
+ if (gdk_screen_get_number (settings->screen) == 0)
+ {
+ GdkDisplay *display = gdk_screen_get_display (settings->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);
+
+ gdk_display_set_double_click_time (display, double_click_time);
+ gdk_display_set_double_click_distance (display, double_click_distance);
+ }
+}
+
+static void
+settings_update_modules (GtkSettings *settings)
+{
+ gchar *modules;
+
+ 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);
+ 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);
+}
+#endif
+
+#define __GTK_SETTINGS_C__
+#include "gtkaliasdef.c"