diff --git a/gtk/gtkcolorpickerportal.c b/gtk/gtkcolorpickerportal.c index 450f0f8343..830ffdd217 100644 --- a/gtk/gtkcolorpickerportal.c +++ b/gtk/gtkcolorpickerportal.c @@ -49,9 +49,9 @@ gtk_color_picker_portal_initable_init (GInitable *initable, GError **error) { GtkColorPickerPortal *picker = GTK_COLOR_PICKER_PORTAL (initable); - char *owner; - GVariant *ret; - guint version; + g_autofree char *owner = NULL; + g_autoptr(GVariant) ret = NULL; + guint version = 0; if (!gtk_should_use_portal ()) return FALSE; @@ -71,18 +71,18 @@ 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 ("org.freedesktop.portal.Screenshot not provided"); g_clear_object (&picker->portal_proxy); return FALSE; } - 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); + if (version != 2) { g_debug ("Screenshot portal version: %u", version); diff --git a/gtk/gtkfilechoosernativeportal.c b/gtk/gtkfilechoosernativeportal.c index 07cbb5b4bc..d005571f1b 100644 --- a/gtk/gtkfilechoosernativeportal.c +++ b/gtk/gtkfilechoosernativeportal.c @@ -294,6 +294,7 @@ show_portal_file_chooser (GtkFileChooserNative *self, GDBusMessage *message; GVariantBuilder opt_builder; gboolean multiple; + gboolean directory; const char *title; char *token; @@ -315,6 +316,7 @@ show_portal_file_chooser (GtkFileChooserNative *self, self, NULL); multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (self)); + directory = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (self)) == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&opt_builder, "{sv}", "handle_token", @@ -323,6 +325,8 @@ show_portal_file_chooser (GtkFileChooserNative *self, g_variant_builder_add (&opt_builder, "{sv}", "multiple", g_variant_new_boolean (multiple)); + g_variant_builder_add (&opt_builder, "{sv}", "directory", + g_variant_new_boolean (directory)); if (self->accept_label) g_variant_builder_add (&opt_builder, "{sv}", "accept_label", g_variant_new_string (self->accept_label)); @@ -422,9 +426,18 @@ gtk_file_chooser_native_portal_show (GtkFileChooserNative *self) 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_%s is not supported by GtkFileChooserNativePortal", action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ? "SELECT_FOLDER" : "CREATE_FOLDER"); + g_warning ("GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER is not supported by GtkFileChooserNativePortal"); return FALSE; } diff --git a/gtk/gtkprivate.c b/gtk/gtkprivate.c index a437047658..134d3bbfe1 100644 --- a/gtk/gtkprivate.c +++ b/gtk/gtkprivate.c @@ -292,6 +292,57 @@ gtk_should_use_portal (void) return use_portal[0] == '1'; } +/* + * 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) +{ + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GVariant) ret = NULL; + g_autofree 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); + return 0; + } + + owner = g_dbus_proxy_get_name_owner (proxy); + if (owner == NULL) + { + g_debug ("%s not provided by any service", interface_name); + return FALSE; + } + + 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); + + return version; +} + static char * get_portal_path (GDBusConnection *connection, const char *kind, diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index af7e58b5e9..80a18a1419 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -100,6 +100,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); #ifdef G_OS_WIN32 void _gtk_load_dll_with_libgtk3_manifest (const char *dllname);