[mutter] backend: Add 'experimental-features' gsetting



commit 094e0356e854c7525c991bdd580b8c5d1b532e0c
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Feb 24 17:48:19 2017 +0800

    backend: Add 'experimental-features' gsetting
    
    This gsetting will allow the adding of keywords to a array, where each
    keyword may enable an experimental feauter, if the given mutter version
    supports that particular experimental feature. Emphasis is put on the
    lack of guarantee that any such keyword has any effect. Currently no
    keywords are defined.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777732

 data/org.gnome.mutter.gschema.xml.in |   14 +++++
 src/backends/meta-backend-private.h  |   13 ++++
 src/backends/meta-backend.c          |  106 ++++++++++++++++++++++++++++++++++
 3 files changed, 133 insertions(+), 0 deletions(-)
---
diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in
index a96af4a..56f16cb 100644
--- a/data/org.gnome.mutter.gschema.xml.in
+++ b/data/org.gnome.mutter.gschema.xml.in
@@ -102,6 +102,20 @@
       </description>
     </key>
 
+    <key name="experimental-features" type="as">
+      <default>[]</default>
+      <summary>Enable experimental features</summary>
+      <description>
+        To enable experimental features, add the feature keyword to the list.
+        Whether the feature requires restarting the compositor depends on the
+        given feature. Any experimental feature is not required to still be
+        available, or configurable. Don't expect adding anything in this
+        setting to be future proof.
+
+        Currently possible keywords: (none)
+      </description>
+    </key>
+
     <child name="keybindings" schema="org.gnome.mutter.keybindings"/>
 
   </schema>
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index 39b42c4..c8d618e 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -97,6 +97,11 @@ struct _MetaBackendClass
 
 };
 
+typedef enum _MetaExperimentalFeature
+{
+  META_EXPERIMENTAL_FEATURE_NONE = 0,
+} MetaExperimentalFeature;
+
 void meta_init_backend (GType backend_gtype);
 
 ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
@@ -146,6 +151,14 @@ ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend);
 
 void meta_backend_monitors_changed (MetaBackend *backend);
 
+gboolean meta_backend_is_experimental_feature_enabled (MetaBackend            *backend,
+                                                       MetaExperimentalFeature feature);
+
+void meta_backend_override_experimental_features (MetaBackend *backend);
+
+void meta_backend_enable_experimental_feature (MetaBackend            *backend,
+                                               MetaExperimentalFeature feature);
+
 gboolean meta_is_stage_views_enabled (void);
 
 MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend);
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index e606404..0360e32 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -68,6 +68,10 @@ struct _MetaBackendPrivate
   MetaRenderer *renderer;
   MetaEgl *egl;
 
+  GSettings *mutter_settings;
+  MetaExperimentalFeature experimental_features;
+  gboolean experimental_features_overridden;
+
   ClutterBackend *clutter_backend;
   ClutterActor *stage;
 
@@ -403,6 +407,96 @@ meta_backend_real_get_relative_motion_deltas (MetaBackend *backend,
   return FALSE;
 }
 
+static gboolean
+experimental_features_handler (GVariant *features_variant,
+                               gpointer *result,
+                               gpointer  data)
+{
+  MetaBackend *backend = data;
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+  GVariantIter features_iter;
+  char *feature;
+  MetaExperimentalFeature features = META_EXPERIMENTAL_FEATURE_NONE;
+
+  if (priv->experimental_features_overridden)
+    {
+      *result = GINT_TO_POINTER (FALSE);
+      return TRUE;
+    }
+
+  g_variant_iter_init (&features_iter, features_variant);
+  while (g_variant_iter_loop (&features_iter, "s", &feature))
+    {
+      /* So far no experimental features defined. */
+      g_info ("Unknown experimental feature '%s'\n", feature);
+    }
+
+  if (features != priv->experimental_features)
+    {
+      priv->experimental_features = features;
+      *result = GINT_TO_POINTER (TRUE);
+    }
+  else
+    {
+      *result = GINT_TO_POINTER (FALSE);
+    }
+
+  return TRUE;
+}
+
+static gboolean
+update_experimental_features (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  return GPOINTER_TO_INT (g_settings_get_mapped (priv->mutter_settings,
+                                                 "experimental-features",
+                                                 experimental_features_handler,
+                                                 backend));
+}
+
+static void
+mutter_settings_changed (GSettings   *settings,
+                         gchar       *key,
+                         MetaBackend *backend)
+{
+  gboolean changed;
+
+  if (!g_str_equal (key, "experimental-features"))
+    return;
+
+  changed = update_experimental_features (backend);
+  if (changed)
+    g_signal_emit_by_name (backend, "experimental-features-changed");
+}
+
+gboolean
+meta_backend_is_experimental_feature_enabled (MetaBackend            *backend,
+                                              MetaExperimentalFeature feature)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  return !!(priv->experimental_features & feature);
+}
+
+void
+meta_backend_override_experimental_features (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  priv->experimental_features = META_EXPERIMENTAL_FEATURE_NONE;
+  priv->experimental_features_overridden = TRUE;
+}
+
+void
+meta_backend_enable_experimental_feature (MetaBackend            *backend,
+                                          MetaExperimentalFeature feature)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  priv->experimental_features |= feature;
+}
+
 static void
 meta_backend_class_init (MetaBackendClass *klass)
 {
@@ -435,6 +529,12 @@ meta_backend_class_init (MetaBackendClass *klass)
                 0,
                 NULL, NULL, NULL,
                 G_TYPE_NONE, 1, G_TYPE_INT);
+  g_signal_new ("experimental-features-changed",
+                G_TYPE_FROM_CLASS (object_class),
+                G_SIGNAL_RUN_LAST,
+                0,
+                NULL, NULL, NULL,
+                G_TYPE_NONE, 0);
 }
 
 static gboolean
@@ -445,6 +545,12 @@ meta_backend_initable_init (GInitable     *initable,
   MetaBackend *backend = META_BACKEND (initable);
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 
+  priv->mutter_settings = g_settings_new ("org.gnome.mutter");
+  g_signal_connect (priv->mutter_settings, "changed",
+                    G_CALLBACK (mutter_settings_changed),
+                    backend);
+  update_experimental_features (backend);
+
   priv->egl = g_object_new (META_TYPE_EGL, NULL);
 
   priv->renderer = META_BACKEND_GET_CLASS (backend)->create_renderer (backend);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]