backend: Move settings into a new MetaSettings object

Introduce MetaSettings and add the settings managed by MetaBackend into
the new object. These settings include: experimental-features and UI
scaling factor.

https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
Jonas Ådahl 2017-04-21 16:40:51 +08:00
parent be175558c3
commit 2718699ccc
13 changed files with 478 additions and 260 deletions

View File

@ -82,6 +82,7 @@ wayland_protocols = \
libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-backend.c \
meta/meta-backend.h \
meta/meta-settings.h \
backends/meta-backend-private.h \
backends/meta-barrier.c \
backends/meta-barrier-private.h \
@ -119,6 +120,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-monitor-manager-dummy.h \
backends/meta-pointer-constraint.c \
backends/meta-pointer-constraint.h \
backends/meta-settings.c \
backends/meta-settings-private.h \
backends/meta-stage.h \
backends/meta-stage.c \
backends/meta-renderer.c \
@ -445,6 +448,7 @@ libmutterinclude_headers = \
meta/meta-idle-monitor.h \
meta/meta-plugin.h \
meta/meta-monitor-manager.h \
meta/meta-settings.h \
meta/meta-shaped-texture.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \

View File

@ -38,6 +38,7 @@
#include "backends/meta-egl.h"
#include "backends/meta-pointer-constraint.h"
#include "backends/meta-renderer.h"
#include "backends/meta-settings-private.h"
#include "core/util-private.h"
#define DEFAULT_XKB_RULES_FILE "evdev"
@ -98,13 +99,6 @@ struct _MetaBackendClass
};
typedef enum _MetaExperimentalFeature
{
META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER = (1 << 1)
} MetaExperimentalFeature;
void meta_init_backend (GType backend_gtype);
void meta_backend_x11_display_opened (MetaBackend *backend);
@ -122,6 +116,7 @@ MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend);
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
MetaRenderer * meta_backend_get_renderer (MetaBackend *backend);
MetaEgl * meta_backend_get_egl (MetaBackend *backend);
MetaSettings * meta_backend_get_settings (MetaBackend *backend);
gboolean meta_backend_grab_device (MetaBackend *backend,
int device_id,
@ -156,16 +151,6 @@ 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);
MetaExperimentalFeature meta_backend_get_experimental_features (MetaBackend *backend);
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_scaled (void);

View File

