feat: give Parent Call a mark that says what it does

Three marks were put on a real panel and judged at the size the bar
actually draws them. A bell sat inches from Plasma's own notification
bell and meant something entirely different. A handset with an outgoing
arrow read as a telephone feature. Breeze has people and it has
telephones and the two never meet, so this is drawn in Breeze's language
instead: an adult, a child, and one small speech bubble, on Breeze's
22-unit grid with its ColorScheme-Text class, so it recolours with the
session and needs no second file for the light theme.

Quick Launch carries it. The Icon widget copies the entry into the user's
home so an update could never change it; a task manager reads the entry
live but also shows every running window, which filled the auxiliary
corner with the lesson's tasks.

One defect found on the way, and it affected the Wonder Ink icon that is
already shipping: gdk-pixbuf recognises an SVG by sniffing the first
bytes, and a licence-length comment above the opening tag pushes it out
of that window. Every GTK program reported "couldn't recognize the image
file format" while Qt rendered the same file happily. The comments live
inside <svg> now.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
ekklesia
2026-09-10 12:47:58 -05:00
co-authored by Claude Opus 5
parent 323989ac61
commit 18cf0249dd
14 changed files with 94 additions and 40 deletions
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" width="22" height="22">
<!-- The comment lives inside <svg>, not above it. gdk-pixbuf
recognises an SVG by sniffing the first bytes of the file, and a
licence-length comment before the opening tag pushes it out of
that window: every GTK program then reports "couldn't recognize
the image file format" while Qt renders it happily. Measured on
both of the classroom's own icons. -->
<!-- Parent Call.
Drawn in Breeze's own language rather than picked from it, because
Breeze has no icon that means "fetch this child's grown-up". It has
people, and it has telephones, and the two never meet. A bare handset
was tried first and read as a telephone feature; a bell was tried
before that and read as Plasma's notifications, which sit in the same
bar.
So: an adult and a child, and one small speech bubble. Same 22-unit
grid, same single path style, same ColorScheme-Text class, so it
recolours with the session exactly as a Breeze icon does and follows
the light and dark themes without a second file. -->
<defs>
<style type="text/css">.ColorScheme-Text { color: #fcfcfc; }</style>
</defs>
<g class="ColorScheme-Text" style="fill:currentColor;fill-opacity:1;stroke:none">
<!-- One small speech bubble, top right, clear of both heads: somebody
is being asked for. It is the only round thing up there, so it
cannot be counted as a third person. -->
<path d="M16.6 1.2c-2.4 0-4.4 1.3-4.4 3s2 3 4.4 3c.3 0 .6 0 .9-.1l2.3 1.2-.5-1.7c1-.5 1.6-1.4
1.6-2.4 0-1.7-2-3-4.3-3z"/>
<!-- The adult: taller, at the back, on the left. -->
<circle cx="6.6" cy="8.2" r="3.1"/>
<path d="M6.6 12.3c-2.9 0-5.1 2.1-5.1 4.9V19h10.2v-1.8c0-2.8-2.2-4.9-5.1-4.9z"/>
<!-- The child: smaller, in front, on the right. -->
<circle cx="14.6" cy="12.4" r="2.2"/>
<path d="M14.6 15.3c-2.1 0-3.6 1.5-3.6 3.3V19h7.2v-.4c0-1.8-1.5-3.3-3.6-3.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

+7 -1
View File
@@ -1,4 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
<!-- The comment lives inside <svg>, not above it. gdk-pixbuf
recognises an SVG by sniffing the first bytes of the file, and a
licence-length comment before the opening tag pushes it out of
that window: every GTK program then reports "couldn't recognize
the image file format" while Qt renders it happily. Measured on
both of the classroom's own icons. -->
<!-- Wonder Ink. <!-- Wonder Ink.
A stand-in for the product's own mark, which the classroom does not A stand-in for the product's own mark, which the classroom does not
@@ -7,7 +14,6 @@
a monochrome glyph on a bar is read as a decoration and not as an a monochrome glyph on a bar is read as a decoration and not as an
application. Somebody asked whether the old browser glyph meant "the application. Somebody asked whether the old browser glyph meant "the
Internet". A tile with its own colour does not get that question. --> Internet". A tile with its own colour does not get that question. -->
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
<defs> <defs>
<linearGradient id="tile" x1="0" y1="0" x2="1" y2="1"> <linearGradient id="tile" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#4FB3A8"/> <stop offset="0" stop-color="#4FB3A8"/>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -2,16 +2,15 @@
Type=Application Type=Application
Name=Parent Call Name=Parent Call
Comment=Ask the sanctuary to call a child's parent to this room Comment=Ask the sanctuary to call a child's parent to this room
# Breeze's own, and deliberately not a bell. # Drawn for this, in Breeze's language, because Breeze has no icon that
# # means "fetch this child's grown-up". Two marks were tried and rejected
# The previous mark was a bell, which sat two inches from Plasma's # on a real panel first: a bell, which sat inches from Plasma's own
# notification bell in the same bar and meant something entirely # notification bell in the same bar, and a handset with an outgoing
# different. A handset with an outgoing arrow cannot be mistaken for an # arrow, which read as a telephone feature. This one is an adult, a
# alert: it reads as placing a call, and the arrow says the call leaves # child, and one small speech bubble. It uses Breeze's ColorScheme-Text
# this room. No stock Breeze icon combines a person with a call, so the # class, so it recolours with the session and needs no second file for
# unambiguous half was chosen over the half that could be read as user # the light theme.
# settings — which is what two grey people on a panel look like. Icon=ekklesia-parent-call
Icon=call-outgoing
Exec=/usr/local/bin/classroom-parent-call Exec=/usr/local/bin/classroom-parent-call
Terminal=false Terminal=false
Categories=Utility; Categories=Utility;
@@ -41,29 +41,29 @@ panel.opacity = "adaptive";
// LEFT — auxiliary. Parent Call is not one of the room's applications and // LEFT — auxiliary. Parent Call is not one of the room's applications and
// is deliberately not in the row with them. // is deliberately not in the row with them.
// A task manager holding one launcher, not the Icon widget. // Quick Launch: a launcher, and only a launcher.
// //
// The Icon widget copies the desktop entry into the user's home and uses // Two other widgets were tried on a real panel. The Icon widget copies
// the copy, so a classroom that had already run would keep the old icon // the desktop entry into the user's home and uses the copy, so an update
// and the old command for ever — an update could never change either. // could never change the icon or the command — it kept showing a bell out
// Measured: it kept showing a bell out of a package that no longer // of a package that no longer contained one. A task manager reads
// contains one. Quick Launch would also do, but Debian does not ship it. // /usr/share/applications live, which fixes that, but a task manager also
// shows every running window, so the auxiliary corner filled up with the
// lesson's tasks.
// //
// This applet reads /usr/share/applications live, which is what an OTA // Quick Launch reads the entry live and shows nothing but the button.
// update writes to, and it costs nothing extra: the classroom already var parentCall = panel.addWidget("org.kde.plasma.quicklaunch");
// runs one for the applications.
var parentCall = panel.addWidget("org.kde.plasma.icontasks");
parentCall.currentConfigGroup = ["General"]; parentCall.currentConfigGroup = ["General"];
parentCall.writeConfig("launchers", "applications:ekklesia-parent-call.desktop"); // A file URL, not applications:. Quick Launch resolves the entry itself
parentCall.writeConfig("groupingStrategy", 0); // and does not copy it, so the path is a live reference to what the
parentCall.writeConfig("showOnlyCurrentDesktop", false); // package installs.
parentCall.writeConfig("showOnlyCurrentActivity", false); parentCall.writeConfig(
parentCall.writeConfig("showOnlyCurrentScreen", false); "launcherUrls",
parentCall.writeConfig("minimizeActiveTaskOnClick", false); "file:///usr/share/applications/ekklesia-parent-call.desktop"
parentCall.writeConfig("fill", false); );
parentCall.writeConfig("maxStripes", 1); parentCall.writeConfig("showLauncherNames", false);
parentCall.writeConfig("wheelEnabled", false); parentCall.writeConfig("enablePopup", false);
parentCall.writeConfig("showToolTips", true); parentCall.writeConfig("maxSectionCount", 1);
var leftGap = panel.addWidget("org.kde.plasma.panelspacer"); var leftGap = panel.addWidget("org.kde.plasma.panelspacer");
leftGap.currentConfigGroup = ["General"]; leftGap.currentConfigGroup = ["General"];
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 30 KiB

+6 -1
View File
@@ -4,7 +4,7 @@ Section: misc
Priority: optional Priority: optional
Architecture: amd64 Architecture: amd64
Maintainer: Ekklesia Maintainer: Ekklesia
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, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, gir1.2-gtklayershell-0.1, libnotify-bin, curl, gnupg, ca-certificates, python3-paho-mqtt Depends: plasma-desktop, plasma-workspace, kwin-wayland, plasma-nm, plasma-pa, plasma-widgets-addons, 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, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, gir1.2-gtklayershell-0.1, libnotify-bin, curl, gnupg, ca-certificates, python3-paho-mqtt
Recommends: vlc Recommends: vlc
Conflicts: plasma-welcome, plasma-discover, kdeconnect, kup-backup Conflicts: plasma-welcome, plasma-discover, kdeconnect, kup-backup
Description: Ekklesia managed classroom environment Description: Ekklesia managed classroom environment
@@ -14,6 +14,11 @@ Description: Ekklesia managed classroom environment
left here is the church's own subject matter — Wonder Ink, the browser, 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 DVD player, the printer, the audio policy and the updater.
. .
plasma-widgets-addons is here for one widget: Quick Launch, which is
the only stock way to put a single launcher on the panel that reads
/usr/share/applications live. The Icon widget copies the entry into the
user's home, so an update could never change it.
.
python3-gi and gtk-layer-shell are still here because the DVD player python3-gi and gtk-layer-shell are still here because the DVD player
draws its own loading cover and control bar as layer-shell surfaces. draws its own loading cover and control bar as layer-shell surfaces.
They are no longer here for a dock. They are no longer here for a dock.
+4
View File
@@ -88,3 +88,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get purge -y \
plasma-discover-backend-fwupd kdeconnect kup-backup \ plasma-discover-backend-fwupd kdeconnect kup-backup \
&& apt-get autoremove -y \ && apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Quick Launch, for the one auxiliary button on the panel.
RUN apt-get update && apt-get install -y --no-install-recommends plasma-widgets-addons \
&& rm -rf /var/lib/apt/lists/*
+3 -1
View File
@@ -97,7 +97,9 @@ ENV
sleep 4 sleep 4
# The room points at the loopback broker, never at the church's. # The room points at the loopback broker, never at the church's.
inlab python3 - <<'PY' # docker exec needs -i or the heredoc reaches nothing at all, which is
# how this silently left the room pointing nowhere.
docker exec -i "$NAME" python3 - <<'PY'
import pathlib import pathlib
p = pathlib.Path("/etc/ekklesia-classroom/device.conf") p = pathlib.Path("/etc/ekklesia-classroom/device.conf")
t = p.read_text() t = p.read_text()