[gnome-software/mwleeds/pwa-plugin: 229/234] Revert "Remove webapp support"
- From: Phaedrus Leeds <mwleeds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/mwleeds/pwa-plugin: 229/234] Revert "Remove webapp support"
- Date: Wed, 2 Feb 2022 20:51:57 +0000 (UTC)
commit 67d40e1bf11cfe678062e1817863644906c41d3d
Author: Phaedrus Leeds <mwleeds protonmail com>
Date: Mon Nov 29 14:09:46 2021 -0800
Revert "Remove webapp support"
This reverts commit ea5eb222f514895f41ad0ce80f48fff98207bdc6.
This is the first step toward bringing back webapp support. I am doing
this as a project sponsored by a GNOME Foundation grant and with Endless
OS as the primary target. The goal is to include a set of Progressive
Web Apps in Software that can be installed via Epiphany's web app
support (and potentially also via Chromium), to expand the selection of
apps available to users who might not otherwise find them. While
Epiphany's web apps do not currently implement support for PWA
manifests, that is hopefully going to be in scope for this project.
While the plan is to only include PWAs in the set hard coded into
Software, non-PWA web apps installed via Epiphany will also show up in
Software.
The previous implementation of web apps in Software was dropped because
it was buggy and users did not like it, since they didn't perceive much
benefit of using sites as web apps versus using a normal browser and
were confused by the apps not being native desktop apps. The following
factors should mitigate or address those issues for the new
implementation:
1) We're going to use a D-Bus API provided by Epiphany for enumerating,
installing, and removing web apps rather than re-implementing those
functions in Software. This avoids bugs that can occur when the
implementations are out of sync.
2) We're going to differentiate web apps from native apps in the UI,
pending design input on how to do so.
3) The set of PWAs included with Software will be mostly or entirely
apps that would not otherwise be available to the user, because they
are only available as PWAs and not native apps.
4) Once we have support for PWA manifests in Epiphany, or support for
Chromium-based web apps which already support manifests, the apps
should be more featureful and closer to native apps than the current
web app implementation, e.g. they may work offline to some extent.
(The reverted changes have been edited, for example to remove the
dependency on epiphany-runtime in the spec file, because it's not clear
yet if this feature will be enabled by default in Fedora and
the plan is to make this work with flatpak'd Epiphany which doesn't have
an analogous way to install epiphany without a desktop icon; see
https://bugzilla.redhat.com/show_bug.cgi?id=1781359 for context)
contrib/gnome-software.spec.in | 2 +
meson_options.txt | 1 +
plugins/epiphany/gs-plugin-epiphany.c | 322 +++++++++++++++++++++
plugins/epiphany/gs-self-test.c | 98 +++++++
plugins/epiphany/meson.build | 52 ++++
....gnome.Software.Plugin.Epiphany.metainfo.xml.in | 11 +
plugins/meson.build | 3 +
7 files changed, 489 insertions(+)
---
diff --git a/contrib/gnome-software.spec.in b/contrib/gnome-software.spec.in
index f3b35578b..5ea8ec639 100644
--- a/contrib/gnome-software.spec.in
+++ b/contrib/gnome-software.spec.in
@@ -144,11 +144,13 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
%{_datadir}/gnome-software/featured-*.svg
%{_datadir}/gnome-software/featured-*.jpg
%{_datadir}/metainfo/org.gnome.Software.appdata.xml
+%{_datadir}/metainfo/org.gnome.Software.Plugin.Epiphany.metainfo.xml
%{_datadir}/metainfo/org.gnome.Software.Plugin.Flatpak.metainfo.xml
%{_datadir}/metainfo/org.gnome.Software.Plugin.Fwupd.metainfo.xml
%dir %{gs_plugin_dir}
%{gs_plugin_dir}/libgs_plugin_appstream.so
%{gs_plugin_dir}/libgs_plugin_dummy.so
+%{gs_plugin_dir}/libgs_plugin_epiphany.so
%{gs_plugin_dir}/libgs_plugin_fedora-langpacks.so
%{gs_plugin_dir}/libgs_plugin_fedora-pkgdb-collections.so
%{gs_plugin_dir}/libgs_plugin_flatpak.so
diff --git a/meson_options.txt b/meson_options.txt
index 70f62c52b..27a844d50 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -9,6 +9,7 @@ option('fwupd', type : 'boolean', value : true, description : 'enable fwupd supp
option('flatpak', type : 'boolean', value : true, description : 'enable Flatpak support')
option('malcontent', type : 'boolean', value : true, description : 'enable parental controls support using
libmalcontent')
option('rpm_ostree', type : 'boolean', value : false, description : 'enable rpm-ostree support')
+option('webapps', type : 'boolean', value : true, description : 'enable webapps support')
option('gudev', type : 'boolean', value : true, description : 'enable GUdev support')
option('apt', type : 'boolean', value : false, description : 'enable apt: URL handler in the .desktop file')
option('snap', type : 'boolean', value : false, description : 'enable Snap support')
diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c
new file mode 100644
index 000000000..9a83e8004
--- /dev/null
+++ b/plugins/epiphany/gs-plugin-epiphany.c
@@ -0,0 +1,322 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013-2014 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2015 Kalev Lember <klember redhat com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <gnome-software.h>
+
+/*
+ * SECTION:
+ * Uses epiphany to launch web applications.
+ *
+ * If the epiphany binary is not present then it self-disables.
+ */
+
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+ g_autofree gchar *epiphany = NULL;
+
+ /* we can only work with epiphany */
+ epiphany = g_find_program_in_path ("epiphany");
+ if (epiphany == NULL) {
+ gs_plugin_set_enabled (plugin, FALSE);
+ g_debug ("disabling '%s' as epiphany does not exist",
+ gs_plugin_get_name (plugin));
+ }
+
+ /* set name of MetaInfo file */
+ gs_plugin_set_appstream_id (plugin, "org.gnome.Software.Plugin.Epiphany");
+
+ /* need help from appstream */
+ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "appstream");
+}
+
+void
+gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app)
+{
+ if (gs_app_get_kind (app) == AS_APP_KIND_WEB_APP &&
+ gs_app_get_bundle_kind (app) != AS_BUNDLE_KIND_PACKAGE) {
+ gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+ }
+}
+
+static gchar *
+_gs_app_get_id_nonfull (GsApp *app)
+{
+ gchar *id;
+ gchar *tmp;
+
+ id = g_strdup (gs_app_get_id (app));
+ tmp = g_strrstr (id, ".desktop");
+ if (tmp != NULL)
+ *tmp = '\0';
+ return id;
+}
+
+gboolean
+gs_plugin_app_install (GsPlugin *plugin, GsApp *app,
+ GCancellable *cancellable, GError **error)
+{
+ AsIcon *icon;
+ GPtrArray *icons;
+ gboolean ret = TRUE;
+ gsize kf_length;
+ g_autoptr(GError) error_local = NULL;
+ g_autofree gchar *app_desktop = NULL;
+ g_autofree gchar *epi_desktop = NULL;
+ g_autofree gchar *epi_dir = NULL;
+ g_autofree gchar *epi_icon = NULL;
+ g_autofree gchar *exec = NULL;
+ g_autofree gchar *hash = NULL;
+ g_autofree gchar *id_nonfull = NULL;
+ g_autofree gchar *kf_data = NULL;
+ g_autofree gchar *wmclass = NULL;
+ g_autoptr(GKeyFile) kf = NULL;
+ g_autoptr(GFile) symlink_desktop = NULL;
+ g_autoptr(GFile) symlink_icon = NULL;
+ const gchar *url = NULL;
+
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app),
+ gs_plugin_get_name (plugin)) != 0)
+ return TRUE;
+
+ /* create the correct directory */
+ id_nonfull = _gs_app_get_id_nonfull (app);
+ hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, gs_app_get_name (app), -1);
+ epi_dir = g_strdup_printf ("%s/epiphany/app-%s-%s",
+ g_get_user_config_dir (),
+ id_nonfull,
+ hash);
+ g_mkdir_with_parents (epi_dir, 0755);
+
+ /* symlink icon */
+ epi_icon = g_build_filename (epi_dir, "app-icon.png", NULL);
+ symlink_icon = g_file_new_for_path (epi_icon);
+ icons = gs_app_get_icons (app);
+ if (icons->len == 0) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_NOT_SUPPORTED,
+ "no icons for %s",
+ gs_app_get_id (app));
+ return FALSE;
+ }
+ icon = g_ptr_array_index (icons, 0);
+ if (as_icon_get_filename (icon) == NULL) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_NOT_SUPPORTED,
+ "no filename for icon %s",
+ as_icon_get_name (icon));
+ return FALSE;
+ }
+ ret = g_file_make_symbolic_link (symlink_icon,
+ as_icon_get_filename (icon),
+ NULL,
+ &error_local);
+ if (!ret) {
+ if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+ g_debug ("ignoring icon symlink failure: %s",
+ error_local->message);
+ } else {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_WRITE_FAILED,
+ "Can't symlink icon: %s",
+ error_local->message);
+ return FALSE;
+ }
+ }
+
+ /* add desktop file */
+ wmclass = g_strdup_printf ("%s-%s", id_nonfull, hash);
+ kf = g_key_file_new ();
+ g_key_file_set_string (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_NAME,
+ gs_app_get_name (app));
+ g_key_file_set_string (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_COMMENT,
+ gs_app_get_summary (app));
+ url = gs_app_get_launchable (app, AS_LAUNCHABLE_KIND_URL);
+ if (url == NULL)
+ url = gs_app_get_url (app, AS_URL_KIND_HOMEPAGE);
+ exec = g_strdup_printf ("epiphany --application-mode --profile=\"%s\" %s",
+ epi_dir,
+ url);
+ g_key_file_set_string (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_EXEC,
+ exec);
+ g_key_file_set_boolean (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY,
+ TRUE);
+ g_key_file_set_boolean (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_TERMINAL,
+ FALSE);
+ g_key_file_set_boolean (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY,
+ FALSE);
+ g_key_file_set_string (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_TYPE,
+ G_KEY_FILE_DESKTOP_TYPE_APPLICATION);
+ g_key_file_set_string (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_ICON,
+ epi_icon);
+ g_key_file_set_string (kf,
+ G_KEY_FILE_DESKTOP_GROUP,
+ G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS,
+ wmclass);
+
+ /* save keyfile */
+ kf_data = g_key_file_to_data (kf, &kf_length, error);
+ if (kf_data == NULL)
+ return FALSE;
+ epi_desktop = g_strdup_printf ("%s/%s.desktop", epi_dir, wmclass);
+ if (!g_file_set_contents (epi_desktop, kf_data, (gssize) kf_length, error))
+ return FALSE;
+
+ /* symlink it to somewhere the shell will notice */
+ app_desktop = g_build_filename (g_get_user_data_dir (),
+ "applications",
+ gs_app_get_id (app),
+ NULL);
+ symlink_desktop = g_file_new_for_path (app_desktop);
+ ret = g_file_make_symbolic_link (symlink_desktop,
+ epi_desktop,
+ NULL,
+ error);
+ if (!ret) {
+ gs_utils_error_convert_gio (error);
+ return FALSE;
+ }
+
+ /* update state */
+ gs_app_set_state (app, AS_APP_STATE_INSTALLING);
+ gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+ return TRUE;
+}
+
+gboolean
+gs_plugin_app_remove (GsPlugin *plugin, GsApp *app,
+ GCancellable *cancellable, GError **error)
+{
+ const gchar *epi_desktop;
+ g_autofree gchar *app_desktop = NULL;
+ g_autoptr(GFile) file_epi = NULL;
+ g_autoptr(GFile) file_app = NULL;
+
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app),
+ gs_plugin_get_name (plugin)) != 0)
+ return TRUE;
+
+ /* remove the epi 'config' file */
+ gs_app_set_state (app, AS_APP_STATE_REMOVING);
+ epi_desktop = gs_app_get_source_id_default (app);
+ file_epi = g_file_new_for_path (epi_desktop);
+ if (!g_file_delete (file_epi, NULL, error))
+ return FALSE;
+
+ /* remove the shared desktop file */
+ app_desktop = g_build_filename (g_get_user_data_dir (),
+ "applications",
+ gs_app_get_id (app),
+ NULL);
+ file_app = g_file_new_for_path (app_desktop);
+ if (!g_file_delete (file_app, NULL, error)) {
+ gs_utils_error_convert_gio (error);
+ return FALSE;
+ }
+ gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+ return TRUE;
+}
+
+gboolean
+gs_plugin_refine_app (GsPlugin *plugin,
+ GsApp *app,
+ GsPluginRefineFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *name;
+ g_autofree gchar *fn = NULL;
+ g_autofree gchar *hash = NULL;
+ g_autofree gchar *id_nonfull = NULL;
+
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app),
+ gs_plugin_get_name (plugin)) != 0)
+ return TRUE;
+
+ gs_app_set_size_installed (app, 4096);
+
+ /* i guess this is technically true */
+ gs_app_add_kudo (app, GS_APP_KUDO_SANDBOXED_SECURE);
+
+ name = gs_app_get_name (app);
+ if (name == NULL) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_INVALID_FORMAT,
+ "name unset for %s",
+ gs_app_get_id (app));
+ return FALSE;
+ }
+ if (gs_app_get_summary (app) == NULL) {
+ g_debug ("faking summary for %s", gs_app_get_id (app));
+ gs_app_set_summary (app, GS_APP_QUALITY_LOWEST,
+ "Web Application");
+ }
+ hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, name, -1);
+ id_nonfull = _gs_app_get_id_nonfull (app);
+ fn = g_strdup_printf ("%s/epiphany/app-%s-%s/%s-%s.desktop",
+ g_get_user_config_dir (),
+ id_nonfull,
+ hash,
+ id_nonfull,
+ hash);
+ /* try the new-style location */
+ if (!g_file_test (fn, G_FILE_TEST_EXISTS)) {
+ g_free (fn);
+ fn = g_strdup_printf ("%s/epiphany/app-%s/%s.desktop",
+ g_get_user_config_dir (),
+ id_nonfull, id_nonfull);
+ }
+ if (g_file_test (fn, G_FILE_TEST_EXISTS)) {
+ gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+ gs_app_add_source_id (app, fn);
+ gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+ return TRUE;
+ }
+ gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+ return TRUE;
+}
+
+gboolean
+gs_plugin_launch (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app),
+ gs_plugin_get_name (plugin)) != 0)
+ return TRUE;
+ return gs_plugin_app_launch (plugin, app, error);
+}
diff --git a/plugins/epiphany/gs-self-test.c b/plugins/epiphany/gs-self-test.c
new file mode 100644
index 000000000..2d2f47888
--- /dev/null
+++ b/plugins/epiphany/gs-self-test.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013-2017 Richard Hughes <richard hughsie com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "config.h"
+
+#include "gnome-software-private.h"
+
+#include "gs-test.h"
+
+static void
+gs_plugins_epiphany_func (GsPluginLoader *plugin_loader)
+{
+ gboolean ret;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GsApp) app = NULL;
+ g_autoptr(GsPluginJob) plugin_job = NULL;
+
+ /* no epiphany, abort */
+ if (!gs_plugin_loader_get_enabled (plugin_loader, "epiphany"))
+ return;
+
+ /* a webapp with a local icon */
+ app = gs_app_new ("arachne.desktop");
+ gs_app_set_kind (app, AS_APP_KIND_WEB_APP);
+ plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REFINE,
+ "app", app,
+ "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON,
+ NULL);
+ ret = gs_plugin_loader_job_action (plugin_loader, plugin_job, NULL, &error);
+ gs_test_flush_main_context ();
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+ g_assert (gs_app_get_pixbuf (app) != NULL);
+}
+
+int
+main (int argc, char **argv)
+{
+ gboolean ret;
+ g_autofree gchar *fn = NULL;
+ g_autofree gchar *xml = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GsPluginLoader) plugin_loader = NULL;
+ const gchar *whitelist[] = {
+ "appstream",
+ "epiphany",
+ "icons",
+ NULL
+ };
+
+ g_test_init (&argc, &argv, NULL);
+ g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
+ g_setenv ("GS_XMLB_VERBOSE", "1", TRUE);
+
+ 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.9\">\n"
+ " <component type=\"webapp\">\n"
+ " <id>arachne.desktop</id>\n"
+ " <name>test</name>\n"
+ " <pkgname>test</pkgname>\n"
+ " <icon type=\"remote\">file://%s</icon>\n"
+ " </component>\n"
+ " <info>\n"
+ " <scope>user</scope>\n"
+ " </info>\n"
+ "</components>\n", fn);
+ g_setenv ("GS_SELF_TEST_APPSTREAM_XML", xml, TRUE);
+
+ /* only critical and error are fatal */
+ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
+
+ /* we can only load this once per process */
+ plugin_loader = gs_plugin_loader_new ();
+ gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR);
+ gs_plugin_loader_add_location (plugin_loader, LOCALPLUGINDIR_CORE);
+ ret = gs_plugin_loader_setup (plugin_loader,
+ (gchar**) whitelist,
+ NULL,
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* plugin tests go here */
+ g_test_add_data_func ("/gnome-software/plugins/epiphany",
+ plugin_loader,
+ (GTestDataFunc) gs_plugins_epiphany_func);
+
+ return g_test_run ();
+}
diff --git a/plugins/epiphany/meson.build b/plugins/epiphany/meson.build
new file mode 100644
index 000000000..9d57c4d16
--- /dev/null
+++ b/plugins/epiphany/meson.build
@@ -0,0 +1,52 @@
+cargs = ['-DG_LOG_DOMAIN="GsPluginEpiphany"']
+
+shared_module(
+ 'gs_plugin_epiphany',
+ sources : 'gs-plugin-epiphany.c',
+ include_directories : [
+ include_directories('../..'),
+ include_directories('../../lib'),
+ ],
+ install : true,
+ install_dir: plugin_dir,
+ c_args : cargs,
+ dependencies : plugin_libs,
+ link_with : [
+ libgnomesoftware
+ ]
+)
+metainfo = 'org.gnome.Software.Plugin.Epiphany.metainfo.xml'
+
+i18n.merge_file(
+ input: metainfo + '.in',
+ output: metainfo,
+ type: 'xml',
+ po_dir: join_paths(meson.source_root(), 'po'),
+ install: true,
+ install_dir: join_paths(get_option('datadir'), 'metainfo')
+)
+
+if get_option('tests')
+ cargs += ['-DLOCALPLUGINDIR="' + meson.current_build_dir() + '"']
+ cargs += ['-DLOCALPLUGINDIR_CORE="' + meson.current_build_dir() + '/../core"']
+ cargs += ['-DTESTDATADIR="' + join_paths(meson.current_source_dir(), '..', '..', 'data') + '"']
+ e = executable(
+ 'gs-self-test-epiphany',
+ compiled_schemas,
+ sources : [
+ 'gs-self-test.c'
+ ],
+ include_directories : [
+ include_directories('../..'),
+ include_directories('../../lib'),
+ ],
+ dependencies : [
+ plugin_libs,
+ ],
+ link_with : [
+ libgnomesoftware
+ ],
+ c_args : cargs,
+ )
+ test('gs-self-test-epiphany', e, suite: ['plugins', 'epiphany'], env: test_env)
+endif
diff --git a/plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in
b/plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in
new file mode 100644
index 000000000..626381f90
--- /dev/null
+++ b/plugins/epiphany/org.gnome.Software.Plugin.Epiphany.metainfo.xml.in
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2013-2016 Richard Hughes <richard hughsie com> -->
+<component type="addon">
+ <id>org.gnome.Software.Plugin.Epiphany</id>
+ <extends>org.gnome.Software.desktop</extends>
+ <name>Web Apps Support</name>
+ <summary>Run popular web applications in a browser</summary>
+ <metadata_license>CC0-1.0</metadata_license>
+ <project_license>GPL-2.0+</project_license>
+ <update_contact>mwleeds_at_protonmail.com</update_contact>
+</component>
diff --git a/plugins/meson.build b/plugins/meson.build
index 01fc42f17..711b488e2 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -38,3 +38,6 @@ endif
if get_option('snap')
subdir('snap')
endif
+if get_option('webapps')
+ subdir('epiphany')
+endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]