diff --git a/data/org.gnome.mutter.gschema.xml.in b/data/org.gnome.mutter.gschema.xml.in index a96af4a9c..56f16cb48 100644 --- a/data/org.gnome.mutter.gschema.xml.in +++ b/data/org.gnome.mutter.gschema.xml.in @@ -102,6 +102,20 @@ + + [] + Enable experimental features + + 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) + + + diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 39b42c4b5..c8d618e3f 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 e606404a4..0360e327f 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);