[gnome-software/mwleeds/hardcoded-pwa-list: 5/14] Fix epiphany self test
- From: Phaedrus Leeds <mwleeds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/mwleeds/hardcoded-pwa-list: 5/14] Fix epiphany self test
- Date: Sat, 26 Mar 2022 18:03:28 +0000 (UTC)
commit e078642bdfe1e5c57871baa268cf75f65fd3ca20
Author: Phaedrus Leeds <mwleeds protonmail com>
Date: Fri Feb 25 20:39:52 2022 -0800
Fix epiphany self test
Use libglib-testing to mock responses from the portal and WebAppProvider
D-Bus services, and test the epiphany plugin's ability to list installed
apps.
.gitlab-ci.yml | 2 +-
.gitlab-ci/fedora.Dockerfile | 1 +
plugins/epiphany/gs-plugin-epiphany.c | 5 +-
plugins/epiphany/gs-self-test.c | 235 ++++++++++++---
plugins/epiphany/meson.build | 25 ++
.../org.freedesktop.portal.DynamicLauncher.xml | 332 +++++++++++++++++++++
subprojects/libglib-testing.wrap | 2 +-
7 files changed, 552 insertions(+), 50 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index daf689856..65d9f2ab8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,7 +20,7 @@ variables:
fedora-x86_64:
extends: .build
- image: registry.gitlab.gnome.org/gnome/gnome-software/fedora:v9
+ image: registry.gitlab.gnome.org/gnome/gnome-software/fedora:v10
stage: build
except:
- tags
diff --git a/.gitlab-ci/fedora.Dockerfile b/.gitlab-ci/fedora.Dockerfile
index 08813fd7c..beea19a90 100644
--- a/.gitlab-ci/fedora.Dockerfile
+++ b/.gitlab-ci/fedora.Dockerfile
@@ -33,6 +33,7 @@ RUN dnf -y install \
libcurl-devel \
libdnf-devel \
libepoxy-devel \
+ libglib-testing-devel \
libgudev-devel \
libjpeg-turbo-devel \
liboauth-devel \
diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c
index 0a712b54e..9b7822639 100644
--- a/plugins/epiphany/gs-plugin-epiphany.c
+++ b/plugins/epiphany/gs-plugin-epiphany.c
@@ -474,8 +474,9 @@ list_installed_apps_thread_cb (GTask *task,
g_debug ("%s: Working on installed web app %s", G_STRFUNC, desktop_file_id);
desktop_info = g_desktop_app_info_new (desktop_file_id);
+
if (desktop_info == NULL) {
- g_warning ("Epiphany returned a non-existent desktop ID %s", desktop_file_id);
+ g_warning ("Epiphany returned a non-existent or invalid desktop ID %s",
desktop_file_id);
continue;
}
@@ -532,6 +533,8 @@ list_installed_apps_thread_cb (GTask *task,
const char *x;
guint64 size = 0;
+ g_debug ("%s: finding size for icon %s", G_STRFUNC, icon_path);
+
g_clear_object (&file_info);
file_info = g_file_query_info (icon_file,
G_FILE_ATTRIBUTE_STANDARD_SIZE,
diff --git a/plugins/epiphany/gs-self-test.c b/plugins/epiphany/gs-self-test.c
index 4bea3e740..a7207b26c 100644
--- a/plugins/epiphany/gs-self-test.c
+++ b/plugins/epiphany/gs-self-test.c
@@ -12,34 +12,188 @@
#include "gnome-software-private.h"
#include "gs-test.h"
+#include "gs-dynamic-launcher-portal-iface.h"
+#include "gs-epiphany-generated.h"
+
+#include <libglib-testing/dbus-queue.h>
+
+/* This is run in a worker thread */
+static void
+epiphany_and_portal_mock_server_cb (GtDBusQueue *queue,
+ gpointer user_data)
+{
+ {
+ g_autoptr(GDBusMethodInvocation) invocation = NULL;
+ g_autoptr(GVariant) properties_variant = NULL;
+ const char *property_interface;
+ invocation = gt_dbus_queue_assert_pop_message (queue,
+ "/org/gnome/Epiphany/WebAppProvider",
+ "org.freedesktop.DBus.Properties",
+ "GetAll", "(&s)",
+ &property_interface);
+ g_assert_cmpstr (property_interface, ==, "org.gnome.Epiphany.WebAppProvider");
+ properties_variant = g_variant_new_parsed ("({'Version': <@u 1>},)");
+ g_dbus_method_invocation_return_value (invocation, g_steal_pointer (&properties_variant));
+ }
+ {
+ g_autoptr(GDBusMethodInvocation) invocation = NULL;
+ const char *property_interface;
+ const char *property_name;
+ g_autoptr(GVariant) property_variant = NULL;
+ invocation = gt_dbus_queue_assert_pop_message (queue,
+ "/org/freedesktop/portal/desktop",
+ "org.freedesktop.DBus.Properties",
+ "Get", "(&s&s)",
+ &property_interface, &property_name);
+ g_assert_cmpstr (property_interface, ==, "org.freedesktop.portal.DynamicLauncher");
+ g_assert_cmpstr (property_name, ==, "version");
+ property_variant = g_variant_new_parsed ("(<@u 1>,)");
+ g_dbus_method_invocation_return_value (invocation, g_steal_pointer (&property_variant));
+ }
+ {
+ g_autoptr(GDBusMethodInvocation) invocation = NULL;
+ g_autoptr(GVariant) properties_variant = NULL;
+ const char *property_interface, *props_dict;
+ invocation = gt_dbus_queue_assert_pop_message (queue,
+ "/org/freedesktop/portal/desktop",
+ "org.freedesktop.DBus.Properties",
+ "GetAll", "(&s)",
+ &property_interface);
+ g_assert_cmpstr (property_interface, ==, "org.freedesktop.portal.DynamicLauncher");
+ props_dict = "({'version': <@u 1>,'SupportedLauncherTypes': <@u 3>},)";
+ properties_variant = g_variant_new_parsed (props_dict);
+ g_dbus_method_invocation_return_value (invocation, g_steal_pointer (&properties_variant));
+ }
+ {
+ g_autoptr(GDBusMethodInvocation) invocation = NULL;
+ const char *installed_apps[] =
{"org.gnome.Epiphany.WebApp_e9d0e1e4b0a10856aa3b38d9eb4375de4070d043.desktop", NULL};
+ invocation = gt_dbus_queue_assert_pop_message (queue,
+ "/org/gnome/Epiphany/WebAppProvider",
+ "org.gnome.Epiphany.WebAppProvider",
+ "GetInstalledApps", "()", NULL);
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(^as)", installed_apps));
+ }
+}
+
+static GtDBusQueue *
+bus_set_up (void)
+{
+ g_autoptr(GError) local_error = NULL;
+ g_autoptr(GtDBusQueue) queue = NULL;
+
+ queue = gt_dbus_queue_new ();
+
+ gt_dbus_queue_connect (queue, &local_error);
+ g_assert_no_error (local_error);
+
+ gt_dbus_queue_own_name (queue, "org.freedesktop.portal.Desktop");
+
+ gt_dbus_queue_export_object (queue,
+ "/org/freedesktop/portal/desktop",
+ (GDBusInterfaceInfo *)
&org_freedesktop_portal_dynamic_launcher_interface,
+ &local_error);
+ g_assert_no_error (local_error);
+
+ gt_dbus_queue_own_name (queue, "org.gnome.Epiphany.WebAppProvider");
+
+ gt_dbus_queue_export_object (queue,
+ "/org/gnome/Epiphany/WebAppProvider",
+ gs_ephy_web_app_provider_interface_info (),
+ &local_error);
+ g_assert_no_error (local_error);
+
+ gt_dbus_queue_set_server_func (queue, epiphany_and_portal_mock_server_cb,
+ NULL);
+
+ return g_steal_pointer (&queue);
+}
static void
gs_plugins_epiphany_func (GsPluginLoader *plugin_loader)
{
- gboolean ret;
+ g_assert_true (gs_plugin_loader_get_enabled (plugin_loader, "epiphany"));
+}
+
+static char *
+create_fake_desktop_file (const char *app_id)
+{
+ g_autofree char *contents = NULL;
g_autoptr(GError) error = NULL;
- g_autoptr(GsApp) app = NULL;
+ g_autofree char *desktop_path = NULL;
+ g_autofree char *icon_path = NULL;
+
+ /* Use an icon we already have locally */
+ icon_path = gs_test_get_filename (TESTDATADIR, "icons/hicolor/scalable/org.gnome.Software.svg");
+ g_assert (icon_path != NULL);
+
+ /* Use true instead of epiphany in Exec and TryExec; otherwise
+ * g_desktop_app_info_new() in the plugin code will look for an
+ * epiphany binary and fail.
+ */
+ contents = g_strdup_printf ("[Desktop Entry]\n"
+ "Name=Pinafore\n"
+ "Exec=true --application-mode \"--profile=/home/nobody/.local/share/%s\"
https://pinafore.social/\n"
+ "StartupNotify=true\n"
+ "Terminal=false\n"
+ "Type=Application\n"
+ "Categories=GNOME;GTK;\n"
+ "Icon=%s\n"
+ "StartupWMClass=%s\n"
+ "X-Purism-FormFactor=Workstation;Mobile;\n"
+ "TryExec=true\n",
+ app_id, icon_path, app_id);
+
+ desktop_path = g_strconcat (g_get_user_data_dir (), G_DIR_SEPARATOR_S,
+ "applications", G_DIR_SEPARATOR_S,
+ app_id, ".desktop", NULL);
+
+ g_debug ("Creating a fake desktop file at path: %s", desktop_path);
+ gs_mkdir_parent (desktop_path, &error);
+ g_assert_no_error (error);
+ g_file_set_contents (desktop_path, contents, -1, &error);
+ g_assert_no_error (error);
+
+ return g_steal_pointer (&desktop_path);
+}
+
+static void
+gs_plugins_epiphany_installed_func (GsPluginLoader *plugin_loader)
+{
g_autoptr(GsPluginJob) plugin_job = NULL;
- GsPlugin *plugin;
-
- /* no epiphany, abort */
- if (!gs_plugin_loader_get_enabled (plugin_loader, "epiphany"))
- return;
-
- /* a webapp with a local icon */
- app = gs_app_new ("app.squoosh.webapp.desktop");
- gs_app_set_kind (app, AS_COMPONENT_KIND_WEB_APP);
- plugin = gs_plugin_loader_find_plugin (plugin_loader, "epiphany");
- gs_app_set_management_plugin (app, plugin);
- plugin_job = gs_plugin_job_refine_new_for_app (app,
- GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON);
- ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error);
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GIcon) icon = NULL;
+ g_autoptr(GsAppList) list = NULL;
+ GsApp *app;
+ const char *app_id = "org.gnome.Epiphany.WebApp_e9d0e1e4b0a10856aa3b38d9eb4375de4070d043";
+ g_autofree char *app_id_desktop = NULL;
+ g_autofree char *desktop_path = NULL;
+
+ app_id_desktop = g_strdup_printf ("%s.desktop", app_id);
+ desktop_path = create_fake_desktop_file (app_id);
+
+ plugin_job = gs_plugin_job_list_installed_apps_new (GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN,
+ 0, GS_PLUGIN_JOB_DEDUPE_FLAGS_DEFAULT,
+ GS_PLUGIN_LIST_INSTALLED_APPS_FLAGS_NONE);
+ list = gs_plugin_loader_job_process (plugin_loader, plugin_job, NULL, &error);
gs_test_flush_main_context ();
g_assert_no_error (error);
- g_assert_true (ret);
+ g_assert_nonnull (list);
+
+ g_assert_cmpint (gs_app_list_length (list), ==, 1);
+ app = gs_app_list_index (list, 0);
+ g_assert_cmpstr (gs_app_get_id (app), ==, app_id_desktop);
+ g_assert_cmpint (gs_app_get_kind (app), ==, AS_COMPONENT_KIND_WEB_APP);
+ g_assert_cmpint (gs_app_get_scope (app), ==, AS_COMPONENT_SCOPE_USER);
+ g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED);
+ g_assert_cmpstr (gs_app_get_name (app), ==, "Pinafore");
+ g_assert_cmpstr (gs_app_get_summary (app), ==, "pinafore.social");
+ g_assert_cmpstr (gs_app_get_origin (app), ==, "gnome-web");
+ g_assert_cmpstr (gs_app_get_origin_ui (app), ==, "GNOME Web");
+ icon = gs_app_get_icon_for_size (app, 4096, 1, NULL);
+ g_assert_nonnull (icon);
+ g_clear_object (&icon);
- g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_AVAILABLE);
- g_assert_nonnull (gs_app_get_icons (app));
+ gs_utils_unlink (desktop_path, NULL);
}
int
@@ -50,40 +204,21 @@ main (int argc, char **argv)
g_autofree gchar *xml = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GsPluginLoader) plugin_loader = NULL;
+ g_autoptr(GtDBusQueue) queue = NULL;
+ int res;
const gchar *allowlist[] = {
- "appstream",
"epiphany",
"icons",
NULL
};
- g_test_init (&argc, &argv, NULL);
- g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ gs_test_init (&argc, &argv);
g_setenv ("GS_XMLB_VERBOSE", "1", TRUE);
- /* Use an icon we already have locally */
- fn = gs_test_get_filename (TESTDATADIR, "icons/hicolor/scalable/org.gnome.Software.svg");
- g_assert (fn != NULL);
- xml = g_strdup_printf ("<?xml version=\"1.0\"?>\n"
- "<components version=\"0.14\">\n"
- " <component type=\"webapp\">\n"
- " <id>app.squoosh.webapp.desktop</id>\n"
- " <metadata_license>CC0-1.0</metadata_license>\n"
- " <project_license>Apache-2.0</project_license>\n"
- " <name>Squoosh</name>\n"
- " <summary>Compress and compare images with different codecs, right in your
browser</summary>\n"
- " <launchable type=\"url\">https://squoosh.app/</launchable>\n"
- " <icon type=\"remote\">file://%s</icon>\n"
- " <categories>\n"
- " <category>Utility</category>\n"
- " </categories>\n"
- " <pkgname>test</pkgname>\n"
- " </component>\n"
- " <info>\n"
- " <scope>user</scope>\n"
- " </info>\n"
- "</components>\n", fn);
- g_setenv ("GS_SELF_TEST_APPSTREAM_XML", xml, TRUE);
+ /* Set up mock D-Bus services for the Epiphany WebAppProvider and the
+ * DynamicLauncher portal
+ */
+ queue = bus_set_up ();
/* we can only load this once per process */
plugin_loader = gs_plugin_loader_new ();
@@ -92,15 +227,21 @@ main (int argc, char **argv)
ret = gs_plugin_loader_setup (plugin_loader,
allowlist,
NULL,
+ gt_dbus_queue_get_client_connection (queue),
NULL,
&error);
g_assert_no_error (error);
g_assert_true (ret);
/* plugin tests go here */
- g_test_add_data_func ("/gnome-software/plugins/epiphany",
+ g_test_add_data_func ("/gnome-software/plugins/epiphany/enabled",
plugin_loader,
(GTestDataFunc) gs_plugins_epiphany_func);
+ g_test_add_data_func ("/gnome-software/plugins/epiphany/installed",
+ plugin_loader,
+ (GTestDataFunc) gs_plugins_epiphany_installed_func);
- return g_test_run ();
+ res = g_test_run ();
+ gt_dbus_queue_disconnect (queue, TRUE);
+ return res;
}
diff --git a/plugins/epiphany/meson.build b/plugins/epiphany/meson.build
index 794920c18..cd5805532 100644
--- a/plugins/epiphany/meson.build
+++ b/plugins/epiphany/meson.build
@@ -37,6 +37,27 @@ i18n.merge_file(
)
if get_option('tests')
+ # The DynamicLauncher interface xml comes from:
+ # https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.portal.DynamicLauncher.xml
+ gdbus_codegen = find_program('gdbus-codegen')
+ dynamic_launcher_portal_iface_h = custom_target(
+ 'gs-dynamic-launcher-portal-iface.h',
+ input: ['org.freedesktop.portal.DynamicLauncher.xml'],
+ output: ['gs-dynamic-launcher-portal-iface.h'],
+ command: [gdbus_codegen,
+ '--interface-info-header',
+ '--output', '@OUTPUT@',
+ '@INPUT@'],
+ )
+ dynamic_launcher_portal_iface_c = custom_target(
+ 'gs-dynamic-launcher-portal-iface.c',
+ input: ['org.freedesktop.portal.DynamicLauncher.xml'],
+ output: ['gs-dynamic-launcher-portal-iface.c'],
+ command: [gdbus_codegen,
+ '--interface-info-body',
+ '--output', '@OUTPUT@',
+ '@INPUT@'],
+ )
cargs += ['-DLOCALPLUGINDIR="' + meson.current_build_dir() + '"']
cargs += ['-DLOCALPLUGINDIR_CORE="' + meson.current_build_dir() + '/../core"']
cargs += ['-DTESTDATADIR="' + join_paths(meson.current_source_dir(), '..', '..', 'data') + '"']
@@ -45,6 +66,9 @@ if get_option('tests')
compiled_schemas,
sources : [
'gs-self-test.c',
+ dynamic_launcher_portal_iface_c,
+ dynamic_launcher_portal_iface_h,
+ epiphany_generated,
],
include_directories : [
include_directories('../..'),
@@ -52,6 +76,7 @@ if get_option('tests')
],
dependencies : [
plugin_libs,
+ dependency('glib-testing-0', fallback: ['libglib-testing', 'libglib_testing_dep']),
],
link_with : [
libgnomesoftware
diff --git a/plugins/epiphany/org.freedesktop.portal.DynamicLauncher.xml
b/plugins/epiphany/org.freedesktop.portal.DynamicLauncher.xml
new file mode 100644
index 000000000..65aa90e1f
--- /dev/null
+++ b/plugins/epiphany/org.freedesktop.portal.DynamicLauncher.xml
@@ -0,0 +1,332 @@
+<?xml version="1.0"?>
+<!--
+ Copyright (C) 2021 Matthew Leeds
+
+ 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: Matthew Leeds <mwleeds protonmail com>
+-->
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+ <!--
+ org.freedesktop.portal.DynamicLauncher:
+ @short_description: Portal for installing application launchers onto the
+ desktop
+
+ The DynamicLauncher portal allows sandboxed (or unsandboxed) applications
+ to install launchers (.desktop files) which have an icon associated with them
+ and which execute a command in the application. The desktop environment
+ would display the launcher to the user in its menu of installed applications.
+ For example this can be used by a sandboxed browser to install web app
+ launchers. The portal also allows apps to uninstall the launchers, launch
+ them, and read the desktop file and icon data for them.
+
+ The standard way to install a launcher is to use the PrepareInstall() method
+ which results in a dialog being presented to the user so they can confirm
+ they want to install the launcher. Then, the token returned by PrepareInstall()
+ would be passed to the Install() method to complete the installation.
+
+ However, in the rare circumstance that an unsandboxed process such as a
+ system component needs to install a launcher without user interaction, this
+ can be accomplished by using the RequestInstallToken() method and passing
+ the acquired token to Install().
+
+ This documentation describes version 1 of this interface.
+ -->
+ <interface name="org.freedesktop.portal.DynamicLauncher">
+ <!--
+ Install:
+ @token: Token proving authorization of the installation
+ @desktop_file_id: The .desktop file name to be used
+ @desktop_entry: The text of the Desktop Entry file to be installed, see below
+ @options: Vardict with optional further information
+
+ Installs a .desktop launcher and icon into appropriate directories to
+ allow the desktop environment to find them. Please note that this method
+ overwrites any existing launcher with the same id. If you want to
+ present the user with a confirmation dialog in that case, you can check
+ for it using the GetDesktopEntry() method and clean up any state from
+ the previous launcher if you want.
+
+ @token must be a token that was returned by a previous
+ org.freedesktop.portal.DynamicLauncher.PrepareInstall() or
+ org.freedesktop.portal.DynamicLauncher.RequestInstallToken() call.
+ The token can only be used once and is valid for up to five minutes.
+
+ The icon and name used for the launcher will be the ones from the previous
+ org.freedesktop.portal.DynamicLauncher.PrepareInstall() or
+ org.freedesktop.portal.DynamicLauncher.RequestInstallToken() call.
+
+ The @desktop_file_id must have ".desktop" as a suffix. Except in the
+ special case when the calling process has no associated app ID,
+ @desktop_file_id must have the app ID followed by a period as a prefix,
+ regardless of whether the calling process is sandboxed or unsandboxed.
+
+ The @desktop_entry should be a valid desktop entry file beginning with
+ "[Desktop Entry]", except it should not include Name= or Icon= entries
+ (if present, these will be overwritten by the portal implementation).
+ The Exec= entry will be rewritten to call the sandboxed application e.g.
+ via "flatpak run", if the application is sandboxed.
+
+ It is recommended to include a TryExec= line with either a binary name
+ or an absolute path. The launcher will be deleted if the TryExec binary
+ cannot be found on session start.
+
+ The @options vardict currently has no supported entries.
+ -->
+ <method name="Install">
+ <arg type="s" name="token" direction="in"/>
+ <arg type="s" name="desktop_file_id" direction="in"/>
+ <arg type="s" name="desktop_entry" direction="in"/>
+ <arg type="a{sv}" name="options" direction="in"/>
+ </method>
+ <!--
+ PrepareInstall:
+ @parent_window: Identifier for the application window, see <link linkend="parent_window">Common
Conventions</link>
+ @name: The default name for the launcher
+ @icon_v: A #GBytesIcon icon as returned by g_icon_serialize(). Must be
+ a png or jpeg no larger than 512x512, or an svg
+ @options: Vardict with optional further information
+ @handle: Object path for the #org.freedesktop.portal.Request object representing this call
+
+ Presents a dialog to the user to allow them to see the icon, potentially
+ change the name, and confirm installation of the launcher.
+
+ Supported keys in the @options vardict:
+ <variablelist>
+ <varlistentry>
+ <term>handle_token s</term>
+ <listitem><para>
+ A string that will be used as the last element of the @handle. Must be a valid
+ object path element. See the #org.freedesktop.portal.Request documentation for
+ more information about the @handle.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>modal b</term>
+ <listitem><para>
+ Whether to make the dialog modal. Defaults to yes.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>launcher_type u</term>
+ <listitem><para>
+ The type of launcher being created. For supported values see the
+ SupportedLauncherTypes property. Defaults to "Application".
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>target s</term>
+ <listitem><para>
+ For a launcher of type "Webapp", this is the URL of the web app
+ being installed. This is displayed in the user-facing dialog.
+ For other launcher types, this is not needed.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>editable_name b</term>
+ <listitem><para>
+ If true, the user will be able to edit the name of the launcher.
+ Defaults to true.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>editable_icon b</term>
+ <listitem><para>
+ If true, the user will be able to edit the icon of the launcher,
+ if the implementation supports this. Defaults to false.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ The following results get returned via the #org.freedesktop.portal.Request::Response signal:
+ <variablelist>
+ <varlistentry>
+ <term>name s</term>
+ <listitem><para>
+ The name chosen by the user for the launcher.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>token s</term>
+ <listitem><para>
+ Token that can be passed to a subsequent org.freedesktop.portal.DynamicLauncher.Install() call
to
+ complete the installation without another dialog.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ -->
+ <method name="PrepareInstall">
+ <arg type="s" name="parent_window" direction="in"/>
+ <arg type="s" name="name" direction="in"/>
+ <arg type="v" name="icon_v" direction="in"/>
+ <arg type="a{sv}" name="options" direction="in"/>
+ <arg type="o" name="handle" direction="out"/>
+ </method>
+ <!--
+ RequestInstallToken:
+ @name: The name that will be used in the desktop file
+ @icon_v: A #GBytesIcon icon as returned by g_icon_serialize(). Must be
+ a png or jpeg no larger than 512x512, or an svg
+ @options: Vardict with optional further information
+ @token: the token to be used with the Install() method
+
+ This method is intended for use only by specific components that
+ have their application ID allowlisted in the portal backend (e.g. GNOME
+ Software and KDE Discover). It is otherwise not guaranteed to work.
+
+ The token returned by this method can be used to avoid the need for a
+ confirmation dialog; the token can be passed to the Install() method
+ just as if it were acquired via the PrepareInstall() method.
+
+ The @options vardict currently has no supported entries.
+ -->
+ <method name="RequestInstallToken">
+ <arg type="s" name="name" direction="in"/>
+ <arg type="v" name="icon_v" direction="in"/>
+ <arg type="a{sv}" name="options" direction="in"/>
+ <arg type="s" name="token" direction="out"/>
+ </method>
+ <!--
+ Uninstall:
+ @desktop_file_id: The .desktop file name
+ @options: Vardict with optional further information
+
+ This method deletes the desktop file and corresponding icon from the
+ appropriate directories to remove the launcher referred to by
+ @desktop_file_id.
+
+ The @desktop_file_id must have ".desktop" as a suffix. Except in the
+ special case when the calling process has no associated app ID,
+ @desktop_file_id must have the app ID followed by a period as a prefix,
+ regardless of whether the calling process is sandboxed or unsandboxed.
+
+ For example, Epiphany, which has the app ID "org.gnome.Epiphany"
+ in stable builds, might use a @desktop_file_id like
+ "org.gnome.Epiphany.WebApp_e9d0e1e4b0a10856aa3b38d9eb4375de4070d043.desktop"
+ In that example the desktop file would exist at the path
+
"~/.local/share/xdg-desktop-portal/applications/org.gnome.Epiphany.WebApp_e9d0e1e4b0a10856aa3b38d9eb4375de4070d043.desktop"
+ with a sym link in "~/.local/share/applications/".
+ The checksum at the end of the file name is an implementation detail in
+ Epiphany and not required by the portal.
+
+ This method is intended to be called by the application that created the
+ launcher, e.g. a web browser, so it can clean up associated data as part
+ of the uninstallation. Consequently, the proper way for a software center
+ to remove a launcher is by using the APIs provided by the application
+ that installed it. For example, for GNOME Software to remove web
+ launchers created by Epiphany, it would use the
+ org.gnome.Epiphany.WebAppProvider D-Bus interface.
+
+ Please note that this method call will fail if the specified launcher
+ already does not exist.
+
+ The @options vardict currently has no supported entries.
+ -->
+ <method name="Uninstall">
+ <arg type="s" name="desktop_file_id" direction="in"/>
+ <arg type="a{sv}" name="options" direction="in"/>
+ </method>
+ <!--
+ GetDesktopEntry:
+ @desktop_file_id: The .desktop file name
+ @contents: the contents of the named .desktop file
+
+ This function returns the contents of a desktop file with the name
+ @desktop_file_id in @contents.
+
+ The @desktop_file_id must have ".desktop" as a suffix. Except in the
+ special case when the calling process has no associated app ID,
+ @desktop_file_id must have the app ID followed by a period as a prefix.
+
+ This method only works for desktop files that were created by the
+ dynamic launcher portal.
+ -->
+ <method name="GetDesktopEntry">
+ <arg type="s" name="desktop_file_id" direction="in"/>
+ <arg type="s" name="contents" direction="out"/>
+ </method>
+ <!--
+ GetIcon:
+ @desktop_file_id: The .desktop file name
+ @icon_v: the icon as a serialized #GBytesIcon
+ @icon_format: one of "png", "jpeg", "svg"
+ @icon_size: the width and height in pixels of the icon
+
+ This function returns the contents of the icon specified in the "Icon"
+ key of the desktop file with the name @desktop_file_id in @icon_v. The
+ icon #GVariant can be passed to g_icon_deserialize() to reconstruct the
+ #GIcon.
+
+ The @desktop_file_id must have ".desktop" as a suffix. Except in the
+ special case when the calling process has no associated app ID,
+ @desktop_file_id must have the app ID followed by a period as a prefix.
+
+ The format and size of the icon are returned in @icon_format and
+ @icon_size. For svg icons, @icon_size is currently always set to 4096,
+ but don't depend on that as it may change in the future.
+
+ This method only works for desktop files that were created by the
+ dynamic launcher portal.
+ -->
+ <method name="GetIcon">
+ <arg type="s" name="desktop_file_id" direction="in"/>
+ <arg type="v" name="icon_v" direction="out"/>
+ <arg type="s" name="icon_format" direction="out"/>
+ <arg type="u" name="icon_size" direction="out"/>
+ </method>
+ <!--
+ Launch:
+ @desktop_file_id: The .desktop file name
+ @options: Vardict with optional further onformation
+
+ This function launches the app specified by @desktop_file_id.
+
+ The @desktop_file_id must have ".desktop" as a suffix. Except in the
+ special case when the calling process has no associated app ID,
+ @desktop_file_id must have the app ID followed by a period as a prefix.
+
+ This method only works for desktop files that were created by the
+ dynamic launcher portal.
+
+ Supported keys in the @options vardict include:
+ <variablelist>
+ <varlistentry>
+ <term>activation_token s</term>
+ <listitem><para>
+ A token that can be used to activate the chosen application.
+ </para><para>
+ The activation_token option was introduced in version 1 of the interface.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ -->
+ <method name="Launch">
+ <arg type="s" name="desktop_file_id" direction="in"/>
+ <arg type="a{sv}" name="options" direction="in"/>
+ </method>
+ <!--
+ SupportedLauncherTypes:
+
+ A bitmask of available launcher types. Currently defined types are:
+
+ <simplelist>
+ <member>1: Application. A launcher that represents an application.</member>
+ <member>2: Webapp. A launcher that represents a web app.</member>
+ </simplelist>
+ -->
+ <property name="SupportedLauncherTypes" type="u" access="read"/>
+ <property name="version" type="u" access="read"/>
+ </interface>
+</node>
diff --git a/subprojects/libglib-testing.wrap b/subprojects/libglib-testing.wrap
index ffb33614b..e3c06f2e8 100644
--- a/subprojects/libglib-testing.wrap
+++ b/subprojects/libglib-testing.wrap
@@ -1,5 +1,5 @@
[wrap-git]
directory = libglib-testing
url = https://gitlab.gnome.org/pwithnall/libglib-testing.git
-revision = 0.1.0
+revision = 0.1.1
depth = 1
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]