@ -43,7 +43,7 @@
#include "backends/meta-idle-monitor-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-dummy.h"
#include "ui/theme-private.h"
#include "backends/meta-settings-private.h"
#define META_IDLE_MONITOR_CORE_DEVICE 0
@ -52,8 +52,7 @@ enum
KEYMAP_CHANGED,
KEYMAP_LAYOUT_GROUP_CHANGED,
LAST_DEVICE_CHANGED,
EXPERIMENTAL_FEATURES_CHANGED,
UI_SCALING_FACTOR_CHANGED,
X11_DISPLAY_OPENED,
N_SIGNALS
};
@ -85,10 +84,7 @@ struct _MetaBackendPrivate
MetaInputSettings *input_settings;
MetaRenderer *renderer;
MetaEgl *egl;
GSettings *mutter_settings;
MetaExperimentalFeature experimental_features;
gboolean experimental_features_overridden;
MetaSettings *settings;
ClutterBackend *clutter_backend;
ClutterActor *stage;
@ -101,8 +97,6 @@ struct _MetaBackendPrivate
MetaPointerConstraint *client_pointer_constraint;
MetaDnd *dnd;
int ui_scaling_factor;
};
typedef struct _MetaBackendPrivate MetaBackendPrivate;
@ -114,9 +108,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaBackend, meta_backend, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
initable_iface_init));
static int
meta_backend_calculate_ui_scaling_factor (MetaBackend *backend);
static void
meta_backend_finalize (GObject *object)
{
@ -131,6 +122,8 @@ meta_backend_finalize (GObject *object)
g_hash_table_destroy (priv->device_monitors);
g_clear_object (&priv->settings);
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
}
@ -160,28 +153,10 @@ center_pointer (MetaBackend *backend)
primary->rect.y + primary->rect.height / 2);
}
static gboolean
meta_backend_update_ui_scaling_factor (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
int ui_scaling_factor;
ui_scaling_factor = meta_backend_calculate_ui_scaling_factor (backend);
if (ui_scaling_factor != priv->ui_scaling_factor)
{
priv->ui_scaling_factor = ui_scaling_factor;
return TRUE;
}
else
{
return FALSE;
}
}
void
meta_backend_monitors_changed (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
@ -199,8 +174,7 @@ meta_backend_monitors_changed (MetaBackend *backend)
center_pointer (backend);
}
if (meta_backend_update_ui_scaling_factor (backend))
meta_backend_notify_ui_scaling_factor_changed (backend);
meta_settings_update_ui_scaling_factor (priv->settings);
}
void
@ -426,8 +400,6 @@ meta_backend_real_post_init (MetaBackend *backend)
meta_backend_sync_screen_size (backend);
meta_backend_update_ui_scaling_factor (backend);
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
priv->device_monitors =
@ -489,105 +461,6 @@ 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. */
if (g_str_equal (feature, "scale-monitor-framebuffer"))
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "monitor-config-manager"))
features |= META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER;
else
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)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaExperimentalFeature old_experimental_features;
gboolean changed;
if (!g_str_equal (key, "experimental-features"))
return;
old_experimental_features = priv->experimental_features;
changed = update_experimental_features (backend);
if (changed)
g_signal_emit (backend, signals[EXPERIMENTAL_FEATURES_CHANGED], 0,
(unsigned int) old_experimental_features);
}
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)
{
@ -624,15 +497,8 @@ meta_backend_class_init (MetaBackendClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_INT);
signals[EXPERIMENTAL_FEATURES_CHANGED] =
g_signal_new ("experimental-features-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
signals[UI_SCALING_FACTOR_CHANGED] =
g_signal_new ("ui-scaling-factor-changed",
signals[X11_DISPLAY_OPENED] =
g_signal_new ("x11-display-opened",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
@ -651,11 +517,7 @@ 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->settings = meta_settings_new (backend);
priv->egl = g_object_new (META_TYPE_EGL, NULL);
@ -690,7 +552,11 @@ meta_backend_init (MetaBackend *backend)
static void
meta_backend_post_init (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
META_BACKEND_GET_CLASS (backend)->post_init (backend);
meta_settings_post_init (priv->settings);
}
/**
@ -757,6 +623,17 @@ meta_backend_get_egl (MetaBackend *backend)
return priv->egl;
}
/**
* meta_backend_get_settings: (skip)
*/
MetaSettings *
meta_backend_get_settings (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return priv->settings;
}
/**
* meta_backend_grab_device: (skip)
*/
@ -1052,27 +929,10 @@ meta_clutter_init (void)
meta_backend_post_init (_backend);
}
static void
xft_dpi_changed (GtkSettings *settings,
GParamSpec *pspec,
MetaBackend *backend)
{
meta_backend_update_ui_scaling_factor (backend);
meta_backend_notify_ui_scaling_factor_changed (backend);
}
void
meta_backend_x11_display_opened (MetaBackend *backend)
{
/*
* gdk-window-scaling-factor is not exported to gtk-settings
* because it is handled inside gdk, so we use gtk-xft-dpi instead
* which also changes when the scale factor changes.
*
* TODO: Don't rely on GtkSettings for this
*/
g_signal_connect (gtk_settings_get_default (), "notify::gtk-xft-dpi",
G_CALLBACK (xft_dpi_changed), backend);
g_signal_emit (backend, signals[X11_DISPLAY_OPENED], 0);
}
gboolean
@ -1137,54 +997,3 @@ meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend,
g_signal_emit (backend, signals[KEYMAP_LAYOUT_GROUP_CHANGED], 0,
locked_group);
}
static int
calculate_ui_scaling_factor (MetaBackend *backend)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
GList *logical_monitors;
GList *l;
int max_scale = 1;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
max_scale = MAX (logical_monitor->scale, max_scale);
}
return max_scale;
}
static int
meta_backend_calculate_ui_scaling_factor (MetaBackend *backend)
{
if (meta_is_stage_views_scaled ())
{
return 1;
}
else
{
if (meta_is_monitor_config_manager_enabled ())
return calculate_ui_scaling_factor (backend);
else
return meta_theme_get_window_scaling_factor ();
}
}
int
meta_backend_get_ui_scaling_factor (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
return priv->ui_scaling_factor;
}
void
meta_backend_notify_ui_scaling_factor_changed (MetaBackend *backend)
{
g_signal_emit (backend, signals[UI_SCALING_FACTOR_CHANGED], 0);
}

