[gnome-settings-daemon] xsettings: Calculate window scale from configuration state
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] xsettings: Calculate window scale from configuration state
- Date: Fri, 14 Jul 2017 13:05:26 +0000 (UTC)
commit 2f553ba812e1bd65e7673348e031e7447f5e173d
Author: Jonas Ådahl <jadahl gmail com>
Date: Tue Apr 18 15:22:32 2017 +0800
xsettings: Calculate window scale from configuration state
If there is a configuration state, i.e. a valid state as returned by
org.gnome.Mutter.DisplayConfig.GetCurrentState(), use that state to
derive a window scale.
The way this is done depends on the active layout mode used by the
compositor. If the active layout mode is 'logical', the window scaling
factor 1 is always used. This will avoid GTK+ X11 clients from being
doubly upscaled. If the active layout mode is 'physical', the window
scaling is determined by taking the scale of the primary logical
monitor.
https://bugzilla.gnome.org/show_bug.cgi?id=781534
plugins/xsettings/gsd-xsettings-manager.c | 167 +++++++++++++++++++++++++++++
1 files changed, 167 insertions(+), 0 deletions(-)
---
diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c
index 9835c02..bba612f 100644
--- a/plugins/xsettings/gsd-xsettings-manager.c
+++ b/plugins/xsettings/gsd-xsettings-manager.c
@@ -78,6 +78,11 @@
#define FONT_HINTING_KEY "hinting"
#define FONT_RGBA_ORDER_KEY "rgba-order"
+typedef enum _DisplayLayoutMode {
+ DISPLAY_LAYOUT_MODE_LOGICAL = 1,
+ DISPLAY_LAYOUT_MODE_PHYSICAL = 2
+} DisplayLayoutMode;
+
/* As we cannot rely on the X server giving us good DPI information, and
* that we don't want multi-monitor screens to have different DPIs (thus
* different text sizes), we'll hard-code the value of the DPI
@@ -283,6 +288,8 @@ struct GnomeXSettingsManagerPrivate
gboolean have_shell;
guint notify_idle_id;
+
+ GDBusConnection *dbus_connection;
};
#define GSD_XSETTINGS_ERROR gsd_xsettings_error_quark ()
@@ -593,6 +600,154 @@ get_dimensions_gdk (int *width,
*height_mm = gdk_screen_get_monitor_height_mm (screen, primary);
}
+static gboolean
+is_experimental_display_config_api_enabled (GnomeXSettingsManager *manager)
+{
+ GVariant *property_variant;
+ GVariant *property_value_variant;
+ GError *error = NULL;
+ gboolean is_experimental_api_enabled;
+
+ property_variant =
+ g_dbus_connection_call_sync (manager->priv->dbus_connection,
+ "org.gnome.Mutter.DisplayConfig",
+ "/org/gnome/Mutter/DisplayConfig",
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ g_variant_new ("(ss)",
+ "org.gnome.Mutter.DisplayConfig",
+ "IsExperimentalApiEnabled"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ NULL,
+ &error);
+ if (!property_variant) {
+ g_warning ("Failed to check API availability: %s",
+ error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_variant_get_child (property_variant, 0, "v", &property_value_variant);
+ is_experimental_api_enabled = g_variant_get_boolean (property_value_variant);
+
+ g_variant_unref (property_variant);
+ g_variant_unref (property_value_variant);
+
+ return is_experimental_api_enabled;
+}
+
+static gboolean
+is_layout_mode_logical (GVariantIter *properties)
+{
+ DisplayLayoutMode layout_mode = DISPLAY_LAYOUT_MODE_LOGICAL;
+ const char *key;
+ GVariant *value;
+
+ while (g_variant_iter_next (properties, "{&sv}", &key, &value)) {
+ DisplayLayoutMode layout_mode_value;
+
+ if (!g_str_equal (key, "layout-mode")) {
+ g_variant_unref (value);
+ continue;
+ }
+
+ layout_mode_value = g_variant_get_uint32 (value);
+ g_variant_unref (value);
+
+ if (layout_mode_value < DISPLAY_LAYOUT_MODE_LOGICAL ||
+ layout_mode_value > DISPLAY_LAYOUT_MODE_PHYSICAL)
+ g_warning ("Unknown layout mode %u", layout_mode_value);
+ else
+ layout_mode = layout_mode_value;
+
+ break;
+ }
+
+ return layout_mode == DISPLAY_LAYOUT_MODE_LOGICAL;
+}
+
+#define MODE_FORMAT "(siiddada{sv})"
+#define MODES_FORMAT "a" MODE_FORMAT
+
+#define MONITOR_SPEC_FORMAT "(ssss)"
+#define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})"
+#define MONITORS_FORMAT "a" MONITOR_FORMAT
+
+#define LOGICAL_MONITOR_FORMAT "(iiduba" MONITOR_SPEC_FORMAT "a{sv})"
+#define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT
+
+#define CURRENT_STATE_FORMAT "(u" MONITORS_FORMAT LOGICAL_MONITORS_FORMAT "a{sv})"
+
+static int
+get_window_scale_experimental (GnomeXSettingsManager *manager)
+{
+ GError *error = NULL;
+ GVariant *current_state;
+ GVariantIter *logical_monitors;
+ GVariant *logical_monitor_variant;
+ GVariantIter *properties;
+ int scale = 1;
+
+ current_state =
+ g_dbus_connection_call_sync (manager->priv->dbus_connection,
+ "org.gnome.Mutter.DisplayConfig",
+ "/org/gnome/Mutter/DisplayConfig",
+ "org.gnome.Mutter.DisplayConfig",
+ "GetCurrentState",
+ NULL,
+ NULL,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1,
+ NULL,
+ &error);
+ if (!current_state) {
+ g_warning ("Failed to get current display configuration state: %s",
+ error->message);
+ g_error_free (error);
+ return 1;
+ }
+
+ g_variant_get (current_state,
+ CURRENT_STATE_FORMAT,
+ NULL,
+ NULL,
+ &logical_monitors,
+ &properties);
+
+ if (is_layout_mode_logical (properties))
+ goto out;
+
+ while (g_variant_iter_next (logical_monitors, "@"LOGICAL_MONITOR_FORMAT,
+ &logical_monitor_variant)) {
+ gboolean is_primary;
+ double logical_monitor_scale;
+
+ g_variant_get (logical_monitor_variant,
+ LOGICAL_MONITOR_FORMAT,
+ NULL, NULL,
+ &logical_monitor_scale,
+ NULL,
+ &is_primary,
+ NULL, NULL);
+
+ if (is_primary) {
+ scale = (int) logical_monitor_scale;
+ break;
+ }
+
+ g_variant_unref (logical_monitor_variant);
+ }
+
+out:
+ g_variant_unref (current_state);
+ g_variant_iter_free (properties);
+ g_variant_iter_free (logical_monitors);
+
+ return scale;
+}
+
static int
get_window_scale (GnomeXSettingsManager *manager)
{
@@ -602,6 +757,9 @@ get_window_scale (GnomeXSettingsManager *manager)
int width_mm, height_mm;
double dpi_x, dpi_y;
+ if (is_experimental_display_config_api_enabled (manager))
+ return get_window_scale_experimental (manager);
+
interface_settings = g_hash_table_lookup (manager->priv->settings, INTERFACE_SETTINGS_SCHEMA);
window_scale =
g_settings_get_uint (interface_settings, SCALING_FACTOR_KEY);
@@ -1369,7 +1527,14 @@ gnome_xsettings_manager_class_init (GnomeXSettingsManagerClass *klass)
static void
gnome_xsettings_manager_init (GnomeXSettingsManager *manager)
{
+ GError *error = NULL;
+
manager->priv = GNOME_XSETTINGS_MANAGER_GET_PRIVATE (manager);
+
+ manager->priv->dbus_connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
+ NULL, &error);
+ if (!manager->priv->dbus_connection)
+ g_error ("Failed to get session bus: %s", error->message);
}
static void
@@ -1389,6 +1554,8 @@ gnome_xsettings_manager_finalize (GObject *object)
if (xsettings_manager->priv->start_idle_id != 0)
g_source_remove (xsettings_manager->priv->start_idle_id);
+ g_clear_object (&xsettings_manager->priv->dbus_connection);
+
G_OBJECT_CLASS (gnome_xsettings_manager_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]