docs: the power button, the maintenance chord, and why long-Escape should change
Records what was measured this pass and, as importantly, what was not. KGlobalAccel will accept a bare Escape and its component carries both a pressed and a released signal, so hold-and-cancel is expressible. What could not be measured here is whether a global shortcut takes the key away from applications, because key injection cannot reach the nested session. The mechanism says it does — KWin matches shortcuts in an input filter ahead of the focused surface — which would cost the classroom every ordinary use of Escape. That is inference, and it is written down as inference, with the thirty-second bench test that settles it. The recommendation is to change the gesture rather than grab the key an appliance uses most: hold-to-confirm on an on-screen control, which is ordinary Qt inside our own surface, or a modifier chord like the one the maintenance terminal just proved. Either keeps the deliberate ceremony without an input daemon. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
30a924d945
commit
6050144e5d
+204
-43
@@ -746,45 +746,6 @@ record failures rather than successes.
|
||||
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:
|
||||
@@ -804,6 +765,178 @@ Not implemented. What the KDE architecture already provides for it:
|
||||
The likely media path (MediaMTX, WHEP) is a property of the player
|
||||
application and does not touch the desktop architecture.
|
||||
|
||||
|
||||
## The power button, and the way back in
|
||||
|
||||
### A press does nothing
|
||||
|
||||
Two layers, and both are needed. While a graphical session is running,
|
||||
PowerDevil takes logind's `handle-power-key` inhibitor and acts on the
|
||||
button itself, so a logind drop-in on its own would be overruled.
|
||||
|
||||
| layer | file | what it says |
|
||||
| --- | --- | --- |
|
||||
| logind | `/etc/systemd/logind.conf.d/ekklesia-classroom.conf` | `HandlePowerKey`, `HandleSuspendKey`, `HandleHibernateKey`, `HandleRebootKey` and every lid switch set to `ignore`, long-press included |
|
||||
| PowerDevil | `/etc/ekklesia-classroom/xdg/powermanagementprofilesrc` | `powerButtonAction=0` and `lidAction=0` in all three profiles, groups marked `[$i]` so the session cannot put an action back |
|
||||
|
||||
logind covers the machine before the session starts, after it ends, and
|
||||
if PowerDevil is not running at all. PowerDevil covers it while a teacher
|
||||
is using it.
|
||||
|
||||
Measured in the lab: with the drop-in installed and logind reloaded,
|
||||
logind reports `ignore` for the power, suspend, hibernate and lid keys —
|
||||
it reported `poweroff` and `suspend` before — and the running graphical
|
||||
session was not disturbed by the reload. The `postinst` therefore
|
||||
reloads logind, so the button stops working at install time rather than
|
||||
at the next boot.
|
||||
|
||||
**Holding the button still cuts the power.** That is firmware, below any
|
||||
operating system, and it is left alone on purpose: it is the only
|
||||
recovery a person standing at a wedged machine has.
|
||||
|
||||
**Needs the hardware.** Nothing in a container has a power button. What
|
||||
is proven is that both layers are configured, packaged, and read back
|
||||
the way they should. Pressing the button is a bench test.
|
||||
|
||||
### One chord opens a terminal
|
||||
|
||||
`Meta+Ctrl+Alt+Shift+K`.
|
||||
|
||||
Normal administration is still SSH. This is for the case where somebody
|
||||
is standing at a machine and SSH is not available.
|
||||
|
||||
The chord is declared in the package — `X-KDE-Shortcuts` in
|
||||
`ekklesia-admin-terminal.desktop` — rather than seeded into a teacher's
|
||||
configuration, where an update could not reach it. KGlobalAccel read the
|
||||
entry and registered a component for it; invoking that component's
|
||||
`_launch` over D-Bus opened a working shell, which is how the whole path
|
||||
was verified without a keyboard.
|
||||
|
||||
It needed a wrapper, for a reason worth recording. The classroom's Kiosk
|
||||
policy sets `shell_access=false` and **Konsole honours it**: with the
|
||||
classroom configuration in its cascade, Konsole starts and prints
|
||||
*Program to run not set.* rather than opening a shell. That restriction
|
||||
is worth keeping for everything else, so `classroom-admin-terminal`
|
||||
lifts it for one process by leaving the classroom's configuration
|
||||
directory out of that process's `XDG_CONFIG_DIRS`. Nothing is patched,
|
||||
no binary is replaced, and the terminal therefore looks like stock KDE
|
||||
rather than like the classroom — which is fair, because it is not part
|
||||
of the classroom.
|
||||
|
||||
**It grants no privilege.** The classroom user has no sudo rule, and
|
||||
anything needing root still needs the administrator's own account and
|
||||
password. `shell_access` was always a barrier in the interface, never a
|
||||
privilege boundary.
|
||||
|
||||
Konsole is a package dependency, so the route exists on every machine.
|
||||
Its own entry is shadowed from `/usr/local/share/applications` with
|
||||
`NoDisplay=true`, leaving Konsole's file exactly where its package put
|
||||
it.
|
||||
|
||||
One thing found while testing, and kept as a second layer rather than
|
||||
removed: **Konsole ships `X-KDE-Shortcuts=Ctrl+Alt+T`**, a chord a great
|
||||
many people know. The shadow entry blanks it, but the registration comes
|
||||
from Konsole's own file and survives that — so it is still registered.
|
||||
It is also inert: Konsole's entry carries
|
||||
`X-KDE-AuthorizeAction=shell_access`, and with the classroom's
|
||||
`shell_access=false` the launch is refused. Measured: invoking that
|
||||
component over D-Bus opened nothing.
|
||||
|
||||
Nothing is pinned to the panel. A task button appears only while a
|
||||
terminal is open, and closing it returns the bar to three launchers.
|
||||
|
||||
**Needs the hardware.** The chord itself has never been pressed — key
|
||||
injection cannot reach the nested session in this lab. What is verified
|
||||
is that the shortcut is registered from the packaged entry and that its
|
||||
action opens a shell.
|
||||
|
||||
|
||||
## Long-Escape to turn the television off: it should change
|
||||
|
||||
The gesture asked for was: hold Escape, silence for three seconds, then a
|
||||
five-second visible countdown, cancel on release. Deliberate, hard to
|
||||
trigger by accident, and a clear intent.
|
||||
|
||||
### What was measured
|
||||
|
||||
* **KGlobalAccel accepts a bare `Escape`.** A probe entry declaring
|
||||
`X-KDE-Shortcuts=Escape` was registered and given its own component. So
|
||||
the binding is possible.
|
||||
* **Press *and release* are both observable.** The component's D-Bus
|
||||
interface carries `globalShortcutPressed` **and**
|
||||
`globalShortcutReleased`. Hold duration and cancel-on-release are
|
||||
therefore expressible without any input daemon of our own.
|
||||
* **KWin's scripting API has no key events at all** — `registerShortcut`
|
||||
and screen edges, and nothing that reports a key going up.
|
||||
|
||||
### What was not measured, and why it decides the answer
|
||||
|
||||
Whether a registered global shortcut **takes the key away from
|
||||
applications**. Key injection cannot reach the nested session in this
|
||||
lab, so this could not be pressed.
|
||||
|
||||
The mechanism says it does: on Wayland, KWin matches global shortcuts in
|
||||
an input filter that runs before the event reaches the focused surface,
|
||||
and a match stops propagation. That is how `Meta+Q` never arrives at an
|
||||
application. A bare `Escape` bound globally should therefore stop
|
||||
reaching anything — no leaving a fullscreen video, no dismissing a Chrome
|
||||
dialog, no closing the Parent Call card.
|
||||
|
||||
**This is inference, not a measurement, and it is a thirty-second bench
|
||||
test**: bind the probe entry above, press Escape in a fullscreen video,
|
||||
and see whether it leaves fullscreen.
|
||||
|
||||
### The recommendation
|
||||
|
||||
**Change the gesture.** Even if Escape were forwarded as well as
|
||||
observed, the whole ceremony would rest on a global grab of the key an
|
||||
appliance uses most, and a countdown driven from the process holding
|
||||
that grab is an input daemon in all but name. That is the fragile thing
|
||||
the classroom keeps removing.
|
||||
|
||||
Two clean alternatives, both using mechanisms already proven here:
|
||||
|
||||
1. **Hold-to-confirm on screen.** A television control where the volume
|
||||
applet is now: press and hold it, a countdown runs, releasing
|
||||
cancels. Press, hold and release inside an application's own surface
|
||||
are ordinary Qt and need no global input at all. This keeps every
|
||||
property the gesture was for — deliberate, visible countdown,
|
||||
cancel-on-release — and costs nothing in reliability.
|
||||
2. **A modifier chord**, the same mechanism as the maintenance terminal
|
||||
and proven to work in this session. Instant rather than ceremonial,
|
||||
but impossible to press by accident. Worth adding as a second route
|
||||
for somebody who cannot find the mouse.
|
||||
|
||||
If a keyboard hold is still wanted after the bench test, it should be on
|
||||
a key the classroom does not otherwise use — never Escape.
|
||||
|
||||
## The television control service
|
||||
|
||||
Unchanged in shape from the previous checkpoint, and now with the
|
||||
gesture question answered:
|
||||
|
||||
```
|
||||
panel control / chord presentation only
|
||||
|
|
||||
v
|
||||
ekklesia-classroom-tv.service small, supervised, ours
|
||||
|
|
||||
+-- backend: CEC over the adapter
|
||||
+-- interface: on, off, volume up, volume down, mute, input
|
||||
```
|
||||
|
||||
* The keyboard and the panel request **"TV off"**. They never speak CEC.
|
||||
* The service decides how. CEC hardware can change without the desktop
|
||||
noticing.
|
||||
* The same service will own automatic TV-on at session start, volume,
|
||||
mute and input, and it is why the computer's own volume applet is
|
||||
expected to leave the bar.
|
||||
* Supervised and self-recovering, the same way the audio policy is.
|
||||
|
||||
**No CEC code has been written and no protocol has been guessed.** The
|
||||
adapters arrive today; the commands get measured before anything is
|
||||
built on them.
|
||||
|
||||
## Unresolved risks
|
||||
|
||||
In the order I would worry about them.
|
||||
@@ -848,6 +981,18 @@ In the order I would worry about them.
|
||||
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.
|
||||
11. **The power button has never been pressed.** Both layers are
|
||||
configured, packaged, and read back correctly, but nothing in a
|
||||
container has a power button.
|
||||
12. **The maintenance chord has never been typed.** The shortcut is
|
||||
registered from the packaged entry and its action opens a shell —
|
||||
verified over D-Bus — but key injection cannot reach the nested
|
||||
session, so `Meta+Ctrl+Alt+Shift+K` itself is unpressed.
|
||||
13. **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
|
||||
restriction rather than on the chord not existing.
|
||||
|
||||
## Would I trust it on a classroom computer, unattended, for a Sunday?
|
||||
|
||||
@@ -872,9 +1017,14 @@ Before any room:
|
||||
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.
|
||||
4. **Press the power button.** Nothing should happen. Then hold it, and
|
||||
confirm the machine still dies — that is the recovery path and it
|
||||
must stay.
|
||||
5. **Type Meta+Ctrl+Alt+Shift+K.** A terminal should open. Then try
|
||||
Ctrl+Alt+T and confirm nothing does.
|
||||
6. Print to Elmer.
|
||||
7. Play a DVD, if that room uses them: cover, picture, controls, eject.
|
||||
8. Leave it running from Friday to Sunday.
|
||||
|
||||
## Alternate operating systems
|
||||
|
||||
@@ -922,13 +1072,24 @@ The existing Debian classroom test VM should be kept.
|
||||
can reach a room that has already run.
|
||||
* **Recovery re-measured against the packaged build**, not a hand-edited
|
||||
session.
|
||||
* **The power button disabled at both layers**, packaged, and read back
|
||||
from logind after a reload that did not disturb the session.
|
||||
* **A maintenance terminal behind one obscure chord**, declared in the
|
||||
package, hidden from every application list, granting no privilege.
|
||||
* **Long-Escape investigated and recommended against**, with the two
|
||||
clean alternatives written down.
|
||||
|
||||
**Next**, in order:
|
||||
|
||||
0. **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
|
||||
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.
|
||||
answer, and each of them is a Sunday-morning path. Add the power
|
||||
button and the maintenance chord to that list.
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user