Repository navigation
Dockerfile update plasma desktop - #394
PierreBeucher wants to merge 41 commits into
Conversation
- plasma-desktop + plasma-workspace + breeze theming per Selkies egl-desktop recipe, stock kwin_x11 first (patch later only if it misbehaves on Xorg-dummy); noble ships Plasma 5.27 so session comes from plasma-workspace (startplasma-x11), no plasma-session-x11 package - start-desktop.sh: startplasma-x11, drop xfce4 wiring - drop xfce4-default config overlay + setup-xfce4-* scripts, xsettings theme application (Plasma applies Breeze itself) - role compose: persist plasma workspace config instead of xfce4 - dev inventory: drop xfce4-default debug mount
- cloudypad-*.desktop launcher files in /usr/share/applications mirroring the former XFCE dock: Steam, Epic, GOG, Heroic, Lutris, Firefox, Konsole, Files (dolphin /cloudy/data), Keyboard/Mouse settings (systemsettings5), Help, Exit - plus systemsettings package - cloudypad-wallpaper.svg installed to /usr/share/wallpapers - setup-plasma-default-desktop.sh: waits for plasmashell then applies wallpaper + task manager pins via org.kde.PlasmaShell.evaluateScript (additive live change, mirrors old setup-xfce4-default-wallpaper pattern)
Cloudy Pad is a headless streamed desktop: Plasma screen locker would lock the user out of their own instance after idle timeout (default ~5min). Disable autolock and lock-on-resume via kscreenlockerrc in the image. Suspend is not possible in-container (no logind) so no powerdevil config needed.
…ttings" This reverts commit 6a18b38dde95f6e346ff8cf5748f65566fa4b69d.
- cloudypad-*.desktop launchers (Steam, Epic, GOG, Heroic, Lutris, Files, Keyboard/Mouse settings, Help, Exit) shipped in overlay conf/cloudypad/ applications/, discovered via XDG_DATA_DIRS (Dockerfile ENV + compose env) - conf/plasma-default/plasma-org.kde.plasma.desktop-appletsrc: default Plasma config with the launchers pinned in the task manager [Configuration][General] group - NOT via the plasmashell scripting API which writes keys to the wrong [Configuration] level (renders one blank broken icon, see script header note) - setup-plasma-default-desktop.sh: seed default appletsrc from overlay when missing (user customizations preserved on restart, XFCE setup-xfce4-default-config pattern) - start-desktop.sh: seed config + rebuild KSycoca services cache BEFORE starting the session (plasmashell caches service lookups at startup; stale cache also renders pins blank)
- mount conf/plasma-default/ into the container on dev VM (sunshine_extra_volumes) so Plasma config changes in the overlay land with a simple container restart, no image rebuild - CLOUDYPAD_PLASMA_DEFAULT_FORCE env (sunshine_plasma_default_force var, default false): re-seed the default appletsrc over the persistent config at each container start in dev; prod keeps seed-once semantics so user customizations survive restarts - dev inventory enables the force flag with rationale
- base image ubuntu:26.04 (pinned SHA), Sunshine ubuntu26.04 asset - Plasma 6.6.6: plasma-session-x11 + kwin-x11 packages (Plasma 6 naming), start-desktop.sh kbuildsycoca version-agnostic (6 then 5), launchers Exec systemsettings (Plasma 6 binary name) - Steam: --allow-downgrades on steam-libs (resolute ships newer i386 libs than Steam pins; Steam runtime containers bundle their own libs) - validated on dev VM: Plasma 5-format appletsrc seeds fine on Plasma 6, launchers render, stock kwin_x11 needs no patches, proton_stable mapping
…ance restarts XDG_CONFIG_HOME pointed to the ephemeral Cloudy Pad conf dir: Plasma user settings (panel layout, mouse, keyboard layout) were lost on container recreation and instance stop/start as the container rw layer lives on the root disk which reverts to the base image snapshot. - point XDG_CONFIG_HOME to the persisted home ($HOME/.config, bind-mounted to the data disk): session/user config persists, defaults stay ephemeral - symlink $HOME/.config/sunshine to CLOUDYPAD_CONF_DIR/sunshine so Sunshine appdata (apps.json, assets, covers) keeps resolving to image-managed conf - seed Plasma defaults (appletsrc, kscreenlockerrc) from CLOUDYPAD_CONF_DIR into persisted config, only when missing (user customizations preserved) - move Heroic config mount to the new $HOME/.config/heroic path (same host source, existing state carries over), drop dead plasma-workspace mount - resolve sudo lecture files from conf dir (cloudy-managed, not user state)
…isorctl socket - capture backend is now templated from CLOUDYPAD_SUNSHINE_CAPTURE compose env: nvfbc on datacenter (Tesla) GPUs - atomic GPU capture avoids stream tearing on fullscreen unredirected games and skips the CPU framebuffer copy - and x11 everywhere else (NvFBC is driver-blocked on GeForce). start-sunshine.sh defaults to x11 so a stale compose without the var never renders an empty capture setting - disable Baloo file indexer via seeded baloofilerc: it has no use on a headless streamed desktop and can cause IO/CPU stutters walking large game libraries on the data disk - restore supervisord control socket (unix_http_server + supervisorctl + rpcinterface) dropped in the Plasma rework, so supervisorctl works in-container again for debugging
…airer tests - remove dev-sunshine-pin.sh + dev:pin task (duplicates cloudypad pair CLI), fix stale supervisorctl and dev:pin references in reset script - remove nvidia-drm-hold service/tasks (stale labwc/Wayland rationale, X11 stack does not need it) - dedupe sunshine_csrf_allowed_origins in dev-vagrant inventory - remove Wayland-justified tmpfs /cloudy/runtime from compose - rename xfce4-dbus-session-bus-address to dbus-session-bus-address - cleanup contribution guide: xfce mount refs, .cursor/rules refs - trim unusable systemtray applets from default Plasma appletsrc - restore autostop timeout default selection (900) in prompter - add Sunshine pairer unit tests (pairing_id flow)
… 60px panel) - ship default look in overlay conf/plasma-default/: BreezeDark theme (kdedefaults/kdeglobals, package, ksplashrc) and 60px panel (plasmashellrc [PlasmaViews][Panel 2][Defaults]) - seed defaults on NEW instances only: freshness gate detects a config dir already used by a Plasma session (session-written files) and keeps whatever existing instances have; protective seeds (kscreenlockerrc, baloofilerc) still apply when missing on any instance - apply default look AFTER session start (apply-plasma-default-lookandfeel.sh): Plasma first-session startup overrides pre-seeded theme files with the stock light theme, so the look is applied via plasma-apply-lookandfeel once plasmashell is up, gated by an ephemeral flag file - move kscreenlockerrc/baloofilerc under conf/plasma-default/ (all seeds in one place) - dev inventory: force re-seed feedback loop applies to all look & feel defaults
- pair CLI command: --pin sends a given PIN (non-interactive), --auto generates a PIN, prints the moonlight pair command and sends it - pairAuto() on pairer/manager/runner: auto branch extracted from the interactive flow, no prompts - Sunshine pairer: persistent SSH connection across polls with 1s interval (was: reconnect per attempt, 2s interval) - Moonlight only waits a few seconds for the PIN confirmation, confirmation must land fast - default retry budget raised to ~2 min (120 x 1s) to cover Moonlight's handshake + confirmation window - hack/dev-pair.sh + task dev:pair: fully non-interactive pairing, removes stale same-hostname Moonlight entries (destroyed/recreated instances keep old server identity, blocking pairing), 10s pairer confirmation health bar with fail-fast diagnostics, end-to-end verification via moonlight list - unit tests for pairing_id flow, multi-pending skip, retry and pairAuto
…g pairing supervisord tracked the start script shell instead of Sunshine itself, so restarts signaled only the shell: Sunshine survived as an orphan keeping 47984/48010 bound while the new process could only serve the web UI (Fatal: Couldn't bind RTSP server to port 48010) - Moonlight pairing then failed with 'PC offline' loops and no pending pairing session on the API. - start-sunshine.sh: exec sunshine so the supervised process IS sunshine (supervisorctl tracks its real PID) - supervisord.conf: stopasgroup/killasgroup on all long-running programs, restarts stop the whole process group (also covers Sunshine's internal privilege-drop fork) Verified on a Scaleway instance: supervisorctl restart sunshine leaves exactly one process with all ports bound, pairing unaffected.
| #!/usr/bin/env bash | ||
|
|
||
| # | ||
| # Apply the Cloudy Pad default look & feel (Breeze Dark) after the Plasma | ||
| # session is up, on fresh instances only. | ||
| # | ||
| # Why after session start: on a fresh user config, Plasma session startup | ||
| # applies the default look & feel (Breeze, light) and overwrites the theme | ||
| # files seeded before the session (kdedefaults/*, kdeglobals) - the pre-session | ||
| # seed cannot win. Applying via plasma-apply-lookandfeel AFTER the session is | ||
| # up is the same code path as System Settings and the result persists across | ||
| # container restarts and instance stop/start. | ||
| # | ||
| # Gated by a flag file written by setup-plasma-default-desktop.sh when the user | ||
| # config is fresh (new instance, or CLOUDYPAD_PLASMA_DEFAULT_FORCE in dev). | ||
| # The flag lives in XDG_RUNTIME_DIR: wiped on container restart, so this runs | ||
| # at most once per fresh instance boot. | ||
| # | ||
|
|
||
| DEFAULT_LOOKANDFEEL_PACKAGE="org.kde.breezedark.desktop" | ||
|
|
||
| FLAG=$XDG_RUNTIME_DIR/cloudypad-apply-plasma-default-lookandfeel | ||
| if [ ! -f "$FLAG" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Fresh Plasma config detected: waiting for session to apply default look & feel..." | ||
|
|
||
| # Wait for plasmashell (up to 120s) | ||
| PLASMASHELL_UP=false | ||
| for i in $(seq 1 60); do | ||
| if pgrep -x plasmashell > /dev/null 2>&1; then | ||
| PLASMASHELL_UP=true | ||
| break | ||
| fi | ||
| sleep 2 | ||
| done | ||
|
|
||
| if [ "$PLASMASHELL_UP" != "true" ]; then | ||
| echo "Warning: plasmashell did not start within timeout, cannot apply default look & feel" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Let the session settle: the default (light) look & feel is applied during | ||
| # session startup, give it time to complete before overriding | ||
| sleep 10 | ||
|
|
||
| source export-dbus-address.sh | ||
|
|
||
| if plasma-apply-lookandfeel --apply "$DEFAULT_LOOKANDFEEL_PACKAGE"; then | ||
| echo "Default look & feel applied: $DEFAULT_LOOKANDFEEL_PACKAGE" | ||
| rm -f "$FLAG" | ||
| else | ||
| echo "Warning: failed to apply default look & feel $DEFAULT_LOOKANDFEEL_PACKAGE" >&2 | ||
| fi |
There was a problem hiding this comment.
Is this still needed since we have default config in Overlay? I don't care anymore about "forcing default" with env var. I just need the overlay data in the base image to be used as default, and runtime overrides to be kept between restart.
There was a problem hiding this comment.
🤖 Answer: still needed, the overlay alone can't cover it. The sequence problem: on a fresh user config, Plasma session startup applies its own default look & feel (Breeze, light) AFTER the session starts and overwrites the theme files seeded before the session (kdedefaults/*, kdeglobals) — the pre-session seed cannot win. So the flow is: (1) overlay seed pre-session via setup-plasma-default-desktop.sh, (2) re-apply the Cloudy Pad default look via plasma-apply-lookandfeel once the session is up — the same code path System Settings uses, so the result persists across restarts.
Runtime overrides are kept between restarts as you asked: the applier is gated by a flag file in XDG_RUNTIME_DIR (wiped on container restart), so it runs at most once per fresh instance — on existing instances the flag is absent and the script exits immediately. No env var involved anymore since the force-reseed removal.
There was a problem hiding this comment.
🤖 Update (5faf068): right — and the analysis showed the L&F overlay files were worse than redundant, they were provably ineffective: on a fresh config, Plasma session startup applies its own look & feel after the seed (that's the very behavior that forced the applier into existence). Removing them changes nothing visible.
Removed from the overlay: kdedefaults/kdeglobals, kdedefaults/ksplashrc, kdedefaults/package (all L&F-related). The overlay now holds only what the applier structurally cannot do:
plasma-org.kde.plasma.desktop-appletsrc: panel layout + task manager launcher pins (scripting API proven broken for pins)plasmashellrc: 60px panel thicknesskscreenlockerrc,baloofilerc: protective seeds (never auto-lock, disable indexer)
Clean separation now: overlay = shell layout + protective seeds, applier = look & feel. Failure mode unchanged (applier failure → stock light theme, same as today since the seed was overwritten anyway). One item to eyeball in dev VM: kdedefaults/package removal — I'm confident it's inert (BreezeDark ships no shell layout template and our full appletsrc seed preempts template use), but worth a once-over on first boot.
- Remove CLOUDYPAD_PLASMA_DEFAULT_FORCE / sunshine_plasma_default_force: force-reseed was only a dev helper; keep seed-once semantics and test default overlay config on fresh containers instead - Taskfile dev-docker-sunshine-to-vm: extract multi-line cmds into hack/dev-docker-sunshine-to-vm.sh - start-sunshine.sh: render csrf_allowed_origins via the sunshine.conf template (envsubst) instead of appending to the rendered file; drop the trailing-newline workaround now that nothing is appended - start-sunshine.sh: fail at start when template variables are unset (envsubst renders unset vars as empty strings, silently producing an invalid config) instead of defaulting capture to x11 in-script: the x11/nvfbc default now lives in compose templates only - sunshine.conf.template: restore original state-files comment
|
🤖 Addressed the review comments in commit 5779d5c (single commit for review): Code changes
Comments answered without code (details in each thread)
|
- Remove CLOUDYPAD_PLASMA_DEFAULT_FORCE / sunshine_plasma_default_force: force-reseed was only a dev helper; keep seed-once semantics and test default overlay config on fresh containers instead - Taskfile dev-docker-sunshine-to-vm: extract multi-line cmds into hack/dev-docker-sunshine-to-vm.sh - start-sunshine.sh: render csrf_allowed_origins via the sunshine.conf template (envsubst) instead of appending to the rendered file; drop the trailing-newline workaround now that nothing is appended - start-sunshine.sh: explicit template variables check before envsubst, failing hard when a variable is UNSET (empty-but-set allowed); keep x11 capture default in-script as a safety net for stale compose files - docker-compose.nvidia.yml: move capture override into the datacenter GPU block, drop redundant x11 rewrite for GeForce - dev-vagrant.yml: drop duplicate capture=x11 additional config (compose x11 default suffices), update Plasma debug mounts comment - sunshine.conf.template: restore original state-files comment
63891ad to
8b83b62
Compare
- Dockerfile: drop 2025.x asset naming note, trim Selkies NOTE block - dev-pair.sh: never touch Moonlight config (detect stale host entry, ask user to remove), log pairer confirmation, stop waiting on Moonlight (grace window then kill, moonlight list stays the verdict) - Sunshine state reset: rewrite as ansible/dev-reset-sunshine-state.yml reusing the dev-vagrant inventory, wrapped as task dev:reset-sunshine-state - Pairer: reset Sunshine pairing state before pairing (stop, wipe state files, restart) then purge stale pending sessions via DELETE /api/pin, so any pending pairing seen during pairing is ours - Pairer unit tests updated for the new deterministic pairing flow
Sunshine appdata (XDG_CONFIG_HOME/sunshine) was a symlink to the ephemeral image-managed conf dir, so user state was lost on container recreation: - apps.json (user-added apps via Web UI) - covers/ (user-uploaded game covers, hardcoded to appdata/covers) Instead, start-sunshine.sh now materializes a real appdata dir in the persisted user home ($XDG_CONFIG_HOME/sunshine): - seed apps.json from the image when missing (new instances, or user deleted it): Cloudy Pad app list, never overwrites user edits - refresh cover images from the image on every start (static, tiny: image updates land without recreation) - symlink covers/ to the persisted data dir (dir is hardcoded by Sunshine, symlink is the only way to persist it) - render sunshine.conf into the appdata dir and pass it explicitly setup-dirs.sh drops the symlink line: back to purely generic XDG hygiene.
Resetting Sunshine state (supervisorctl stop, wipe state files, restart) would restart the Sunshine server in the middle of the pairing flow and clobber an in-flight Moonlight pairing handshake - rollback of option 2. Keep option 3: purge stale pending pairing sessions via DELETE /api/pin before the pairing flow, so any pending session seen during the pairing window is ours (no restart involved).
Desktop launchers (cloudypad-*.desktop) and icons lived under the
Cloudy Pad conf dir (conf/cloudypad) exposed via a custom
XDG_DATA_DIRS entry - both in the Dockerfile and the compose template
(setting the identical value, redundant).
Config vs data separation: launchers and icons are XDG *data* (read-only
resources discovered by Plasma), not config. Move them to the standard
system path /usr/local/share/cloudypad (overlay/usr/local/share), which
is part of the default XDG_DATA_DIRS chain: no custom env entry needed
anywhere.
- overlay/usr/local/share/cloudypad/{applications,icons}: launchers and
icons moved from conf/cloudypad
- conf/cloudypad keeps only sudo/ (password-secured config, not XDG data)
- epic/gog .desktop icon paths updated to /usr/local/share/cloudypad/icons
- Dockerfile: drop custom XDG_DATA_DIRS entry
- compose template: drop the redundant XDG_DATA_DIRS entry
- dev-vagrant.yml: debug bind mount follows the new path
The kdedefaults/ theme seeds (kdeglobals, ksplashrc, package) were provably ineffective: on a fresh user config, Plasma session startup applies its own default look & feel (Breeze, light) AFTER the pre-session seed and overwrites the theme files. The post-session applier (apply-plasma-default-lookandfeel.sh, plasma-apply-lookandfeel) is the only mechanism that wins - the overlay theme files just duplicated it. Overlay now holds only what the applier cannot do: - plasma-org.kde.plasma.desktop-appletsrc: panel layout + task manager launcher pins (scripting API proven broken for pins) - plasmashellrc: 60px panel thickness - kscreenlockerrc, baloofilerc: protective seeds (never auto-lock, disable file indexer)
Desktop launchers (cloudypad-*.desktop) now ship in the image at /usr/local/share/applications and icons at /usr/local/share/pixmaps: both are standard XDG_DATA_DIRS system paths scanned by Plasma by default, so launchers and icons resolve without any custom env var. (/usr/local/share/cloudypad was not on the XDG chain, which broke icon/launcher discovery.) - epic/gog icons referenced via /usr/local/share/pixmaps absolute paths - dev VM bind mounts follow the new paths - Dockerfile XDG_DATA_DIRS stays on the default chain (no conf-dir hack)
- cloudypad-mouse launcher: input-mouse icon instead of input-tablet - cloudypad-help launcher: help-about icon instead of help-contents - Dockerfile: set SHELL=/bin/bash globally (supervisord children, session processes and docker exec shells inherit it): Konsole warned 'could not find ""' on every open, falling back to /bin/bash, as no process had $SHELL set - setup-sudo.sh: fix latent undefined SUDO_LECTURE_DIR variable in mkdir (use dirname of lecture file); add set -euo pipefail so this class of bug cannot pass silently
Game launchers (Steam, Heroic, Epic, GOG, Lutris) set StartupNotify=false, inherited from upstream steam.desktop, so Plasma showed no loading indicator on click (KIO marks non-notifying apps silent, see kio kprocessrunner.cpp checkStartupNotify). Set StartupNotify=true with StartupWMClass per launcher: spinner clears when a window matching the class maps, no dependency on apps implementing the startup notification protocol (Heroic for Epic/GOG which run inside it). Steam startup is slow and sometimes shows no window for tens of seconds (steamwebhelper, see ValveSoftware/steam-for-linux#10775), which feels like a crash. Desktop launcher now opens a minimal xterm log viewer: - steam-start.sh always detaches Steam with setsid (terminal close no longer kills Steam, SIGHUP goes to the console session only) and logs to $CLOUDYPAD_LOG_DIR/steam-user.log while tail --pid follows it, so the console closes automatically when Steam exits and logs persist - xterm over konsole: konsole toolbars (New Tab, Split View, Copy...) cannot be hidden on Konsole 25.12 (no --hide-toolbars) while xterm is bare by design
Simplify sudo setup: cloudy user gets passwordless sudo, no lecture file and no sudo password. Container changes are not persistent by nature, which is already stated in documentation and on-site help launcher. Rationale: sudo on Ubuntu 24.10+/26.04 is sudo-rs which has no lecture feature (trifectatechfoundation/sudo-rs#400) - unknown Defaults abort every sudo call, and PAM-based echoes are suppressed by sudo-rs' silent mode for direct invocations. Generating a sudo password and warning file cannot work reliably on all supported bases; passwordless access removes the whole class of problem.
…ers, clean-instance workflow)
No description provided.