142 lines
6.9 KiB
Plaintext
142 lines
6.9 KiB
Plaintext
# Sway kiosk session for the thin client.
|
|
# Installed to /home/<KIOSK_USERNAME>/.config/sway/config by build-thin-client-iso.sh.
|
|
#
|
|
# Every `exec` below inherits the environment set by /usr/local/bin/kiosk-session,
|
|
# which sources /etc/thinclient-agent/config.env — that is how $DIGEST_WEB_URL gets
|
|
# here without this file being templated.
|
|
|
|
set $mod Mod4
|
|
set $ws_web 1:web
|
|
set $ws_digest 2:digest
|
|
set $ws_media 3:media
|
|
|
|
# Workspace names are a contract with thinclient_agent/digest_canvas.py and
|
|
# thinclient_agent/sway_control.py — changing one side means changing the other.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Output / input
|
|
# ---------------------------------------------------------------------------
|
|
output * bg #101014 solid_color
|
|
|
|
input type:keyboard {
|
|
xkb_layout @KEYBOARD_LAYOUT@
|
|
}
|
|
|
|
input type:touchpad {
|
|
tap enabled
|
|
natural_scroll enabled
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Look — no bars, no borders. Primary control is HA/MQTT and wayvnc; the local
|
|
# display is a media surface, not a desktop.
|
|
# ---------------------------------------------------------------------------
|
|
default_border none
|
|
default_floating_border none
|
|
hide_edge_borders both
|
|
gaps inner 0
|
|
gaps outer 0
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Remote control
|
|
# ---------------------------------------------------------------------------
|
|
# exec_always so a `swaymsg reload` re-establishes it. start-wayvnc refuses to run
|
|
# until /etc/wayvnc/wayvnc-password has been set on this machine.
|
|
exec_always /usr/local/bin/start-wayvnc
|
|
|
|
# Now-playing widget. Session-scoped (dies with sway, unlike thinclient-agent) — see
|
|
# fullscreen-watcher.sh's own comment for why it isn't part of the system service.
|
|
# Its own PID-file guard makes exec_always safe across `swaymsg reload`.
|
|
exec_always /usr/local/bin/fullscreen-watcher
|
|
|
|
# Camera gesture control. Session-scoped for the same blast-radius reason as the widget
|
|
# above, plus a privacy one: the camera must not be open while there is no session whose
|
|
# pointer it could move. It no-ops both when the image was built without it and when
|
|
# gesture-config.json still has the default "enabled": false — see the wrapper.
|
|
exec_always /usr/local/bin/gesture-control
|
|
|
|
# thinclient-agent is NOT started here. systemd owns it (thinclient-agent.service,
|
|
# enabled by 0700-thinclient-agent.hook.chroot) so that it is up and connected to
|
|
# Mosquitto whether or not a graphical session ever comes up, and so it survives a
|
|
# sway restart. Starting it from sway too would give two competing MQTT clients.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Applications
|
|
# ---------------------------------------------------------------------------
|
|
# No `assign [app_id=...]` rules here on purpose: both digest-browser and web-browser
|
|
# (added for the minimal-chrome general-browsing app) launch the same firefox-esr
|
|
# app_id on different profiles, and `assign` cannot tell those two windows apart —
|
|
# it would fight thinclient_agent.sway_control.launch_app()'s switch-workspace-then-
|
|
# launch approach for whichever one it matched. Every launch path, including the one
|
|
# below, is therefore explicit about its own workspace instead.
|
|
# Steam Link runs under Xwayland (native Wayland black-screens on wlroots), so it
|
|
# appears as an X11 class, not a Wayland app_id.
|
|
assign [class="steamlink"] $ws_media
|
|
for_window [class="steamlink"] fullscreen enable
|
|
for_window [app_id="mpv"] fullscreen enable
|
|
|
|
# Guarded so a powered-off container host (or an unset DIGEST_WEB_URL) leaves an
|
|
# empty workspace instead of hanging the session — Phase 11.10. The explicit
|
|
# `swaymsg workspace` mirrors launch_app()'s own switch-then-launch order, since this
|
|
# runs before thinclient-agent's MQTT-driven launches ever fire.
|
|
exec sh -c '[ -n "$DIGEST_WEB_URL" ] && { swaymsg workspace $ws_digest; /usr/local/bin/digest-browser "$DIGEST_WEB_URL/full.html?detail_level=full"; }'
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Idle
|
|
# ---------------------------------------------------------------------------
|
|
# Never lock: this is an always-on shared media station, and a lock screen would make
|
|
# the room's display unusable to anyone who isn't holding a keyboard. Any wayvnc or
|
|
# local input resumes it.
|
|
#
|
|
# After 15 minutes, idle-gallery replaces the old unconditional "blank the panel"
|
|
# behaviour with a photo slideshow from the gallery SMB share (Phase 11 follow-up) —
|
|
# but it degrades all the way back to that exact blank-the-panel behaviour itself if
|
|
# no share is configured, unreachable, or empty, so a freshly-built or offline thin
|
|
# client behaves exactly as before. See configs/idle-gallery/idle-gallery.sh.
|
|
exec swayidle -w \
|
|
timeout 900 '/usr/local/bin/idle-gallery' \
|
|
resume 'swaymsg "output * power on"; /usr/local/bin/idle-gallery stop'
|
|
|
|
# Media playback keeps the screen alive.
|
|
for_window [class="steamlink"] inhibit_idle focus
|
|
for_window [app_id="mpv"] inhibit_idle focus
|
|
for_window [app_id="firefox-esr"] inhibit_idle fullscreen
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Local override keys — a fallback for standing in front of the machine, not the
|
|
# primary control surface.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Maintenance shell. A deliberately obscure chord (not $mod+Return, which is the
|
|
# ordinary local-terminal key above it) so it is not something a visitor bumps into,
|
|
# floating so it overlays the kiosk content instead of tiling against it. It only opens
|
|
# a shell — it does not pause thinclient-agent or anything else, since standing at the
|
|
# machine already means treating it as a maintenance session; if that turns out to be
|
|
# too little, tightening it is a config change here, not a new subsystem.
|
|
bindsym $mod+Shift+Ctrl+m exec foot --title maintenance-shell
|
|
for_window [title="maintenance-shell"] floating enable, resize set width 800 height 500, move position center
|
|
|
|
bindsym $mod+Return exec foot
|
|
bindsym $mod+q kill
|
|
bindsym $mod+f fullscreen toggle
|
|
bindsym $mod+Shift+c reload
|
|
bindsym $mod+1 workspace $ws_web
|
|
bindsym $mod+2 workspace $ws_digest
|
|
bindsym $mod+3 workspace $ws_media
|
|
bindsym $mod+Left focus left
|
|
bindsym $mod+Right focus right
|
|
bindsym $mod+Up focus up
|
|
bindsym $mod+Down focus down
|
|
|
|
bindsym XF86AudioPlay exec playerctl -p mpv,spotifyd play-pause
|
|
bindsym XF86AudioNext exec playerctl -p mpv,spotifyd next
|
|
bindsym XF86AudioPrev exec playerctl -p mpv,spotifyd previous
|
|
bindsym XF86AudioRaiseVolume exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
|
bindsym XF86AudioLowerVolume exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
|
bindsym XF86AudioMute exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
|
|
|
# Deliberately no exit binding: `swaymsg exit` would drop to a black VT, and greetd
|
|
# would just autologin straight back in. Use SSH or the local terminal to administer.
|
|
|
|
workspace $ws_digest
|