feat: scale the shell to the room's television
A 32" panel a few feet from the children and a 65" set across a hall want the same design at different sizes. UI_SCALE in device.conf now sets that, and nobody has to edit CSS or source to tune a room. The stylesheet and the notification config become templates carrying measurement tokens. classroom-dock resolves the stylesheet in memory at startup; classroom-notifications resolves the notification config into the session's runtime directory and execs mako on it, so the process is still just mako and everything that looks for it by name still finds it. Neither template is rewritten on disk, so an update cannot lose a room's setting and a room cannot drift from the packaged design. Dock height and the reserved strip, corner radii, padding, button size, spacing, every icon, the clock and its inset, and the notification geometry all follow the scale. Colours, translucency and the hairline borders do not: those are the design, not the size. At UI_SCALE=1.0 the rendered stylesheet is byte-identical to the one the shell used before any of this existed, which is the property worth keeping. Values outside 0.8 to 1.5 are clamped and anything that is not a number falls back to 1.0, so a typo in device.conf cannot produce an unusable classroom. Device configuration moves into a shared module, since the dock and the notification daemon now have to agree about what a setting means. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
02094a6931
commit
428eb27a74
@@ -0,0 +1,65 @@
|
||||
"""Device configuration for the Ekklesia Classroom shell.
|
||||
|
||||
Everything that has to agree about /etc/ekklesia-classroom/device.conf
|
||||
reads it through here, so the dock, the notification daemon and the DVD
|
||||
commands cannot drift apart over what a setting means.
|
||||
"""
|
||||
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
CONFIG_FILE = Path("/etc/ekklesia-classroom/device.conf")
|
||||
|
||||
TRUTHY = {"1", "true", "yes", "on", "enabled"}
|
||||
|
||||
# The dock is tuned for a 1080p classroom TV at 1.0. Smaller rooms with a
|
||||
# 32" panel sit near the bottom of this range, a 65" set near the top.
|
||||
UI_SCALE_DEFAULT = 1.0
|
||||
UI_SCALE_MIN = 0.8
|
||||
UI_SCALE_MAX = 1.5
|
||||
|
||||
|
||||
def read_device_config(path=None):
|
||||
config = {}
|
||||
path = Path(path) if path is not None else CONFIG_FILE
|
||||
|
||||
if not path.exists():
|
||||
return config
|
||||
|
||||
for raw_line in path.read_text().splitlines():
|
||||
line = raw_line.strip()
|
||||
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
|
||||
key, value = line.split("=", 1)
|
||||
config[key.strip()] = value.strip()
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def enabled(config, key, default=False):
|
||||
if key not in config:
|
||||
return default
|
||||
|
||||
return config[key].lower() in TRUTHY
|
||||
|
||||
|
||||
def ui_scale(config):
|
||||
"""UI_SCALE, clamped to something a classroom can actually use."""
|
||||
raw = config.get("UI_SCALE", "")
|
||||
|
||||
try:
|
||||
value = float(raw)
|
||||
except (TypeError, ValueError):
|
||||
return UI_SCALE_DEFAULT
|
||||
|
||||
if not math.isfinite(value):
|
||||
return UI_SCALE_DEFAULT
|
||||
|
||||
return min(max(value, UI_SCALE_MIN), UI_SCALE_MAX)
|
||||
|
||||
|
||||
def scaled(value, scale):
|
||||
"""A pixel measurement at the configured scale, never smaller than 1."""
|
||||
return max(1, int(round(value * scale)))
|
||||
Reference in New Issue
Block a user