View File

@ -609,22 +609,25 @@ static gboolean
is_monitor_framebuffers_scaled (void)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_backend_is_experimental_feature_enabled (
backend,
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
}
static MetaMonitorManagerCapability
meta_monitor_manager_dummy_get_capabilities (MetaMonitorManager *manager)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
MetaMonitorManagerCapability capabilities =
META_MONITOR_MANAGER_CAPABILITY_NONE;
capabilities |= META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
if (meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
if (meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;

View File

@ -77,8 +77,11 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
gboolean
meta_is_monitor_config_manager_enabled (void)
{
return meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER);
}
@ -521,7 +524,7 @@ done:
}
static void
experimental_features_changed (MetaBackend *backend,
experimental_features_changed (MetaSettings *settings,
MetaExperimentalFeature old_experimental_features,
MetaMonitorManager *manager)
{
@ -531,7 +534,6 @@ experimental_features_changed (MetaBackend *backend,
gboolean is_config_manager_enabled;
gboolean is_stage_views_scaled;
gboolean should_reconfigure = FALSE;
int ui_scaling_factor;
is_config_manager_enabled = meta_is_monitor_config_manager_enabled ();
was_config_manager_enabled =
@ -545,21 +547,18 @@ experimental_features_changed (MetaBackend *backend,
!!(old_experimental_features &
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
is_stage_views_scaled =
meta_backend_is_experimental_feature_enabled (
backend,
meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
if (is_config_manager_enabled != was_config_manager_enabled ||
is_stage_views_scaled != was_stage_views_scaled)
should_reconfigure = TRUE;
ui_scaling_factor = meta_backend_get_ui_scaling_factor (backend);
if (should_reconfigure)
meta_monitor_manager_on_hotplug (manager);
if (ui_scaling_factor != meta_backend_get_ui_scaling_factor (backend))
meta_backend_notify_ui_scaling_factor_changed (backend);
meta_settings_update_ui_scaling_factor (settings);
}
static void
@ -569,9 +568,11 @@ meta_monitor_manager_constructed (GObject *object)
MetaDBusDisplayConfig *skeleton = META_DBUS_DISPLAY_CONFIG (manager);
MetaMonitorManagerClass *manager_class =
META_MONITOR_MANAGER_GET_CLASS (manager);
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
manager->experimental_features_changed_handler_id =
g_signal_connect (meta_get_backend (),
g_signal_connect (settings,
"experimental-features-changed",
G_CALLBACK (experimental_features_changed),
manager);

View File

@ -0,0 +1,57 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_SETTINGS_PRIVATE_H
#define META_SETTINGS_PRIVATE_H
#include <glib-object.h>
#include "meta/meta-settings.h"
#include "meta/types.h"
typedef enum _MetaExperimentalFeature
{
META_EXPERIMENTAL_FEATURE_NONE = 0,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER = (1 << 1)
} MetaExperimentalFeature;
#define META_TYPE_SETTINGS (meta_settings_get_type ())
G_DECLARE_FINAL_TYPE (MetaSettings, meta_settings,
META, SETTINGS, GObject)
MetaSettings * meta_settings_new (MetaBackend *backend);
void meta_settings_post_init (MetaSettings *settings);
void meta_settings_update_ui_scaling_factor (MetaSettings *settings);
gboolean meta_settings_is_experimental_feature_enabled (MetaSettings *settings,
MetaExperimentalFeature feature);
MetaExperimentalFeature meta_settings_get_experimental_features (MetaSettings *settings);
void meta_settings_override_experimental_features (MetaSettings *settings);
void meta_settings_enable_experimental_feature (MetaSettings *settings,
MetaExperimentalFeature feature);
#endif /* META_SETTINGS_PRIVATE_H */

View File

@ -0,0 +1,320 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#include "backends/meta-settings-private.h"
#include <gio/gio.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-private.h"
#include "ui/theme-private.h"
enum
{
UI_SCALING_FACTOR_CHANGED,
EXPERIMENTAL_FEATURES_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS];
struct _MetaSettings
{
GObject parent;
MetaBackend *backend;
GSettings *mutter_settings;
int ui_scaling_factor;
MetaExperimentalFeature experimental_features;
gboolean experimental_features_overridden;
};
G_DEFINE_TYPE (MetaSettings, meta_settings, G_TYPE_OBJECT)
static int
calculate_ui_scaling_factor (MetaSettings *settings)
{
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (settings->backend);
GList *logical_monitors;
GList *l;
int max_scale = 1;
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
max_scale = MAX (meta_logical_monitor_get_scale (logical_monitor),
max_scale);
}
return max_scale;
}
static int
get_xsettings_scaling_factor (void)
{
GdkScreen *screen;
GValue value = G_VALUE_INIT;
g_value_init (&value, G_TYPE_INT);
screen = gdk_screen_get_default ();
if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value))
return g_value_get_int (&value);
else
return 1;
}
static gboolean
update_ui_scaling_factor (MetaSettings *settings)
{
int ui_scaling_factor;
if (meta_is_stage_views_scaled ())
{
ui_scaling_factor = 1;
}
else
{
if (meta_is_monitor_config_manager_enabled ())
ui_scaling_factor = calculate_ui_scaling_factor (settings);
else
ui_scaling_factor = get_xsettings_scaling_factor ();
}
if (settings->ui_scaling_factor != ui_scaling_factor)
{
settings->ui_scaling_factor = ui_scaling_factor;
return TRUE;
}
else
{
return FALSE;
}
}
static void
xft_dpi_changed (GtkSettings *gtk_settings,
GParamSpec *pspec,
MetaSettings *settings)
{
/* This only matters when we rely on XSettings. */
if (meta_is_monitor_config_manager_enabled ())
return;
meta_settings_update_ui_scaling_factor (settings);
}
static void
x11_display_opened (MetaBackend *backend,
MetaSettings *settings)
{
/*
* gdk-window-scaling-factor is not exported to gtk-settings
* because it is handled inside gdk, so we use gtk-xft-dpi instead
* which also changes when the scale factor changes.
*
* TODO: Only rely on our own configured scale when we only have
* MetaMonitorConfigManager.
*/
g_signal_connect (gtk_settings_get_default (), "notify::gtk-xft-dpi",
G_CALLBACK (xft_dpi_changed), settings);
}
void
meta_settings_update_ui_scaling_factor (MetaSettings *settings)
{
if (update_ui_scaling_factor (settings))
g_signal_emit (settings, signals[UI_SCALING_FACTOR_CHANGED], 0);
}
int
meta_settings_get_ui_scaling_factor (MetaSettings *settings)
{
g_assert (settings->ui_scaling_factor != 0);
return settings->ui_scaling_factor;
}
gboolean
meta_settings_is_experimental_feature_enabled (MetaSettings *settings,
MetaExperimentalFeature feature)
{
return !!(settings->experimental_features & feature);
}
void
meta_settings_override_experimental_features (MetaSettings *settings)
{
settings->experimental_features = META_EXPERIMENTAL_FEATURE_NONE;
settings->experimental_features_overridden = TRUE;
}
void
meta_settings_enable_experimental_feature (MetaSettings *settings,
MetaExperimentalFeature feature)
{
g_assert (settings->experimental_features_overridden);
settings->experimental_features |= feature;
}
static gboolean
experimental_features_handler (GVariant *features_variant,
gpointer *result,
gpointer data)
{
MetaSettings *settings = data;
GVariantIter features_iter;
char *feature;
MetaExperimentalFeature features = META_EXPERIMENTAL_FEATURE_NONE;
if (settings->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. */
if (g_str_equal (feature, "scale-monitor-framebuffer"))
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
else if (g_str_equal (feature, "monitor-config-manager"))
features |= META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER;
else
g_info ("Unknown experimental feature '%s'\n", feature);
}
if (features != settings->experimental_features)
{
settings->experimental_features = features;
*result = GINT_TO_POINTER (TRUE);
}
else
{
*result = GINT_TO_POINTER (FALSE);
}
return TRUE;
}
static gboolean
update_experimental_features (MetaSettings *settings)
{
return GPOINTER_TO_INT (g_settings_get_mapped (settings->mutter_settings,
"experimental-features",
experimental_features_handler,
settings));
}
static void
mutter_settings_changed (GSettings *mutter_settings,
gchar *key,
MetaSettings *settings)
{
MetaExperimentalFeature old_experimental_features;
if (!g_str_equal (key, "experimental-features"))
return;
old_experimental_features = settings->experimental_features;
if (update_experimental_features (settings))
g_signal_emit (settings, signals[EXPERIMENTAL_FEATURES_CHANGED], 0,
(unsigned int) old_experimental_features);
}
MetaSettings *
meta_settings_new (MetaBackend *backend)
{
MetaSettings *settings;
settings = g_object_new (META_TYPE_SETTINGS, NULL);
settings->backend = backend;
g_signal_connect (backend, "x11-display-opened",
G_CALLBACK (x11_display_opened),
settings);
return settings;
}
static void
meta_settings_dispose (GObject *object)
{
MetaSettings *settings = META_SETTINGS (object);
g_clear_object (&settings->mutter_settings);
G_OBJECT_CLASS (meta_settings_parent_class)->dispose (object);
}
static void
meta_settings_init (MetaSettings *settings)
{
settings->mutter_settings = g_settings_new ("org.gnome.mutter");
g_signal_connect (settings->mutter_settings, "changed",
G_CALLBACK (mutter_settings_changed),
settings);
update_experimental_features (settings);
}
void
meta_settings_post_init (MetaSettings *settings)
{
update_ui_scaling_factor (settings);
}
static void
meta_settings_class_init (MetaSettingsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_settings_dispose;
signals[UI_SCALING_FACTOR_CHANGED] =
g_signal_new ("ui-scaling-factor-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[EXPERIMENTAL_FEATURES_CHANGED] =
g_signal_new ("experimental-features-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
}

View File

@ -1932,13 +1932,14 @@ static MetaMonitorManagerCapability
meta_monitor_manager_kms_get_capabilities (MetaMonitorManager *manager)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
MetaMonitorManagerCapability capabilities =
META_MONITOR_MANAGER_CAPABILITY_NONE;
if (meta_backend_is_experimental_feature_enabled (
backend,
if (meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
@ -1975,11 +1976,14 @@ meta_monitor_manager_kms_get_max_screen_size (MetaMonitorManager *manager,
static MetaLogicalMonitorLayoutMode
meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
if (!meta_is_stage_views_enabled ())
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
if (meta_backend_is_experimental_feature_enabled (
meta_get_backend (),
if (meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
else

View File

@ -51,8 +51,11 @@ void meta_backend_set_numlock (MetaBackend *backend,
int meta_backend_get_ui_scaling_factor (MetaBackend *backend);
ClutterActor *meta_backend_get_stage (MetaBackend *backend);
MetaDnd *meta_backend_get_dnd (MetaBackend *backend);
MetaSettings *meta_backend_get_settings (MetaBackend *backend);
void meta_clutter_init (void);
#endif /* META_BACKEND_H */

29
src/meta/meta-settings.h Normal file
View File

@ -0,0 +1,29 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2017 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_SETTINGS_H
#define META_SETTINGS_H
#include "meta/types.h"
int meta_settings_get_ui_scaling_factor (MetaSettings *settings);
#endif /* META_SETTINGS_H */

View File

@ -40,5 +40,6 @@ typedef struct _MetaKeyBinding MetaKeyBinding;
typedef struct _MetaCursorTracker MetaCursorTracker;
typedef struct _MetaDnd MetaDnd;
typedef struct _MetaSettings MetaSettings;
#endif

View File

@ -403,9 +403,10 @@ static gboolean
is_monitor_framebuffer_scaled (void)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
return meta_backend_is_experimental_feature_enabled (
backend,
return meta_settings_is_experimental_feature_enabled (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
}

View File

@ -215,17 +215,18 @@ static gboolean
run_tests (gpointer data)
{
MetaBackend *backend = meta_get_backend ();
MetaSettings *settings = meta_backend_get_settings (backend);
gboolean ret;
meta_backend_override_experimental_features (backend);
meta_settings_override_experimental_features (settings);
if (g_strcmp0 (g_getenv ("MUTTER_USE_CONFIG_MANAGER"), "1") == 0)
{
meta_backend_enable_experimental_feature (
backend,
meta_settings_enable_experimental_feature (
settings,
META_EXPERIMENTAL_FEATURE_MONITOR_CONFIG_MANAGER);
meta_backend_enable_experimental_feature (
backend,
meta_settings_enable_experimental_feature (
settings,
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
}