Add desktop page

This commit is contained in:
Peter Eisenmann
2024-10-08 21:22:03 -05:00
parent ac21b7370f
commit eddcfd4bf0
21 changed files with 226 additions and 4 deletions

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 3 0 c -1.660156 0 -3 1.339844 -3 3 v 7 c 0 1.660156 1.339844 3 3 3 h 10 c 1.660156 0 3 -1.339844 3 -3 v -7 c 0 -1.660156 -1.339844 -3 -3 -3 z m 0 2 h 10 c 0.554688 0 1 0.445312 1 1 v 7 c 0 0.554688 -0.445312 1 -1 1 h -10 c -0.554688 0 -1 -0.445312 -1 -1 v -7 c 0 -0.554688 0.445312 -1 1 -1 z m 2 12 c -1.105469 0 -2 0.894531 -2 2 h 10 c 0 -1.105469 -0.894531 -2 -2 -2 z m 0 0" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 543 B

View File

@@ -6,6 +6,7 @@ blueprints = custom_target('blueprints',
'ui/main_window.blp',
'ui/pages/choices.blp',
'ui/pages/confirm.blp',
'ui/pages/desktop.blp',
'ui/pages/disk.blp',
'ui/pages/done.blp',
'ui/pages/encrypt.blp',
@@ -23,6 +24,7 @@ blueprints = custom_target('blueprints',
'ui/pages/summary.blp',
'ui/pages/user.blp',
'ui/pages/welcome.blp',
'ui/widgets/desktop_entry.blp',
'ui/widgets/device_row.blp',
'ui/widgets/multi_selection_row.blp',
'ui/widgets/page_wrapper.blp',

View File

@@ -9,6 +9,7 @@
<file>style.css</file>
<!-- Icons -->
<file preprocess="xml-stripblanks">icon/scalable/actions/computer-symbolic.svg</file>
<file preprocess="xml-stripblanks">icon/scalable/actions/globe-symbolic.svg</file>
<file preprocess="xml-stripblanks">icon/scalable/actions/language-symbolic.svg</file>
<file preprocess="xml-stripblanks">icon/scalable/actions/map-symbolic.svg</file>
@@ -24,6 +25,7 @@
<file preprocess="xml-stripblanks">ui/pages/choices.ui</file>
<file preprocess="xml-stripblanks">ui/pages/confirm.ui</file>
<file preprocess="xml-stripblanks">ui/pages/desktop.ui</file>
<file preprocess="xml-stripblanks">ui/pages/disk.ui</file>
<file preprocess="xml-stripblanks">ui/pages/done.ui</file>
<file preprocess="xml-stripblanks">ui/pages/encrypt.ui</file>
@@ -42,6 +44,7 @@
<file preprocess="xml-stripblanks">ui/pages/user.ui</file>
<file preprocess="xml-stripblanks">ui/pages/welcome.ui</file>
<file preprocess="xml-stripblanks">ui/widgets/desktop_entry.ui</file>
<file preprocess="xml-stripblanks">ui/widgets/device_row.ui</file>
<file preprocess="xml-stripblanks">ui/widgets/multi_selection_row.ui</file>
<file preprocess="xml-stripblanks">ui/widgets/page_wrapper.ui</file>

View File

@@ -0,0 +1,44 @@
using Gtk 4.0;
using Gio 2.0;
Gio.ListStore model {}
template $DesktopPage: Box {
orientation: vertical;
spacing:12;
Picture selected_image {
content-fit: contain;
halign: center;
height-request: 178;
styles ["card"]
}
Label selected_description {
margin-end: 12;
margin-start: 12;
ellipsize: end;
lines: 3;
}
Button continue_button {
/* Translators: On button, brackets will be replaced with desktop name. */
label: _("_Use {}");
focusable: true;
receives-default: true;
halign: center;
valign: center;
use-underline: true;
clicked => $continue();
styles ["suggested-action", "pill"]
}
Grid grid {
column-homogeneous: true;
row-homogeneous: true;
column-spacing: 12;
row-spacing: 12;
hexpand: true;
}
}

View File

@@ -0,0 +1,27 @@
using Gtk 4.0;
template $DesktopEntry: Button {
overflow: hidden;
styles ["card"]
child: Box {
halign: center;
orientation: vertical;
Picture image {
content-fit: contain;
halign: center;
height-request: 80;
}
Label name {
ellipsize: none;
margin-start: 12;
margin-end: 12;
margin-top: 6;
margin-bottom: 6;
styles ["heading"]
}
};
}

View File

@@ -58,6 +58,32 @@ minimum_disk_size: 5
# Default: yes
offer_disk_encryption: yes
# Provide multiple desktop environments to choose from
#
# name string Name of desktop. Translatable.
# description string Optional. Short descripiton of the desktop.
# image_path string Absolute path of an image to display.
# keyword string Forwarded to the installation script as is.
#
# Default: [] (no desktop selection page)
desktop:
- name : 'GNOME'
description : 'Simple desktop that can be personalized with extensions.'
image_path : '/etc/os-installer/desktops/gnome.jpg'
keyword : 'gnome'
- name : 'KDE Plasma'
description : 'Configurable desktop that is similar to Windows.'
image_path : '/etc/os-installer/desktops/kde.png'
keyword : 'kde'
- name : 'Xfce'
description : 'Lightweight desktop with focus on modularity.'
image_path : '/etc/os-installer/desktops/xfce.png'
keyword : 'xfce'
- name : 'Enlightenment'
description : 'Highly configurable, lightweight desktop for tinkerers.'
image_path : '/etc/os-installer/desktops/enlightenment.png'
keyword : 'enlightenment'
# gnome-initial-setup can handle user and locale setup.
# These settings allow to disable these pages.
#

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 KiB

View File

@@ -3,6 +3,7 @@
# This is an example installer script. For OS-Installer to use it, place it at:
# /etc/os-installer/scripts/install.sh
# The script gets called with the following environment variables set:
# OSI_DESKTOP : Desktop keyword, or empty if 'desktop' was not configured
# OSI_LOCALE : Locale to be used in the new system
# OSI_DEVICE_PATH : Device path at which to install
# OSI_DEVICE_IS_PARTITION : 1 if the specified device is a partition (0 -> disk)
@@ -11,7 +12,8 @@
# OSI_ENCRYPTION_PIN : The encryption pin to use (if encryption is set)
# sanity check that all variables were set
if [ -z ${OSI_LOCALE+x} ] || \
if [ -z ${OSI_DESKTOP+x} ] || \
[ -z ${OSI_LOCALE+x} ] || \
[ -z ${OSI_KEYBOARD_LAYOUT+x} ] || \
[ -z ${OSI_DEVICE_PATH+x} ] || \
[ -z ${OSI_DEVICE_IS_PARTITION+x} ] || \
@@ -26,6 +28,7 @@ fi
echo 'Installation started.'
echo ''
echo 'Variables set to:'
echo 'OSI_DESKTOP ' $OSI_DESKTOP
echo 'OSI_LOCALE ' $OSI_LOCALE
echo 'OSI_KEYBOARD_LAYOUT ' $OSI_KEYBOARD_LAYOUT
echo 'OSI_DEVICE_PATH ' $OSI_DEVICE_PATH

View File

@@ -7,6 +7,7 @@ data/resources/ui/main_window.blp
data/resources/ui/pages/choices.blp
data/resources/ui/pages/confirm.blp
data/resources/ui/pages/desktop.blp
data/resources/ui/pages/disk.blp
data/resources/ui/pages/done.blp
data/resources/ui/pages/encrypt.blp
@@ -14,12 +15,10 @@ data/resources/ui/pages/failed.blp
data/resources/ui/pages/filter.blp
data/resources/ui/pages/install.blp
data/resources/ui/pages/internet.blp
data/resources/ui/pages/keyboard_language.blp
data/resources/ui/pages/keyboard_layout.blp
data/resources/ui/pages/keyboard_overview.blp
data/resources/ui/pages/locale.blp
data/resources/ui/pages/partition.blp
data/resources/ui/pages/restart.blp
data/resources/ui/pages/summary.blp
data/resources/ui/pages/user.blp
data/resources/ui/pages/welcome.blp

View File

@@ -22,6 +22,8 @@ default_config = {
# disk
'minimum_disk_size': 5,
'offer_disk_encryption': True,
# desktop
'desktop': [],
# optional pages
'skip_user': False,
'skip_locale': False,
@@ -43,6 +45,7 @@ internal_values = {
'internet_connection': False,
'use_encryption': False,
'encryption_pin': '',
'desktop_chosen': '',
'user_name': '',
'user_autologin': False,
'user_password': '',

View File

@@ -23,6 +23,7 @@ os_installer_sources = [
'global_state.py',
'main.py',
'provider/choices_provider.py',
'provider/desktop_provider.py',
'provider/disk_provider.py',
'provider/format_provider.py',
'provider/internet_provider.py',
@@ -33,6 +34,7 @@ os_installer_sources = [
'ui/page_wrapper.py',
'ui/pages/choices.py',
'ui/pages/confirm.py',
'ui/pages/desktop.py',
'ui/pages/disk.py',
'ui/pages/done.py',
'ui/pages/encrypt.py',

View File

@@ -0,0 +1,38 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import NamedTuple
from .config import config
from .preloadable import Preloadable
class Desktop(NamedTuple):
name: str
description: str
image_path: str
keyword: str
class DesktopProvider(Preloadable):
def __init__(self):
Preloadable.__init__(self, self._get_desktops)
def _get_desktops(self):
self.desktops: list = []
for entry in config.get('desktop'):
if not set(entry).issuperset(['name', 'keyword', 'image_path']):
print(f'Desktop choice not correctly configured: {entry}')
continue
description = entry['description'] if 'description' in entry else ''
desktop = Desktop(entry['name'], description,
entry['image_path'], entry['keyword'])
self.desktops.append(desktop)
### public methods ###
def get_desktops(self):
self.assert_preloaded()
return self.desktops
desktop_provider = DesktopProvider()

View File

@@ -3,12 +3,13 @@
from threading import Thread
from .choices_provider import choices_provider
from .desktop_provider import desktop_provider
from .disk_provider import disk_provider
from .internet_provider import internet_provider
from .language_provider import language_provider
providers = [language_provider, internet_provider,
disk_provider, choices_provider]
disk_provider, desktop_provider, choices_provider]
class PreloadManager:

View File

@@ -9,6 +9,7 @@ from .config import config
from .choices import FeaturePage, SoftwarePage
from .confirm import ConfirmPage
from .desktop import DesktopPage
from .disk import DiskPage
from .done import DonePage
from .encrypt import EncryptPage
@@ -29,6 +30,8 @@ page_name_to_page_title = {
# Translators: Page title
'confirm': _('Confirmation'),
# Translators: Page title
'desktop': _('Desktop Selection'),
# Translators: Page title
'disk': _('Disk Selection'),
# Translators: Page title
'done': _('Installation Complete'),
@@ -72,6 +75,7 @@ page_name_to_page_title = {
page_name_to_image = {
'confirm': 'question-round-symbolic',
'desktop': 'computer-symbolic',
'disk': 'drive-harddisk-system-symbolic',
'done': 'success-symbolic',
'encrypt': 'dialog-password-symbolic',
@@ -96,6 +100,7 @@ special_image_pages = {'internet', 'welcome'}
page_name_to_type = {
'confirm': ConfirmPage,
'desktop': DesktopPage,
'disk': DiskPage,
'done': DonePage,
'encrypt': EncryptPage,

48
src/ui/pages/desktop.py Normal file
View File

@@ -0,0 +1,48 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from gi.repository import Gtk
from .config import config
from .global_state import global_state
from .desktop_provider import desktop_provider
from .widgets import DesktopEntry
@Gtk.Template(resource_path='/com/github/p3732/os-installer/ui/pages/desktop.ui')
class DesktopPage(Gtk.Box):
__gtype_name__ = __qualname__
grid = Gtk.Template.Child()
continue_button = Gtk.Template.Child()
selected_description = Gtk.Template.Child()
selected_image = Gtk.Template.Child()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.button_label = self.continue_button.get_label()
number = 0
for desktop in desktop_provider.get_desktops():
if number == 0:
self._set_selected_desktop(desktop)
entry = DesktopEntry(desktop)
entry.connect('clicked', self._desktop_activated)
self.grid.attach(entry, number % 3, int(number/3), 1, 1)
number += 1
def _set_selected_desktop(self, desktop):
self.continue_button.set_label(self.button_label.format(desktop.name))
self.selected_image.set_filename(desktop.image_path)
self.selected_description.set_label(desktop.description)
config.set('desktop_chosen', desktop.keyword)
### callbacks ###
def _desktop_activated(self, button):
self._set_selected_desktop(button.desktop)
@Gtk.Template.Callback('continue')
def _continue(self, object):
if self.continue_button.is_sensitive():
global_state.advance(self)

View File

@@ -12,6 +12,21 @@ def reset_model(model, new_values):
model.splice(0, n_prev_items, new_values)
@Gtk.Template(resource_path='/com/github/p3732/os-installer/ui/widgets/desktop_entry.ui')
class DesktopEntry(Gtk.Button):
__gtype_name__ = __qualname__
image = Gtk.Template.Child()
name = Gtk.Template.Child()
def __init__(self, desktop, **kwargs):
super().__init__(**kwargs)
self.desktop = desktop
self.name.set_label(desktop.name)
self.image.set_filename(desktop.image_path)
@Gtk.Template(resource_path='/com/github/p3732/os-installer/ui/widgets/device_row.ui')
class DeviceRow(Adw.ActionRow):
__gtype_name__ = __qualname__

View File

@@ -111,6 +111,7 @@ class OsInstallerWindow(Adw.ApplicationWindow):
('disk', True),
('partition', True),
('encrypt', config.get('offer_disk_encryption')),
('desktop', config.get('desktop')),
('confirm', exists('/etc/os-installer/scripts/install.sh')),
# configuration section
('user', not config.get('skip_user')),

View File

@@ -36,6 +36,7 @@ def create_envs(installation_step: InstallationStep):
envs = []
if with_install_envs:
envs += [
f'OSI_DESKTOP={_get("desktop_chosen")}',
f'OSI_LOCALE={_get("locale")}',
f'OSI_KEYBOARD_LAYOUT={_get("keyboard_layout")}',
f'OSI_DEVICE_PATH={_get("disk")}',