The look of a seat¶
A seat opens a plain Xfce session. Out of the box it looks like Debian: two panels, a gradient wallpaper, the system font and icons. Pupitre gives it the look of PrimTux 9, the distribution the classroom already knows, without shipping a single byte of PrimTux.
The split: the configuration here, the themes there¶
Pupitre ships the configuration of the look, scripts/pupitre-apparence, installed as
/usr/lib/pupitre/pupitre-apparence and called by the seat.
The themes, icons and font are PrimTux's own packages, which are not in Debian. Install them once on the server:
sudo pupitre-themes-primtux
Three packages, 3.5 MB downloaded, about 13 MB installed, plus the 41 MB of primtux8-wallpapers
which is only ever a SOURCE: the mascot is cut out of it once, at installation, and the wallpaper
itself never reaches a screen. pupitre-themes-primtux --sans-fond skips that part. The four
profile packages, 85 to 150 MB each, are of no use to us at all.
None of this is needed for a seat to work. Without the packages every missing setting is
logged and the session keeps Xfce's own default for it. PUPITRE_APPARENCE=0 skips the whole
thing.
What is applied, and where it comes from¶
Taken from PrimTux 9's own profil-* packages:
| setting | value |
|---|---|
| GTK theme | Colloid-Light-Nord |
| window theme | Colloid-Dark-Nord, the light over dark mix is deliberate |
| icons | Colloid-light |
| font | Luciole 10, the one drawn for dyslexic children |
| cursor | Breeze_Snow, or Breeze_Light which is its name on Debian 13 |
| panel | one, at the bottom, 48 px, full width, locked |
| window buttons | O|SHMC, centered title |
| workspaces | 1 |
Two settings do not come from PrimTux but from our throughput budget:
- the backdrop is a flat
#ebeee7fill carrying PrimTux's mascot, not PrimTux's wallpaper. The wallpaper looks flat and is not: its dominant tint covers only 6.9 % of its pixels, the rest being a faint noisy gradient, and it costs 2 584 997 bytes of RLE per full screen. So the seat gets the tint, and the mascot cut out of that same wallpaper (see below); - compositing is off, shadows and transparency being gradients.
Subpixel rendering is off too (Xft/RGBA=none): it paints coloured fringes along every glyph
edge, which is exactly what a run length encoder cannot compress.
The panel carries Xfce's own top bar plugins, plus and minus what a classroom desk needs:
- launchers for Firefox, LibreOffice Writer and the file manager, so that a child reaches them without walking the menu. Only those actually installed are put in;
- no workspace pager, there is a single workspace;
- no "actions" plugin. It is the one showing the system account's name, and it offers Log out and Shut down: one click and a child kills the seat's whole session.
The desktop keeps the Home icon only: "Filesystem" leads a child into the server's innards, and the trash of a system account means nothing.
LibreOffice needs libreoffice-gtk3, a dependency of the package: without it, it falls back to
its own X11 rendering and looks like a 2005 application, ignoring both the theme and Luciole.
What it saves¶
One full 1280x1024 screen of a bare desktop, encoded by tools/rle_encode.py, only the appearance differing:
| desktop | RLE payload | compression | transfer at 3.7 MB/s |
|---|---|---|---|
PrimTux's own wallpaper leon-light.png |
2 584 997 B | 1.5:1 | 699 ms |
| Xfce default, gradient wallpaper | 465 317 B | 8.5:1 | 126 ms |
| PrimTux look, flat fill and mascot | 127 364 B | 30.9:1 | 34 ms |
| the same, bare fill without the mascot | 72 378 B | 54.3:1 | 20 ms |
The mascot doubles the cost of a full screen and still leaves it 3.7 times cheaper than Xfce's default and 20 times cheaper than PrimTux's own wallpaper, times thirteen seats. And it is only a full screen that costs that: afterwards the mascot never changes, so it is never sent again.
The mascot, and why it is not just a copy¶
The mascots are shipped as images nowhere: they are drawn into the profile wallpapers.
pupitre-themes-primtux cuts Léon out of leon-light.png at installation
time, with tools/fond_primtux.py: keep the saturated pixels, keep the biggest connected blob
among them, big enough to be a drawing rather than a stray line of the decor, paint everything
else with the exact tint, then place him above the panel in the bottom right corner. The result is written to
/var/lib/pupitre/fond-primtux.png, and the seat uses it if it is there.
That is what --sans-fond skips, and with it the 41 MB of primtux8-wallpapers. Nothing of
PrimTux is copied into pupitre's package: the cutting happens on the school's own server, from
the package PrimTux publishes.
The login screen¶
In PUPITRE_CONNEXION=eleves a seat opens on LightDM's lightdm-gtk-greeter, and
config/lightdm/50-pupitre-greeter.conf gives it the same look as the desktop: the backdrop
above, the Colloid theme and icons, Luciole 12, the Breeze cursor, and as default user picture
Léon's head, which fond_primtux.py --avatar cuts from the same blob as the backdrop and writes to
/var/lib/pupitre/avatar-primtux.png (128x128, on the tint, the greeter rounds it). The panel
keeps only accessibility and the clock: no server name, no session chooser, no power button.
The whole login screen costs 148 765 bytes of RLE (26.4:1),
the backdrop alone 127 364. Two limits of version 2.0.9: background is an image OR a colour,
so without fond-primtux.png the screen is black, not the tint; and at Luciole 12 (11 as well)
the password placeholder is cut to "Saisir votre mot de…", the entry's width being fixed.
The snippet is not limited to the seats: LightDM's greeter configuration is global, so a LightDM
greeter on the server's own console gets the same look, with no power button and no session
chooser there either (the console then offers only the default session), and a black background
if fond-primtux.png is absent.
How it is applied: before the session, not during¶
pupitre-apparence runs after Xvfb and before xfce4-session. It writes the four xfconf
channels (xsettings, xfwm4, xfce4-desktop, xfce4-panel) into
$XDG_CONFIG_HOME/xfce4/xfconf/xfce-perchannel-xml/, which the session reads as it starts.
The other way round, configuring the live session with xfconf-query, is not used: changing the panel's configuration means restarting the panel, a restarted panel
restarts its plugins, and the notification area plugin then died over and over until the panel put
its "plugin unexpectedly left the panel" dialog in the middle of the seat's screen. Writing before
the session has no such failure mode, and no race with the defaults each component writes on its
first start.
Two details to know:
/panelsis an array of panel numbers. Written as a plain integer, the panel can no longer read its own configuration and dies at once: the seat has no bar at all;colloid-icons-primtux8untars a.tar.xzin its postinst without declaringxz-utils. On a minimal Debian it fails silently and dpkg believes it installed while it laid down nothing.pupitre-themes-primtuxinstallsxz-utilsfirst, and checks at the end what is on disk rather than what dpkg believes.
Changing it¶
Everything is overridable from the seat's environment, without touching the script:
PUPITRE_GTK_THEME, PUPITRE_WM_THEME, PUPITRE_ICON_THEME, PUPITRE_CURSOR_THEME,
PUPITRE_FONT, PUPITRE_TITLE_FONT, PUPITRE_MONO_FONT, PUPITRE_PANEL_SIZE,
PUPITRE_PANEL_ICON_SIZE, PUPITRE_BG_RGBA (four doubles), PUPITRE_LANCEURS (a list of
.desktop names), PUPITRE_FOND_IMAGE (the backdrop, empty for the bare fill), and
PUPITRE_APPARENCE=0 for none of it.
A theme or a font named but absent is detected: the setting is left out and the reason logged. The
font is looked up with fc-match, which always answers something, so it counts as installed only
if the family it answers is the family asked for.