Files
Classroom_Desktop/tools/build-release.sh
T
ekklesiaandClaude Opus 5 a1a218b29f fix: draw classroom icons at the display's real pixel density
Icons went soft under UI_SCALE while the clock text beside them stayed
sharp, which is visible on a 24" monitor even if it hides on a TV.

new_from_file_at_scale rasterises an SVG at its *logical* size. The
artwork is vector, but by the time sway scaled the session it was
already a fixed raster, and the compositor enlarged that. Text never had
the problem because GTK draws it at the real density.

GTK 3 has no fractional scaling, so sway advertises the ceiling integer
scale and scales the finished buffer down. Measured under sway: scale
factor 1 at output scale 1.0, and 2 at 1.25, 1.5 and 2.0. So each icon
is now rasterised at size x scale_factor physical pixels and handed to
GTK as a cairo surface carrying that device scale. The icon lands at the
real density; its logical size, and the whole dock layout, is unchanged.

Icons redraw on notify::scale-factor as well as at realize, since the
scale factor is not known until a widget is on a display and changes if
UI_SCALE is changed under a running session.

Browser, DVD, LIVE and all six DVD control icons go through it, in a
shared module so the dock and the DVD session cannot diverge. The
throbber is drawn rather than loaded and had the same flaw, so it draws
on a device-scaled surface too rather than being the one soft thing left
in a sharp dock.

The artwork is untouched. Verified by rendering the dock under sway at
1.0, 1.25, 1.5 and 2.0 against the previous build: apparent icon size is
identical at every scale (28, 35, 42, 56 px), 1.0 is unchanged
pixel-for-pixel, and peak edge contrast on the Chrome icon goes from 60
to 99 at 1.25, 49 to 83 at 1.5, and 37 to 82 at 2.0 out of 255. The DVD
control bar was checked the same way.

Also records that Wonder Ink session-only cookies are confirmed working
on the endpoint, which settles the question 0.1.34 shipped as unverified
and tells us the session is in cookies rather than localStorage.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 14:19:38 -05:00

