summaryrefslogtreecommitdiffstats
path: root/src/st/st-settings.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/st/st-settings.c402
1 files changed, 402 insertions, 0 deletions
diff --git a/src/st/st-settings.c b/src/st/st-settings.c
new file mode 100644
index 0000000..0ece3cc
--- /dev/null
+++ b/src/st/st-settings.c
@@ -0,0 +1,402 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * st-settings.c: Global settings
+ *
+ * Copyright 2019 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include <gio/gio.h>
+
+#include "st-private.h"
+#include "st-settings.h"
+
+#define KEY_ENABLE_ANIMATIONS "enable-animations"
+#define KEY_PRIMARY_PASTE "gtk-enable-primary-paste"
+#define KEY_DRAG_THRESHOLD "drag-threshold"
+#define KEY_FONT_NAME "font-name"
+#define KEY_GTK_THEME "gtk-theme"
+#define KEY_GTK_ICON_THEME "icon-theme"
+#define KEY_MAGNIFIER_ACTIVE "screen-magnifier-enabled"
+
+enum {
+ PROP_0,
+ PROP_ENABLE_ANIMATIONS,
+ PROP_PRIMARY_PASTE,
+ PROP_DRAG_THRESHOLD,
+ PROP_FONT_NAME,
+ PROP_GTK_THEME,
+ PROP_GTK_ICON_THEME,
+ PROP_MAGNIFIER_ACTIVE,
+ PROP_SLOW_DOWN_FACTOR,
+ N_PROPS
+};
+
+GParamSpec *props[N_PROPS] = { 0 };
+
+struct _StSettings
+{
+ GObject parent_object;
+ GSettings *interface_settings;
+ GSettings *mouse_settings;
+ GSettings *a11y_settings;
+
+ gchar *font_name;
+ gchar *gtk_theme;
+ gchar *gtk_icon_theme;
+ int inhibit_animations_count;
+ gboolean enable_animations;
+ gboolean primary_paste;
+ gboolean magnifier_active;
+ gint drag_threshold;
+ double slow_down_factor;
+};
+
+G_DEFINE_TYPE (StSettings, st_settings, G_TYPE_OBJECT)
+
+#define EPSILON (1e-10)
+
+static void
+st_settings_set_slow_down_factor (StSettings *settings,
+ double factor)
+{
+ if (fabs (settings->slow_down_factor - factor) < EPSILON)
+ return;
+
+ settings->slow_down_factor = factor;
+ g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_SLOW_DOWN_FACTOR]);
+}
+
+static gboolean
+get_enable_animations (StSettings *settings)
+{
+ if (settings->inhibit_animations_count > 0)
+ return FALSE;
+ else
+ return settings->enable_animations;
+}
+
+void
+st_settings_inhibit_animations (StSettings *settings)
+{
+ gboolean enable_animations;
+
+ enable_animations = get_enable_animations (settings);
+ settings->inhibit_animations_count++;
+
+ if (enable_animations != get_enable_animations (settings))
+ g_object_notify_by_pspec (G_OBJECT (settings),
+ props[PROP_ENABLE_ANIMATIONS]);
+}
+
+void
+st_settings_uninhibit_animations (StSettings *settings)
+{
+ gboolean enable_animations;
+
+ enable_animations = get_enable_animations (settings);
+ settings->inhibit_animations_count--;
+
+ if (enable_animations != get_enable_animations (settings))
+ g_object_notify_by_pspec (G_OBJECT (settings),
+ props[PROP_ENABLE_ANIMATIONS]);
+}
+
+static void
+st_settings_finalize (GObject *object)
+{
+ StSettings *settings = ST_SETTINGS (object);
+
+ g_object_unref (settings->interface_settings);
+ g_object_unref (settings->mouse_settings);
+ g_object_unref (settings->a11y_settings);
+ g_free (settings->font_name);
+ g_free (settings->gtk_theme);
+ g_free (settings->gtk_icon_theme);
+
+ G_OBJECT_CLASS (st_settings_parent_class)->finalize (object);
+}
+
+static void
+st_settings_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ StSettings *settings = ST_SETTINGS (object);
+
+ switch (prop_id)
+ {
+ case PROP_SLOW_DOWN_FACTOR:
+ st_settings_set_slow_down_factor (settings, g_value_get_double (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+st_settings_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ StSettings *settings = ST_SETTINGS (object);
+
+ switch (prop_id)
+ {
+ case PROP_ENABLE_ANIMATIONS:
+ g_value_set_boolean (value, get_enable_animations (settings));
+ break;
+ case PROP_PRIMARY_PASTE:
+ g_value_set_boolean (value, settings->primary_paste);
+ break;
+ case PROP_DRAG_THRESHOLD:
+ g_value_set_int (value, settings->drag_threshold);
+ break;
+ case PROP_FONT_NAME:
+ g_value_set_string (value, settings->font_name);
+ break;
+ case PROP_GTK_THEME:
+ g_value_set_string (value, settings->gtk_theme);
+ break;
+ case PROP_GTK_ICON_THEME:
+ g_value_set_string (value, settings->gtk_icon_theme);
+ break;
+ case PROP_MAGNIFIER_ACTIVE:
+ g_value_set_boolean (value, settings->magnifier_active);
+ break;
+ case PROP_SLOW_DOWN_FACTOR:
+ g_value_set_double (value, settings->slow_down_factor);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+st_settings_class_init (StSettingsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = st_settings_finalize;
+ object_class->set_property = st_settings_set_property;
+ object_class->get_property = st_settings_get_property;
+
+ /**
+ * StSettings:enable-animations:
+ *
+ * Whether animations are enabled.
+ */
+ props[PROP_ENABLE_ANIMATIONS] = g_param_spec_boolean ("enable-animations",
+ "Enable animations",
+ "Enable animations",
+ TRUE,
+ ST_PARAM_READABLE);
+
+ /**
+ * StSettings:primary-paste:
+ *
+ * Whether pasting from the `PRIMARY` selection is supported (eg. middle-click
+ * paste).
+ */
+ props[PROP_PRIMARY_PASTE] = g_param_spec_boolean ("primary-paste",
+ "Primary paste",
+ "Primary paste",
+ TRUE,
+ ST_PARAM_READABLE);
+
+ /**
+ * StSettings:drag-threshold:
+ *
+ * The threshold before a drag operation begins.
+ */
+ props[PROP_DRAG_THRESHOLD] = g_param_spec_int ("drag-threshold",
+ "Drag threshold",
+ "Drag threshold",
+ 0, G_MAXINT, 8,
+ ST_PARAM_READABLE);
+
+ /**
+ * StSettings:font-name:
+ *
+ * The current font name.
+ */
+ props[PROP_FONT_NAME] = g_param_spec_string ("font-name",
+ "font name",
+ "font name",
+ "",
+ ST_PARAM_READABLE);
+
+ /**
+ * StSettings:gtk-theme:
+ *
+ * The current GTK theme.
+ */
+ props[PROP_GTK_THEME] = g_param_spec_string ("gtk-theme",
+ "GTK Theme",
+ "GTK Theme",
+ "",
+ ST_PARAM_READABLE);
+
+ /**
+ * StSettings:gtk-icon-theme:
+ *
+ * The current GTK icon theme
+ */
+ props[PROP_GTK_ICON_THEME] = g_param_spec_string ("gtk-icon-theme",
+ "GTK Icon Theme",
+ "GTK Icon Theme",
+ "",
+ ST_PARAM_READABLE);
+
+ /**
+ * StSettings:magnifier-active:
+ *
+ * Whether the accessibility magnifier is active.
+ */
+ props[PROP_MAGNIFIER_ACTIVE] = g_param_spec_boolean("magnifier-active",
+ "Magnifier is active",
+ "Whether the a11y magnifier is active",
+ FALSE,
+ ST_PARAM_READABLE);
+
+ /**
+ * StSettings:slow-down-factor:
+ *
+ * The slow-down factor applied to all animation durations.
+ */
+ props[PROP_SLOW_DOWN_FACTOR] = g_param_spec_double("slow-down-factor",
+ "Slow down factor",
+ "Factor applied to all animation durations",
+ EPSILON, G_MAXDOUBLE, 1.0,
+ ST_PARAM_READWRITE);
+
+ g_object_class_install_properties (object_class, N_PROPS, props);
+}
+
+static void
+on_interface_settings_changed (GSettings *g_settings,
+ const gchar *key,
+ StSettings *settings)
+{
+ if (g_str_equal (key, KEY_ENABLE_ANIMATIONS))
+ {
+ settings->enable_animations = g_settings_get_boolean (g_settings, key);
+ g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_ENABLE_ANIMATIONS]);
+ }
+ else if (g_str_equal (key, KEY_PRIMARY_PASTE))
+ {
+ settings->primary_paste = g_settings_get_boolean (g_settings, key);
+ g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_PRIMARY_PASTE]);
+ }
+ else if (g_str_equal (key, KEY_FONT_NAME))
+ {
+ g_free (settings->font_name);
+ settings->font_name = g_settings_get_string (g_settings, key);
+ g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_FONT_NAME]);
+ }
+ else if (g_str_equal (key, KEY_GTK_THEME))
+ {
+ g_free (settings->gtk_theme);
+ settings->gtk_theme = g_settings_get_string (g_settings, key);
+ g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_GTK_THEME]);
+ }
+ else if (g_str_equal (key, KEY_GTK_ICON_THEME))
+ {
+ g_free (settings->gtk_icon_theme);
+ settings->gtk_icon_theme = g_settings_get_string (g_settings, key);
+ g_object_notify_by_pspec (G_OBJECT (settings),
+ props[PROP_GTK_ICON_THEME]);
+ }
+}
+
+static void
+on_mouse_settings_changed (GSettings *g_settings,
+ const gchar *key,
+ StSettings *settings)
+{
+ if (g_str_equal (key, KEY_DRAG_THRESHOLD))
+ {
+ settings->drag_threshold = g_settings_get_int (g_settings, key);
+ g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_DRAG_THRESHOLD]);
+ }
+}
+
+static void
+on_a11y_settings_changed (GSettings *g_settings,
+ const gchar *key,
+ StSettings *settings)
+{
+ if (g_str_equal (key, KEY_MAGNIFIER_ACTIVE))
+ {
+ settings->magnifier_active = g_settings_get_boolean (g_settings, key);
+ g_object_notify_by_pspec (G_OBJECT (settings), props[PROP_MAGNIFIER_ACTIVE]);
+ }
+}
+
+static void
+st_settings_init (StSettings *settings)
+{
+ settings->interface_settings = g_settings_new ("org.gnome.desktop.interface");
+ g_signal_connect (settings->interface_settings, "changed",
+ G_CALLBACK (on_interface_settings_changed), settings);
+
+ settings->mouse_settings = g_settings_new ("org.gnome.settings-daemon.peripherals.mouse");
+ g_signal_connect (settings->interface_settings, "changed",
+ G_CALLBACK (on_mouse_settings_changed), settings);
+
+ settings->a11y_settings = g_settings_new ("org.gnome.desktop.a11y.applications");
+ g_signal_connect (settings->a11y_settings, "changed",
+ G_CALLBACK (on_a11y_settings_changed), settings);
+
+ settings->enable_animations = g_settings_get_boolean (settings->interface_settings,
+ KEY_ENABLE_ANIMATIONS);
+ settings->primary_paste = g_settings_get_boolean (settings->interface_settings,
+ KEY_PRIMARY_PASTE);
+ settings->font_name = g_settings_get_string (settings->interface_settings,
+ KEY_FONT_NAME);
+ settings->gtk_theme = g_settings_get_string (settings->interface_settings,
+ KEY_GTK_THEME);
+ settings->gtk_icon_theme = g_settings_get_string (settings->interface_settings,
+ KEY_GTK_ICON_THEME);
+ settings->drag_threshold = g_settings_get_int (settings->mouse_settings,
+ KEY_DRAG_THRESHOLD);
+ settings->magnifier_active = g_settings_get_boolean (settings->a11y_settings,
+ KEY_MAGNIFIER_ACTIVE);
+ settings->slow_down_factor = 1.;
+}
+
+/**
+ * st_settings_get:
+ *
+ * Gets the global #StSettings object.
+ *
+ * Returns: (transfer none): the global #StSettings object
+ **/
+StSettings *
+st_settings_get (void)
+{
+ static StSettings *settings = NULL;
+
+ if (!settings)
+ settings = g_object_new (ST_TYPE_SETTINGS, NULL);
+
+ return settings;
+}