summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhaedrus Leeds <mwleeds@protonmail.com>2021-11-29 17:53:02 -0800
committerPhaedrus Leeds <mwleeds@protonmail.com>2022-03-21 13:07:44 -0700
commit7547094e246e1e9277a6fbc66f1a7fd6db7b5b6e (patch)
tree55325b5c8358e03120f91c30c4a702f476c15ef8 /src
parent9d6193b25dd0a39ac604b0bec1877b1e5d5b4fa3 (diff)
downloadepiphany-7547094e246e1e9277a6fbc66f1a7fd6db7b5b6e.tar.gz
Add a WebAppProvider D-Bus interface
This commit adds a D-Bus service that exposes the web apps managed by Epiphany so that a client can enumerate them, install a new one, or remove an installed one. The intended client is GNOME Software, since I am soon going to add back a webapp plugin to Software which will make use of this interface. This is part of a larger effort to improve the support for Progressive Web Apps in GNOME (though Epiphany's web apps do not support PWA manifest features). The great thing about having this be a service exposed by Epiphany, rather than having Software try to install Epiphany-compatible web apps on its own as it used to do, is that the implementation of how to create and manage the web apps can stay in Epiphany, and there can never be disagreement between Epiphany and Software about the proper on-disk format for them (e.g. the algorithm used for generating the app ID from the name). The goal for the PWA project is to support Flatpak'd Epiphany, whereas currently only non-Flatpak Epiphany can do web apps. This will be accomplished with new portals to allow installing and removing the .desktop launchers. The Flatpak support requirement is reflected in the design of the API here, specifically the install_token parameter for the Install() method. This token is to be acquired by the client of the D-Bus interface (Software) so that the installation can be achieved without any additional user interaction since the user would've already clicked "Install" in Software. Web app installation directly via Flatpak'd Epiphany's UI would involve a dialog created by the portal; this is because we don't want sandboxed applications in general to be able to create desktop launchers without user interaction. The Uninstall() method by contrast doesn't require such a token, because the portal can ensure that only apps created by an application are deleted by that application. The GetInstalledApps() method is implemented by looking at the profile directories of the apps, because we don't want to have to poke a sandbox hole to allow access to the actual desktop files.
Diffstat (limited to 'src')
-rw-r--r--src/ephy-main.c2
-rw-r--r--src/meson.build23
-rw-r--r--src/webapp-provider/ephy-webapp-provider-main.c61
-rw-r--r--src/webapp-provider/ephy-webapp-provider.c282
-rw-r--r--src/webapp-provider/ephy-webapp-provider.h36
-rw-r--r--src/webapp-provider/org.gnome.Epiphany.WebAppProvider.xml85
-rw-r--r--src/window-commands.c3
7 files changed, 488 insertions, 4 deletions
diff --git a/src/ephy-main.c b/src/ephy-main.c
index 48b6c684b..bcf5ce703 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -370,7 +370,7 @@ main (int argc,
/* Delete the requested web application, if any. Must happen after
* ephy_file_helpers_init (). */
if (application_to_delete) {
- ephy_web_application_delete (application_to_delete);
+ ephy_web_application_delete (application_to_delete, NULL);
exit (0);
}
diff --git a/src/meson.build b/src/meson.build
index eaee92180..50f6710b3 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -111,7 +111,7 @@ ephy_profile_migrator = executable('ephy-profile-migrator',
)
-codegen = gnome.gdbus_codegen('ephy-shell-search-provider-generated',
+search_provider_codegen = gnome.gdbus_codegen('ephy-shell-search-provider-generated',
'search-provider/org.gnome.ShellSearchProvider2.xml',
interface_prefix: 'org.gnome',
namespace: 'Ephy'
@@ -120,7 +120,7 @@ codegen = gnome.gdbus_codegen('ephy-shell-search-provider-generated',
search_provider_sources = [
'search-provider/ephy-search-provider.c',
'search-provider/ephy-search-provider-main.c',
- codegen
+ search_provider_codegen
]
executable('epiphany-search-provider',
@@ -131,6 +131,25 @@ executable('epiphany-search-provider',
install_rpath: pkglibdir
)
+webapp_codegen = gnome.gdbus_codegen('ephy-webapp-provider-generated',
+ 'webapp-provider/org.gnome.Epiphany.WebAppProvider.xml',
+ interface_prefix: 'org.gnome.Epiphany',
+ namespace: 'Ephy'
+)
+
+webapp_provider_sources = [
+ 'webapp-provider/ephy-webapp-provider.c',
+ 'webapp-provider/ephy-webapp-provider-main.c',
+ webapp_codegen
+]
+
+executable('epiphany-webapp-provider',
+ webapp_provider_sources,
+ dependencies: ephymain_dep,
+ install: true,
+ install_dir: libexecdir,
+ install_rpath: pkglibdir
+)
resource_files = files('resources/epiphany.gresource.xml')
resources = gnome.compile_resources('epiphany-resources',
diff --git a/src/webapp-provider/ephy-webapp-provider-main.c b/src/webapp-provider/ephy-webapp-provider-main.c
new file mode 100644
index 000000000..e4fdcfb55
--- /dev/null
+++ b/src/webapp-provider/ephy-webapp-provider-main.c
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright (c) 2013 Igalia S.L.
+ *
+ * This file is part of Epiphany.
+ *
+ * Epiphany is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Epiphany 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Epiphany. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ephy-webapp-provider.h"
+#include "ephy-file-helpers.h"
+
+#include <glib/gi18n.h>
+#include <locale.h>
+
+int
+main (int argc,
+ char **argv)
+{
+ g_autoptr (EphyWebAppProviderService) webapp_provider = NULL;
+ int status;
+ GError *error = NULL;
+
+ g_setenv ("GIO_USE_VFS", "local", TRUE);
+
+ g_debug ("started %s", argv[0]);
+
+ /* Initialize the i18n stuff */
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ if (!ephy_file_helpers_init (NULL, 0, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ return 1;
+ }
+
+ webapp_provider = ephy_web_app_provider_service_new ();
+ status = g_application_run (G_APPLICATION (webapp_provider), argc, argv);
+
+ ephy_file_helpers_shutdown ();
+
+ g_debug ("stopping %s with status %d", argv[0], status);
+
+ return status;
+}
diff --git a/src/webapp-provider/ephy-webapp-provider.c b/src/webapp-provider/ephy-webapp-provider.c
new file mode 100644
index 000000000..af5fd7e05
--- /dev/null
+++ b/src/webapp-provider/ephy-webapp-provider.c
@@ -0,0 +1,282 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright (c) 2021 Matthew Leeds <mwleeds@protonmail.com>
+ *
+ * This file is part of Epiphany.
+ *
+ * Epiphany is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Epiphany 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Epiphany. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "ephy-webapp-provider.h"
+
+#include "ephy-web-app-utils.h"
+#include "ephy-flatpak-utils.h"
+
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+
+struct _EphyWebAppProviderService {
+ GApplication parent_instance;
+
+ EphyWebAppProvider *skeleton;
+};
+
+struct _EphyWebAppProviderServiceClass {
+ GApplicationClass parent_class;
+};
+
+G_DEFINE_TYPE (EphyWebAppProviderService, ephy_web_app_provider_service, G_TYPE_APPLICATION)
+
+#define INACTIVITY_TIMEOUT 60 * 1000 /* One minute, in milliseconds */
+
+typedef enum {
+ EPHY_WEBAPP_PROVIDER_ERROR_FAILED,
+ EPHY_WEBAPP_PROVIDER_ERROR_INVALID_ARGS,
+ EPHY_WEBAPP_PROVIDER_ERROR_NOT_INSTALLED,
+ EPHY_WEBAPP_PROVIDER_ERROR_LAST = EPHY_WEBAPP_PROVIDER_ERROR_NOT_INSTALLED, /*< skip >*/
+} EphyWebAppProviderError;
+
+static const GDBusErrorEntry ephy_webapp_provider_error_entries[] = {
+ { EPHY_WEBAPP_PROVIDER_ERROR_FAILED, "org.gnome.Epiphany.WebAppProvider.Error.Failed" },
+ { EPHY_WEBAPP_PROVIDER_ERROR_INVALID_ARGS, "org.gnome.Epiphany.WebAppProvider.Error.InvalidArgs" },
+ { EPHY_WEBAPP_PROVIDER_ERROR_NOT_INSTALLED, "org.gnome.Epiphany.WebAppProvider.Error.NotInstalled" },
+};
+
+/* Ensure that every error code has an associated D-Bus error name */
+G_STATIC_ASSERT (G_N_ELEMENTS (ephy_webapp_provider_error_entries) == EPHY_WEBAPP_PROVIDER_ERROR_LAST + 1);
+
+#define EPHY_WEBAPP_PROVIDER_ERROR (ephy_webapp_provider_error_quark ())
+GQuark
+ephy_webapp_provider_error_quark (void)
+{
+ static gsize quark = 0;
+ g_dbus_error_register_error_domain ("ephy-webapp-provider-error-quark",
+ &quark,
+ ephy_webapp_provider_error_entries,
+ G_N_ELEMENTS (ephy_webapp_provider_error_entries));
+ return (GQuark)quark;
+}
+
+static gboolean
+handle_get_installed_apps (EphyWebAppProvider *skeleton,
+ GDBusMethodInvocation *invocation,
+ EphyWebAppProviderService *self)
+{
+ g_auto (GStrv) desktop_ids = NULL;
+
+ g_debug ("%s", G_STRFUNC);
+
+ g_application_hold (G_APPLICATION (self));
+
+ desktop_ids = ephy_web_application_get_desktop_id_list ();
+
+ ephy_web_app_provider_complete_get_installed_apps (skeleton, invocation,
+ (const gchar * const *)desktop_ids);
+
+ g_application_release (G_APPLICATION (self));
+
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
+}
+
+static gboolean
+handle_install (EphyWebAppProvider *skeleton,
+ GDBusMethodInvocation *invocation,
+ char *url,
+ char *name,
+ char *install_token,
+ EphyWebAppProviderService *self)
+{
+ g_autofree char *id = NULL;
+ g_autofree char *desktop_path = NULL;
+ g_autofree char *desktop_file_id = NULL;
+
+ g_debug ("%s", G_STRFUNC);
+
+ g_application_hold (G_APPLICATION (self));
+
+ /* We need an install token acquired by a trusted system component such as
+ * gnome-software because otherwise the Flatpak/Snap sandbox prevents us from
+ * installing the app without using a portal (which would not be appropriate
+ * since Epiphany is not the focused application). We use the same code path
+ * when not running under a sandbox too.
+ */
+ if (!install_token || *install_token == '\0') {
+ g_dbus_method_invocation_return_error (invocation, EPHY_WEBAPP_PROVIDER_ERROR,
+ EPHY_WEBAPP_PROVIDER_ERROR_INVALID_ARGS,
+ _("The install_token is required for the Install() method"));
+ goto out;
+ }
+ if (!g_uri_is_valid (url, G_URI_FLAGS_NONE, NULL)) {
+ g_dbus_method_invocation_return_error (invocation, EPHY_WEBAPP_PROVIDER_ERROR,
+ EPHY_WEBAPP_PROVIDER_ERROR_INVALID_ARGS,
+ _("The url passed was not valid: ‘%s’"), url);
+ goto out;
+ }
+ if (!name || *name == '\0') {
+ g_dbus_method_invocation_return_error (invocation, EPHY_WEBAPP_PROVIDER_ERROR,
+ EPHY_WEBAPP_PROVIDER_ERROR_INVALID_ARGS,
+ _("The name passed was not valid"));
+ goto out;
+ }
+
+ id = ephy_web_application_get_app_id_from_name (name);
+
+ desktop_path = ephy_web_application_create (id, url, name,
+ NULL, NULL, /* icon_pixbuf, icon_path */
+ install_token,
+ EPHY_WEB_APPLICATION_NONE);
+ if (!desktop_path) {
+ g_dbus_method_invocation_return_error (invocation, EPHY_WEBAPP_PROVIDER_ERROR,
+ EPHY_WEBAPP_PROVIDER_ERROR_FAILED,
+ _("Installing the web application ‘%s’ (%s) failed"),
+ name, url);
+ goto out;
+ }
+
+ desktop_file_id = g_path_get_basename (desktop_path);
+ ephy_web_app_provider_complete_install (skeleton, invocation, desktop_file_id);
+
+out:
+ g_application_release (G_APPLICATION (self));
+
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
+}
+
+static gboolean
+handle_uninstall (EphyWebAppProvider *skeleton,
+ GDBusMethodInvocation *invocation,
+ char *desktop_file_id,
+ EphyWebAppProviderService *self)
+{
+ EphyWebAppFound app_found;
+
+ g_debug ("%s", G_STRFUNC);
+
+ g_application_hold (G_APPLICATION (self));
+
+ if (!desktop_file_id || !g_str_has_suffix (desktop_file_id, ".desktop")) {
+ g_dbus_method_invocation_return_error (invocation, EPHY_WEBAPP_PROVIDER_ERROR,
+ EPHY_WEBAPP_PROVIDER_ERROR_INVALID_ARGS,
+ _("The desktop file ID passed ‘%s’ was not valid"),
+ desktop_file_id ? desktop_file_id : "(null)");
+ goto out;
+ }
+
+ if (!ephy_web_application_delete_by_desktop_file_id (desktop_file_id, &app_found)) {
+ if (app_found == EPHY_WEB_APP_NOT_FOUND) {
+ g_dbus_method_invocation_return_error (invocation, EPHY_WEBAPP_PROVIDER_ERROR,
+ EPHY_WEBAPP_PROVIDER_ERROR_NOT_INSTALLED,
+ _("The web application ‘%s’ does not exist"),
+ desktop_file_id);
+ } else {
+ g_dbus_method_invocation_return_error (invocation, EPHY_WEBAPP_PROVIDER_ERROR,
+ EPHY_WEBAPP_PROVIDER_ERROR_FAILED,
+ _("The web application ‘%s’ could not be deleted"),
+ desktop_file_id);
+ }
+ goto out;
+ }
+
+ ephy_web_app_provider_complete_uninstall (skeleton, invocation);
+
+out:
+ g_application_release (G_APPLICATION (self));
+
+ return G_DBUS_METHOD_INVOCATION_HANDLED;
+}
+
+static void
+ephy_web_app_provider_service_init (EphyWebAppProviderService *self)
+{
+ g_application_set_flags (G_APPLICATION (self), G_APPLICATION_IS_SERVICE);
+
+ g_application_set_inactivity_timeout (G_APPLICATION (self), INACTIVITY_TIMEOUT);
+}
+
+static gboolean
+ephy_web_app_provider_service_dbus_register (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path,
+ GError **error)
+{
+ EphyWebAppProviderService *self;
+
+ g_debug ("registering at object path %s", object_path);
+
+ if (!G_APPLICATION_CLASS (ephy_web_app_provider_service_parent_class)->dbus_register (application,
+ connection,
+ object_path,
+ error))
+ return FALSE;
+
+ self = EPHY_WEB_APP_PROVIDER_SERVICE (application);
+ self->skeleton = ephy_web_app_provider_skeleton_new ();
+ ephy_web_app_provider_set_version (EPHY_WEB_APP_PROVIDER (self->skeleton), 1);
+
+ g_signal_connect (self->skeleton, "handle-get-installed-apps",
+ G_CALLBACK (handle_get_installed_apps), self);
+ g_signal_connect (self->skeleton, "handle-install",
+ G_CALLBACK (handle_install), self);
+ g_signal_connect (self->skeleton, "handle-uninstall",
+ G_CALLBACK (handle_uninstall), self);
+
+ return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->skeleton),
+ connection, object_path, error);
+}
+
+static void
+ephy_web_app_provider_service_dbus_unregister (GApplication *application,
+ GDBusConnection *connection,
+ const gchar *object_path)
+{
+ EphyWebAppProviderService *self;
+ GDBusInterfaceSkeleton *skeleton;
+
+ g_debug ("unregistering at object path %s", object_path);
+
+ self = EPHY_WEB_APP_PROVIDER_SERVICE (application);
+ skeleton = G_DBUS_INTERFACE_SKELETON (self->skeleton);
+ if (g_dbus_interface_skeleton_has_connection (skeleton, connection))
+ g_dbus_interface_skeleton_unexport_from_connection (skeleton, connection);
+
+ g_clear_object (&self->skeleton);
+
+ G_APPLICATION_CLASS (ephy_web_app_provider_service_parent_class)->dbus_unregister (application,
+ connection,
+ object_path);
+}
+
+static void
+ephy_web_app_provider_service_class_init (EphyWebAppProviderServiceClass *klass)
+{
+ GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
+
+ application_class->dbus_register = ephy_web_app_provider_service_dbus_register;
+ application_class->dbus_unregister = ephy_web_app_provider_service_dbus_unregister;
+}
+
+EphyWebAppProviderService *
+ephy_web_app_provider_service_new (void)
+{
+ /* Note the application ID is constant for release/devel/canary builds
+ * because we want to always use the same well-known D-Bus name.
+ */
+ g_autofree gchar *app_id = g_strconcat ("org.gnome.Epiphany.WebAppProvider", NULL);
+
+ return g_object_new (EPHY_TYPE_WEB_APP_PROVIDER_SERVICE,
+ "application-id", app_id,
+ NULL);
+}
diff --git a/src/webapp-provider/ephy-webapp-provider.h b/src/webapp-provider/ephy-webapp-provider.h
new file mode 100644
index 000000000..1286cf0e0
--- /dev/null
+++ b/src/webapp-provider/ephy-webapp-provider.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Copyright (c) 2021 Matthew Leeds <mwleeds@protonmail.com>
+ *
+ * This file is part of Epiphany.
+ *
+ * Epiphany is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Epiphany 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Epiphany. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "ephy-webapp-provider-generated.h"
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_WEB_APP_PROVIDER_SERVICE (ephy_web_app_provider_service_get_type ())
+
+G_DECLARE_FINAL_TYPE (EphyWebAppProviderService, ephy_web_app_provider_service, EPHY, WEB_APP_PROVIDER_SERVICE, GApplication)
+
+EphyWebAppProviderService *ephy_web_app_provider_service_new (void);
+
+G_END_DECLS
diff --git a/src/webapp-provider/org.gnome.Epiphany.WebAppProvider.xml b/src/webapp-provider/org.gnome.Epiphany.WebAppProvider.xml
new file mode 100644
index 000000000..6c2954dc3
--- /dev/null
+++ b/src/webapp-provider/org.gnome.Epiphany.WebAppProvider.xml
@@ -0,0 +1,85 @@
+<!DOCTYPE node PUBLIC
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
+<node>
+
+ <!--
+ org.gnome.Epiphany.WebAppProvider:
+ @short_description: Webapp provider interface
+
+ The interface used for handling Epiphany Webapps in GNOME Software, or other
+ clients (version 1).
+ -->
+ <interface name="org.gnome.Epiphany.WebAppProvider">
+ <!--
+ GetInstalledApps:
+ @desktop_file_ids: An array of .desktop file names, one for each
+ installed web app, with the .desktop suffix included
+
+ Returns the set of installed Epiphany web applications. The caller can
+ use them with g_desktop_app_info_new() if outside the sandbox.
+ -->
+ <method name="GetInstalledApps">
+ <arg type="as" name="webapps" direction="out" />
+ </method>
+
+ <!--
+ Install:
+ @url: the URL of the web app
+ @name: the human readable name of the web app
+ @install_token: the token acquired via org.freedesktop.portal.InstallDynamicLauncher
+ @desktop_file_id: the desktop file id of the installed app, with a
+ ".desktop" suffix
+
+ Installs a web app. This interface is expected to be used by trusted
+ system components such as GNOME Software, which can acquire an
+ @install_token using the portal method
+ org.freedesktop.portal.DynamicLauncher.RequestInstallToken(). This allows Epiphany
+ to install the web app without user interaction and despite being sandboxed.
+ This is desirable because the user would've already clicked "Install" in
+ Software; they should not have to confirm the operation again in a different
+ app (Epiphany).
+
+ The @install_token must be provided so that Epiphany can complete the
+ installation without a user-facing dialog. The icon given to
+ org.freedesktop.portal.InstallDynamicLauncher.RequestInstallToken() will
+ be used, and the name given to that method should match the @name given here.
+
+ If the arguments passed are invalid this method returns the error
+ `org.gnome.Epiphany.WebAppProvider.Error.InvalidArgs`, and otherwise
+ `org.gnome.Epiphany.WebAppProvider.Error.Failed`.
+ -->
+ <method name="Install">
+ <arg type="s" name="url" direction="in" />
+ <arg type="s" name="name" direction="in" />
+ <arg type="s" name="install_token" direction="in" />
+ <arg type="s" name="desktop_file_id" direction="out" />
+ </method>
+
+ <!--
+ Uninstall:
+ @desktop_file_id: the filename of the .desktop file for an installed web
+ app, with the .desktop suffix
+
+ Uninstalls a web app. Note that the @desktop_file_id is just a filename
+ not a full path, and it's the same one returned by the
+ GetInstalledWebApps() method.
+
+ The error `org.gnome.Epiphany.WebAppProvider.Error.NotInstalled` will be
+ returned if the specified web app is not installed. The other possible
+ error values are `org.gnome.Epiphany.WebAppProvider.Error.InvalidArgs`
+ and `org.gnome.Epiphany.WebAppProvider.Error.Failed`.
+ -->
+ <method name="Uninstall">
+ <arg type="s" name="desktop_file_id" direction="in" />
+ </method>
+ <!--
+ Version:
+
+ The API version number, to be incremented for backwards compatible
+ changes so clients can determine which features are available. For
+ backwards incompatible changes, the interface name will change.
+ -->
+ <property name="Version" type="u" access="read"/>
+ </interface>
+</node>
diff --git a/src/window-commands.c b/src/window-commands.c
index 91d62b14c..32f10091d 100644
--- a/src/window-commands.c
+++ b/src/window-commands.c
@@ -1793,6 +1793,7 @@ save_as_application_proceed (EphyApplicationDialogData *data)
webkit_web_view_get_uri (WEBKIT_WEB_VIEW (data->view)),
app_name,
gtk_image_get_pixbuf (GTK_IMAGE (data->image)),
+ NULL, NULL, /* icon_path, install_token */
data->webapp_options);
if (desktop_file)
@@ -1842,7 +1843,7 @@ dialog_save_as_application_confirmation_cb (GtkDialog *dialog,
gtk_widget_destroy (GTK_WIDGET (dialog));
if (response == GTK_RESPONSE_OK) {
- ephy_web_application_delete (app_id);
+ ephy_web_application_delete (app_id, NULL);
save_as_application_proceed (data);
}
}