/** * 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 */ #include "clutter-build-config.h" #include "clutter-settings.h" #ifdef HAVE_PANGO_FT2 /* for pango_fc_font_map_cache_clear() */ #define PANGO_ENABLE_BACKEND #include #endif /* HAVE_PANGO_FT2 */ #include "clutter-debug.h" #include "clutter-settings-private.h" #include "clutter-stage-private.h" #include "clutter-private.h" #include #include #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)) typedef struct { cairo_antialias_t cairo_antialias; gint clutter_font_antialias; cairo_hint_style_t cairo_hint_style; const char *clutter_font_hint_style; cairo_subpixel_order_t cairo_subpixel_order; const char *clutter_font_subpixel_order; } FontSettings; /** * ClutterSettings: * * `ClutterSettings` is an opaque structure whose * members cannot be directly accessed. * * Since: 1.4 */ struct _ClutterSettings { GObject parent_instance; ClutterBackend *backend; GSettings *font_settings; GSettings *mouse_settings; GSettings *mouse_a11y_settings; 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 unscaled_font_dpi; }; 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_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 : "", self->xft_rgba != NULL ? self->xft_rgba : ""); 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 get_font_gsettings (GSettings *settings, FontSettings *output) { /* org.gnome.desktop.GDesktopFontAntialiasingMode */ static const struct { cairo_antialias_t cairo_antialias; gint clutter_font_antialias; } antialiasings[] = { /* none=0 */ {CAIRO_ANTIALIAS_NONE, 0}, /* grayscale=1 */ {CAIRO_ANTIALIAS_GRAY, 1}, /* rgba=2 */ {CAIRO_ANTIALIAS_SUBPIXEL, 1}, }; /* org.gnome.desktop.GDesktopFontHinting */ static const struct { cairo_hint_style_t cairo_hint_style; const char *clutter_font_hint_style; } hintings[] = { /* none=0 */ {CAIRO_HINT_STYLE_NONE, "hintnone"}, /* slight=1 */ {CAIRO_HINT_STYLE_SLIGHT, "hintslight"}, /* medium=2 */ {CAIRO_HINT_STYLE_MEDIUM, "hintmedium"}, /* full=3 */ {CAIRO_HINT_STYLE_FULL, "hintfull"}, }; /* org.gnome.desktop.GDesktopFontRgbaOrder */ static const struct { cairo_subpixel_order_t cairo_subpixel_order; const char *clutter_font_subpixel_order; } rgba_orders[] = { /* rgba=0 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"}, /* XXX what is 'rgba'? */ /* rgb=1 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"}, /* bgr=2 */ {CAIRO_SUBPIXEL_ORDER_BGR, "bgr"}, /* vrgb=3 */ {CAIRO_SUBPIXEL_ORDER_VRGB, "vrgb"}, /* vbgr=4 */ {CAIRO_SUBPIXEL_ORDER_VBGR, "vbgr"}, }; guint i; i = g_settings_get_enum (settings, "font-hinting"); if (i < G_N_ELEMENTS (hintings)) { output->cairo_hint_style = hintings[i].cairo_hint_style; output->clutter_font_hint_style = hintings[i].clutter_font_hint_style; } else { output->cairo_hint_style = CAIRO_HINT_STYLE_DEFAULT; output->clutter_font_hint_style = NULL; } i = g_settings_get_enum (settings, "font-antialiasing"); if (i < G_N_ELEMENTS (antialiasings)) { output->cairo_antialias = antialiasings[i].cairo_antialias; output->clutter_font_antialias = antialiasings[i].clutter_font_antialias; } else { output->cairo_antialias = CAIRO_ANTIALIAS_DEFAULT; output->clutter_font_antialias = -1; } i = g_settings_get_enum (settings, "font-rgba-order"); if (i < G_N_ELEMENTS (rgba_orders)) { output->cairo_subpixel_order = rgba_orders[i].cairo_subpixel_order; output->clutter_font_subpixel_order = rgba_orders[i].clutter_font_subpixel_order; } else { output->cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; output->clutter_font_subpixel_order = NULL; } if (output->cairo_antialias == CAIRO_ANTIALIAS_GRAY) output->clutter_font_subpixel_order = "none"; } static void init_font_options (ClutterSettings *self) { GSettings *settings = self->font_settings; cairo_font_options_t *options = cairo_font_options_create (); FontSettings fs; get_font_gsettings (settings, &fs); cairo_font_options_set_hint_style (options, fs.cairo_hint_style); cairo_font_options_set_antialias (options, fs.cairo_antialias); cairo_font_options_set_subpixel_order (options, fs.cairo_subpixel_order); clutter_backend_set_font_options (self->backend, options); cairo_font_options_destroy (options); } static void sync_mouse_options (ClutterSettings *self) { int double_click; int drag_threshold; double_click = g_settings_get_int (self->mouse_settings, "double-click"); drag_threshold = g_settings_get_int (self->mouse_settings, "drag-threshold"); g_object_set (self, "double-click-time", double_click, "dnd-drag-threshold", drag_threshold, NULL); } static gboolean on_font_settings_change_event (GSettings *settings, gpointer keys, gint n_keys, gpointer user_data) { ClutterSettings *self = CLUTTER_SETTINGS (user_data); FontSettings fs; gint hinting; get_font_gsettings (settings, &fs); hinting = fs.cairo_hint_style == CAIRO_HINT_STYLE_NONE ? 0 : 1; g_object_set (self, "font-hinting", hinting, "font-hint-style", fs.clutter_font_hint_style, "font-antialias", fs.clutter_font_antialias, "font-subpixel-order", fs.clutter_font_subpixel_order, NULL); return FALSE; } static gboolean on_mouse_settings_change_event (GSettings *settings, gpointer keys, gint n_keys, gpointer user_data) { ClutterSettings *self = CLUTTER_SETTINGS (user_data); sync_mouse_options (self); return FALSE; } struct _pointer_a11y_settings_flags_pair { const char *name; ClutterPointerA11yFlags flag; } pointer_a11y_settings_flags_pair[] = { { "secondary-click-enabled", CLUTTER_A11Y_SECONDARY_CLICK_ENABLED }, { "dwell-click-enabled", CLUTTER_A11Y_DWELL_ENABLED }, }; static ClutterPointerA11yDwellDirection pointer_a11y_dwell_direction_from_setting (ClutterSettings *self, const char *key) { GDesktopMouseDwellDirection dwell_gesture_direction; dwell_gesture_direction = g_settings_get_enum (self->mouse_a11y_settings, key); switch (dwell_gesture_direction) { case G_DESKTOP_MOUSE_DWELL_DIRECTION_LEFT: return CLUTTER_A11Y_DWELL_DIRECTION_LEFT; break; case G_DESKTOP_MOUSE_DWELL_DIRECTION_RIGHT: return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT; break; case G_DESKTOP_MOUSE_DWELL_DIRECTION_UP: return CLUTTER_A11Y_DWELL_DIRECTION_UP; break; case G_DESKTOP_MOUSE_DWELL_DIRECTION_DOWN: return CLUTTER_A11Y_DWELL_DIRECTION_DOWN; break; default: break; } return CLUTTER_A11Y_DWELL_DIRECTION_NONE; } static void sync_pointer_a11y_settings (ClutterSettings *self, ClutterSeat *seat) { ClutterPointerA11ySettings pointer_a11y_settings; GDesktopMouseDwellMode dwell_mode; int i; clutter_seat_get_pointer_a11y_settings (seat, &pointer_a11y_settings); pointer_a11y_settings.controls = 0; for (i = 0; i < G_N_ELEMENTS (pointer_a11y_settings_flags_pair); i++) { if (!g_settings_get_boolean (self->mouse_a11y_settings, pointer_a11y_settings_flags_pair[i].name)) continue; pointer_a11y_settings.controls |= pointer_a11y_settings_flags_pair[i].flag; } /* "secondary-click-time" is expressed in seconds */ pointer_a11y_settings.secondary_click_delay = (1000 * g_settings_get_double (self->mouse_a11y_settings, "secondary-click-time")); /* "dwell-time" is expressed in seconds */ pointer_a11y_settings.dwell_delay = (1000 * g_settings_get_double (self->mouse_a11y_settings, "dwell-time")); pointer_a11y_settings.dwell_threshold = g_settings_get_int (self->mouse_a11y_settings, "dwell-threshold"); dwell_mode = g_settings_get_enum (self->mouse_a11y_settings, "dwell-mode"); if (dwell_mode == G_DESKTOP_MOUSE_DWELL_MODE_WINDOW) pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_WINDOW; else pointer_a11y_settings.dwell_mode = CLUTTER_A11Y_DWELL_MODE_GESTURE; pointer_a11y_settings.dwell_gesture_single = pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-single"); pointer_a11y_settings.dwell_gesture_double = pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-double"); pointer_a11y_settings.dwell_gesture_drag = pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-drag"); pointer_a11y_settings.dwell_gesture_secondary = pointer_a11y_dwell_direction_from_setting (self, "dwell-gesture-secondary"); clutter_seat_set_pointer_a11y_settings (seat, &pointer_a11y_settings); } static gboolean on_mouse_a11y_settings_change_event (GSettings *settings, gpointer keys, int n_keys, gpointer user_data) { ClutterSettings *self = CLUTTER_SETTINGS (user_data); ClutterSeat *seat = clutter_backend_get_default_seat (self->backend); sync_pointer_a11y_settings (self, seat); return FALSE; } static void load_initial_settings (ClutterSettings *self) { static const gchar *font_settings_path = "org.gnome.desktop.interface"; static const gchar *mouse_settings_path = "org.gnome.desktop.peripherals.mouse"; static const char *mouse_a11y_settings_path = "org.gnome.desktop.a11y.mouse"; GSettingsSchemaSource *source = g_settings_schema_source_get_default (); GSettingsSchema *schema; schema = g_settings_schema_source_lookup (source, font_settings_path, TRUE); if (!schema) { g_warning ("Failed to find schema: %s", font_settings_path); } else { self->font_settings = g_settings_new_full (schema, NULL, NULL); if (self->font_settings) { init_font_options (self); g_signal_connect (self->font_settings, "change-event", G_CALLBACK (on_font_settings_change_event), self); } } schema = g_settings_schema_source_lookup (source, mouse_settings_path, TRUE); if (!schema) { g_warning ("Failed to find schema: %s", mouse_settings_path); } else { self->mouse_settings = g_settings_new_full (schema, NULL, NULL); if (self->mouse_settings) { sync_mouse_options (self); g_signal_connect (self->mouse_settings, "change-event", G_CALLBACK (on_mouse_settings_change_event), self); } } schema = g_settings_schema_source_lookup (source, mouse_a11y_settings_path, TRUE); if (!schema) { g_warning ("Failed to find schema: %s", mouse_settings_path); } else { self->mouse_a11y_settings = g_settings_new_full (schema, NULL, NULL); g_signal_connect (self->mouse_a11y_settings, "change-event", G_CALLBACK (on_mouse_a11y_settings_change_event), self); } } 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_clear_object (&self->font_settings); g_clear_object (&self->mouse_settings); g_clear_object (&self->mouse_a11y_settings); 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_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); g_object_set_property (G_OBJECT (self), property, value); } 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; 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_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) { 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; } /** * 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; load_initial_settings (settings); } void clutter_settings_ensure_pointer_a11y_settings (ClutterSettings *settings, ClutterSeat *seat) { sync_pointer_a11y_settings (settings, seat); }