build: package the desktop instead of the shell
The install list loses the dock, the window helper, the Chrome window arbiter, the notification wrapper, the compositor and bar configs and the GTK icon and stylesheet machinery, and gains a look and feel package, a colour scheme, window rules, Kiosk restrictions and two supervised user services. Dependencies follow: Plasma and SDDM in, sway, waybar, mako and gtk-layer-shell out. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d87990f0ac
commit
6e4786f448
@@ -0,0 +1,24 @@
|
|||||||
|
# The classroom logs itself in, and logs itself back in.
|
||||||
|
#
|
||||||
|
# The old session started from ~/.bash_profile on an autologin getty, which
|
||||||
|
# has one bad property: when the session ends for any reason, the teacher is
|
||||||
|
# looking at a shell prompt on a machine that is supposed to have no
|
||||||
|
# terminal. A display manager ends that. Relogin means the room comes
|
||||||
|
# straight back to the classroom instead of to anything else.
|
||||||
|
#
|
||||||
|
# SDDM is never seen. There is one user, no password, and no chooser.
|
||||||
|
|
||||||
|
[Autologin]
|
||||||
|
User=classroom
|
||||||
|
Session=plasma
|
||||||
|
Relogin=true
|
||||||
|
|
||||||
|
[General]
|
||||||
|
DisplayServer=wayland
|
||||||
|
# No user switching, no second session.
|
||||||
|
InputMethod=
|
||||||
|
|
||||||
|
[Users]
|
||||||
|
MaximumUid=1000
|
||||||
|
MinimumUid=1000
|
||||||
|
HideShells=/usr/sbin/nologin,/bin/false
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 252 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
@@ -4,7 +4,16 @@ Section: misc
|
|||||||
Priority: optional
|
Priority: optional
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
Maintainer: Ekklesia
|
Maintainer: Ekklesia
|
||||||
Depends: sway, swaybg, waybar, mako-notifier, dbus-user-session, xwayland, fonts-dejavu, fonts-noto, network-manager, pipewire, pipewire-audio, wireplumber, cups, cups-client, cups-filters, foomatic-db-compressed-ppds, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, gir1.2-gtklayershell-0.1, adwaita-icon-theme, libnotify-bin, curl, gnupg, ca-certificates, python3-paho-mqtt
|
Depends: plasma-desktop, plasma-workspace, kwin-wayland, plasma-nm, plasma-pa, sddm, dbus-user-session, xwayland, fonts-dejavu, fonts-noto, network-manager, pipewire, pipewire-audio, wireplumber, pulseaudio-utils, cups, cups-client, cups-filters, foomatic-db-compressed-ppds, libnotify-bin, curl, gnupg, ca-certificates, python3-paho-mqtt
|
||||||
Recommends: vlc
|
Recommends: vlc
|
||||||
|
Conflicts: plasma-welcome, plasma-discover, kdeconnect, kup-backup
|
||||||
Description: Ekklesia managed classroom environment
|
Description: Ekklesia managed classroom environment
|
||||||
A minimal Wayland classroom environment for Ekklesia-managed church computers.
|
A classroom appliance built on Debian's own Plasma desktop. The room's
|
||||||
|
panel, window behaviour, notifications, palette and lockdown are
|
||||||
|
configuration for that desktop rather than a shell of our own; what is
|
||||||
|
left here is the church's own subject matter — Wonder Ink, the browser,
|
||||||
|
the DVD player, the printer, the audio policy and the updater.
|
||||||
|
.
|
||||||
|
The Conflicts line is deliberate. A welcome tour, a software centre and
|
||||||
|
a phone pairing daemon are all things plasma-desktop recommends and a
|
||||||
|
room a teacher walks into should not have.
|
||||||
|
|||||||
+44
-27
@@ -1,20 +1,14 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
"""Apply the room's UI scale to the whole classroom session.
|
"""Make everything in the room bigger or smaller, once.
|
||||||
|
|
||||||
UI_SCALE is a property of the television, not of one program, so it is
|
UI_SCALE is the display's scale factor, so it scales the browser, VLC, the
|
||||||
applied where it reaches everything: sway's output scale. Chrome's tabs
|
bar and every dialog together rather than each of them separately. Plasma
|
||||||
and omnibox, its menus, VLC, and the classroom's own dock and
|
owns display configuration, so this asks Plasma's own tool to do it — which
|
||||||
notifications are then all measured in the same scaled logical pixels.
|
is the whole of what replaced the compositor-specific version.
|
||||||
|
|
||||||
The display mode is untouched — the panel stays at its native
|
|
||||||
resolution. Only the logical coordinate space shrinks, which is what
|
|
||||||
makes everything drawn in it larger.
|
|
||||||
|
|
||||||
Run from the sway config before anything else starts, so surfaces come
|
|
||||||
up at the right size rather than being resized underneath themselves.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -28,27 +22,50 @@ sys.path.insert(
|
|||||||
from classroom_config import read_device_config, ui_scale # noqa: E402
|
from classroom_config import read_device_config, ui_scale # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def outputs():
|
||||||
scale = ui_scale(read_device_config())
|
"""Every connected display, by name.
|
||||||
|
|
||||||
|
The JSON form rather than the human one: kscreen-doctor's plain output
|
||||||
|
is full of terminal colour codes, and a regular expression over it
|
||||||
|
silently matched nothing.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(
|
listing = subprocess.run(
|
||||||
["swaymsg", "output", "*", "scale", f"{scale:g}"],
|
["kscreen-doctor", "-j"],
|
||||||
capture_output=True,
|
capture_output=True, text=True, timeout=20, check=False,
|
||||||
text=True,
|
).stdout
|
||||||
)
|
found = json.loads(listing or "{}").get("outputs") or []
|
||||||
except OSError as error:
|
except (OSError, subprocess.SubprocessError, ValueError) as error:
|
||||||
print(f"classroom-scale: {error}", file=sys.stderr)
|
print(f"classroom-scale: {error}", file=sys.stderr)
|
||||||
return 1
|
return []
|
||||||
|
|
||||||
if result.returncode != 0:
|
return [
|
||||||
print(
|
output["name"] for output in found
|
||||||
f"classroom-scale: {result.stderr.strip() or 'sway refused the scale'}",
|
if output.get("name") and output.get("connected", True)
|
||||||
file=sys.stderr,
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# classroom_config clamps a nonsense or out-of-range value rather than
|
||||||
|
# obeying it, so a mistyped UI_SCALE cannot leave a room unusable.
|
||||||
|
scale = ui_scale(read_device_config())
|
||||||
|
found = outputs()
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
print("classroom-scale: no outputs", file=sys.stderr)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
for output in found:
|
||||||
|
result = subprocess.run(
|
||||||
|
["kscreen-doctor", f"output.{output}.scale.{scale}"],
|
||||||
|
capture_output=True, text=True, timeout=20, check=False,
|
||||||
)
|
)
|
||||||
return 1
|
|
||||||
|
|
||||||
print(f"classroom-scale: session scale {scale:g}")
|
if result.returncode == 0:
|
||||||
|
print(f"classroom-scale: {output} scale {scale}")
|
||||||
|
else:
|
||||||
|
print(f"classroom-scale: {output}: {result.stderr.strip()}",
|
||||||
|
file=sys.stderr)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|||||||
+84
-60
@@ -79,31 +79,15 @@ install -m755 \
|
|||||||
"$ROOT/packaging/debian/postinst" \
|
"$ROOT/packaging/debian/postinst" \
|
||||||
"$STAGE/DEBIAN/postinst"
|
"$STAGE/DEBIAN/postinst"
|
||||||
|
|
||||||
# Classroom UI configuration.
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/config/sway/config" \
|
|
||||||
"$STAGE/etc/ekklesia-classroom/sway/config"
|
|
||||||
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/config/waybar/config.jsonc" \
|
|
||||||
"$STAGE/etc/ekklesia-classroom/waybar/config.jsonc"
|
|
||||||
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/config/waybar/style.css" \
|
|
||||||
"$STAGE/etc/ekklesia-classroom/waybar/style.css"
|
|
||||||
|
|
||||||
# Classroom commands.
|
# Classroom commands.
|
||||||
install -Dm755 \
|
install -Dm755 \
|
||||||
"$ROOT/scripts/classroom-browser" \
|
"$ROOT/scripts/classroom-browser" \
|
||||||
"$STAGE/usr/local/bin/classroom-browser"
|
"$STAGE/usr/local/bin/classroom-browser"
|
||||||
|
|
||||||
install -Dm755 \
|
|
||||||
"$ROOT/scripts/classroom-chrome-windows" \
|
|
||||||
"$STAGE/usr/local/bin/classroom-chrome-windows"
|
|
||||||
|
|
||||||
install -Dm755 \
|
|
||||||
"$ROOT/scripts/classroom-window" \
|
|
||||||
"$STAGE/usr/local/bin/classroom-window"
|
|
||||||
|
|
||||||
install -Dm755 \
|
install -Dm755 \
|
||||||
"$ROOT/scripts/classroom-dvd" \
|
"$ROOT/scripts/classroom-dvd" \
|
||||||
@@ -117,21 +101,12 @@ install -Dm755 \
|
|||||||
"$ROOT/scripts/classroom-dvd-css-setup" \
|
"$ROOT/scripts/classroom-dvd-css-setup" \
|
||||||
"$STAGE/usr/local/bin/classroom-dvd-css-setup"
|
"$STAGE/usr/local/bin/classroom-dvd-css-setup"
|
||||||
|
|
||||||
install -Dm755 \
|
|
||||||
"$ROOT/scripts/classroom-notify" \
|
|
||||||
"$STAGE/usr/local/bin/classroom-notify"
|
|
||||||
|
|
||||||
install -Dm755 \
|
|
||||||
"$ROOT/scripts/classroom-notify-test" \
|
|
||||||
"$STAGE/usr/local/bin/classroom-notify-test"
|
|
||||||
|
|
||||||
install -Dm755 \
|
install -Dm755 \
|
||||||
"$ROOT/scripts/classroom-mqtt" \
|
"$ROOT/scripts/classroom-mqtt" \
|
||||||
"$STAGE/usr/local/bin/classroom-mqtt"
|
"$STAGE/usr/local/bin/classroom-mqtt"
|
||||||
|
|
||||||
install -Dm755 \
|
|
||||||
"$ROOT/scripts/classroom-notifications" \
|
|
||||||
"$STAGE/usr/local/bin/classroom-notifications"
|
|
||||||
|
|
||||||
install -Dm755 \
|
install -Dm755 \
|
||||||
"$ROOT/scripts/classroom-scale" \
|
"$ROOT/scripts/classroom-scale" \
|
||||||
@@ -162,47 +137,24 @@ install -Dm644 \
|
|||||||
"$ROOT/lib/classroom_chrome.py" \
|
"$ROOT/lib/classroom_chrome.py" \
|
||||||
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_chrome.py"
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_chrome.py"
|
||||||
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/lib/classroom_icons.py" \
|
|
||||||
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_icons.py"
|
|
||||||
|
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/lib/classroom_mqtt.py" \
|
"$ROOT/lib/classroom_mqtt.py" \
|
||||||
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_mqtt.py"
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_mqtt.py"
|
||||||
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/lib/classroom_style.py" \
|
|
||||||
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_style.py"
|
|
||||||
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/lib/classroom_sway.py" \
|
|
||||||
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_sway.py"
|
|
||||||
|
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/lib/classroom_vlc.py" \
|
"$ROOT/lib/classroom_vlc.py" \
|
||||||
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_vlc.py"
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_vlc.py"
|
||||||
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/lib/classroom_optical.py" \
|
|
||||||
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_optical.py"
|
|
||||||
|
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/config/wallpapers/classroom-default.png" \
|
"$ROOT/config/wallpapers/classroom-calm.png" \
|
||||||
"$STAGE/usr/share/backgrounds/ekklesia/classroom-default.png"
|
"$STAGE/usr/share/backgrounds/ekklesia/classroom-calm.png"
|
||||||
|
|
||||||
install -Dm755 \
|
|
||||||
"$ROOT/scripts/classroom-dock" \
|
|
||||||
"$STAGE/usr/local/bin/classroom-dock"
|
|
||||||
|
|
||||||
# Stylesheet and notification templates. Both carry measurement tokens
|
|
||||||
# that are resolved from UI_SCALE when the session starts.
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/config/dock/style.css.in" \
|
|
||||||
"$STAGE/etc/ekklesia-classroom/dock/style.css.in"
|
|
||||||
|
|
||||||
install -Dm644 \
|
|
||||||
"$ROOT/config/mako/config.in" \
|
|
||||||
"$STAGE/etc/ekklesia-classroom/mako/config.in"
|
|
||||||
|
|
||||||
# Chrome enterprise policy: suppress first-run and sign-in nags, and pin
|
# Chrome enterprise policy: suppress first-run and sign-in nags, and pin
|
||||||
# Home to Wonder Ink. Nothing here restricts where teachers can browse.
|
# Home to Wonder Ink. Nothing here restricts where teachers can browse.
|
||||||
@@ -220,8 +172,8 @@ install -Dm755 \
|
|||||||
|
|
||||||
# System configuration.
|
# System configuration.
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/systemd/autologin/autologin.conf" \
|
"$ROOT/config/sddm/ekklesia-classroom.conf" \
|
||||||
"$STAGE/etc/systemd/system/[email protected]/autologin.conf"
|
"$STAGE/etc/sddm.conf.d/ekklesia-classroom.conf"
|
||||||
|
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/systemd/updater/ekklesia-classroom-update.service" \
|
"$ROOT/systemd/updater/ekklesia-classroom-update.service" \
|
||||||
@@ -243,21 +195,93 @@ install -Dm644 \
|
|||||||
"$ROOT/systemd/mqtt/ekklesia-classroom-mqtt.service" \
|
"$ROOT/systemd/mqtt/ekklesia-classroom-mqtt.service" \
|
||||||
"$STAGE/etc/systemd/system/ekklesia-classroom-mqtt.service"
|
"$STAGE/etc/systemd/system/ekklesia-classroom-mqtt.service"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The classroom desktop.
|
||||||
|
#
|
||||||
|
# Not a shell, and not a daemon: a Plasma session described in files Plasma
|
||||||
|
# already reads. The panel, the window behaviour, the notifications, the
|
||||||
|
# lockdown and the palette are all in here, which is why there is no longer
|
||||||
|
# a dock, a window helper, a notification wrapper or a compositor config in
|
||||||
|
# the list above.
|
||||||
|
|
||||||
|
for setting in kdeglobals kwinrc kwinrulesrc kscreenlockerrc ksmserverrc \
|
||||||
|
krunnerrc plasmanotifyrc; do
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/config/icons/dvd.svg" \
|
"$ROOT/config/plasma/xdg/${setting}" \
|
||||||
"$STAGE/etc/ekklesia-classroom/icons/dvd.svg"
|
"$STAGE/etc/xdg/${setting}"
|
||||||
|
done
|
||||||
|
|
||||||
|
for scheme in EkklesiaDark EkklesiaLight; do
|
||||||
|
install -Dm644 \
|
||||||
|
"$ROOT/config/plasma/colors/${scheme}.colors" \
|
||||||
|
"$STAGE/usr/share/color-schemes/${scheme}.colors"
|
||||||
|
done
|
||||||
|
|
||||||
|
LOOK="$STAGE/usr/share/plasma/look-and-feel/org.ekklesia.classroom.desktop"
|
||||||
|
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/config/icons/live.svg" \
|
"$ROOT/config/plasma/lookandfeel/metadata.json" \
|
||||||
"$STAGE/etc/ekklesia-classroom/icons/live.svg"
|
"$LOOK/metadata.json"
|
||||||
|
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/config/icons/live-off.svg" \
|
"$ROOT/config/plasma/lookandfeel/contents/defaults" \
|
||||||
"$STAGE/etc/ekklesia-classroom/icons/live-off.svg"
|
"$LOOK/contents/defaults"
|
||||||
|
|
||||||
install -Dm644 \
|
install -Dm644 \
|
||||||
"$ROOT/config/icons/browser.svg" \
|
"$ROOT/config/plasma/lookandfeel/contents/layouts/org.kde.plasma.desktop-layout.js" \
|
||||||
"$STAGE/etc/ekklesia-classroom/icons/browser.svg"
|
"$LOOK/contents/layouts/org.kde.plasma.desktop-layout.js"
|
||||||
|
|
||||||
|
for entry in "$ROOT"/config/plasma/applications/*.desktop; do
|
||||||
|
install -Dm644 "$entry" \
|
||||||
|
"$STAGE/usr/share/applications/$(basename "$entry")"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Shadows Chrome's own entry. XDG_DATA_DIRS searches /usr/local/share first,
|
||||||
|
# so the panel matches a Chrome window to this launcher instead of to
|
||||||
|
# Chrome's, and the room gets one button rather than two.
|
||||||
|
for entry in "$ROOT"/config/plasma/applications-local/*.desktop; do
|
||||||
|
install -Dm644 "$entry" \
|
||||||
|
"$STAGE/usr/local/share/applications/$(basename "$entry")"
|
||||||
|
done
|
||||||
|
|
||||||
|
install -Dm644 \
|
||||||
|
"$ROOT/config/plasma/solid/ekklesia-dvd.desktop" \
|
||||||
|
"$STAGE/usr/share/solid/actions/ekklesia-dvd.desktop"
|
||||||
|
|
||||||
|
for icon in ekklesia-wonderink ekklesia-parent-call; do
|
||||||
|
install -Dm644 \
|
||||||
|
"$ROOT/config/icons/${icon}.svg" \
|
||||||
|
"$STAGE/usr/share/icons/hicolor/scalable/apps/${icon}.svg"
|
||||||
|
done
|
||||||
|
|
||||||
|
# The panel is the only way a teacher has of getting anywhere. Plasma gives
|
||||||
|
# up restarting it after three crashes in a minute; this does not.
|
||||||
|
install -Dm644 \
|
||||||
|
"$ROOT/systemd/user/plasma-plasmashell.service.d/ekklesia-classroom.conf" \
|
||||||
|
"$STAGE/etc/systemd/user/plasma-plasmashell.service.d/ekklesia-classroom.conf"
|
||||||
|
|
||||||
|
install -Dm644 \
|
||||||
|
"$ROOT/systemd/user/ekklesia-classroom-audio.service" \
|
||||||
|
"$STAGE/etc/systemd/user/ekklesia-classroom-audio.service"
|
||||||
|
|
||||||
|
install -Dm755 \
|
||||||
|
"$ROOT/scripts/classroom-wonderink" \
|
||||||
|
"$STAGE/usr/local/bin/classroom-wonderink"
|
||||||
|
|
||||||
|
install -Dm755 \
|
||||||
|
"$ROOT/scripts/classroom-audio" \
|
||||||
|
"$STAGE/usr/local/bin/classroom-audio"
|
||||||
|
|
||||||
|
install -Dm755 \
|
||||||
|
"$ROOT/scripts/classroom-theme" \
|
||||||
|
"$STAGE/usr/local/bin/classroom-theme"
|
||||||
|
|
||||||
|
install -Dm644 \
|
||||||
|
"$ROOT/lib/classroom_audio.py" \
|
||||||
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_audio.py"
|
||||||
|
|
||||||
# DVD mode control bar.
|
# DVD mode control bar.
|
||||||
for icon in media-play media-pause chapter-prev chapter-next \
|
for icon in media-play media-pause chapter-prev chapter-next \
|
||||||
|
|||||||
@@ -76,3 +76,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
# pointer to be clicked with.
|
# pointer to be clicked with.
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends seatd \
|
RUN apt-get update && apt-get install -y --no-install-recommends seatd \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# What a classroom would not install.
|
||||||
|
#
|
||||||
|
# plasma-desktop recommends a welcome tour, a software centre, a phone
|
||||||
|
# pairing daemon and a backup tool. None of them belong in a room a teacher
|
||||||
|
# walks into, and a classroom package would simply not pull them in; the lab
|
||||||
|
# removes them so it is testing the same desktop.
|
||||||
|
RUN DEBIAN_FRONTEND=noninteractive apt-get purge -y \
|
||||||
|
plasma-welcome plasma-discover plasma-discover-common \
|
||||||
|
plasma-discover-backend-fwupd kdeconnect kup-backup \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|||||||
Reference in New Issue
Block a user