[gtk/wip/settings-portal: 8/8] wayland: Support the settings portal
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/settings-portal: 8/8] wayland: Support the settings portal
- Date: Fri, 2 Nov 2018 18:43:09 +0000 (UTC)
commit 98495bf5e3ff64f86c46bcac5cc69a42f7493537
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Nov 1 19:47:46 2018 -0400
wayland: Support the settings portal
Under Wayland, we are currently directly using gsettings
for desktop settings. But in a sandbox, we may not have
access to dconf, so this may fail. Use the new settings
portal instead.
gdk/wayland/gdkdisplay-wayland.c | 338 ++++++++++++++++++++++++++++++++++-----
gdk/wayland/gdkdisplay-wayland.h | 1 +
2 files changed, 301 insertions(+), 38 deletions(-)
---
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 0e49ce2773..1f9804d644 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -730,7 +730,10 @@ gdk_wayland_display_finalize (GObject *object)
g_ptr_array_free (display_wayland->monitors, TRUE);
- g_hash_table_destroy (display_wayland->settings);
+ if (display_wayland->settings)
+ g_hash_table_destroy (display_wayland->settings);
+
+ g_clear_object (&display_wayland->settings_portal);
G_OBJECT_CLASS (gdk_wayland_display_parent_class)->finalize (object);
}
@@ -1369,6 +1372,21 @@ _gdk_wayland_is_shm_surface (cairo_surface_t *surface)
return cairo_surface_get_user_data (surface, &gdk_wayland_shm_surface_cairo_key) != NULL;
}
+typedef struct _TranslationEntry TranslationEntry;
+struct _TranslationEntry {
+ gboolean valid;
+ const gchar *schema;
+ const gchar *key;
+ const gchar *setting;
+ GType type;
+ union {
+ const char *s;
+ gint i;
+ gboolean b;
+ } fallback;
+};
+
+
typedef enum
{
GSD_FONT_ANTIALIASING_MODE_NONE,
@@ -1376,6 +1394,20 @@ typedef enum
GSD_FONT_ANTIALIASING_MODE_RGBA
} GsdFontAntialiasingMode;
+static int
+get_antialiasing (const char *s)
+{
+ const char *names[] = { "none", "grayscale", "rgba" };
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (names); i++)
+ if (strcmp (s, names[i]) == 0)
+ return i;
+
+ g_warning ("antialiasing: %s not found", s);
+ return 0;
+}
+
typedef enum
{
GSD_FONT_HINTING_NONE,
@@ -1384,6 +1416,19 @@ typedef enum
GSD_FONT_HINTING_FULL
} GsdFontHinting;
+static int
+get_hinting (const char *s)
+{
+ const char *names[] = { "none", "slight", "medium", "full" };
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (names); i++)
+ if (strcmp (s, names[i]) == 0)
+ return i;
+
+ return 0;
+}
+
typedef enum
{
GSD_FONT_RGBA_ORDER_RGBA,
@@ -1393,6 +1438,19 @@ typedef enum
GSD_FONT_RGBA_ORDER_VBGR
} GsdFontRgbaOrder;
+static int
+get_order (const char *s)
+{
+ const char *names[] = { "rgba", "rgb", "bgr", "vrgb", "vbgr" };
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (names); i++)
+ if (strcmp (s, names[i]) == 0)
+ return i;
+
+ return 0;
+}
+
static gdouble
get_dpi_from_gsettings (GdkWaylandDisplay *display_wayland)
{
@@ -1409,6 +1467,10 @@ get_dpi_from_gsettings (GdkWaylandDisplay *display_wayland)
return 96.0 * factor;
}
+
+static TranslationEntry * find_translation_entry_by_schema (const char *schema,
+ const char *key);
+
static void
update_xft_settings (GdkDisplay *display)
{
@@ -1419,25 +1481,47 @@ update_xft_settings (GdkDisplay *display)
GsdFontRgbaOrder order;
gboolean use_rgba = FALSE;
GsdXftSettings xft_settings;
+ double dpi;
- settings = g_hash_table_lookup (display_wayland->settings,
- "org.gnome.settings-daemon.plugins.xsettings");
-
- if (settings)
+ if (gdk_should_use_portal ())
{
- antialiasing = g_settings_get_enum (settings, "antialiasing");
- hinting = g_settings_get_enum (settings, "hinting");
- order = g_settings_get_enum (settings, "rgba-order");
+ TranslationEntry *entry;
+
+ entry = find_translation_entry_by_schema ("org.gnome.settings-daemon.plugins.xsettings",
"antialiasing");
+ antialiasing = entry->fallback.i;
+
+ entry = find_translation_entry_by_schema ("org.gnome.settings-daemon.plugins.xsettings", "hinting");
+ hinting = entry->fallback.i;
+
+ entry = find_translation_entry_by_schema ("org.gnome.settings-daemon.plugins.xsettings", "rgba-order");
+ order = entry->fallback.i;
+
+ entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "text-scaling-factor");
+ dpi = 96.0 * entry->fallback.i / 65536.0 * 1024; /* Xft wants 1/1024th of an inch */
}
else
{
- antialiasing = GSD_FONT_ANTIALIASING_MODE_GRAYSCALE;
- hinting = GSD_FONT_HINTING_MEDIUM;
- order = GSD_FONT_RGBA_ORDER_RGB;
+ settings = g_hash_table_lookup (display_wayland->settings,
+ "org.gnome.settings-daemon.plugins.xsettings");
+
+ if (settings)
+ {
+ antialiasing = g_settings_get_enum (settings, "antialiasing");
+ hinting = g_settings_get_enum (settings, "hinting");
+ order = g_settings_get_enum (settings, "rgba-order");
+ }
+ else
+ {
+ antialiasing = GSD_FONT_ANTIALIASING_MODE_GRAYSCALE;
+ hinting = GSD_FONT_HINTING_MEDIUM;
+ order = GSD_FONT_RGBA_ORDER_RGB;
+ }
+
+ dpi = get_dpi_from_gsettings (display_wayland) * 1024;
}
xft_settings.hinting = (hinting != GSD_FONT_HINTING_NONE);
- xft_settings.dpi = get_dpi_from_gsettings (display_wayland) * 1024; /* Xft wants 1/1024ths of an inch */
+ xft_settings.dpi = dpi;
switch (hinting)
{
@@ -1524,20 +1608,6 @@ update_xft_settings (GdkDisplay *display)
}
}
-typedef struct _TranslationEntry TranslationEntry;
-struct _TranslationEntry {
- gboolean valid;
- const gchar *schema;
- const gchar *key;
- const gchar *setting;
- GType type;
- union {
- const gchar *s;
- gint i;
- gboolean b;
- } fallback;
-};
-
static TranslationEntry translations[] = {
{ FALSE, "org.gnome.desktop.interface", "gtk-theme", "gtk-theme-name" , G_TYPE_STRING, { .s = "Adwaita" }
},
{ FALSE, "org.gnome.desktop.interface", "icon-theme", "gtk-icon-theme-name", G_TYPE_STRING, { .s = "gnome"
} },
@@ -1569,28 +1639,35 @@ static TranslationEntry translations[] = {
{ FALSE, "org.gnome.desktop.a11y", "always-show-text-caret", "gtk-keynav-use-caret", G_TYPE_BOOLEAN, { .b
= FALSE } }
};
+
static TranslationEntry *
-find_translation_entry_by_key (GSettings *settings,
- const char *key)
+find_translation_entry_by_schema (const char *schema,
+ const char *key)
{
guint i;
- char *schema;
-
- g_object_get (settings, "schema", &schema, NULL);
for (i = 0; i < G_N_ELEMENTS (translations); i++)
{
if (g_str_equal (schema, translations[i].schema) &&
g_str_equal (key, translations[i].key))
- {
- g_free (schema);
- return &translations[i];
- }
+ return &translations[i];
}
+ return NULL;
+}
+
+static TranslationEntry *
+find_translation_entry_by_key (GSettings *settings,
+ const char *key)
+{
+ char *schema;
+ TranslationEntry *entry;
+
+ g_object_get (settings, "schema", &schema, NULL);
+ entry = find_translation_entry_by_schema (schema, key);
g_free (schema);
- return NULL;
+ return entry;
}
static TranslationEntry *
@@ -1625,6 +1702,69 @@ settings_changed (GSettings *settings,
}
}
+static gboolean
+apply_portal_setting (TranslationEntry *entry,
+ GVariant *value,
+ GdkDisplay *display)
+{
+ switch (entry->type)
+ {
+ case G_TYPE_STRING:
+ entry->fallback.s = g_intern_string (g_variant_get_string (value, NULL));
+ return TRUE;
+ case G_TYPE_INT:
+ entry->fallback.i = g_variant_get_int32 (value);
+ return TRUE;
+ case G_TYPE_BOOLEAN:
+ entry->fallback.b = g_variant_get_boolean (value);
+ return TRUE;
+ case G_TYPE_NONE:
+ if (strcmp (entry->key, "antialiasing") == 0)
+ entry->fallback.i = get_antialiasing (g_variant_get_string (value, NULL));
+ else if (strcmp (entry->key, "hinting") == 0)
+ entry->fallback.i = get_hinting (g_variant_get_string (value, NULL));
+ else if (strcmp (entry->key, "rgba-order") == 0)
+ entry->fallback.i = get_order (g_variant_get_string (value, NULL));
+ else if (strcmp (entry->key, "text-scaling-factor") == 0)
+ entry->fallback.i = (int) (g_variant_get_double (value) * 65536.0);
+ update_xft_settings (display);
+ return TRUE;
+ default:;
+ }
+
+ return FALSE;
+}
+
+static void
+settings_portal_changed (GDBusProxy *proxy,
+ const char *sender_name,
+ const char *signal_name,
+ GVariant *parameters,
+ GdkDisplay *display)
+{
+ if (strcmp (signal_name, "PropertyChanged") == 0)
+ {
+ const char *namespace;
+ const char *name;
+ GVariant *value;
+ TranslationEntry *entry;
+
+ g_variant_get (parameters, "(&s&sv)", &namespace, &name, &value);
+
+ entry = find_translation_entry_by_schema (namespace, name);
+ if (apply_portal_setting (entry, value, display))
+ gdk_display_setting_changed (display, entry->setting);
+ else
+ g_warning ("ignoring portal setting %s %s", namespace, name);
+
+ g_variant_unref (value);
+ }
+}
+
+#define PORTAL_BUS_NAME "org.freedesktop.portal.Desktop"
+#define PORTAL_OBJECT_PATH "/org/freedesktop/portal/desktop"
+#define PORTAL_SETTINGS_INTERFACE "org.freedesktop.portal.Settings"
+
static void
init_settings (GdkDisplay *display)
{
@@ -1634,6 +1774,85 @@ init_settings (GdkDisplay *display)
GSettings *settings;
gint i;
+ if (gdk_should_use_portal ())
+ {
+ GVariant *ret;
+ GError *error = NULL;
+ const char *schema;
+ GVariant *val;
+ GVariantIter *iter;
+
+ display_wayland->settings_portal = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ PORTAL_BUS_NAME,
+ PORTAL_OBJECT_PATH,
+ PORTAL_SETTINGS_INTERFACE,
+ NULL,
+ &error);
+ if (error)
+ {
+ g_warning ("Setting portal not found: %s", error->message);
+ g_error_free (error);
+
+ goto fallback;
+ }
+
+ ret = g_dbus_proxy_call_sync (display_wayland->settings_portal,
+ "ReadAll",
+ g_variant_new ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_warning ("Failed to read portal settings: %s", error->message);
+ g_error_free (error);
+ g_clear_object (&display_wayland->settings_portal);
+
+ goto fallback;
+ }
+
+ g_variant_get (ret, "(a{sa{sv}})", &iter);
+
+ while (g_variant_iter_loop (iter, "{s@a{sv}}", &schema, &val))
+ {
+ GVariantIter *iter2 = g_variant_iter_new (val);
+ const char *key;
+ GVariant *v;
+
+ while (g_variant_iter_loop (iter2, "{sv}", &key, &v))
+ {
+ TranslationEntry *entry = find_translation_entry_by_schema (schema, key);
+ if (entry)
+ {
+ char *a = g_variant_print (v, FALSE);
+ g_debug ("Using portal setting for %s %s: %s\n", schema, key, a);
+ g_free (a);
+ apply_portal_setting (entry, v, display);
+ }
+ else
+ {
+ g_debug ("Ignoring portal setting for %s %s", schema, key);
+ }
+ }
+ g_variant_iter_free (iter2);
+ }
+ g_variant_iter_free (iter);
+
+ g_variant_unref (ret);
+
+ g_signal_connect (display_wayland->settings_portal, "g-signal",
+ G_CALLBACK (settings_portal_changed), display_wayland);
+
+ return;
+
+fallback:
+ g_debug ("Failed to use settings portal; falling back to gsettings");
+ }
+
g_intern_static_string ("antialiasing");
g_intern_static_string ("hinting");
g_intern_static_string ("rgba-order");
@@ -1705,6 +1924,41 @@ set_value_from_entry (GdkDisplay *display,
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GSettings *settings;
+ if (gdk_should_use_portal ())
+ {
+ switch (entry->type)
+ {
+ case G_TYPE_STRING:
+ g_value_set_string (value, entry->fallback.s);
+ break;
+ case G_TYPE_INT:
+ g_value_set_int (value, entry->fallback.i);
+ break;
+ case G_TYPE_BOOLEAN:
+ g_value_set_boolean (value, entry->fallback.b);
+ break;
+ case G_TYPE_NONE:
+ if (g_str_equal (entry->setting, "gtk-xft-antialias"))
+ g_value_set_int (value, display_wayland->xft_settings.antialias);
+ else if (g_str_equal (entry->setting, "gtk-xft-hinting"))
+ g_value_set_int (value, display_wayland->xft_settings.hinting);
+ else if (g_str_equal (entry->setting, "gtk-xft-hintstyle"))
+ g_value_set_static_string (value, display_wayland->xft_settings.hintstyle);
+ else if (g_str_equal (entry->setting, "gtk-xft-rgba"))
+ g_value_set_static_string (value, display_wayland->xft_settings.rgba);
+ else if (g_str_equal (entry->setting, "gtk-xft-dpi"))
+ g_value_set_int (value, display_wayland->xft_settings.dpi);
+ else
+ g_assert_not_reached ();
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return;
+ }
+
settings = (GSettings *)g_hash_table_lookup (display_wayland->settings, entry->schema);
switch (entry->type)
{
@@ -1756,7 +2010,14 @@ set_decoration_layout_from_entry (GdkDisplay *display,
GValue *value)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
- GSettings *settings;
+ GSettings *settings = NULL;
+ const char *session;
+
+ if (gdk_should_use_portal ())
+ {
+ g_value_set_string (value, entry->fallback.s);
+ return;
+ }
settings = (GSettings *)g_hash_table_lookup (display_wayland->settings, entry->schema);
@@ -1794,7 +2055,8 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
{
TranslationEntry *entry;
- if (g_hash_table_size (GDK_WAYLAND_DISPLAY (display)->settings) == 0)
+ if (GDK_WAYLAND_DISPLAY (display)->settings != NULL &&
+ g_hash_table_size (GDK_WAYLAND_DISPLAY (display)->settings) == 0)
return FALSE;
entry = find_translation_entry_by_setting (name);
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index fa2647cfdb..8f06188841 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -77,6 +77,7 @@ struct _GdkWaylandDisplay
GHashTable *settings;
GsdXftSettings xft_settings;
+ GDBusProxy *settings_portal;
guint32 shell_capabilities;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]