feat: one setting per application, and never the shape of the machine
A laptop is going in for the women's Bible study, and the obvious way to
build that — a laptop profile that turns off the children's church
applications — is the wrong way. A laptop may well take children's church,
and a tower may well be a Bible study. Hardware cannot be allowed to
decide purpose, so every optional application gets a setting of its own:
WONDERINK_ENABLED already existed; behaviour unchanged
DVD_ENABLED new
PARENT_CALL_ENABLED new
and DEVICE_TYPE says only what the hardware IS. classroom-desktop-layout
never reads it, and there is a test that says so, because this is the rule
that will be under pressure the first time somebody adds a device.
All three default to true, so an existing classroom that has never heard
of any of them comes up exactly as it did before. The settings are
appended to device.conf by the same mechanism every other setting has
used, so an upgrade gains them without losing a byte an administrator
wrote.
The disc player is the one place hardware still votes, and it is a veto:
DVD_ENABLED can take the player away from a machine that has a drive,
nothing can put it on a machine that has none. A button that cannot work
is worse than no button.
The layout's launcher markers are replaced by a feature block of three
plain booleans. The old mechanism commented a line out of an array, which
worked for launchers and could not express Parent Call, because that is a
whole widget rather than one entry. Three booleans express both, and the
launcher list is now built from them in one fixed order, so a disabled
application closes the row up rather than leaving a gap, and the same
enabled set produces the same bar on every machine in the church.
Also here, because it is the bar and not a feature: sortingStrategy=0.
Plasma's default is 1, "manually", and the task manager accepts a
reordering drop only in that mode — MouseHandler.qml tests
tasksModel.sortMode === SortManual before it will move anything. The
classroom never wrote the key, so it had the default, and any teacher
could drag the launchers into a different order. This is the applet's own
lever refusing the drop rather than something of ours putting the bar back
afterwards.
The test now runs the layout the package actually ships, in node, with
Plasma's API stubbed, and asserts the launcher string that comes out.
Asserting against a copy of the file's text in the test was how the old
one worked, and a copy is a thing that drifts.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fc764b0621
commit
7f4a122900
@@ -73,6 +73,56 @@ MQTT_PASSWORD=
|
||||
# false takes the launcher off the panel and stops the command starting.
|
||||
# The ordinary browser, Parent Call and everything else are untouched.
|
||||
WONDERINK_ENABLED=true
|
||||
|
||||
# What kind of machine this is.
|
||||
#
|
||||
# desktop a classroom tower. This is every existing room.
|
||||
# laptop a machine with a lid and an internal panel.
|
||||
#
|
||||
# This says what the hardware IS. It decides nothing about which
|
||||
# applications the device offers: a laptop running children's church needs
|
||||
# Wonder Ink, and a desktop used for Bible study does not. Every
|
||||
# application below is its own setting, on purpose, so that moving a
|
||||
# machine between rooms is a matter of saying what it is for rather than
|
||||
# what shape it is.
|
||||
DEVICE_TYPE=desktop
|
||||
|
||||
# Whether this device offers the disc player.
|
||||
#
|
||||
# The machine is asked as well: a room with no optical drive never shows
|
||||
# the player whatever this says, because a button that cannot work is
|
||||
# worse than no button. This setting is how a device that HAS a drive is
|
||||
# told not to offer it anyway.
|
||||
DVD_ENABLED=true
|
||||
|
||||
# Whether this device offers Parent Call.
|
||||
#
|
||||
# A room full of children needs it. A Bible study does not, and the button
|
||||
# in the corner is then one more thing to explain.
|
||||
PARENT_CALL_ENABLED=true
|
||||
|
||||
# Which network this device is meant to be on.
|
||||
#
|
||||
# wired an Ethernet cable is the intended connection.
|
||||
# wifi this device is meant to be on Wi-Fi. Normal and expected; the
|
||||
# room is not warned about a missing cable.
|
||||
#
|
||||
# This changes what the network indicator offers, never what
|
||||
# NetworkManager is allowed to connect to. Wi-Fi hardware is not disabled
|
||||
# on a wired device, and a wired device is not stopped from falling back.
|
||||
NETWORK_PREFERENCE=wired
|
||||
|
||||
# Which displays this device drives.
|
||||
#
|
||||
# all every connected display, which is what a tower with one
|
||||
# television wants and what every existing room gets.
|
||||
# external-only the external display only, with an internal laptop
|
||||
# panel switched off. For a laptop installed as a fixed
|
||||
# appliance with its lid shut.
|
||||
#
|
||||
# external-only is a setting rather than something inferred from having a
|
||||
# lid, because another laptop may want its own screen or both.
|
||||
DISPLAY_MODE=all
|
||||
"""
|
||||
|
||||
|
||||
@@ -127,6 +177,71 @@ UI_SCALE=1.0
|
||||
# The ordinary browser, Parent Call and everything else are untouched.
|
||||
WONDERINK_ENABLED=true
|
||||
''',
|
||||
),
|
||||
(
|
||||
"DEVICE_TYPE",
|
||||
"""# What kind of machine this is.
|
||||
#
|
||||
# desktop a classroom tower. This is every existing room.
|
||||
# laptop a machine with a lid and an internal panel.
|
||||
#
|
||||
# This says what the hardware IS. It decides nothing about which
|
||||
# applications the device offers: a laptop running children's church needs
|
||||
# Wonder Ink, and a desktop used for Bible study does not. Every
|
||||
# application below is its own setting, on purpose, so that moving a
|
||||
# machine between rooms is a matter of saying what it is for rather than
|
||||
# what shape it is.
|
||||
DEVICE_TYPE=desktop
|
||||
""",
|
||||
),
|
||||
(
|
||||
"DVD_ENABLED",
|
||||
"""# Whether this device offers the disc player.
|
||||
#
|
||||
# The machine is asked as well: a room with no optical drive never shows
|
||||
# the player whatever this says, because a button that cannot work is
|
||||
# worse than no button. This setting is how a device that HAS a drive is
|
||||
# told not to offer it anyway.
|
||||
DVD_ENABLED=true
|
||||
""",
|
||||
),
|
||||
(
|
||||
"PARENT_CALL_ENABLED",
|
||||
"""# Whether this device offers Parent Call.
|
||||
#
|
||||
# A room full of children needs it. A Bible study does not, and the button
|
||||
# in the corner is then one more thing to explain.
|
||||
PARENT_CALL_ENABLED=true
|
||||
""",
|
||||
),
|
||||
(
|
||||
"NETWORK_PREFERENCE",
|
||||
"""# Which network this device is meant to be on.
|
||||
#
|
||||
# wired an Ethernet cable is the intended connection.
|
||||
# wifi this device is meant to be on Wi-Fi. Normal and expected; the
|
||||
# room is not warned about a missing cable.
|
||||
#
|
||||
# This changes what the network indicator offers, never what
|
||||
# NetworkManager is allowed to connect to. Wi-Fi hardware is not disabled
|
||||
# on a wired device, and a wired device is not stopped from falling back.
|
||||
NETWORK_PREFERENCE=wired
|
||||
""",
|
||||
),
|
||||
(
|
||||
"DISPLAY_MODE",
|
||||
"""# Which displays this device drives.
|
||||
#
|
||||
# all every connected display, which is what a tower with one
|
||||
# television wants and what every existing room gets.
|
||||
# external-only the external display only, with an internal laptop
|
||||
# panel switched off. For a laptop installed as a fixed
|
||||
# appliance with its lid shut.
|
||||
#
|
||||
# external-only is a setting rather than something inferred from having a
|
||||
# lid, because another laptop may want its own screen or both.
|
||||
DISPLAY_MODE=all
|
||||
""",
|
||||
),
|
||||
(
|
||||
"MQTT_ENABLED",
|
||||
@@ -198,6 +313,52 @@ def ensure_device_config(path=None):
|
||||
path.write_text(text + separator + "\n\n".join(additions) + "\n")
|
||||
|
||||
|
||||
DEVICE_TYPES = ("desktop", "laptop")
|
||||
NETWORK_PREFERENCES = ("wired", "wifi")
|
||||
DISPLAY_MODES = ("all", "external-only")
|
||||
|
||||
# Every optional application, and what a device that has never heard of
|
||||
# the setting should do. All true: an existing classroom upgrading to this
|
||||
# release must come up exactly as it was, and every existing classroom has
|
||||
# all of these.
|
||||
FEATURES = {
|
||||
"WONDERINK_ENABLED": True,
|
||||
"DVD_ENABLED": True,
|
||||
"PARENT_CALL_ENABLED": True,
|
||||
}
|
||||
|
||||
|
||||
def feature(config, name):
|
||||
"""Whether an optional application is offered on this device.
|
||||
|
||||
Deliberately reads one key per application and never consults
|
||||
DEVICE_TYPE. A laptop taking children's church needs Wonder Ink and a
|
||||
tower used for Bible study does not, so shape cannot be allowed to
|
||||
decide purpose — that rule is the whole reason these are separate
|
||||
settings rather than a profile.
|
||||
"""
|
||||
return enabled(config, name, default=FEATURES.get(name, False))
|
||||
|
||||
|
||||
def _choice(config, key, allowed, default):
|
||||
value = (config.get(key) or "").strip().lower()
|
||||
|
||||
return value if value in allowed else default
|
||||
|
||||
|
||||
def device_type(config):
|
||||
"""What the hardware is. Never what it is for."""
|
||||
return _choice(config, "DEVICE_TYPE", DEVICE_TYPES, "desktop")
|
||||
|
||||
|
||||
def network_preference(config):
|
||||
return _choice(config, "NETWORK_PREFERENCE", NETWORK_PREFERENCES, "wired")
|
||||
|
||||
|
||||
def display_mode(config):
|
||||
return _choice(config, "DISPLAY_MODE", DISPLAY_MODES, "all")
|
||||
|
||||
|
||||
def ui_scale(config):
|
||||
"""UI_SCALE, clamped to something a classroom can actually use."""
|
||||
raw = config.get("UI_SCALE", "")
|
||||
|
||||
Reference in New Issue
Block a user