diff --git a/docs/classroom-v2-experiment.md b/docs/classroom-v2-experiment.md index de40f93..1e861d6 100644 --- a/docs/classroom-v2-experiment.md +++ b/docs/classroom-v2-experiment.md @@ -351,9 +351,230 @@ leaves, so a room without a drive shows nothing and no room needs `DVD_ENABLED` edited. Nothing polls, and `classroom_optical`'s two-second loop goes away. **Not exercised** — the lab has no optical drive. + +## Parent Call + +The coordinator already existed and its contract is frozen. It was read +from `/home/media/docker/parent-call/README.md` and its source on the +control computer, not guessed, and nothing here changes it. + +### What the teacher does + +Click the mark on the left of the bar. A small card appears in the middle +of the screen, above whatever they were reading. It already knows the +room. They type a child's name and press **Call parent**. The card says +what happened, in the coordinator's own words, and closes itself four +seconds after a call is on its way. + +Four steps, one of which is typing a name. The room is never asked for: +this machine knows which room it is, and offering a list is a chance to +pick the wrong one. + +### The mark + +Three were put on a real panel and judged at the size the bar draws them. + +| tried | why it lost | +| --- | --- | +| a bell | sat inches from Plasma's own notification bell in the same bar | +| `call-outgoing`, a handset with an arrow | read as a telephone feature, not as fetching somebody | +| **an adult, a child, and one speech bubble** | kept | + +Breeze has people and it has telephones and the two never meet, so the +kept mark is drawn rather than picked — 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. `docs/screenshots/pc-icon-vs-notifications.png` +is it beside the notification bell. + +It is carried by **Quick Launch**, on the left, apart from the +applications. Two other widgets were tried first and both failed in ways +worth writing down: + +* the **Icon** widget copies the desktop entry into the user's home and + uses the copy, so an update can never change the icon or the command — + it kept showing a bell out of a package that no longer contained one; +* a **task manager** reads the entry live, which fixes that, but a task + manager also shows every running window, so the auxiliary corner filled + up with the lesson's tasks. + +### The states a teacher sees + +Every word comes back from the coordinator in the `message` field. The +classroom never composes one for a call, because the coordinator is the +only thing that knows what happened. + +| coordinator status | on screen | what the card does | +| --- | --- | --- | +| `submitted` | Sending | waits | +| `waiting_approval` | Waiting for approval | waits, amber | +| `sending` | Sending to sanctuary | waits | +| `sent_to_sanctuary` | Sent to sanctuary | green, closes after 4s | +| `rejected` | Not approved | red, offers Try again | +| `expired` | Expired before it was sent | red, offers Try again | +| `unavailable` | Parent Call is unavailable | red, no way to send | +| `error` | Could not reach the sanctuary | red, offers Try again | + +**Nothing says "displayed".** A ProPresenter call that succeeded means the +message was accepted, not that anyone saw it, and *Sent to sanctuary* is +the strongest claim the room is entitled to make. + +Before a name can be typed at all, the card reads the two retained topics +and refuses in four different ways: no broker (*Cannot reach the church +network*), no coordinator (*The sanctuary system is not running*), mode +`off` (*Parent Call is unavailable*, the coordinator's own wording), and +no retained mode at all (*Parent Call has not been set up yet*). A teacher +is never left believing a call went out. + +### How it is built + +``` +Quick Launch -> classroom-parent-call a separate process + | + +-- classroom_parent_call topics, payloads, states + +-- paho, one short-lived clean session +``` + +Not a Plasma applet. A broker library, a network timeout and a text entry +have no business inside the only way a teacher has of getting anywhere. +Measured: killing the card leaves the panel untouched, and clicking the +mark again starts a new one. + +Three properties the contract asks for and this keeps: + +* the status topic is subscribed **before** the request is published, so + an answer cannot arrive before anyone is listening; +* the session is **clean** and nothing is retained, so a call from last + Sunday cannot replay into this one; +* listening stops the moment a status is terminal. + +Bounded everywhere: 5s to reach the broker, 1.5s for retained state, 8s +for the coordinator's first answer, and 210s overall — its own +`REQUEST_TTL` is 180. Silence is reported as *No answer from the +sanctuary*, which is not the same as a refusal and is not shown as one. + +Sixty tests cover the contract with no broker at all +(`tests/test-classroom-parent-call.sh`). + +### Testing it without touching the sanctuary + +`tools/lab/parent-call-rig` runs the **real coordinator** — copied from +the control computer — against a broker on loopback and a ProPresenter +that is a mock, and it **rejects the church's own networks from inside +the container before it will start**. That guard is not a convention; the +rig exits if either address is still reachable. It was needed: +`10.40.0.2:1883` is reachable from this development host. + +Verified end to end on the packaged install: request accepted, queued, +approved by an operator, delivered as +`Name=Emma, Room=Nursery`, and *Sent to sanctuary* shown. Also `off`, +`rejected`, and the broker stopped. + + +## DVD + +### It is an application now + +DVD used to sit in the status row beside the clock, as though a disc were +a machine reading. It is in the row with Wonder Ink and the browser, with +Breeze's optical-disc mark, and Plasma gives it the same closed / running +/ active treatment as the others. + +`DVD_ENABLED` is gone. `classroom-desktop-layout` asks the machine for +`/dev/sr*` and removes the launcher from the layout on a room that has no +drive. A computer that moves between rooms takes its drive with it, and +nobody remembers to edit a file when it does. + +**Disc presence is not shown on the launcher.** Doing that needs either +polling or rewriting the panel while it runs, and rewriting the panel +while it runs was measured to destroy it. The launcher tracks the drive, +not the disc; a room with a drive and no disc gets a notification saying +so when it is pressed. + +### The panel is rebuilt from the package at every login + +Plasma keeps whatever panel it first built. An update could therefore +change the bar in the package and never change it in a room — which is +exactly what happened to an icon that outlived the file it came from. + +`classroom-desktop-reset` removes the panel configuration before +plasmashell starts, so the bar is built from the layout every time. The +desktop is stateless: there is nothing in a teacher's home an update +cannot reach, and a damaged panel is repaired by the next login. Nothing +is lost, because Kiosk policy means a teacher never had anything in that +file. + +Editing the live configuration instead was tried first and destroyed the +panel — the shell owns that file and rewrites it, so an edit races with +it. That is why this runs `Before=plasma-plasmashell.service`. + +### The last of sway + +The DVD player was the only thing still speaking a compositor the room no +longer runs. It asked sway's tree whether VLC's window had really gone +fullscreen, because VLC reports playing while its window is still the +black startup one the loading cover exists to hide. + +**VLC's own status was measured as a replacement and is not one.** It +reports `true` in the same 250ms poll as +`playing`, because the flag is the option it was started +with and not a report about its window. So the cover is held for a floor +(`MINIMUM_COVER_SECONDS`) and still capped by the deadline that was +already there, and the compositor is not asked anything at all. + +Focus-or-launch went the same way: the session already takes an exclusive +lock so a second one cannot start, and bringing an existing one to the +front is the panel's job. + +Gone with it: `classroom-window`, `classroom_sway.py`, and +`classroom_chrome.py`, which turned out to be reachable from nothing. +**One mention of sway remains in the whole tree**, and it is the upgrade +step in `postinst` that removes the sway-era login shell from a room +being upgraded. Nothing executes it, imports it, or asks it anything. + +Still unproven, and it is the same gap as before: playback end to end. +The lab has a drive with no readable disc and no libdvdcss, so VLC exits +on `--key-length=`. The loading cover, the control bar and the session's +own lifecycle all run; the picture does not. + + +## Audio: how to test it on the hardware + +Nothing below can be done in the lab: the container has no sound card, so +the policy is tested as a function and applying it is not tested at all. +`classroom-audio show` prints what it can see and what it would choose, +and changes nothing — start there. + +1. **Television on before the computer.** Boot with the TV on and an + input selected. Expected: sound comes out of the TV with nothing + touched. Check with `classroom-audio show`; the chosen port should be + an `hdmi-output-*`. +2. **Television off during boot, switched on afterwards.** Boot with the + TV off, wait for the desktop, then switch the TV on. Expected: within + a couple of seconds the output moves to HDMI by itself. This is the + case the room actually failed on, and the one worth watching. +3. **Browser already playing.** Start a YouTube video, then switch the TV + on or change the output. Expected: the sound follows **without + restarting Chrome**. That is the whole point of moving existing + streams; if Chrome still has to be restarted, the policy is not doing + its job and `journalctl --user -u ekklesia-classroom-audio` will say + how many streams it moved. +4. **Unplug and replug HDMI** while something is playing. Expected: falls + back, then returns. +5. **VLC already playing**, same as 3. +6. **Overrides.** `AUDIO_OUTPUT=analog` in + `/etc/ekklesia-classroom/device.conf`, restart the user service, and + confirm it obeys even with the TV on. Then `hdmi`, then back to + `auto`. + +What to capture if something is wrong: `classroom-audio show`, +`pactl list cards short`, `pactl list sinks short`, and the service +journal. The decision is a pure function, so a bad choice can be +reproduced as a test case from what those print. + ## Custom code this deletes -Deleted on this branch, and counted rather than estimated: +Deleted on this branch across both milestones, and counted rather than +estimated: | | lines | replaced by | | --- | --- | --- | @@ -367,7 +588,12 @@ Deleted on this branch, and counted rather than estimated: | `config/waybar/*` | 55 | the Plasma panel | | `config/bash_profile`, getty autologin | 6 | SDDM | | `config/icons/browser.svg` | — | Chrome's own icon | -| **total** | **1 695** | | +| `scripts/classroom-window` | 208 | the panel, and a lock the DVD session already took | +| `lib/classroom_sway.py` | 127 | — | +| `lib/classroom_chrome.py` | 66 | nothing: it was reachable from nowhere | +| `tests/test-classroom-window.sh` | 214 | — | +| `config/icons/*` (dock set) | — | Breeze, and two marks the classroom draws | +| **total** | **≈ 2 310** | | Rewritten rather than deleted: `classroom-browser` (41 → 30 lines, it no longer decides launch-or-focus-or-minimise), `classroom-scale` (sway output @@ -375,11 +601,16 @@ scale → `kscreen-doctor`), `classroom-notify` (found the session by looking for sway and refused to run without mako; now looks for the compositor and the shell). -**Still present, and still sway-shaped.** `classroom-window`, -`classroom_sway.py`, `classroom_icons.py`, `classroom_style.py` and -`classroom_optical.py` are all reachable only from the DVD player and the -MQTT notifier, and they were deliberately not rewritten — see *the DVD -player* under unresolved risks. Another ~590 lines go when that is done. +**Nothing in the classroom speaks to a compositor any more.** +`classroom_icons.py`, +`classroom_style.py` and `classroom_optical.py` remain, reachable only +from the DVD player and the MQTT notifier: the DVD overlay draws its own +layer-shell surfaces and still needs the icon and stylesheet helpers the +dock shared, and disc detection is still ours. + +Added since: the audio policy and its tests, the theme switch, Parent +Call and its contract module, the layout tailor, the panel reset, and +configuration. Kept because they are the classroom's own subject matter: the DVD session and CSS setup, printer setup, provisioning, MQTT, the updater, shutdown. @@ -418,6 +649,24 @@ is the most useful negative result in this document. has no app mode, which is what makes Wonder Ink an application; Debian's Chromium ships no Widevine. Chrome is what Wonder Ink is known to work in. + +### Recovery, measured against the package + +`tools/lab/recovery-check`, run after `tools/lab/from-package`, against +the lab exactly as the `.deb` built it: + +| | | +| --- | --- | +| panel, 8 × SIGKILL one second apart | back every time, 2.2–2.5s | +| compositor, 2 × SIGKILL | back in 0.1s | +| audio policy, 3 × SIGKILL | active every time | +| Parent Call killed | panel untouched | +| browser killed | panel untouched | +| afterwards | panel, compositor, 10 applets, audio all standing | + +The drop-in that makes the panel restart unconditional is in the package, +not only in a hand-edited session: `/etc/systemd/user/plasma-plasmashell.service.d/`. + ## Reliability results | test | result | @@ -488,33 +737,109 @@ record failures rather than successes. connectivity for it. Online, connecting and offline transitions need a machine whose network NetworkManager actually owns. + +## Television control, and where CEC will fit + +The devices arrive today. **Nothing here guesses at their protocol** and +no CEC code has been written. + +What the architecture needs to leave room for: the volume control in the +bar today is the *computer's* volume, and once the television is under +CEC control that is the wrong thing for a teacher to be adjusting. The +teacher should be turning the television up, not the computer. + +The shape that keeps Plasma out of the hardware: + +``` +panel button / notification presentation only + | + v +ekklesia-classroom-tv.service a small supervised user service + | the same shape as the audio policy + +-- backend: CEC over the adapter + +-- interface: on, off, volume up, volume down, mute, input +``` + +Three properties to hold to: + +* **Plasma is presentation.** The panel may show state and send an + action; it must not contain the protocol. That is why the audio policy + is a service and not a plasmoid, and this should follow it. +* **The interface is verbs, not device commands.** "Volume up" is the + contract; whether that is a CEC user-control-pressed opcode or + something else is the backend's business. +* **Supervised and failure-tolerant.** A television that is off, an + adapter that is unplugged, or a set that ignores CEC must degrade to + nothing happening, never to a stuck classroom. + +When the hardware has been exercised, the computer volume applet comes +out of the bar and a television control goes in. Until then it stays, +because a room with no sound control at all is worse. + + +## Live View, and whether this desktop can carry it + +Not implemented. What the KDE architecture already provides for it: + +* **A small status widget on the idle desktop.** A Plasma applet, or — + preferring less custom desktop code — a notification when the sanctuary + goes live plus a launcher in the bar. +* **A preview that expands.** A separate application window, not + something embedded in the panel. The panel may launch it and show that + something is live; it must not be the player. +* **Pin above other applications.** This is KWin's *Keep Above*, which is + already a window state with a title-bar button, and a window rule can + force it for the preview's class. Nothing has to be invented, which was + the open question when this experiment started. +* **Unpin returns it to normal stacking.** The same button. + +The likely media path (MediaMTX, WHEP) is a property of the player +application and does not touch the desktop architecture. + ## Unresolved risks In the order I would worry about them. -1. **The DVD player is half-ported.** Its surfaces and its disc detection - work; its window focusing still speaks sway and silently does nothing. - A room that uses DVDs should not take this build until that is finished - and a real disc has been played. -2. **SDDM is configured and untested.** It cannot be exercised in a +1. **DVD playback has never run end to end on this desktop.** The port off + sway is done and nothing asks a compositor anything, but the lab has a + drive with no readable disc and no libdvdcss, so VLC exits before a + picture. A room that uses DVDs should not take this build until a real + disc has played, the cover has dropped at the right moment, and eject + has returned cleanly to the desktop. +2. **The loading cover is now timed, not observed.** It used to wait for + the window manager to confirm VLC was fullscreen. It waits for a floor + instead, because VLC's own fullscreen flag was measured to be the + option it was given rather than a report about its window. On real + hardware the disc is far slower than the floor, so this should not + show — but if the cover ever drops onto a black VLC window, this is + why, and the fix is to raise `MINIMUM_COVER_SECONDS`. +3. **Parent Call has never had a real key pressed into it.** Keyboard + injection cannot reach the nested session in this lab at all — the + same limit that stopped it reaching Chrome — and the one tool that + tries disturbs the session enough to close the card. The name was + typed through a lab-only `--child` argument. **Type a name on the + bench before a Sunday.** +4. **SDDM is configured and untested.** It cannot be exercised in a container, and it is the thing that starts the session. If the config is wrong the room boots to nothing. This is the first thing to check on a VM or a bench machine, and it is why the checklist below starts there. -3. **No real audio hardware has been through the policy.** The decision is +5. **No real audio hardware has been through the policy.** The decision is well tested; applying it is not. A wrong `pactl set-card-profile` on real hardware is a silent room. -4. **Plasma is a much larger surface than sway.** More code, more services, +6. **Plasma is a much larger surface than sway.** More code, more services, more that can regress in a Debian point release. The mitigations are that all of it is supervised, that Debian 13 is frozen apart from security updates, and that the OTA channel structure already lets a build be held back. But it is a real trade and it should be named. -5. **Performance is unmeasured on classroom hardware.** Everything here ran +7. **Performance is unmeasured on classroom hardware.** Everything here ran on llvmpipe, which says nothing useful about an old office machine with Intel graphics. Plasma with compositing is heavier than sway. -6. **Chrome remains a third-party repository.** Unchanged from today, but +8. **Chrome remains a third-party repository.** Unchanged from today, but still the one part of the stack Debian does not update. -7. **The wallpaper is a stand-in.** The real illustration has not been seen - against this palette. +9. **The wallpaper is a stand-in.** The real illustration has not been seen + against this palette, and is to be supplied separately. +10. **The disc launcher tracks the drive, not the disc.** A room with a + drive shows the DVD button whether or not anything is in it. ## Would I trust it on a classroom computer, unattended, for a Sunday? @@ -534,10 +859,14 @@ Before any room: 1. Boot a bench machine from the package and confirm SDDM autologins, and that killing the session brings it back rather than a shell. 2. Put a television on HDMI, switch it on after the computer, and confirm - sound arrives without touching anything, with the browser already open. -3. Print to Elmer. -4. Play a DVD, if that room uses them. -5. Leave it running from Friday to Sunday. + sound arrives without touching anything, with the browser already + open. The full procedure is under *Audio: how to test it on the + hardware*. +3. Press Parent Call and **type a name with a real keyboard**. Then do it + with the coordinator's mode off, and with the broker stopped. +4. Print to Elmer. +5. Play a DVD, if that room uses them: cover, picture, controls, eject. +6. Leave it running from Friday to Sunday. ## Alternate operating systems @@ -572,16 +901,31 @@ The existing Debian classroom test VM should be kept. both fixed. * `tools/lab/from-package` run: fresh machine, `.deb`, session up, both applications launched, one button each. +* **Parent Call built** against the coordinator's own frozen contract, + and proven end to end on a rig that rejects the church's networks + before it starts. +* **Parent Call's mark** replaced twice and judged on a real panel. +* **The last of sway removed**: the DVD player asks no compositor + anything, and `classroom-window`, `classroom_sway` and + `classroom_chrome` are gone. +* **DVD moved out of the status row** into the applications, and the + launcher now follows the machine's drive rather than `DVD_ENABLED`. +* **The panel is rebuilt from the package at every login**, so an update + can reach a room that has already run. +* **Recovery re-measured against the packaged build**, not a hand-edited + session. **Next**, in order: -1. Port `classroom-window` off sway so the DVD player is whole. It is the - last thing on this branch that still speaks a compositor the classroom - no longer runs. +1. **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. 2. Publish `0.1.45~plasma1` to a channel of its own, the way the Hyprland milestone did, so a stable or canary room can never be offered it. 3. Bench-test SDDM: autologin, and that ending the session brings the classroom back rather than a shell. -4. On real hardware: a DVD, a television switched on after the computer, - printing to Elmer, display scaling at 1.25 and 1.5, and a weekend of - uptime. +4. 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*. +5. Live View, when the rest is quiet. diff --git a/docs/screenshots/README.md b/docs/screenshots/README.md index de7587f..2d9274d 100644 --- a/docs/screenshots/README.md +++ b/docs/screenshots/README.md @@ -25,6 +25,30 @@ container lab. See [../classroom-v2-experiment.md](../classroom-v2-experiment.md | `v2-both-apps` | both applications, one button each, from the packaged install | | `labelled-tasks` | the labelled task manager, evaluated and rejected: it shows changing page titles rather than application names | +## Parent Call + +| | | +| --- | --- | +| `pc-icon-vs-notifications` | the Parent Call mark beside Plasma's notification bell — the comparison that decided it | +| `pc-mark` | the mark at 32, 48 and 64px, beside the two marks it replaced | +| `pc-panel` | the whole bar: Parent Call left, applications centre, status right | +| `pc-ready` | the card, ready, in approval mode | +| `pc-waiting` | waiting for a volunteer to approve | +| `pc-sent` | *Sent to sanctuary* — never "displayed" | +| `pc-rejected` | not approved, offering Try again | +| `pc-off` | the coordinator's mode is off | +| `pc-nobroker` | the broker is unreachable | +| `pc-typed` | a name in the field | +| `icon-candidates-2` | sixteen Breeze person icons at real panel size, none of which meant Parent Call | + +## DVD + +| | | +| --- | --- | +| `dvd-panel` | DVD in the row with the applications, out of the status area | +| `dvd-cover` | the DVD launcher's tooltip on the packaged install | +| `v2-dvd-overlay`, `v2-layershell` | the loading cover: a gtk-layer-shell overlay under KWin | + ## Windows | | | @@ -50,5 +74,5 @@ container lab. See [../classroom-v2-experiment.md](../classroom-v2-experiment.md | | | | --- | --- | -| `wtype-probe` | keyboard injection never reached the nested session, so every interaction in this experiment was driven by the pointer instead | +| — | keyboard injection never reached the nested session, so every interaction in this experiment was driven by the pointer. It is why Parent Call has never had a real key pressed into it, and why that is the first bench test. | | `m-closed`, `m-minimized` | the pair whose pixels were sampled to show that Plasma draws minimised and closed differently, but minimised and *behind* the same | diff --git a/docs/screenshots/dvd-click.png b/docs/screenshots/dvd-click.png deleted file mode 100644 index 7a5f576..0000000 Binary files a/docs/screenshots/dvd-click.png and /dev/null differ diff --git a/docs/screenshots/dvd-live.png b/docs/screenshots/dvd-live.png deleted file mode 100644 index ea4e5f9..0000000 Binary files a/docs/screenshots/dvd-live.png and /dev/null differ diff --git a/docs/screenshots/icon-candidates.png b/docs/screenshots/icon-candidates.png deleted file mode 100644 index bd693c5..0000000 Binary files a/docs/screenshots/icon-candidates.png and /dev/null differ diff --git a/docs/screenshots/page-state.png b/docs/screenshots/page-state.png deleted file mode 100644 index e49bdd1..0000000 Binary files a/docs/screenshots/page-state.png and /dev/null differ diff --git a/docs/screenshots/pc-crop.png b/docs/screenshots/pc-crop.png deleted file mode 100644 index f97325b..0000000 Binary files a/docs/screenshots/pc-crop.png and /dev/null differ diff --git a/docs/screenshots/pc-not-set-up.png b/docs/screenshots/pc-not-set-up.png deleted file mode 100644 index 0bce018..0000000 Binary files a/docs/screenshots/pc-not-set-up.png and /dev/null differ diff --git a/docs/screenshots/pc-panel-left.png b/docs/screenshots/pc-panel-left.png deleted file mode 100644 index 5851a2a..0000000 Binary files a/docs/screenshots/pc-panel-left.png and /dev/null differ diff --git a/docs/screenshots/pc-panel.png b/docs/screenshots/pc-panel.png index 703440a..4d87289 100644 Binary files a/docs/screenshots/pc-panel.png and b/docs/screenshots/pc-panel.png differ diff --git a/docs/screenshots/pc-state.png b/docs/screenshots/pc-state.png deleted file mode 100644 index 78d759c..0000000 Binary files a/docs/screenshots/pc-state.png and /dev/null differ diff --git a/docs/screenshots/pd.png b/docs/screenshots/pd.png deleted file mode 100644 index 718f7d9..0000000 Binary files a/docs/screenshots/pd.png and /dev/null differ diff --git a/docs/screenshots/v2-dark-bar.png b/docs/screenshots/v2-dark-bar.png index 2118a6e..c5f342c 100644 Binary files a/docs/screenshots/v2-dark-bar.png and b/docs/screenshots/v2-dark-bar.png differ diff --git a/docs/screenshots/v2-idle-desktop.png b/docs/screenshots/v2-idle-desktop.png index 6497c15..51ada94 100644 Binary files a/docs/screenshots/v2-idle-desktop.png and b/docs/screenshots/v2-idle-desktop.png differ diff --git a/docs/screenshots/wtype-probe.png b/docs/screenshots/wtype-probe.png deleted file mode 100644 index b3b1af1..0000000 Binary files a/docs/screenshots/wtype-probe.png and /dev/null differ diff --git a/lib/classroom_config.py b/lib/classroom_config.py index 0c77d7b..7c523b8 100644 --- a/lib/classroom_config.py +++ b/lib/classroom_config.py @@ -172,9 +172,10 @@ def ui_scale(config): # The scale the classroom's own GTK surfaces render at. # -# UI_SCALE is applied by sway to the whole output (see classroom-scale), +# UI_SCALE is applied to the whole output (see classroom-scale), # which scales Chrome, VLC and every other application along with the -# dock. Our surfaces are measured in the same logical pixels sway is +# panel. Our surfaces are measured in the same logical pixels the +# compositor is # already scaling, so scaling them here as well would apply UI_SCALE # twice and the dock would come out half again too big. # diff --git a/lib/classroom_icons.py b/lib/classroom_icons.py index 9fee007..ac203ad 100644 --- a/lib/classroom_icons.py +++ b/lib/classroom_icons.py @@ -1,13 +1,14 @@ """Icons that stay sharp when the compositor scales the session. new_from_file_at_scale rasterises an SVG at its *logical* size. Under -sway's output scaling the compositor then enlarges that finished raster, +output scaling the compositor then enlarges that finished raster, which is why icons went soft while the clock text and the dock surface stayed crisp: those are drawn by GTK at the display's real pixel density, and the icon was not. -GTK 3 has no fractional scaling, so sway advertises the ceiling integer -scale and scales the finished buffer down. Measured under sway: scale +GTK 3 has no fractional scaling, so the compositor advertises the ceiling +integer +scale and scales the finished buffer down. Measured: scale factor 1 at output scale 1.0, and 2 at 1.25, 1.5 and 2.0. So the fix is to rasterise at size * scale_factor physical pixels and diff --git a/lib/classroom_vlc.py b/lib/classroom_vlc.py index 0eac03f..8334d19 100644 --- a/lib/classroom_vlc.py +++ b/lib/classroom_vlc.py @@ -65,7 +65,8 @@ CLASSROOM_HOTKEYS = { # VLC dressed down to a playback surface. Verified against 3.0.23. PRESENTATION = ( - # DVD mode is the whole display, and sway fullscreens the window the + # DVD mode is the whole display, and the compositor fullscreens the + # window the # moment it maps so no wallpaper is ever visible around it. "--fullscreen", # No menu bar, no panels, dark rather than light grey. diff --git a/scripts/classroom-dvd-session b/scripts/classroom-dvd-session index 118c605..522c06b 100755 --- a/scripts/classroom-dvd-session +++ b/scripts/classroom-dvd-session @@ -79,8 +79,9 @@ LEAVE_HIDE_SECONDS = 1 # How long the cover stays up at the very least. # -# This replaced a query to the window manager. Under sway the session -# walked the tree until VLC's window was really fullscreen, because VLC +# This replaced a query to the window manager. The session used to walk +# the compositor's tree until VLC's window was really fullscreen, because +# VLC # reports playing while its window is still the ordinary one — the black # startup window the cover exists to hide. #