From bd55c5842e77331d46ec377542861710a56e1541 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 23 Mar 2020 14:45:57 +0100 Subject: [PATCH 1/3] colorpickerportal: Simplify version fetching code Simplify version checking code by using a function to fetch the uint out of the GVariant and don't throw a warning if it can't be fetched. --- gtk/gtkcolorpickerportal.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/gtk/gtkcolorpickerportal.c b/gtk/gtkcolorpickerportal.c index a382f51056..2f64a8fa9f 100644 --- a/gtk/gtkcolorpickerportal.c +++ b/gtk/gtkcolorpickerportal.c @@ -51,7 +51,7 @@ gtk_color_picker_portal_initable_init (GInitable *initable, GtkColorPickerPortal *picker = GTK_COLOR_PICKER_PORTAL (initable); char *owner; GVariant *ret; - guint version; + guint version = 0; if (!gdk_should_use_portal ()) return FALSE; @@ -71,7 +71,7 @@ gtk_color_picker_portal_initable_init (GInitable *initable, return FALSE; } - owner = g_dbus_proxy_get_name_owner (picker->portal_proxy); + owner = g_dbus_proxy_get_name_owner (picker->portal_proxy); if (owner == NULL) { g_debug ("%s not provided", PORTAL_SCREENSHOT_INTERFACE); @@ -81,8 +81,12 @@ gtk_color_picker_portal_initable_init (GInitable *initable, g_free (owner); ret = g_dbus_proxy_get_cached_property (picker->portal_proxy, "version"); - g_variant_get (ret, "u", &version); - g_variant_unref (ret); + if (ret) + { + version = g_variant_get_uint32 (ret); + g_variant_unref (ret); + } + if (version != 2) { g_debug ("Screenshot portal version: %u", version); From 027ca22defe39ad48033dee3e0f38cf3f5a33116 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 23 Mar 2020 14:56:43 +0100 Subject: [PATCH 2/3] Add portal version checking helper Add gtk_get_portal_interface_version() to check the version of a portal. --- gtk/gtkprivate.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ gtk/gtkprivate.h | 2 ++ 2 files changed, 59 insertions(+) diff --git a/gtk/gtkprivate.c b/gtk/gtkprivate.c index 8de1e81a5e..9a6cd584dc 100644 --- a/gtk/gtkprivate.c +++ b/gtk/gtkprivate.c @@ -268,6 +268,63 @@ _gtk_ensure_resources (void) g_once (®ister_resources_once, register_resources, NULL); } +/* + * gtk_get_portal_interface_version: + * @connection: a session #GDBusConnection + * @interface_name: the interface name for the portal interface + * we're interested in. + * + * Returns: the version number of the portal, or 0 on error. + */ +guint +gtk_get_portal_interface_version (GDBusConnection *connection, + const char *interface_name) +{ + GDBusProxy *proxy = NULL; + GError *error = NULL; + GVariant *ret = NULL; + char *owner = NULL; + guint version = 0; + + proxy = g_dbus_proxy_new_sync (connection, + 0, + NULL, + "org.freedesktop.portal.Desktop", + "/org/freedesktop/portal/desktop", + interface_name, + NULL, + &error); + if (!proxy) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Could not query portal version on interface '%s': %s", + interface_name, error->message); + goto out; + } + + owner = g_dbus_proxy_get_name_owner (proxy); + if (owner == NULL) + { + g_debug ("%s not provided by any service", interface_name); + goto out; + } + + ret = g_dbus_proxy_get_cached_property (proxy, "version"); + if (ret) + version = g_variant_get_uint32 (ret); + + g_debug ("Got version %u for portal interface '%s'", + version, interface_name); + +out: + g_clear_object (&proxy); + g_clear_error (&error); + g_clear_pointer (&ret, g_variant_unref); + g_clear_pointer (&owner, g_free); + + return version; +} + static char * get_portal_path (GDBusConnection *connection, const char *kind, diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index 6cac03c763..f4ba489ba6 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -115,6 +115,8 @@ char *gtk_get_portal_request_path (GDBusConnection *connection, char **token); char *gtk_get_portal_session_path (GDBusConnection *connection, char **token); +guint gtk_get_portal_interface_version (GDBusConnection *connection, + const char *interface_name); #define PORTAL_BUS_NAME "org.freedesktop.portal.Desktop" #define PORTAL_OBJECT_PATH "/org/freedesktop/portal/desktop" From 8cf41c1b6651dac252e193534bc4b4f31586ecca Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 30 Mar 2020 14:18:11 +0200 Subject: [PATCH 3/3] filechoosernativeportal: Fall back if portal is too old Add portal version checking as originally implemented for the GTK 3.x branch. See: 35fec1c6b298e0e294530e1ffc8615b5bd261531 --- gtk/gtkfilechoosernativeportal.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gtk/gtkfilechoosernativeportal.c b/gtk/gtkfilechoosernativeportal.c index 2e3c49a887..8d58dc253d 100644 --- a/gtk/gtkfilechoosernativeportal.c +++ b/gtk/gtkfilechoosernativeportal.c @@ -423,11 +423,19 @@ gtk_file_chooser_native_portal_show (GtkFileChooserNative *self, action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (self)); - if (action == GTK_FILE_CHOOSER_ACTION_OPEN || - action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) + if (action == GTK_FILE_CHOOSER_ACTION_OPEN) method_name = "OpenFile"; else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) method_name = "SaveFile"; + else if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) + { + if (gtk_get_portal_interface_version (connection, "org.freedesktop.portal.FileChooser") < 3) + { + g_warning ("GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER is not supported by GtkFileChooserNativePortal because portal is too old"); + return FALSE; + } + method_name = "OpenFile"; + } else { g_warning ("GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER is not supported by GtkFileChooserNativePortal");