feat: give the classroom a desktop instead of a shell

The whole appliance UI is now configuration for a desktop Debian already
ships: a Plasma 6.3 session with a colour scheme, a look and feel package
that builds the bar, window rules, and KDE's own Kiosk restrictions.

Two things were measured rather than assumed, and both changed a decision.

Plasma restarts a crashed panel three times a minute and then gives up,
which is the failure a classroom has already had. Four lines of systemd
drop-in make it unconditional; the panel then survived eight SIGKILLs a
second apart, back each time in 2.4s.

Plasma draws a minimised task and a background task identically, so the
five states the room needs cannot all be shown. Rather than write a task
manager, the classroom removes minimise: clicking a launcher always means
show me this.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
ekklesia
2026-09-10 08:35:12 -05:00
co-authored by Claude Opus 5
parent bfc7caf28f
commit 87b55761c6
51 changed files with 1352 additions and 36 deletions
@@ -0,0 +1,25 @@
[Desktop Entry]
# The room's browser, installed to /usr/local/share/applications, which
# XDG_DATA_DIRS searches before /usr/share. Chrome's own entry is left
# where Chrome's package put it and is simply never the one that is found.
#
# It has to carry Chrome's file name rather than a name of our own. Plasma
# matches a window to its launcher by the application id the window
# reports, and Chrome reports "google-chrome". A launcher under any other
# name gives a teacher two buttons for one browser: a launcher that always
# looks closed, and a window that appears beside it. That was measured, not
# assumed — it is what the first build did.
Type=Application
Name=Browser
GenericName=Web browser
Comment=YouTube and the rest of the web
Icon=google-chrome
Exec=/usr/local/bin/classroom-browser %U
Terminal=false
Categories=Network;WebBrowser;
StartupNotify=true
StartupWMClass=google-chrome
MimeType=text/html;x-scheme-handler/http;x-scheme-handler/https;
# Chrome's own entry offers a new window and an incognito window from the
# launcher's right-click menu. Neither belongs in a shared room.
Actions=
@@ -0,0 +1,13 @@
[Desktop Entry]
Type=Application
Name=DVD
Comment=Play the disc in the drive
Exec=/usr/local/bin/classroom-dvd
Icon=media-optical-dvd
Terminal=false
Categories=AudioVideo;Player;
StartupNotify=true
StartupWMClass=vlc
# Never in a menu or a launcher by itself. The DVD appears when a disc is
# in the drive, through Plasma's own device notifier, and goes away with it.
NoDisplay=true
@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Name=Parent Call
Comment=Ask for a child's parent to come to the room
Exec=/usr/local/bin/classroom-parent-call
Icon=ekklesia-parent-call
Terminal=false
Categories=Utility;
StartupNotify=false
NoDisplay=false
@@ -0,0 +1,15 @@
[Desktop Entry]
Type=Application
Name=Wonder Ink
GenericName=Lesson
Comment=The Wonder Ink lesson for this room
Exec=/usr/local/bin/classroom-wonderink
Icon=ekklesia-wonderink
Terminal=false
Categories=Education;
StartupNotify=true
# How the panel knows that the window on screen belongs to this launcher.
# Chrome derives an app id from the --app URL, and this must match it
# exactly or the launcher and the window become two separate buttons.
StartupWMClass=chrome-app.wonderink.org__-Default
X-GNOME-SingleWindow=true
+155
View File
@@ -0,0 +1,155 @@
# Ekklesia Classroom — dark. The default.
#
# One set of tokens for the whole session: Plasma reads this file for the
# panel, the notifications, the window decorations and every Qt dialog, so
# there is one place to change a colour rather than a stylesheet per surface.
#
# The hues come from the classroom wallpaper — sage, teal, blue, lavender —
# so the desktop sits on the landscape rather than in front of it.
[General]
Name=Ekklesia Classroom Dark
ColorScheme=EkklesiaDark
shadeSortColumn=true
accentActiveTitlebar=false
[ColorEffects:Disabled]
ChangeSelectionColor=
Color=56,66,71
ColorAmount=0
ColorEffect=0
ContrastAmount=0.5
ContrastEffect=1
Enable=
IntensityAmount=0
IntensityEffect=0
[ColorEffects:Inactive]
ChangeSelectionColor=true
Color=112,111,110
ColorAmount=0.025
ColorEffect=2
ContrastAmount=0.1
ContrastEffect=2
Enable=false
IntensityAmount=0
IntensityEffect=0
[Colors:Button]
BackgroundAlternate=30,42,47
BackgroundNormal=25,35,40
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=79,179,168
ForegroundInactive=147,165,170
ForegroundLink=126,196,255
ForegroundNegative=227,106,106
ForegroundNeutral=224,177,92
ForegroundNormal=230,237,239
ForegroundPositive=111,207,151
ForegroundVisited=156,138,222
[Colors:Selection]
BackgroundAlternate=79,179,168
BackgroundNormal=79,179,168
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=14,21,24
ForegroundInactive=14,21,24
ForegroundLink=14,21,24
ForegroundNegative=14,21,24
ForegroundNeutral=14,21,24
ForegroundNormal=10,16,18
ForegroundPositive=14,21,24
ForegroundVisited=14,21,24
[Colors:Tooltip]
BackgroundAlternate=25,35,40
BackgroundNormal=20,28,32
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=79,179,168
ForegroundInactive=147,165,170
ForegroundLink=126,196,255
ForegroundNegative=227,106,106
ForegroundNeutral=224,177,92
ForegroundNormal=230,237,239
ForegroundPositive=111,207,151
ForegroundVisited=156,138,222
[Colors:View]
BackgroundAlternate=20,28,32
BackgroundNormal=15,23,26
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=79,179,168
ForegroundInactive=147,165,170
ForegroundLink=126,196,255
ForegroundNegative=227,106,106
ForegroundNeutral=224,177,92
ForegroundNormal=230,237,239
ForegroundPositive=111,207,151
ForegroundVisited=156,138,222
[Colors:Window]
BackgroundAlternate=25,35,40
BackgroundNormal=20,28,32
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=79,179,168
ForegroundInactive=147,165,170
ForegroundLink=126,196,255
ForegroundNegative=227,106,106
ForegroundNeutral=224,177,92
ForegroundNormal=230,237,239
ForegroundPositive=111,207,151
ForegroundVisited=156,138,222
[Colors:Complementary]
BackgroundAlternate=25,35,40
BackgroundNormal=20,28,32
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=79,179,168
ForegroundInactive=147,165,170
ForegroundLink=126,196,255
ForegroundNegative=227,106,106
ForegroundNeutral=224,177,92
ForegroundNormal=230,237,239
ForegroundPositive=111,207,151
ForegroundVisited=156,138,222
[Colors:Header]
BackgroundAlternate=25,35,40
BackgroundNormal=18,26,30
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=79,179,168
ForegroundInactive=147,165,170
ForegroundLink=126,196,255
ForegroundNegative=227,106,106
ForegroundNeutral=224,177,92
ForegroundNormal=230,237,239
ForegroundPositive=111,207,151
ForegroundVisited=156,138,222
[Colors:Header][Inactive]
BackgroundAlternate=20,28,32
BackgroundNormal=16,23,26
DecorationFocus=79,179,168
DecorationHover=79,179,168
ForegroundActive=79,179,168
ForegroundInactive=125,142,147
ForegroundLink=126,196,255
ForegroundNegative=227,106,106
ForegroundNeutral=224,177,92
ForegroundNormal=170,186,191
ForegroundPositive=111,207,151
ForegroundVisited=156,138,222
[WM]
activeBackground=18,26,30
activeBlend=79,179,168
activeForeground=230,237,239
inactiveBackground=16,23,26
inactiveBlend=147,165,170
inactiveForeground=147,165,170
+158
View File
@@ -0,0 +1,158 @@
# Ekklesia Classroom — light.
#
# GENERATED from EkklesiaDark.colors by tools/build-light-scheme.
# Edit the dark scheme and regenerate; do not edit this file by hand.
#
# One set of tokens for the whole session: Plasma reads this file for the
# panel, the notifications, the window decorations and every Qt dialog, so
# there is one place to change a colour rather than a stylesheet per surface.
#
# The hues come from the classroom wallpaper — sage, teal, blue, lavender —
# so the desktop sits on the landscape rather than in front of it.
[General]
Name=Ekklesia Classroom Light
ColorScheme=EkklesiaLight
shadeSortColumn=true
accentActiveTitlebar=false
[ColorEffects:Disabled]
ChangeSelectionColor=
Color=56,66,71
ColorAmount=0
ColorEffect=0
ContrastAmount=0.5
ContrastEffect=1
Enable=
IntensityAmount=0
IntensityEffect=0
[ColorEffects:Inactive]
ChangeSelectionColor=true
Color=112,111,110
ColorAmount=0.025
ColorEffect=2
ContrastAmount=0.1
ContrastEffect=2
Enable=false
IntensityAmount=0
IntensityEffect=0
[Colors:Button]
BackgroundAlternate=225,231,230
BackgroundNormal=233,238,237
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=46,140,130
ForegroundInactive=96,116,122
ForegroundLink=26,110,180
ForegroundNegative=192,57,57
ForegroundNeutral=166,116,24
ForegroundNormal=22,35,42
ForegroundPositive=38,142,86
ForegroundVisited=104,80,180
[Colors:Selection]
BackgroundAlternate=46,140,130
BackgroundNormal=46,140,130
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=255,255,255
ForegroundInactive=255,255,255
ForegroundLink=255,255,255
ForegroundNegative=255,255,255
ForegroundNeutral=255,255,255
ForegroundNormal=255,255,255
ForegroundPositive=255,255,255
ForegroundVisited=255,255,255
[Colors:Tooltip]
BackgroundAlternate=233,238,237
BackgroundNormal=242,245,244
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=46,140,130
ForegroundInactive=96,116,122
ForegroundLink=26,110,180
ForegroundNegative=192,57,57
ForegroundNeutral=166,116,24
ForegroundNormal=22,35,42
ForegroundPositive=38,142,86
ForegroundVisited=104,80,180
[Colors:View]
BackgroundAlternate=242,245,244
BackgroundNormal=255,255,255
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=46,140,130
ForegroundInactive=96,116,122
ForegroundLink=26,110,180
ForegroundNegative=192,57,57
ForegroundNeutral=166,116,24
ForegroundNormal=22,35,42
ForegroundPositive=38,142,86
ForegroundVisited=104,80,180
[Colors:Window]
BackgroundAlternate=233,238,237
BackgroundNormal=242,245,244
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=46,140,130
ForegroundInactive=96,116,122
ForegroundLink=26,110,180
ForegroundNegative=192,57,57
ForegroundNeutral=166,116,24
ForegroundNormal=22,35,42
ForegroundPositive=38,142,86
ForegroundVisited=104,80,180
[Colors:Complementary]
BackgroundAlternate=233,238,237
BackgroundNormal=242,245,244
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=46,140,130
ForegroundInactive=96,116,122
ForegroundLink=26,110,180
ForegroundNegative=192,57,57
ForegroundNeutral=166,116,24
ForegroundNormal=22,35,42
ForegroundPositive=38,142,86
ForegroundVisited=104,80,180
[Colors:Header]
BackgroundAlternate=233,238,237
BackgroundNormal=236,241,240
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=46,140,130
ForegroundInactive=96,116,122
ForegroundLink=26,110,180
ForegroundNegative=192,57,57
ForegroundNeutral=166,116,24
ForegroundNormal=22,35,42
ForegroundPositive=38,142,86
ForegroundVisited=104,80,180
[Colors:Header][Inactive]
BackgroundAlternate=242,245,244
BackgroundNormal=228,234,233
DecorationFocus=46,140,130
DecorationHover=46,140,130
ForegroundActive=46,140,130
ForegroundInactive=120,138,144
ForegroundLink=26,110,180
ForegroundNegative=192,57,57
ForegroundNeutral=166,116,24
ForegroundNormal=80,99,105
ForegroundPositive=38,142,86
ForegroundVisited=104,80,180
[WM]
activeBackground=236,241,240
activeBlend=46,140,130
activeForeground=22,35,42
inactiveBackground=228,234,233
inactiveBlend=96,116,122
inactiveForeground=96,116,122
@@ -0,0 +1,31 @@
# Everything the classroom's appearance is made of, in one place.
#
# Plasma reads this when the look and feel is applied, so the panel, the
# window decorations, the notifications and every Qt dialog in the session
# are described here rather than in a stylesheet per surface.
[kdeglobals][KDE]
widgetStyle=Breeze
[kdeglobals][General]
ColorScheme=EkklesiaDark
AccentColor=79,179,168
[kdeglobals][Icons]
Theme=breeze-dark
[plasmarc][Theme]
name=default
[kcminputrc][Mouse]
cursorTheme=breeze_cursors
[kwinrc][org.kde.kdecoration2]
library=org.kde.breeze
theme=Breeze
[Wallpaper]
Image=/usr/share/backgrounds/ekklesia/classroom-calm.png
[KSplash]
Theme=None
@@ -0,0 +1,124 @@
// The Ekklesia Classroom desktop.
//
// Plasma runs this once, when a session has no panel yet, and again on
// demand — `plasma-apply-lookandfeel -a org.ekklesia.classroom.desktop
// --resetLayout` rebuilds the whole desktop from this file. That is the
// classroom's recovery path for a damaged shell, and it is Plasma's own
// mechanism rather than something written here.
//
// One full-width bar along the bottom. Left is auxiliary, the middle is
// applications, the right is the small amount of status a teacher needs.
// Nothing else is on the screen.
var WALLPAPER = "/usr/share/backgrounds/ekklesia/classroom-calm.png";
// Matches the 76px strip the classroom has always used, so muscle memory
// and the room's viewing distance both carry over.
var PANEL_HEIGHT = 76;
// The idle desktop: the wallpaper, and nothing on it.
var screens = desktops();
for (var i = 0; i < screens.length; i++) {
var desktop = screens[i];
desktop.wallpaperPlugin = "org.kde.image";
desktop.currentConfigGroup = ["Wallpaper", "org.kde.image", "General"];
desktop.writeConfig("Image", "file://" + WALLPAPER);
desktop.writeConfig("SlidePaths", "");
// 2 is "scaled and cropped": the landscape fills the display at any
// aspect ratio without being stretched out of shape.
desktop.writeConfig("FillMode", 2);
desktop.reloadConfig();
}
var panel = new Panel();
panel.location = "bottom";
panel.height = PANEL_HEIGHT;
panel.hiding = "none";
panel.floating = false;
panel.lengthMode = "fill";
panel.alignment = "center";
panel.opacity = "adaptive";
// LEFT — auxiliary. Parent Call is not one of the room's applications and
// is deliberately not in the row with them.
var parentCall = panel.addWidget("org.kde.plasma.icon");
parentCall.currentConfigGroup = ["General"];
parentCall.writeConfig(
"url",
"file:///usr/share/applications/ekklesia-parent-call.desktop"
);
var leftGap = panel.addWidget("org.kde.plasma.panelspacer");
leftGap.currentConfigGroup = ["General"];
leftGap.writeConfig("expanding", true);
// CENTRE — the applications, and the whole of the running/minimised/active
// story. This applet is the reason the classroom stops writing a dock.
var tasks = panel.addWidget("org.kde.plasma.icontasks");
tasks.currentConfigGroup = ["General"];
tasks.writeConfig("launchers", [
"applications:ekklesia-wonderink.desktop",
"applications:google-chrome.desktop"
].join(","));
// Every window gets its own button. Teachers should never have to open a
// group to find out that a second window exists.
tasks.writeConfig("groupingStrategy", 0);
tasks.writeConfig("showOnlyCurrentDesktop", false);
tasks.writeConfig("showOnlyCurrentActivity", false);
tasks.writeConfig("showOnlyCurrentScreen", false);
// Clicking a button always means "show me this", and never "hide it".
//
// This was measured before it was decided. Plasma 6.3 draws a minimised
// task and a task that is merely behind another window identically: no
// indicator for closed, a grey indicator for running, a teal one for
// active — three marks for four states. Rather than write a task manager
// that draws a fourth, the classroom removes the state. There is nothing
// on the idle desktop for a teacher to want to see, so minimising an
// application in this room has no purpose and only ever loses it.
//
// A window minimised some other way is still shown as running and comes
// back with one click, so it can never be lost even then.
tasks.writeConfig("minimizeActiveTaskOnClick", false);
tasks.writeConfig("fill", false);
tasks.writeConfig("maxStripes", 1);
tasks.writeConfig("indicateAudioStreams", false);
tasks.writeConfig("wheelEnabled", false);
tasks.writeConfig("middleClickAction", "NewInstance");
tasks.writeConfig("showToolTips", true);
tasks.writeConfig("iconSpacing", 2);
var rightGap = panel.addWidget("org.kde.plasma.panelspacer");
rightGap.currentConfigGroup = ["General"];
rightGap.writeConfig("expanding", true);
// RIGHT — status.
//
// Four ordinary applets straight on the bar, and no system tray around
// them. A tray is a container that discovers whatever is installed and
// then hides most of it behind an arrow; measured in the lab it collected
// battery, brightness, clipboard, keyboard layout, camera, vaults and
// screen management on a machine that has none of those to say anything
// about. Naming the four the classroom actually uses is both smaller and
// deterministic, and it leaves nothing for a teacher to expand.
panel.addWidget("org.kde.plasma.networkmanagement");
panel.addWidget("org.kde.plasma.volume");
// Present only while there is something in a drive. Plasma's own Solid
// device notifier is what makes the DVD appear with the disc and leave
// with it, so nothing in the classroom polls for media.
panel.addWidget("org.kde.plasma.devicenotifier");
panel.addWidget("org.kde.plasma.notifications");
var clock = panel.addWidget("org.kde.plasma.digitalclock");
clock.currentConfigGroup = ["Appearance"];
clock.writeConfig("showDate", true);
clock.writeConfig("dateFormat", "custom");
clock.writeConfig("customDateFormat", "ddd d MMM");
clock.writeConfig("showSeconds", 0);
clock.writeConfig("dateDisplayFormat", "BelowTime");
// Left to itself the clock grows to the height of the bar and becomes the
// largest text in the room. It is status, not a headline.
clock.writeConfig("autoFontAndSize", false);
clock.writeConfig("fontSize", 15);
clock.writeConfig("fontWeight", 500);
+17
View File
@@ -0,0 +1,17 @@
{
"KPackageStructure": "Plasma/LookAndFeel",
"KPlugin": {
"Authors": [
{
"Name": "Ekklesia"
}
],
"Category": "",
"Description": "The classroom appliance desktop",
"Id": "org.ekklesia.classroom.desktop",
"License": "GPLv2+",
"Name": "Ekklesia Classroom",
"Website": "https://riverofglorymn.org"
},
"X-Plasma-APIVersion": "2"
}
+13
View File
@@ -0,0 +1,13 @@
[Desktop Entry]
Type=Service
# Solid decides when this exists. Plasma's device notifier offers it while
# a video DVD is in the drive and withdraws it when the disc is ejected, so
# a room without a drive shows nothing and a room with one needs no setting
# changed. Nothing polls.
X-KDE-Solid-Predicate=[[ StorageVolume.ignored == false AND StorageVolume.usage == 'Other' ] AND [ OpticalDisc.availableContent & 'VideoDvd' ]]
Actions=Play;
[Desktop Action Play]
Name=Play the DVD
Icon=media-optical-dvd
Exec=/usr/local/bin/classroom-dvd %f
+60
View File
@@ -0,0 +1,60 @@
# Ekklesia Classroom session policy.
#
# Installed to /etc/xdg/kdeglobals, where it is the bottom of Plasma's
# configuration cascade. Every group is marked [$i] — immutable — so a
# teacher, a stray click or a misbehaving application cannot override it
# from the user's own configuration. This is KDE's own Kiosk mechanism:
# nothing here is achieved by deleting a binary or hiding a menu entry.
#
# Lifting a restriction for maintenance is a one-line edit to this file
# followed by a session restart, which is what makes the appliance
# serviceable rather than merely locked.
[KDE Action Restrictions][$i]
# No way to reach a shell, a command line, or an arbitrary program.
action/kdesktop_rmb=false
action/kwin_rmb=false
action/openwith=false
action/switch_user=false
action/start_new_session=false
action/lock_screen=false
run_command=false
shell_access=false
logout=false
# The desktop and the panel are a fixed part of the appliance.
editable_desktop_icons=false
editable_bookmarks=false
movable_toolbars=false
plasma/plasmashell/unlockedDesktop=false
plasma-desktop/scripting_console=false
# Nothing in the classroom should offer to file a bug or open a manual.
action/help_report_bug=false
action/help_about_kde=false
action/help_contents=false
[General][$i]
ColorScheme=EkklesiaDark
AccentColor=79,179,168
# The teacher's own words are not decoration: keep text rendering plain
# and readable rather than styled.
XftAntialias=true
XftHintStyle=hintslight
XftSubPixel=rgb
[KDE][$i]
widgetStyle=Breeze
LookAndFeelPackage=org.ekklesia.classroom.desktop
SingleClick=false
AnimationDurationFactor=0.5
[Icons][$i]
Theme=breeze-dark
[KFileDialog Settings][$i]
Allow Expansion=false
Automatically select filename extension=true
Show Bookmarks=false
Show Full Path=false
Show Inline Previews=false
Show Speedbar=false
Sort directories first=true
+9
View File
@@ -0,0 +1,9 @@
# KRunner is a command line with a nicer face. The classroom has neither.
[General][$i]
Enabled=false
ActivateWhenTypingOnDesktop=false
[Plugins][$i]
shellEnabled=false
baloosearchEnabled=false
krunner_appstreamEnabled=false
krunner_shellEnabled=false
+9
View File
@@ -0,0 +1,9 @@
# A classroom appliance must never present a password prompt to a teacher.
# There is no lock screen, and nothing can bring one up: the action itself
# is disabled in kdeglobals as well, so a keyboard shortcut cannot reach it.
[Daemon][$i]
Autolock=false
LockOnResume=false
LockOnStart=false
LockGrace=0
Timeout=0
+8
View File
@@ -0,0 +1,8 @@
# The room is not somebody's account. Every session starts from the same
# empty desktop, so what the last teacher left open is never the first
# thing the next one sees.
[General][$i]
loginMode=emptySession
confirmLogout=false
offerShutdown=false
shutdownType=0
+102
View File
@@ -0,0 +1,102 @@
# The classroom's window manager.
#
# The shape of this file is the argument for the whole architecture: window
# stacking, minimising, dialog placement and full-screen media are settings
# here, not code somewhere in the classroom.
[Compositing][$i]
Enabled=true
# Let KWin choose between OpenGL and software rendering by itself. A
# classroom machine that loses acceleration after a kernel update should
# come up slower, not blank.
WindowsBlockCompositing=true
AllowTearing=false
LatencyPolicy=Medium
[Desktops][$i]
Number=1
Rows=1
# One desktop, so a teacher cannot land on an empty one and conclude the
# computer has lost their work.
[Windows][$i]
Placement=Centered
FocusPolicy=ClickToFocus
AutoRaise=false
DelayFocus=0
FocusStealingPreventionLevel=1
# A dialog belongs to the window that opened it and stays with it. This is
# what keeps a print dialog in front of the page it is printing without
# anything in the classroom arranging it.
SeparateScreenFocus=false
ActiveMouseScreen=false
TitlebarDoubleClickCommand=Maximize
MaximizeButtonLeftClickCommand=Maximize
MaximizeButtonMiddleClickCommand=Maximize
MaximizeButtonRightClickCommand=Maximize
[MouseBindings][$i]
CommandAllKey=Meta
CommandAll1=Move
CommandAll2=Nothing
CommandAll3=Nothing
CommandTitlebarWheel=Nothing
CommandAllWheel=Nothing
[TabBox][$i]
# No window switcher overlay. The bottom bar is the way between windows.
ShowTabBox=false
[Plugins][$i]
# Effects the classroom uses, and nothing else. Every line that is false is
# an effect that will not be loaded at all.
blurEnabled=true
contrastEnabled=true
kwin4_effect_fadeEnabled=true
kwin4_effect_translucencyEnabled=false
kwin4_effect_dialogparentEnabled=true
kwin4_effect_squashEnabled=true
kwin4_effect_maximizeEnabled=true
kwin4_effect_scaleEnabled=true
kwin4_effect_fullscreenEnabled=true
slidingpopupsEnabled=true
screenedgeEnabled=false
cubeEnabled=false
desktopgridEnabled=false
overviewEnabled=false
windowviewEnabled=false
wobblywindowsEnabled=false
magiclampEnabled=false
slideEnabled=false
zoomEnabled=false
mouseclickEnabled=false
showfpsEnabled=false
thumbnailasideEnabled=false
kwin4_effect_dimscreenEnabled=false
kwin4_effect_morphingpopupsEnabled=false
[Effect-blur][$i]
BlurStrength=8
NoiseStrength=2
[org.kde.kdecoration2][$i]
library=org.kde.breeze
theme=Breeze
# A pin and a close button, and nothing else.
#
# The pin is the Live View story: keeping a window above the others is a
# window-manager state, not a feature the classroom has to invent. There is
# deliberately no minimise button, because a minimised window is the one
# thing a teacher cannot see the state of — measured, not assumed. Double
# clicking the title bar still maximises, so nothing is unreachable.
ButtonsOnLeft=
ButtonsOnRight=FX
ShowToolTips=false
BorderSize=None
BorderSizeAuto=false
[Script-desktopchangeosd][$i]
Enabled=false
[Xwayland][$i]
Scale=1
+48
View File
@@ -0,0 +1,48 @@
# Window rules.
#
# There are three, they are all about size, and none of them is about
# stacking. Dialogs staying in front of the window that opened them,
# secondary windows floating over the main one instead of resizing it, and
# a print dialog being the window in front are all ordinary window-manager
# behaviour here, so there is nothing to write down.
#
# `types=1` is NET::Normal only. Without it a rule that maximises would
# also maximise the dialogs, which is exactly the behaviour the classroom
# is moving away from.
[General]
count=3
rules=classroom-browser,classroom-wonderink,classroom-video
[classroom-browser]
Description=The classroom browser fills the screen
wmclass=google-chrome
wmclassmatch=1
wmclasscomplete=false
types=1
maximizehoriz=true
maximizehorizrule=3
maximizevert=true
maximizevertrule=3
[classroom-wonderink]
Description=Wonder Ink fills the screen
# Chrome derives this from the --app URL. Measured on a running session
# rather than guessed; it is also what the launcher's StartupWMClass says,
# and the two have to agree or the panel shows two buttons for one app.
wmclass=chrome-app.wonderink.org__-Default
wmclassmatch=1
wmclasscomplete=false
types=1
maximizehoriz=true
maximizehorizrule=3
maximizevert=true
maximizevertrule=3
[classroom-video]
Description=Video is an appliance screen, not a window
wmclass=vlc
wmclassmatch=2
wmclasscomplete=false
noborder=true
noborderrule=2
+16
View File
@@ -0,0 +1,16 @@
# Small cards, top right, out of the way of the bottom bar and of anything
# a teacher is reading. Plasma's own notification service does this; the
# classroom does not run a notification daemon of its own.
[Notifications][$i]
PopupPosition=TopRight
PopupTimeout=6000
LowPriorityPopups=false
LowPriorityHistory=false
[Jobs][$i]
PermanentPopups=false
InNotifications=true
[DoNotDisturb][$i]
WhenFullscreen=true
WhenScreensMirrored=false