diff --git a/src/Makefile.am b/src/Makefile.am index 2e8d73b9c..34dd545da 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index 0a5a7c18a..d2c3a91a1 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -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); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 6aa78abd0..171c61109 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -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); -} diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c index 05ffd4d89..21608a169 100644 --- a/src/backends/meta-monitor-manager-dummy.c +++ b/src/backends/meta-monitor-manager-dummy.c @@ -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; diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index eea84c72e..ba071caca 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -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); diff --git a/src/backends/meta-settings-private.h b/src/backends/meta-settings-private.h new file mode 100644 index 000000000..775b58bd7 --- /dev/null +++ b/src/backends/meta-settings-private.h @@ -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 + +#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 */ diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c new file mode 100644 index 000000000..69c139009 --- /dev/null +++ b/src/backends/meta-settings.c @@ -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 + +#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); +} diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index 46cd5c2b1..81ba3e4a2 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -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 diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h index 3010fa5d3..50afa721a 100644 --- a/src/meta/meta-backend.h +++ b/src/meta/meta-backend.h @@ -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 */ diff --git a/src/meta/meta-settings.h b/src/meta/meta-settings.h new file mode 100644 index 000000000..1edc8600e --- /dev/null +++ b/src/meta/meta-settings.h @@ -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 */ diff --git a/src/meta/types.h b/src/meta/types.h index 22778899d..d3a5ca32b 100644 --- a/src/meta/types.h +++ b/src/meta/types.h @@ -40,5 +40,6 @@ typedef struct _MetaKeyBinding MetaKeyBinding; typedef struct _MetaCursorTracker MetaCursorTracker; typedef struct _MetaDnd MetaDnd; +typedef struct _MetaSettings MetaSettings; #endif diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c index e5a8f6fdf..ed582f980 100644 --- a/src/tests/meta-monitor-manager-test.c +++ b/src/tests/meta-monitor-manager-test.c @@ -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); } diff --git a/src/tests/unit-tests.c b/src/tests/unit-tests.c index 77a6a87fc..36494f27e 100644 --- a/src/tests/unit-tests.c +++ b/src/tests/unit-tests.c @@ -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); }