R1 — Persisted wallpaper is now always the canonical /wallpapers/wallpaperN.jpg
form, never the resolved file:// URL. Swatch clicks pass WALLPAPER_PATHS[i]
(the relative path) to onWallpaperChange; the resolved URL stays in
wallpaperPreviewUrls for rendering only. This prevents machine-specific paths
from being written into project JSON and avoids break-on-upgrade /
break-on-share regressions. Legacy projects carrying resolved file:// URLs are
rewritten by a new normalizer in normalizeProjectEditor:
file://…(/assets)?/wallpapers/wallpaperN.jpg → /wallpapers/wallpaperN.jpg.
R2 — resolveImageWallpaperUrl now catches anything getAssetPath throws
(UnsafeAssetPathError, AssetBaseUnavailableError) and rewraps as
BackgroundLoadError with the original as cause. Callers (videoExporter retry
loop, gifExporter catch, VideoEditor toast) only need one instanceof check and
users always see the translated errors.exportBackgroundLoadFailed toast.
R3 — src/vite-env.d.ts no longer duplicates Window.electronAPI. The interface
had drifted — renderer declaration was missing readBinaryFile, getPlatform,
revealInFolder, getShortcuts, saveShortcuts, hudOverlay*, countdown overlay
methods that electron-env.d.ts already declares. Removed the duplicate and
kept the triple-slash reference so the authoritative declaration is the one
in electron/electron-env.d.ts.
N1 — GRADIENT_RE accepts optional "repeating-" prefix so
repeating-linear/radial/conic-gradient values classify as gradients instead
of falling through to color.
N2 — displayBasename returns "(unknown)" sentinel for URLs without a
meaningful basename (file:///, bare /) instead of leaking the original string.
N3 — electron-builder.json5 extraResources block gets an inline comment
pointing at preload.ts:assetBaseDir so the bidirectional coupling is
discoverable from either file.
Tests: 54 unit tests pass (up from 35). New coverage for repeating
gradients, displayBasename sentinels, BackgroundLoadError cause wrapping,
legacy file:// wallpaper normalization (5 cases).
Three independent defects plus one SSOT violation caused reported symptom
of image wallpapers rendering solid black in exported MP4/GIF while
appearing correctly in the editor preview.
Bug A — Dev-mode IPC handler returned <appPath>/public/assets/, but
wallpapers live at public/wallpapers/. No assets/ subdirectory exists in
source.
Bug B — FrameRenderer.setupBackground bypassed getAssetPath and did
window.location.origin + wallpaper, producing file:///wallpapers/*.jpg
404s in packaged Electron.
Bug C — setupBackground silently caught any background-load error and
filled black. Masked Bug B from the export pipeline; why the bug shipped.
Smell D — Asset layout asymmetric: public/wallpapers/ (dev) vs
resources/assets/wallpapers/ (packaged). assets/ subdirectory had no
other consumers.
Fixes:
- Unify asset layout. electron-builder extraResources now copies to
resources/wallpapers/ (no assets/). Main handler returns
<resourcesPath>/ packaged and <appPath>/public/ unpackaged. Same
convention in both modes: /wallpapers/x.jpg maps to <base>/wallpapers/x.jpg.
Nix package.nix mirror updated.
- New src/lib/wallpaper.ts module owns the wallpaper contract:
DEFAULT_WALLPAPER, classifyWallpaper (color/gradient/image), and
resolveImageWallpaperUrl (pure URL resolver, wraps getAssetPath).
BackgroundLoadError typed error for short-circuit detection.
- FrameRenderer.setupBackground uses the new helpers. Silent black
fallback removed; rethrows as BackgroundLoadError. Export pipeline
(VideoExporter + GifExporter) short-circuits encoder-retry loop on
BackgroundLoadError. VideoEditor catch site dispatches to translated
exportBackgroundLoadFailed toast.
- VideoPlayback editor preview consolidated onto the same helpers.
Three default-wallpaper path literals (useEditorHistory,
projectPersistence, VideoPlayback) collapsed onto DEFAULT_WALLPAPER.
- i18n: new errors.exportBackgroundLoadFailed key added to all seven
locales (en, zh-CN, zh-TW, es, fr, tr, ko-KR).
- Tests: 20 unit tests for wallpaper module (classifyWallpaper +
resolveImageWallpaperUrl branches + BackgroundLoadError).
videoExporter.browser.test.ts and gifExporter.browser.test.ts extended
with image-wallpaper happy path and BackgroundLoadError failure path.
Migration note: packaged users upgrading in place may retain an empty
resources/assets/ directory from the prior layout. Unreferenced at
runtime; cosmetic only. DMG/AppImage fresh installs get the new layout
directly.
- Add pacman package build target for Arch Linux in electron-builder.json5
- Update build:linux script in package.json to include pacman target
- Fix dialog window issues on Wayland/Hyprland:
* Pass mainWindow reference to dialog.showSaveDialog and dialog.showOpenDialog in electron/ipc/handlers.ts
* Required for proper dialog functionality on Wayland compositors
* Previously dialogs opened without parent window attachment causing issues on Hyprland
Changes ensure:
- Correct video export on Arch Linux + Hyprland systems
- Ability to install via pacman package manager
- Improved compatibility with Wayland compositors
Add a top-level publish config in electron-builder.json5 pointing to
GitHub Releases. This embeds the update information URL in the AppImage
header, enabling tools like AppImageUpdate, AppImageLauncher, and
AppManager to perform delta updates instead of full re-downloads.
Also update the Linux build workflow to upload the generated .zsync file
alongside the .AppImage artifact.
Fixes#219
Change compression from "maximum" to "normal" for electron-builder.
The "maximum" compression setting causes gzip/xz compression in the
squashfs filesystem, which has extremely poor random access performance
(~35 MB/s). This results in 50+ second boot times on Linux AppImage
releases due to FUSE overhead during Electron's many small file reads
at startup.
With "normal" compression, the AppImage uses faster decompression
algorithms, dramatically improving startup time while only marginally
increasing package size.
Refs: electron-userland/electron-builder#6317
Refs: electron-userland/electron-builder#7483