From 094e0356e854c7525c991bdd580b8c5d1b532e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 24 Feb 2017 17:48:19 +0800 Subject: [PATCH] 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(+) 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);