mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 18:52:09 +01:00
Use OpenFile for local files
The OpenURI portal has a separate method to handle local files now. Use it. At the same time, split out the openuri helpers into separate files, and generate code for the OpenURI portal.
This commit is contained in:
parent
b5e8e4eea9
commit
0bc386c4cb
@ -281,6 +281,8 @@ unix_sources = \
|
||||
gportalnotificationbackend.c \
|
||||
gdocumentportal.c \
|
||||
gdocumentportal.h \
|
||||
gopenuriportal.c \
|
||||
gopenuriportal.h \
|
||||
gportalsupport.c \
|
||||
gportalsupport.h \
|
||||
$(portal_sources) \
|
||||
@ -368,6 +370,7 @@ CLEANFILES += $(xdp_dbus_built_sources)
|
||||
|
||||
portal_interfaces = \
|
||||
org.freedesktop.portal.Documents.xml \
|
||||
org.freedesktop.portal.OpenURI.xml \
|
||||
org.freedesktop.portal.NetworkMonitor.xml \
|
||||
org.freedesktop.portal.ProxyResolver.xml \
|
||||
$(NULL)
|
||||
@ -383,6 +386,7 @@ $(xdp_dbus_built_sources) : $(portal_interfaces)
|
||||
--generate-c-code $(builddir)/xdp-dbus \
|
||||
--annotate "org.freedesktop.portal.Documents.Add()" "org.gtk.GDBus.C.UnixFD" "true" \
|
||||
--annotate "org.freedesktop.portal.Documents.AddNamed()" "org.gtk.GDBus.C.UnixFD" "true" \
|
||||
--annotate "org.freedesktop.portal.OpenURI.OpenFile()" "org.gtk.GDBus.C.UnixFD" "true" \
|
||||
$^
|
||||
|
||||
portal_sources = \
|
||||
|
264
gio/gappinfo.c
264
gio/gappinfo.c
@ -32,15 +32,12 @@
|
||||
#ifdef G_OS_UNIX
|
||||
#include "gdbusconnection.h"
|
||||
#include "gdbusmessage.h"
|
||||
#include "gdocumentportal.h"
|
||||
#include "gportalsupport.h"
|
||||
#endif
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#define FLATPAK_OPENURI_PORTAL_BUS_NAME "org.freedesktop.portal.Desktop"
|
||||
#define FLATPAK_OPENURI_PORTAL_PATH "/org/freedesktop/portal/desktop"
|
||||
#define FLATPAK_OPENURI_PORTAL_IFACE "org.freedesktop.portal.OpenURI"
|
||||
#define FLATPAK_OPENURI_PORTAL_METHOD "OpenURI"
|
||||
#include "gunixfdlist.h"
|
||||
#include "gopenuriportal.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -687,240 +684,6 @@ g_app_info_should_show (GAppInfo *appinfo)
|
||||
return (* iface->should_show) (appinfo);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static void
|
||||
response_received (GDBusConnection *connection,
|
||||
const char *sender_name,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
const char *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task = user_data;
|
||||
guint32 response;
|
||||
guint signal_id;
|
||||
|
||||
signal_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "signal-id"));
|
||||
g_dbus_connection_signal_unsubscribe (connection, signal_id);
|
||||
|
||||
g_variant_get (parameters, "(u@a{sv})", &response, NULL);
|
||||
|
||||
if (response == 0)
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else if (response == 1)
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Launch cancelled");
|
||||
else
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Launch failed");
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
open_uri_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDBusConnection *connection = G_DBUS_CONNECTION (source);
|
||||
GTask *task = user_data;
|
||||
GVariant *res;
|
||||
GError *error = NULL;
|
||||
const char *path;
|
||||
guint signal_id;
|
||||
|
||||
res = g_dbus_connection_call_finish (connection, result, &error);
|
||||
|
||||
if (res == NULL)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_get (res, "(&o)", &path);
|
||||
|
||||
signal_id =
|
||||
g_dbus_connection_signal_subscribe (connection,
|
||||
"org.freedesktop.portal.Desktop",
|
||||
"org.freedesktop.portal.Request",
|
||||
"Response",
|
||||
path,
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
|
||||
response_received,
|
||||
task, NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (task), "signal-id", GINT_TO_POINTER (signal_id));
|
||||
|
||||
g_variant_unref (res);
|
||||
}
|
||||
|
||||
static char *
|
||||
real_uri_for_portal (const char *uri,
|
||||
GAppLaunchContext *context,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GFile *file = NULL;
|
||||
char *real_uri = NULL;
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
if (g_file_is_native (file))
|
||||
{
|
||||
real_uri = g_document_portal_add_document (file, error);
|
||||
g_object_unref (file);
|
||||
|
||||
if (real_uri == NULL)
|
||||
{
|
||||
g_task_report_error (context, callback, user_data, NULL, *error);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_unref (file);
|
||||
real_uri = g_strdup (uri);
|
||||
}
|
||||
|
||||
return real_uri;
|
||||
}
|
||||
|
||||
static void
|
||||
launch_default_with_portal_async (const char *uri,
|
||||
GAppLaunchContext *context,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDBusConnection *session_bus;
|
||||
GVariantBuilder opt_builder;
|
||||
const char *parent_window = NULL;
|
||||
char *real_uri;
|
||||
GTask *task;
|
||||
GAsyncReadyCallback dbus_callback;
|
||||
GError *error = NULL;
|
||||
|
||||
session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (session_bus == NULL)
|
||||
{
|
||||
g_task_report_error (context, callback, user_data, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (context && context->priv->envp)
|
||||
parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
|
||||
|
||||
real_uri = real_uri_for_portal (uri, context, cancellable, callback, user_data, &error);
|
||||
if (real_uri == NULL)
|
||||
{
|
||||
g_object_unref (session_bus);
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
if (callback)
|
||||
{
|
||||
task = g_task_new (context, cancellable, callback, user_data);
|
||||
dbus_callback = open_uri_done;
|
||||
}
|
||||
else
|
||||
{
|
||||
task = NULL;
|
||||
dbus_callback = NULL;
|
||||
}
|
||||
|
||||
g_dbus_connection_call (session_bus,
|
||||
FLATPAK_OPENURI_PORTAL_BUS_NAME,
|
||||
FLATPAK_OPENURI_PORTAL_PATH,
|
||||
FLATPAK_OPENURI_PORTAL_IFACE,
|
||||
FLATPAK_OPENURI_PORTAL_METHOD,
|
||||
g_variant_new ("(ss@a{sv})",
|
||||
parent_window ? parent_window : "",
|
||||
real_uri,
|
||||
g_variant_builder_end (&opt_builder)),
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
G_MAXINT,
|
||||
cancellable,
|
||||
dbus_callback,
|
||||
task);
|
||||
|
||||
g_dbus_connection_flush (session_bus, cancellable, NULL, NULL);
|
||||
g_object_unref (session_bus);
|
||||
g_free (real_uri);
|
||||
}
|
||||
|
||||
static void
|
||||
launch_default_with_portal_sync (const char *uri,
|
||||
GAppLaunchContext *context)
|
||||
{
|
||||
GDBusConnection *session_bus;
|
||||
GVariantBuilder opt_builder;
|
||||
GVariant *res = NULL;
|
||||
const char *parent_window = NULL;
|
||||
char *real_uri;
|
||||
GError *error = NULL;
|
||||
|
||||
session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (session_bus == NULL)
|
||||
{
|
||||
g_task_report_error (context, NULL, NULL, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (context && context->priv->envp)
|
||||
parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
|
||||
|
||||
real_uri = real_uri_for_portal (uri, context, NULL, NULL, NULL, &error);
|
||||
if (real_uri == NULL)
|
||||
{
|
||||
g_object_unref (session_bus);
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
/* Calling the D-Bus method for the OpenURI portal "protects" the logic from
|
||||
* not ever having the remote method running in case the xdg-desktop-portal
|
||||
* process is not yet running and the caller quits quickly after the call.
|
||||
*/
|
||||
res = g_dbus_connection_call_sync (session_bus,
|
||||
FLATPAK_OPENURI_PORTAL_BUS_NAME,
|
||||
FLATPAK_OPENURI_PORTAL_PATH,
|
||||
FLATPAK_OPENURI_PORTAL_IFACE,
|
||||
FLATPAK_OPENURI_PORTAL_METHOD,
|
||||
g_variant_new ("(ss@a{sv})",
|
||||
parent_window ? parent_window : "",
|
||||
real_uri,
|
||||
g_variant_builder_end (&opt_builder)),
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
G_MAXINT,
|
||||
NULL,
|
||||
&error);
|
||||
if (res == NULL)
|
||||
g_task_report_error (context, NULL, NULL, NULL, error);
|
||||
else
|
||||
g_variant_unref (res);
|
||||
|
||||
g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
|
||||
g_object_unref (session_bus);
|
||||
g_free (real_uri);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
launch_default_with_portal (const char *uri,
|
||||
GAppLaunchContext *context,
|
||||
GError **error)
|
||||
{
|
||||
launch_default_with_portal_sync (uri, context);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
launch_default_for_uri (const char *uri,
|
||||
GAppLaunchContext *context,
|
||||
@ -985,10 +748,16 @@ g_app_info_launch_default_for_uri (const char *uri,
|
||||
#ifdef G_OS_UNIX
|
||||
if (glib_should_use_portal ())
|
||||
{
|
||||
const char *parent_window = NULL;
|
||||
|
||||
/* Reset any error previously set by launch_default_for_uri */
|
||||
g_clear_error (error);
|
||||
|
||||
return launch_default_with_portal (uri, launch_context, error);
|
||||
if (launch_context && launch_context->priv->envp)
|
||||
parent_window = g_environ_getenv (launch_context->priv->envp, "PARENT_WINDOW_ID");
|
||||
|
||||
return g_openuri_portal_open_uri (uri, parent_window, error);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1028,7 +797,12 @@ g_app_info_launch_default_for_uri_async (const char *uri,
|
||||
#ifdef G_OS_UNIX
|
||||
if (!res && glib_should_use_portal ())
|
||||
{
|
||||
launch_default_with_portal_async (uri, context, cancellable, callback, user_data);
|
||||
const char *parent_window = NULL;
|
||||
|
||||
if (context && context->priv->envp)
|
||||
parent_window = g_environ_getenv (context->priv->envp, "PARENT_WINDOW_ID");
|
||||
|
||||
g_openuri_portal_open_uri_async (uri, parent_window, cancellable, callback, user_data);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -1057,7 +831,7 @@ gboolean
|
||||
g_app_info_launch_default_for_uri_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
return g_openuri_portal_open_uri_finish (result, error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
287
gio/gopenuriportal.c
Normal file
287
gio/gopenuriportal.c
Normal file
@ -0,0 +1,287 @@
|
||||
/* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright 2017 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "gopenuriportal.h"
|
||||
#include "xdp-dbus.h"
|
||||
#include "gstdio.h"
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
#include "gunixfdlist.h"
|
||||
#endif
|
||||
|
||||
#ifndef O_PATH
|
||||
#define O_PATH 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#else
|
||||
#define HAVE_O_CLOEXEC 1
|
||||
#endif
|
||||
|
||||
static GXdpOpenURI *openuri;
|
||||
|
||||
static gboolean
|
||||
init_openuri_portal (void)
|
||||
{
|
||||
static gsize openuri_inited = 0;
|
||||
|
||||
if (g_once_init_enter (&openuri_inited))
|
||||
{
|
||||
GError *error = NULL;
|
||||
GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
|
||||
if (connection != NULL)
|
||||
{
|
||||
openuri = gxdp_open_uri_proxy_new_sync (connection, 0,
|
||||
"org.freedesktop.portal.Desktop",
|
||||
"/org/freedesktop/portal/desktop",
|
||||
NULL, &error);
|
||||
if (openuri == NULL)
|
||||
{
|
||||
g_warning ("Cannot create document portal proxy: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Cannot connect to session bus when initializing document portal: %s",
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_once_init_leave (&openuri_inited, 1);
|
||||
}
|
||||
|
||||
return openuri != NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_openuri_portal_open_uri (const char *uri,
|
||||
const char *parent_window,
|
||||
GError **error)
|
||||
{
|
||||
GFile *file = NULL;
|
||||
GVariantBuilder opt_builder;
|
||||
gboolean res;
|
||||
|
||||
if (!init_openuri_portal ())
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"OpenURI portal is not available");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
if (g_file_is_native (file))
|
||||
{
|
||||
char *path;
|
||||
GUnixFDList *fd_list;
|
||||
int fd, fd_id;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
fd = open (path, O_PATH | O_CLOEXEC);
|
||||
#ifndef HAVE_O_CLOEXEC
|
||||
fcntl (fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
fd_list = g_unix_fd_list_new_from_array (&fd, 1);
|
||||
fd_id = 0;
|
||||
|
||||
res = gxdp_open_uri_call_open_file_sync (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
g_variant_new ("h", fd_id),
|
||||
g_variant_builder_end (&opt_builder),
|
||||
fd_list,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
error);
|
||||
g_free (path);
|
||||
g_object_unref (fd_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = gxdp_open_uri_call_open_uri_sync (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
uri,
|
||||
g_variant_builder_end (&opt_builder),
|
||||
NULL,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
response_received (GDBusConnection *connection,
|
||||
const char *sender_name,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
const char *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task = user_data;
|
||||
guint32 response;
|
||||
guint signal_id;
|
||||
|
||||
signal_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "signal-id"));
|
||||
g_dbus_connection_signal_unsubscribe (connection, signal_id);
|
||||
|
||||
g_variant_get (parameters, "(u@a{sv})", &response, NULL);
|
||||
|
||||
if (response == 0)
|
||||
g_task_return_boolean (task, TRUE);
|
||||
else if (response == 1)
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, "Launch cancelled");
|
||||
else
|
||||
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Launch failed");
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
open_call_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GDBusConnection *connection = G_DBUS_CONNECTION (source);
|
||||
GTask *task = user_data;
|
||||
GError *error = NULL;
|
||||
gboolean open_file;
|
||||
gboolean res;
|
||||
char *path;
|
||||
guint signal_id;
|
||||
|
||||
open_file = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "open-file"));
|
||||
|
||||
if (open_file)
|
||||
res = gxdp_open_uri_call_open_file_finish (openuri, &path, NULL, result, &error);
|
||||
else
|
||||
res = gxdp_open_uri_call_open_uri_finish (openuri, &path, result, &error);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
g_free (path);
|
||||
return;
|
||||
}
|
||||
|
||||
signal_id = g_dbus_connection_signal_subscribe (connection,
|
||||
"org.freedesktop.portal.Desktop",
|
||||
"org.freedesktop.portal.Request",
|
||||
"Response",
|
||||
path,
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
|
||||
response_received,
|
||||
task,
|
||||
NULL);
|
||||
g_object_set_data (G_OBJECT (task), "signal-id", GINT_TO_POINTER (signal_id));
|
||||
}
|
||||
|
||||
void
|
||||
g_openuri_portal_open_uri_async (const char *uri,
|
||||
const char *parent_window,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
GFile *file;
|
||||
GVariantBuilder opt_builder;
|
||||
|
||||
if (!init_openuri_portal ())
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "OpenURI portal is not available");
|
||||
g_task_report_error (NULL, callback, user_data, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback)
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
else
|
||||
task = NULL;
|
||||
|
||||
g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
file = g_file_new_for_uri (uri);
|
||||
if (g_file_is_native (file))
|
||||
{
|
||||
char *path;
|
||||
GUnixFDList *fd_list;
|
||||
int fd, fd_id;
|
||||
|
||||
if (task)
|
||||
g_object_set_data (G_OBJECT (task), "open-file", GINT_TO_POINTER (TRUE));
|
||||
|
||||
path = g_file_get_path (file);
|
||||
fd = open (path, O_PATH | O_CLOEXEC);
|
||||
#ifndef HAVE_O_CLOEXEC
|
||||
fcntl (fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
fd_list = g_unix_fd_list_new_from_array (&fd, 1);
|
||||
fd_id = 0;
|
||||
|
||||
gxdp_open_uri_call_open_file (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
g_variant_new ("h", fd_id),
|
||||
g_variant_builder_end (&opt_builder),
|
||||
fd_list,
|
||||
cancellable,
|
||||
task ? open_call_done : NULL,
|
||||
task);
|
||||
g_object_unref (fd_list);
|
||||
g_free (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
gxdp_open_uri_call_open_uri (openuri,
|
||||
parent_window ? parent_window : "",
|
||||
uri,
|
||||
g_variant_builder_end (&opt_builder),
|
||||
cancellable,
|
||||
task ? open_call_done : NULL,
|
||||
task);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_openuri_portal_open_uri_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
41
gio/gopenuriportal.h
Normal file
41
gio/gopenuriportal.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright 2017 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __G_OPEN_URI_PORTAL_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean g_openuri_portal_open_uri (const char *uri,
|
||||
const char *parent_window,
|
||||
GError **error);
|
||||
|
||||
void g_openuri_portal_open_uri_async (const char *uri,
|
||||
const char *parent_window,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean g_openuri_portal_open_uri_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
105
gio/org.freedesktop.portal.OpenURI.xml
Normal file
105
gio/org.freedesktop.portal.OpenURI.xml
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 Red Hat, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Matthias Clasen <mclasen@redhat.com>
|
||||
-->
|
||||
|
||||
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||
<!--
|
||||
org.freedesktop.portal.OpenURI:
|
||||
@short_description: Portal for opening URIs
|
||||
|
||||
The OpenURI portal allows sandboxed applications to open
|
||||
URIs (e.g. a http: link to the applications homepage)
|
||||
under the control of the user.
|
||||
-->
|
||||
<interface name="org.freedesktop.portal.OpenURI">
|
||||
<!--
|
||||
OpenURI:
|
||||
@parent_window: Identifier for the application window
|
||||
@uri: The uri to open
|
||||
@options: Vardict with optional further onformation
|
||||
@handle: Object path for the #org.freedesktop.portal.Request object representing this call
|
||||
|
||||
Asks to open a uri.
|
||||
|
||||
The @parent_window identifier must be of the form "x11:$XID" for an X11
|
||||
window. Support for other window systems may be added in the future.
|
||||
|
||||
Note that file:// uris are explicitly not supported by this method.
|
||||
To request opening local files, use org.freedesktop.portal.OpenFile().
|
||||
|
||||
Supported keys in the @options vardict include:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>writable b</term>
|
||||
<listitem><para>
|
||||
Whether to allow the chosen application to write to the file.
|
||||
</para><para>
|
||||
This key only takes effect the uri points to a local file that
|
||||
is exported in the document portal, and the chosen application
|
||||
is sandboxed itself.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
-->
|
||||
<method name="OpenURI">
|
||||
<arg type="s" name="parent_window" direction="in"/>
|
||||
<arg type="s" name="uri" direction="in"/>
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="o" name="handle" direction="out"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
OpenFile:
|
||||
@parent_window: Identifier for the application window
|
||||
@fd: File descriptor for the file to open
|
||||
@options: Vardict with optional further onformation
|
||||
@handle: Object path for the #org.freedesktop.portal.Request object representing this call
|
||||
|
||||
Asks to open a local file.
|
||||
|
||||
The @parent_window identifier must be of the form "x11:$XID" for an X11
|
||||
window. Support for other window systems may be added in the future.
|
||||
|
||||
Supported keys in the @options vardict include:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>writable b</term>
|
||||
<listitem><para>
|
||||
Whether to allow the chosen application to write to the file.
|
||||
</para><para>
|
||||
This key only takes effect the uri points to a local file that
|
||||
is exported in the document portal, and the chosen application
|
||||
is sandboxed itself.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
The OpenFile method was introduced in version 2 of the OpenURI portal API.
|
||||
-->
|
||||
<method name="OpenFile">
|
||||
<arg type="s" name="parent_window" direction="in"/>
|
||||
<arg type="h" name="fd" direction="in"/>
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="o" name="handle" direction="out"/>
|
||||
</method>
|
||||
|
||||
<property name="version" type="u" access="read"/>
|
||||
</interface>
|
||||
</node>
|
Loading…
x
Reference in New Issue
Block a user