feat: give every room the broker, one scale, and its own panel back
Little Waders took the Plasma build and reported what a container cannot. A disc player on a machine with no optical drive, a clock nobody at the back of the room could read, a browser at half the size of the panel around it, and Parent Call with no broker to call. The broker is the same for every classroom, so it is a default now and not something to fill in room by room. classroom-migrate brings an existing room to the same place without touching its name, its username or its password, and Parent Call distinguishes a broker it cannot reach from one that was never set up: those send somebody to look at completely different things. The disc player's detection was right and ran too late — alongside the session rather than before it, and the panel is built from the layout the moment a session starts. It runs before the display manager now, and again from udev when a drive is plugged in. UI_SCALE had a ceiling of 1.5, which cannot express a 4K television; a clock pinned at 15 points, which is the same size at every scale; and a browser that was never told the number at all. All three are fixed and the room doubles together at 200%. This also brings 0.1.47's work into the repository, where it had only ever existed in a build directory under /tmp: the hidden display dialog, its authenticated writer, the polkit action, and the church's own wallpaper. One piece of it is deliberately left out. The custom volume display needed a shell package of our own, and with one selected plasmashell builds no panel at all — measured twice, with that build's own files, on a classroom that deletes its panel configuration at every login by design. The lab connected to the real church broker the moment the package defaulted to it. Nothing was left behind, which was checked, but the guard that should have stopped it had never worked: it used iptables, which the lab image does not have, and probed with /dev/tcp under dash, where that always fails. Both reported success. Co-Authored-By: Claude Opus 5 <[email protected]>
@@ -1096,6 +1096,111 @@ Measured: `classroom-theme light`, log out, and the bar came back dark.
|
||||
The rule is now whose the defaults are: the classroom's are kept, another
|
||||
desktop's are removed.
|
||||
|
||||
## The rooms themselves: 0.1.48
|
||||
|
||||
The first real classroom, Little Waders, took the Plasma build and then
|
||||
reported what a lab cannot: a disc player on a machine with no drive, a
|
||||
clock nobody could read, a browser at half the size of the panel around
|
||||
it, and Parent Call with no broker to call.
|
||||
|
||||
### The broker every room shares
|
||||
|
||||
There is one, at 10.40.0.2, and every classroom uses it. It is a default
|
||||
now rather than something to fill in room by room: a fresh machine is
|
||||
pointed at it, and `classroom-migrate` brings an existing one to the same
|
||||
place — switched on if it was off, addressed if it was blank, and left
|
||||
exactly as it is if somebody deliberately pointed it elsewhere. The room
|
||||
name, the username and the password are read by none of it and printed by
|
||||
none of it, which `tests/test-classroom-migrate-config.sh` checks against
|
||||
the real migration code rather than a copy of it.
|
||||
|
||||
The link restarts on `always` rather than `on-failure`, because it exits
|
||||
cleanly when it finds no broker configured and a machine set up before
|
||||
the church had one would otherwise never pick it up.
|
||||
|
||||
Parent Call now says which of the two problems a teacher has. "Cannot
|
||||
reach the church network" and "This room has no church network set up"
|
||||
send somebody to look at completely different things, and saying the
|
||||
first when the truth is the second costs an hour at a router.
|
||||
|
||||
### A disc player on a machine with no drive
|
||||
|
||||
The detection was right and it ran too late. `classroom-provision` runs at
|
||||
boot *alongside* the session rather than before it, and the panel is built
|
||||
from the layout the moment a session starts: a room told about its own
|
||||
hardware afterwards keeps the wrong bar until the next login.
|
||||
`ekklesia-classroom-layout.service` runs it before the display manager
|
||||
instead, a udev rule re-runs it when a drive is plugged in or pulled out,
|
||||
and the login says so in the journal when the layout and the hardware
|
||||
disagree. Measured in a mount namespace with no `/dev/sr*`: the launcher
|
||||
is removed and the rebuilt panel has ten applets and no disc.
|
||||
|
||||
### One scale, and everything that was not following it
|
||||
|
||||
`UI_SCALE` had been packaged, clamped, documented — and applied by an
|
||||
autostart entry that only appeared in 0.1.47. Three things were still
|
||||
outside it:
|
||||
|
||||
* **The ceiling was 1.5.** A 4K television wants 2.0, so a room asking for
|
||||
it silently got 1.5. It is 3.0 now, and the hidden display dialog
|
||||
offers up to it.
|
||||
* **The clock was pinned at 15 points**, which is the same size at every
|
||||
scale. It is sized by the bar now, which follows the scale like
|
||||
everything else.
|
||||
* **Chrome was not told.** On Wayland it did not follow the compositor's
|
||||
output scale, so the browser was half the size of the panel around it.
|
||||
Both launchers pass `--force-device-scale-factor`, from the one command
|
||||
that owns the number.
|
||||
|
||||
Measured at 200% in the lab: the panel, the clock, the notification card,
|
||||
Chrome's tab strip and the page itself all doubled together.
|
||||
|
||||
### The notification card
|
||||
|
||||
A Plasma style, which is the supported way and the reason no QML was
|
||||
replaced. A style is a set of pictures and anything the classroom does not
|
||||
provide comes from Breeze, so the worst this can do is look wrong — never
|
||||
fail to appear. Replacing the notification plasmoid's QML was the other
|
||||
route and a QML error there is a room with no notifications at all.
|
||||
|
||||
Web pages are blocked from notifying at the policy level, with no prompt:
|
||||
a permission dialog in a classroom is a dialog a child can agree to.
|
||||
|
||||
### The volume display, and a shell package that costs the panel
|
||||
|
||||
The 0.1.47 build replaced Plasma's on-screen volume display with its own,
|
||||
through a shell package of its own. Plasma 6.3 does read the display from
|
||||
there and from nowhere else — the look and feel is not consulted, which
|
||||
was measured — so the mechanism was right.
|
||||
|
||||
**With that shell package selected, plasmashell builds no panel at all.**
|
||||
Not ours, not the stock one. Measured twice, with the 0.1.47 package's own
|
||||
files. The classroom deletes its panel configuration at every login on
|
||||
purpose, so every login was one step away from a television showing a
|
||||
wallpaper and nothing else.
|
||||
|
||||
So it is gone, and the volume display is Plasma's own. It is drawn at the
|
||||
room's scale like everything else, which is what the television actually
|
||||
needed. `classroom-desktop-reset` also strips a `ShellPackage` line out of
|
||||
a profile written while the old build was installed.
|
||||
|
||||
The chime stays off, in `plasmaparc`, which is the file Plasma 6 actually
|
||||
reads for it.
|
||||
|
||||
### What the lab was allowed to reach
|
||||
|
||||
Pointing the package at the real broker had an immediate consequence: the
|
||||
lab connected to it, under a container id, as a room. Nothing was left
|
||||
behind — the broker held no retained status for it afterwards, which was
|
||||
checked — but the lab had no business being there.
|
||||
|
||||
`tools/lab/lab up` now blackholes both church networks before anything
|
||||
starts, and refuses to continue if either is still reachable. The rig had
|
||||
carried a guard for this since it was written and it had never once
|
||||
worked: it used `iptables`, which is not installed in the lab image, and
|
||||
it probed with `/dev/tcp` under `sh`, which is a bash feature and fails
|
||||
under dash whatever the network is doing. Both were reported as success.
|
||||
|
||||
## Unresolved risks
|
||||
|
||||
In the order I would worry about them.
|
||||
@@ -1160,7 +1265,17 @@ In the order I would worry about them.
|
||||
take it back, and nothing is published there. Until it is, a v2
|
||||
machine takes no updates at all. That is deliberate; it is also a
|
||||
thing to remember before leaving one in a room.
|
||||
15. **Ctrl+Alt+T is still registered.** Konsole's own entry declares it
|
||||
15. **Nothing in this pass has been on the classroom machines.** The
|
||||
development host has no route to Little Waders — its SSH refuses this
|
||||
machine's key, and the control computer cannot reach it either — so
|
||||
every result above is the lab's. The package is built and the deploy
|
||||
commands are written down; the room itself is unverified.
|
||||
16. **The v2 channel still has no manifest.** `update_classroom_v2.sh`
|
||||
exists now and has not been run. Until it is, a v2 room takes no
|
||||
updates at all, and `classroom-migrate` moves every upgraded machine
|
||||
onto that channel — deliberately, because stable and canary would
|
||||
both hand a Plasma room the sway build back.
|
||||
17. **Ctrl+Alt+T is still registered.** Konsole's own entry declares it
|
||||
and the registration survives being shadowed. It is inert, because
|
||||
Konsole refuses to open a shell under the classroom's
|
||||
`shell_access=false` — measured — but it rests on that one
|
||||
@@ -1260,29 +1375,44 @@ The existing Debian classroom test VM should be kept.
|
||||
session's configuration path by hand, it restarts the machine, and it
|
||||
asks a fresh install and a machine upgraded from the Hyprland
|
||||
experiment the same sixty questions. Both answer them identically.
|
||||
* **0.1.47's work brought into the repository**, where it had only ever
|
||||
existed in a build directory: the hidden display dialog behind
|
||||
Meta+Ctrl+Alt+Shift+D, its authenticated writer, the polkit action, the
|
||||
autostart entry that applies the scale, and the church's own wallpaper.
|
||||
* **The broker given to every room**, the disc player decided before the
|
||||
session starts, the clock and the browser brought under the one scale,
|
||||
the notification card given a Plasma style of its own, and the shell
|
||||
package that cost the panel taken back out — 0.1.48.
|
||||
|
||||
**Next**, in order:
|
||||
|
||||
0. **The thirty-second Escape test**, before anything is built on the
|
||||
0. **Deploy 0.1.48 to Little Waders and run the list.** Everything in
|
||||
*The rooms themselves* is lab work: the development host cannot reach
|
||||
the classroom machines at all. The deploy and rollback commands are in
|
||||
the report that accompanies this build, and the checks that matter are
|
||||
the panel after a reboot, the clock and the browser at the room's
|
||||
scale, Parent Call with a typed name, the broker, HDMI audio and the
|
||||
volume keys.
|
||||
1. **The thirty-second Escape test**, before anything is built on the
|
||||
gesture: bind a probe entry to `Escape`, press it in a fullscreen
|
||||
video, and see whether the video leaves fullscreen. That settles the
|
||||
one thing this pass could not measure.
|
||||
1. **On the bench, tonight.** Type a name into Parent Call with a real
|
||||
2. **On the bench, tonight.** Type a name into Parent Call with a real
|
||||
keyboard. Switch a television on after the computer and listen. Play a
|
||||
disc. These three are the only things left that a container cannot
|
||||
answer, and each of them is a Sunday-morning path. Add the power
|
||||
button and the maintenance chord to that list.
|
||||
2. Publish the v2 channel. `classroom-migrate` already moves a migrated
|
||||
3. Publish the v2 channel. `classroom-migrate` already moves a migrated
|
||||
room onto `CHANNEL=classroom-v2`, and nothing serves that manifest
|
||||
yet, so those machines are taking no updates at all. This is now the
|
||||
first packaging job rather than a tidy-up.
|
||||
3. Take the upgraded VM through the same list by hand:
|
||||
4. Take the upgraded VM through the same list by hand:
|
||||
`tools/lab/converged-check` is the shape of it, and the things a
|
||||
container cannot answer are the lock screen never appearing after an
|
||||
hour alone, and the machine still being there on Monday.
|
||||
4. Bench-test SDDM on hardware: autologin all the way to a picture, and
|
||||
5. Bench-test SDDM on hardware: autologin all the way to a picture, and
|
||||
that ending the session brings the classroom back rather than a shell.
|
||||
5. When the CEC adapters have been exercised, replace the computer volume
|
||||
6. When the CEC adapters have been exercised, replace the computer volume
|
||||
applet with a television control, behind the service boundary in
|
||||
*Television control, and where CEC will fit*.
|
||||
6. Live View, when the rest is quiet.
|
||||
7. Live View, when the rest is quiet.
|
||||
|
||||
@@ -87,6 +87,20 @@ container lab. See [../classroom-v2-experiment.md](../classroom-v2-experiment.md
|
||||
| `migration-parent-call` | Parent Call on the migrated machine, saying it cannot reach the church network rather than pretending it can |
|
||||
| `theme-light-live`, `theme-light-after-logout` | the room's own light theme, and the same room after logging out and back in. The first attempt at this pass lost it. |
|
||||
|
||||
## The rooms themselves
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| `v2-from-package` | the classroom with the church's own wallpaper and the real Wonder Ink mark |
|
||||
| `wonderink-icon` | the same mark as a running application's button |
|
||||
| `display-settings` | the hidden display-size dialog, saying that saving needs an administrator |
|
||||
| `scale-200`, `scale-200-notification`, `scale-200-chrome` | the room at 200%: the panel, a notification card, and the browser, all doubled together |
|
||||
| `notification-style` | the notification card on the classroom's own Plasma style |
|
||||
| `osd-volume` | Plasma's volume display, which the room keeps |
|
||||
| `osd-shellpackage` | the custom one, which rendered correctly and cost the panel |
|
||||
| `pc-unreachable`, `pc-not-configured` | Parent Call telling a broker it cannot reach from one that was never set up |
|
||||
| `dvd-absent-bar` | the bar on a machine with no optical drive |
|
||||
|
||||
## Failures, kept
|
||||
|
||||
| | |
|
||||
|
||||
|
After Width: | Height: | Size: 204 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 823 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 253 KiB After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 96 KiB |
@@ -1,106 +1,69 @@
|
||||
# UI scale
|
||||
# Classroom display size (Plasma v2)
|
||||
|
||||
Every classroom gets the same design at a size that suits its TV. A 32"
|
||||
panel a few feet from the children and a 65" set across a hall want
|
||||
different sizes of the same room, not different rooms.
|
||||
Each room keeps its own `UI_SCALE` in `/etc/ekklesia-classroom/device.conf`.
|
||||
Package upgrades preserve the value. Plasma applies it at every classroom login.
|
||||
Native display resolution is unchanged.
|
||||
|
||||
## Changing it
|
||||
## Administrator setting
|
||||
|
||||
Edit `/etc/ekklesia-classroom/device.conf` on that endpoint:
|
||||
On the classroom keyboard press **Meta+Ctrl+Alt+Shift+D** to open Display size.
|
||||
It is hidden from application lists and the teacher's panel. Saving requires
|
||||
administrator authentication through polkit; the keyboard shortcut grants no
|
||||
privilege. Choose a percentage and press Save and apply. Canceling the password
|
||||
prompt leaves the saved setting unchanged.
|
||||
|
||||
Start at **200% for a 4K TV**, which gives 1920×1080 logical space while retaining
|
||||
3840×2160 output. The offered values are 100, 125, 150, 175, 200, 225, 250 and 300%.
|
||||
The choice applies to all connected, enabled displays on that classroom computer.
|
||||
|
||||
For SSH administration, the fixed-purpose helper can also be run as root:
|
||||
|
||||
```
|
||||
UI_SCALE=1.25
|
||||
sudo /usr/local/bin/classroom-set-scale 2
|
||||
```
|
||||
|
||||
Then restart the classroom shell:
|
||||
It writes only UI_SCALE, preserving room configuration, broker credentials and
|
||||
file ownership and permissions. The new size takes effect at the next classroom
|
||||
login, or by running `classroom-scale` inside the classroom's graphical session.
|
||||
The hidden window saves and applies in one operation.
|
||||
|
||||
```
|
||||
sudo systemctl restart getty@tty1
|
||||
```
|
||||
## Implementation and validation limits
|
||||
|
||||
That ends the session and the autologin brings it straight back at the
|
||||
new size. A reboot does the same. Nothing else needs touching, and no
|
||||
CSS or source file is ever edited to change a room's size.
|
||||
`classroom-scale` uses `kscreen-doctor`; the login autostart runs only in KDE and
|
||||
the script applies only to the classroom account. Values read from older/manual
|
||||
configurations remain clamped to 0.8–3.0; invalid/nonfinite values become 1.0.
|
||||
The helper accepts only the window's predefined choices, takes no paths, and
|
||||
writes the root-owned settings file atomically. Polkit requires auth_admin for
|
||||
every save, with no retained authorization.
|
||||
|
||||
## What it scales
|
||||
Hardware checks required: shortcut registration, administrator authentication,
|
||||
200% at 4K, logout/reboot persistence, and Chrome/Parent Call/DVD sizing. XWayland
|
||||
applications may be softer than native Wayland applications when scaled.
|
||||
|
||||
**Everything.** UI_SCALE is a property of the television, not of one
|
||||
program, so it is applied where it reaches the whole session: sway's
|
||||
output scale.
|
||||
## Wallpaper in the v2 package
|
||||
|
||||
- Chrome's tabs, omnibox, toolbar icons and menus
|
||||
- VLC, and any other application's own interface
|
||||
- The dock, the clock, notifications and the DVD control bar
|
||||
- Mouse hit targets, because they scale with the widgets
|
||||
The approved background source is `config/wallpapers/classroom-calm.png`. The
|
||||
package installs it at `/usr/share/backgrounds/ekklesia/classroom-calm.png`, the
|
||||
path used by the packaged Plasma layout. The layout is rebuilt at login, so
|
||||
upgraded classrooms receive the package wallpaper without per-room copying.
|
||||
|
||||
The display mode is **not** changed. The panel stays at its native
|
||||
1920x1080. Only the logical coordinate space shrinks, which is what
|
||||
makes everything drawn in it larger:
|
||||
## What the one number reaches
|
||||
|
||||
| UI_SCALE | Logical space | Roughly |
|
||||
| --- | --- | --- |
|
||||
| 0.8 | 2400x1350 | Small or close-up panel |
|
||||
| 1.0 | 1920x1080 | Default. 32–50" classroom TV |
|
||||
| 1.25 | 1536x864 | Large room, or a set viewed from further back |
|
||||
| 1.5 | 1280x720 | 65"+ |
|
||||
`classroom-ui-scale` prints it, clamped, and everything that cannot read
|
||||
the display scale for itself asks that command rather than the file:
|
||||
|
||||
Anything outside 0.8–1.5 is clamped, and anything that is not a number
|
||||
falls back to 1.0, so a typo in device.conf cannot produce an unusable
|
||||
shell.
|
||||
* **Plasma** — the panel, the clock, notifications, the volume display and
|
||||
every dialog, because `classroom-scale` sets it as the display's scale
|
||||
through `kscreen-doctor` at every login.
|
||||
* **Chrome and Wonder Ink** — `--force-device-scale-factor`, because
|
||||
Chrome on Wayland was measured not to follow the compositor's output
|
||||
scale on its own. It is the same number, not a second scaling: Chrome
|
||||
replaces its detected scale with it.
|
||||
* **The disc player's own surfaces** — they are measured in the logical
|
||||
pixels the compositor is already scaling, so they follow without being
|
||||
told.
|
||||
|
||||
## Measured
|
||||
|
||||
Against 1920x1080 under sway, with Chrome 152:
|
||||
|
||||
| | 1.0 | 1.25 | 1.5 |
|
||||
| --- | --- | --- | --- |
|
||||
| Chrome tab strip | 40px | 49px (x1.23) | 59px (x1.48) |
|
||||
| sway title bar | 25px | 31px (x1.24) | 38px (x1.52) |
|
||||
| Classroom dock | 74px | 92px (x1.24) | 110px (x1.49) |
|
||||
|
||||
Everything scales once, together.
|
||||
|
||||
## Why our own surfaces do not scale themselves
|
||||
|
||||
`classroom-scale` runs first in the sway config and sets the output
|
||||
scale. From then on the dock, the notifications and the DVD control bar
|
||||
are measured in the same logical pixels sway is already scaling, so they
|
||||
must render **unscaled** — `SHELL_SCALE` in `classroom_config.py` is
|
||||
`1.0`. Scaling them again would apply UI_SCALE twice and the dock would
|
||||
come out half again too big.
|
||||
|
||||
The stylesheet templates still take a scale, and `SHELL_SCALE` is the
|
||||
one place it comes from. If compositor scaling ever has to be abandoned,
|
||||
setting it back to `ui_scale(config)` restores per-surface scaling
|
||||
without touching a template.
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
**GTK 3 has no fractional scaling.** At UI_SCALE=1.5 sway advertises an
|
||||
integer scale of 2 to GTK, which renders at 2x, and sway scales the
|
||||
result down to 1.5x. The dock is the right size but very slightly softer
|
||||
than at 1.0. On a TV at classroom distance this is not visible.
|
||||
|
||||
Icons have to be drawn for that themselves. `new_from_file_at_scale`
|
||||
rasterises an SVG at its *logical* size, and the compositor then
|
||||
enlarges that finished raster — which made icons visibly soft on a 24"
|
||||
monitor while the clock text beside them stayed sharp. `classroom_icons`
|
||||
renders each SVG at `size x scale_factor` physical pixels and hands GTK
|
||||
a cairo surface carrying that device scale, so the artwork lands at the
|
||||
display's real density and the layout is unchanged. Measured on the
|
||||
Chrome icon, peak edge contrast at UI_SCALE 1.5 went from 49 to 83 out
|
||||
of 255, and at 2.0 from 37 to 82; at 1.0 it is identical to before.
|
||||
|
||||
**XWayland is softer at fractional scale.** X11 clients have no concept
|
||||
of a fractional output scale, so sway renders them at the logical size
|
||||
and scales the buffer. Measured on terminal text, scale 1.5 produced
|
||||
about 50% more intermediate-tone pixels than scale 1.0 — real, modest
|
||||
softening.
|
||||
|
||||
VLC is the only XWayland application in the classroom, and in DVD mode
|
||||
none of its interface is on screen: only video, from a 720x480 disc
|
||||
being upscaled regardless. Chrome runs on Wayland natively and is sharp
|
||||
at every scale, which is what matters for reading.
|
||||
|
||||
At UI_SCALE=1.0 nothing is scaled at all and the session is identical to
|
||||
one with no scaling.
|
||||
The clock is the one thing that used to be left behind. It was pinned at
|
||||
15 points, which is the same 15 points at every scale, and on a 4K
|
||||
television it was a clock nobody at the back of the room could read. It
|
||||
is sized by the bar now.
|
||||
|
||||