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
This commit is contained in:
Jonas Ådahl 2017-02-24 17:48:19 +08:00
parent 63450d69d3
commit 094e0356e8
3 changed files with 133 additions and 0 deletions

View File

@ -102,6 +102,20 @@
</description> </description>
</key> </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"/> <child name="keybindings" schema="org.gnome.mutter.keybindings"/>
</schema> </schema>

View File

@ -97,6 +97,11 @@ struct _MetaBackendClass
}; };
typedef enum _MetaExperimentalFeature
{
META_EXPERIMENTAL_FEATURE_NONE = 0,
} MetaExperimentalFeature;
void meta_init_backend (GType backend_gtype); void meta_init_backend (GType backend_gtype);
ClutterBackend * meta_backend_get_clutter_backend (MetaBackend *backend); 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); 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); gboolean meta_is_stage_views_enabled (void);
MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend); MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend);

View File

@ -68,6 +68,10 @@ struct _MetaBackendPrivate
MetaRenderer *renderer; MetaRenderer *renderer;
MetaEgl *egl; MetaEgl *egl;
GSettings *mutter_settings;
MetaExperimentalFeature experimental_features;
gboolean experimental_features_overridden;
ClutterBackend *clutter_backend; ClutterBackend *clutter_backend;
ClutterActor *stage; ClutterActor *stage;
@ -403,6 +407,96 @@ meta_backend_real_get_relative_motion_deltas (MetaBackend *backend,
return FALSE; 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 static void
meta_backend_class_init (MetaBackendClass *klass) meta_backend_class_init (MetaBackendClass *klass)
{ {
@ -435,6 +529,12 @@ meta_backend_class_init (MetaBackendClass *klass)
0, 0,
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_INT); 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 static gboolean
@ -445,6 +545,12 @@ meta_backend_initable_init (GInitable *initable,
MetaBackend *backend = META_BACKEND (initable); MetaBackend *backend = META_BACKEND (initable);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend); 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->egl = g_object_new (META_TYPE_EGL, NULL);
priv->renderer = META_BACKEND_GET_CLASS (backend)->create_renderer (backend); priv->renderer = META_BACKEND_GET_CLASS (backend)->create_renderer (backend);