252 lines
6.9 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
if [[ $# -ne 1 ]]; then
echo "Usage: $0 VERSION"
exit 1
fi
VERSION="$1"
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Invalid version: $VERSION"
echo "Expected MAJOR.MINOR.PATCH, for example 0.1.6"
exit 1
fi
STAGE="$ROOT/packaging/root"
OUTPUT="$ROOT/dist/ekklesia-classroom_${VERSION}_amd64.deb"
# Syntax check everything the package ships, by shebang, so this cannot
# drift out of date as classroom commands are added.
echo "Validating sources"
for script in "$ROOT/packaging/debian/postinst" "$ROOT"/scripts/* "$ROOT"/tests/*; do
[[ -f "$script" ]] || continue
case "$(head -n 1 "$script")" in
*python3*)
python3 -m py_compile "$script"
;;
*bash*|*bin/sh*)
bash -n "$script"
;;
esac
done
for module in "$ROOT"/lib/*.py; do
[[ -f "$module" ]] || continue
python3 -m py_compile "$module"
done
for policy in "$ROOT"/config/chrome/policies/*/*.json; do
[[ -f "$policy" ]] || continue
python3 -c 'import json, sys; json.load(open(sys.argv[1]))' "$policy"
done
find "$ROOT/scripts" "$ROOT/lib" \
-name '__pycache__' -type d -prune -exec rm -rf {} + 2>/dev/null || true
for test in "$ROOT"/tests/test-*.sh; do
[[ -x "$test" ]] || continue
echo "Running $(basename "$test")"
"$test" > /dev/null || {
echo "Tests failed. Run it directly to see why:"
echo " $test"
exit 1
}
done
echo "Building Ekklesia Classroom ${VERSION}"
# Always construct the package from clean canonical sources.
rm -rf "$STAGE"
mkdir -p "$STAGE/DEBIAN" "$ROOT/dist"
# Debian package metadata.
sed \
"s/^Version: @VERSION@$/Version: ${VERSION}/" \
"$ROOT/packaging/debian/control.template" \
> "$STAGE/DEBIAN/control"
install -m755 \
"$ROOT/packaging/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.
install -Dm755 \
"$ROOT/scripts/classroom-browser" \
"$STAGE/usr/local/bin/classroom-browser"
install -Dm755 \
"$ROOT/scripts/classroom-window" \
"$STAGE/usr/local/bin/classroom-window"
install -Dm755 \
"$ROOT/scripts/classroom-dvd" \
"$STAGE/usr/local/bin/classroom-dvd"
install -Dm755 \
"$ROOT/scripts/classroom-dvd-session" \
"$STAGE/usr/local/bin/classroom-dvd-session"
install -Dm755 \
"$ROOT/scripts/classroom-dvd-css-setup" \
"$STAGE/usr/local/bin/classroom-dvd-css-setup"
install -Dm755 \
"$ROOT/scripts/classroom-notify-test" \
"$STAGE/usr/local/bin/classroom-notify-test"
install -Dm755 \
"$ROOT/scripts/classroom-notifications" \
"$STAGE/usr/local/bin/classroom-notifications"
install -Dm755 \
"$ROOT/scripts/classroom-scale" \
"$STAGE/usr/local/bin/classroom-scale"
install -Dm755 \
"$ROOT/scripts/classroom-shutdown" \
"$STAGE/usr/local/bin/classroom-shutdown"
install -Dm755 \
"$ROOT/scripts/classroom-chrome-setup" \
"$STAGE/usr/local/bin/classroom-chrome-setup"
install -Dm755 \
"$ROOT/scripts/classroom-provision" \
"$STAGE/usr/local/bin/classroom-provision"
# Shared helpers imported by the classroom commands.
install -Dm644 \
"$ROOT/lib/classroom_config.py" \
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_config.py"
install -Dm644 \
"$ROOT/lib/classroom_icons.py" \
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_icons.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 \
"$ROOT/lib/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 \
"$ROOT/config/wallpapers/classroom-default.png" \
"$STAGE/usr/share/backgrounds/ekklesia/classroom-default.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
# Home to Wonder Ink. Nothing here restricts where teachers can browse.
install -Dm644 \
"$ROOT/config/chrome/policies/managed/ekklesia-classroom.json" \
"$STAGE/etc/opt/chrome/policies/managed/ekklesia-classroom.json"
install -Dm644 \
"$ROOT/config/chrome/policies/recommended/ekklesia-classroom.json" \
"$STAGE/etc/opt/chrome/policies/recommended/ekklesia-classroom.json"
install -Dm755 \
"$ROOT/scripts/ekklesia-classroom-update" \
"$STAGE/usr/local/bin/ekklesia-classroom-update"
# System configuration.
install -Dm644 \
"$ROOT/systemd/autologin/autologin.conf" \
"$STAGE/etc/systemd/system/[email protected]/autologin.conf"
install -Dm644 \
"$ROOT/systemd/updater/ekklesia-classroom-update.service" \
"$STAGE/etc/systemd/system/ekklesia-classroom-update.service"
install -Dm644 \
"$ROOT/systemd/updater/ekklesia-classroom-update.timer" \
"$STAGE/etc/systemd/system/ekklesia-classroom-update.timer"
install -Dm644 \
"$ROOT/systemd/provision/ekklesia-classroom-provision.service" \
"$STAGE/etc/systemd/system/ekklesia-classroom-provision.service"
install -Dm644 \
"$ROOT/systemd/shutdown/ekklesia-classroom-shutdown.service" \
"$STAGE/etc/systemd/system/ekklesia-classroom-shutdown.service"
install -Dm644 \
"$ROOT/config/icons/dvd.svg" \
"$STAGE/etc/ekklesia-classroom/icons/dvd.svg"
install -Dm644 \
"$ROOT/config/icons/live.svg" \
"$STAGE/etc/ekklesia-classroom/icons/live.svg"
install -Dm644 \
"$ROOT/config/icons/live-off.svg" \
"$STAGE/etc/ekklesia-classroom/icons/live-off.svg"
install -Dm644 \
"$ROOT/config/icons/browser.svg" \
"$STAGE/etc/ekklesia-classroom/icons/browser.svg"
# DVD mode control bar.
for icon in media-play media-pause chapter-prev chapter-next \
disc-menu eject close; do
install -Dm644 \
"$ROOT/config/icons/${icon}.svg" \
"$STAGE/etc/ekklesia-classroom/icons/${icon}.svg"
done
printf '%s\n' "$VERSION" > "$ROOT/VERSION"
dpkg-deb \
--root-owner-group \
--build "$STAGE" "$OUTPUT"
echo
echo "Built:"
echo "$OUTPUT"
sha256sum "$OUTPUT"