From 837ed09dc3eda87965926dd4ad8182777ee5b29b Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Sun, 12 Jan 2025 20:49:23 -0800 Subject: [PATCH] gnome: Add app to provide a graphical desktop environment - This app is useful for people who can connect a monitor, a keyboard, and a mouse to their FreedomBox. - Later this app allow a headless FreedomBox to be used as a remote desktop server. Users will be able to connect and access desktop applications from LAN or WAN. - No functional tests as they will likely fail in CI and container setups. Tests: - In a VM, install the app. Installation succeeds. - Disabling the app makes systemd switch to multi-user.target shutting down any service that any mean for GUI such as gnome-remote-desktop.service. Graphical login is not shown on the VM's virtual monitor. - Enabling the app make systemd switch to graphical.target and all the services are started again. Graphical login is shown on the VM's virtual monitor. - Login to desktop using VM's graphical terminal works. Settings, apps, browser etc. work. Signed-off-by: Sunil Mohan Adapa Reviewed-by: Veiko Aasa --- debian/copyright | 2 + plinth/modules/gnome/__init__.py | 90 +++ .../share/freedombox/modules-enabled/gnome | 1 + plinth/modules/gnome/manifest.py | 15 + plinth/modules/gnome/static/icons/gnome.png | Bin 0 -> 26096 bytes plinth/modules/gnome/static/icons/gnome.svg | 549 ++++++++++++++++++ plinth/modules/gnome/urls.py | 10 + 7 files changed, 667 insertions(+) create mode 100644 plinth/modules/gnome/__init__.py create mode 100644 plinth/modules/gnome/data/usr/share/freedombox/modules-enabled/gnome create mode 100644 plinth/modules/gnome/manifest.py create mode 100644 plinth/modules/gnome/static/icons/gnome.png create mode 100644 plinth/modules/gnome/static/icons/gnome.svg create mode 100644 plinth/modules/gnome/urls.py diff --git a/debian/copyright b/debian/copyright index 577de3278..fca404714 100644 --- a/debian/copyright +++ b/debian/copyright @@ -64,6 +64,8 @@ Files: plinth/modules/ejabberd/static/icons/ejabberd.png plinth/modules/ejabberd/static/icons/ejabberd.svg plinth/modules/email/static/icons/email.png plinth/modules/email/static/icons/email.svg + plinth/modules/email/static/icons/gnome.png + plinth/modules/email/static/icons/gnome.svg plinth/modules/matrixsynapse/static/icons/matrixsynapse.svg plinth/modules/privoxy/static/icons/privoxy.png plinth/modules/privoxy/static/icons/privoxy.svg diff --git a/plinth/modules/gnome/__init__.py b/plinth/modules/gnome/__init__.py new file mode 100644 index 000000000..a464232f2 --- /dev/null +++ b/plinth/modules/gnome/__init__.py @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""FreedomBox app to configure GNOME desktop.""" + +from django.utils.translation import gettext_lazy as _ + +from plinth import action_utils +from plinth import app as app_module +from plinth import cfg, menu +from plinth.modules.backups.components import BackupRestore +from plinth.package import Packages +from plinth.privileged import service as service_privileged +from plinth.utils import format_lazy + +from . import manifest + +_description = [ + _('GNOME is a desktop environment that focuses on simplicity and ease of ' + 'use.'), + format_lazy( + _('This app turns your {box_name} into a desktop computer if you ' + 'physically connect a monitor, a keyboard, and a mouse to it. A ' + 'browser, an office suite, and other basic utilities are available. ' + 'You may install further graphical applications using the software ' + 'center provided within.'), box_name=_(cfg.box_name)), + _('This app is not suitable for low-end hardware. It requires at least ' + '4GiB for RAM, 4GiB or disk space and a GPU capable of basic 3D ' + 'acceleration.'), +] + + +class GNOMEApp(app_module.App): + """FreedomBox app for GNOME desktop.""" + + app_id = 'gnome' + + _version = 1 + + def __init__(self) -> None: + """Create components for the app.""" + super().__init__() + + info = app_module.Info(app_id=self.app_id, version=self._version, + name=_('GNOME'), icon_filename='gnome', + description=_description, manual_page='GNOME', + donation_url='https://www.gnome.org/donate/', + tags=manifest.tags) + self.add(info) + + menu_item = menu.Menu('menu-gnome', info.name, info.icon_filename, + info.tags, 'gnome:index', parent_url_name='apps') + self.add(menu_item) + + packages = Packages('packages-gnome', ['gnome']) + self.add(packages) + + system_target = SystemTarget('system-target-gnome', 'graphical.target') + self.add(system_target) + + backup_restore = BackupRestore('backup-restore-gnome', + **manifest.backup) + self.add(backup_restore) + + def setup(self, old_version): + """Install and configure the app.""" + super().setup(old_version) + if not old_version: + self.enable() + + +class SystemTarget(app_module.LeaderComponent): + """Component to set the default target systemd will boot into.""" + + _DEFAULT_TARGET: str = 'multi-user.target' + + def __init__(self, component_id: str, target: str): + """Initialize the component.""" + super().__init__(component_id) + self.target = target + + def is_enabled(self) -> bool: + """Return whether the component is enabled.""" + return action_utils.systemd_get_default() == self.target + + def enable(self) -> None: + """Run operations to enable the component.""" + service_privileged.systemd_set_default(self.target) + + def disable(self) -> None: + """Run operations to disable the component.""" + service_privileged.systemd_set_default(self._DEFAULT_TARGET) diff --git a/plinth/modules/gnome/data/usr/share/freedombox/modules-enabled/gnome b/plinth/modules/gnome/data/usr/share/freedombox/modules-enabled/gnome new file mode 100644 index 000000000..94ddfc9c8 --- /dev/null +++ b/plinth/modules/gnome/data/usr/share/freedombox/modules-enabled/gnome @@ -0,0 +1 @@ +plinth.modules.gnome diff --git a/plinth/modules/gnome/manifest.py b/plinth/modules/gnome/manifest.py new file mode 100644 index 000000000..de18fdb4a --- /dev/null +++ b/plinth/modules/gnome/manifest.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Application manifest for GNOME.""" + +from django.utils.translation import gettext_lazy as _ + +backup = {} + +tags = [ + _('Desktop'), + _('Browser'), + _('Office suite'), + _('Software store'), + _('GUI'), + _('Graphical apps') +] diff --git a/plinth/modules/gnome/static/icons/gnome.png b/plinth/modules/gnome/static/icons/gnome.png new file mode 100644 index 0000000000000000000000000000000000000000..4d341cb5b7772a93fa2241a395546ac14e8e488c GIT binary patch literal 26096 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 gG&HohWZ% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plinth/modules/gnome/urls.py b/plinth/modules/gnome/urls.py new file mode 100644 index 000000000..a4a4fa0f4 --- /dev/null +++ b/plinth/modules/gnome/urls.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""URLs for the GNOME module.""" + +from django.urls import re_path + +from plinth.views import AppView + +urlpatterns = [ + re_path(r'^apps/gnome/$', AppView.as_view(app_id='gnome'), name='index'), +]