Introduction¶
The DSH workbench is a persistent window; it stays open for hours. Solid backgrounds can cause eye strain over time, but very few skin plugins actually “put a wallpaper behind the interface” – they mostly just change the color scheme. Existing approaches usually involve manually grabbing an image and stuffing it into CSS; it breaks when the port changes or file paths change, and there is no proper place for image caching.
The dsh-skin (NPM package name dsh-skin-bg) introduced below is designed for this purpose: it places image bed direct links, local images, and Wallpaper Engine library assets behind the DSH interface, accompanied by transparency, blur, carousel, and shortcuts. The plugin is maintained by Avan0203, categorized under “Fun Skins” in the community directory, and is licensed under MIT.
What is it¶
In short: This is a DSH interface skin plugin that renders the wallpaper behind the application framework, reads local media using same-origin HTTP routes, and manages sources and appearance in the settings page.
It solves three problems:
- The Web UI runs on
http://127.0.0.1:<port>. Browsers cannot readfile://paths, andlocalStoragefails when the port changes—so configuration and media are placed on the Host side. - There are multiple wallpaper sources (Image beds, local, Wallpaper Engine), and they need to be mutually exclusive. The playlist must be rebuilt immediately upon switching.
- Changing the wallpaper should not affect operation: Popups must remain solid, shortcuts must be editable, and other skin plugins should not overwrite colors when enabled simultaneously.
Core Capabilities¶
Three Wallpaper Sources¶
Choose one; the list reloads and the playlist is rebuilt immediately upon switching.
- Image Bed Links: One
https://…direct link per line, up to 100 items. Supportspng jpg jpeg jfif webp gif avif bmp svgformats, and acceptsmp4 webm ogv mov m4vvideos. Every switch includesfresh=1to fetch a new image and save it by address; old images remain in “Loaded Images” and persist after restart. - Local Images: Enter a single file or an entire directory, with a maximum of 200 files and 50 directories respectively; you can also import a folder by clicking “Select Folder” in settings (this imports a copy; the original file remains untouched).
- Wallpaper Engine: Points to the Wallpaper Engine Workshop
431960directory or any downloaded wallpaper directory, automatically scanning for images and videos. Videos play in a muted loop.
Appearance and Playback¶
Three sliders control the hierarchy: Wallpaper Opacity (0–100), Interface Opacity (0–100, the lower the value, the more visible the wallpaper is), and Gaussian Blur (0–80 px). The transparency of the interface layer is implemented by rewriting the alpha of --dsw-alias-bg-base, --dsw-specific-sidebar-fill, --dsw-alias-bg-layer-1/2, and --dsw-alias-bg-overlay. It reads the current token values, so colors changed by other skins will still show through the wallpaper; popups use an opaque copy of the same token, ensuring [role="dialog"] and [aria-modal="true"] remain solid.
Regarding the carousel: interval 3 seconds to 24 hours, random order, 0–5 seconds crossfade; videos can be set to “auto-switch after playing” or loop, and are muted by default (automatically falls back to muted if blocked by the browser from autoplaying).
Shortcuts and Persistence¶
Two commands, dsh-skin-bg.next and dsh-skin-bg.previous, correspond to Next / Previous. The default keys are Ctrl+Alt+←/→ on Windows/Linux, and ⌘+⌥+Shift on macOS. These can be changed in Settings -> General -> Shortcuts. If registration fails, the panel will explain it; it won’t be silently ignored.
Configuration is saved at $DSH_HOME/data/dsh-skin/config.json; the media route supports Range, allowing video scrubbing. The interface is bilingual (English/Chinese) and follows the DSH language settings.
Installation and Enablement¶
The plugin only renders on the Web UI. The prerequisite is that DSH (Desktop version or dsh web) has the webServer service enabled. DSH plugins are regular npm packages installed in the profile. There is no unified dsh plugin add command; you need to manually enter the profile directory.
Method 1: Install from GitHub (Recommended in README):
cd "$HOME/.dsh/profiles/desktop"
pnpm add github:Avan0203/dsh-skin
On Windows, the profile defaults to %USERPROFILE%\.dsh\profiles\desktop. Then edit package.json in the same directory, adding the package name to dsh.profile.bundles:
{
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"dsh-skin-bg"
]
}
}
}
Restart DSH and open Settings -> Background Wallpaper. Note a common pitfall: The repository name is dsh-skin, but the NPM package name is dsh-skin-bg—the name dsh-skin is already occupied by another plugin in the npm and plugin market indices, so you must write dsh-skin-bg in bundles.
Method 2: Use the compressed package from Releases:
cd "$HOME/.dsh/profiles/desktop"
pnpm add ./dsh-skin-bg-1.0.3.tgz
Download dsh-skin-bg-<version>.tgz from Releases (if a specific version does not include a compressed package, use Method 1 or the “Source code” zip generated by GitHub). Similarly, add "dsh-skin-bg" to dsh.profile.bundles and restart.
Method 3: Local development link, suitable for code modification:
git clone https://github.com/Avan0203/dsh-skin.git
cd "$HOME/.dsh/profiles/desktop"
pnpm add link:/绝对路径/dsh-skin
Afterward, modifying client.js will take effect upon refreshing the page, while modifying index.js (Host side) requires restarting DSH.
Package Name Change on Upgrading to 1.0.x¶
The package name changed from dsh-skin to dsh-skin-bg. Upgrade steps:
- Replace
dsh-skinwithdsh-skin-bgin the profile’spackage.json(both in dependencies anddsh.profile.bundles); - Run
pnpm installand restart DSH.
Settings and archived wallpapers will not be affected: the data directory remains $DSH_HOME/data/dsh-skin/, and the HTTP route prefix remains /plugin-skin. The only thing that changes is the shortcut ID (dsh-skin.next → dsh-skin-bg.next). If you have customized keys, you need to reset them in Settings -> General -> Shortcuts.
Configuration¶
Settings are saved at $DSH_HOME/data/dsh-skin/config.json; you can also edit this file directly, then restart DSH or open the settings page to save. Common fields are as follows:
| Field | Default Value | Range / Values | Description |
|---|---|---|---|
enabled |
true |
Boolean | Disables the wallpaper layer immediately when turned off. |
source |
"urls" |
urls / local / wallpaper |
The currently used source. |
urls |
[] |
Max 100 items | Direct links to image beds. |
folders |
[] |
Max 50 items | Directories for local images/videos. |
files |
[] |
Max 200 items | Single local media files. |
cacheUrls |
true |
Boolean | When enabled, each switch to an image bed image triggers a re-download and separate save; when disabled, it directly requests the image bed without saving to disk (history archives will still be listed). |
cacheDir |
"" |
Path | If left empty, uses $DSH_HOME/data/dsh-skin/library. |
wallpaperDir |
"" |
Path | Wallpaper Engine workshop directory. |
opacity |
100 |
0–100 | The opacity of the wallpaper itself. |
surfaceOpacity |
62 |
0–100 | Opacity of the main interface panels. |
blur |
0 |
0–80 | Gaussian blur of the wallpaper (in pixels). |
intervalSec |
30 |
3–86400 | Carousel interval (in seconds). |
random |
false |
Boolean | Random playback order. |
advanceOnEnd |
true |
Boolean | Automatically switch to the next image when a video finishes. |
videoMuted |
true |
Boolean | Videos are muted by default. |
fadeSec |
1.2 |
0–5 | Duration for crossfading between two wallpapers (in seconds). |
Typical Usage¶
After installation, open Settings -> Background Wallpaper and configure in the following order:
- Select a source (Image Bed Links / Local Images / Wallpaper Engine) from the list; the list reloads immediately upon switching.
- Fill in the source: paste image bed direct links, add local files or directories, or fill in the Wallpaper Engine directory and click “Rescan”.
- Adjust appearance: First set the “Interface Opacity” between 40 and 70 so both the wallpaper and controls are visible; add blur to 10–20 px if you want a cleaner background.
- Set playback: Determine the carousel interval according to your own rhythm; set a small interval if you want the background to change frequently. Keep the default muted if you don’t want sound from videos.
- Use shortcuts to switch images:
Ctrl+Alt+←/→. If you want the wallpaper to appear only when you are not using DSH, it is more direct to use theenabledtoggle or lower theopacityrather than changing the shortcuts.
Images from the image bed source are cached in folders by address, and the list displays a maximum of the most recent 5000. Click a thumbnail in “Loaded Images” to switch immediately; hover and click × to delete a single image; clicking “Clear” in the top-right only clears the address list for the current source, it does not delete cached files.
Implementation and Security Boundaries¶
The plugin is split into two halves. index.js is the Host side, responsible for persistent configuration and providing media files via same-origin HTTP routes; client.js is the Browser side, responsible for the wallpaper layer, carousel, settings page, and shortcuts. There is also cordis.patch.yml to insert this bundle into the profile, and locale/{zh,en}.json provides bilingual text.
The Host requires an HTTP route prefix, mounted under /plugin-skin:
| Method | Path | Purpose |
|---|---|---|
GET |
/plugin-skin/state |
Read config + current playlist, ?refresh=1 forces a directory rescan. |
POST |
/plugin-skin/config |
Save the full configuration (JSON). |
GET/HEAD |
/plugin-skin/media?path=… |
Stream and read local media files. |
GET/HEAD |
/plugin-skin/remote?url=… |
Proxy and cache image bed images, &fresh=1 fetches a new one and saves it. |
GET |
/plugin-skin/cache |
List cached image bed images. |
POST |
/plugin-skin/upload?name=… |
Write files to the cache directory when importing via “Select Folder”. |
The security boundaries are defined clearly:
- The
mediaroute only allows access to directories/files declared in the current configuration (whitelist determined bysource); other paths return 403; - Only allowed image/video extensions are permitted; others return 415;
- Directory scanning is limited to a maximum of 4 levels and 4000 entries; remote downloads are capped at 64 MB with a 20-second timeout;
- Apart from image bed addresses you actively add, it does not initiate any external requests, does not upload data, does not track statistics, and local media is processed only through
127.0.0.1same-origin routes.
Use Cases and Notes¶
It is suitable for people who want to change their DSH workbench to a familiar wallpaper, already have a Wallpaper Engine asset library, or developers who need a clean background for screenshots and screen recordings. As long as you are using a DSH build that includes webServer, both the Desktop version and dsh web work.
Points to note.
- The plugin runs with the permissions of the current DSH process and will register same-origin HTTP routes and read/write directories under
$DSH_HOME/data/and thepackage.jsonin the profile. Read the source code and license (this repository is MIT) before deciding to install. - Known limitations: Random playback does not work for image bed sources; they rotate by address; when auto-switching after a video ends, the carousel interval is ignored for that video, and the switch timing is determined by the video duration; the wallpaper layer is fixed at
z-index:-1, acting only as a background and not replacing any official controls. - It does not conflict with other skin plugins when enabled simultaneously: The interface opacity listens to
theme/changeand recalculates the alpha using the current token value each time. - Change reminders: Modifying
index.jsrequires restarting DSH, while modifyingclient.jsonly requires refreshing the page.
Conclusion¶
What dsh-skin does is narrow—putting the wallpaper under the DSH interface without touching controls or building a theme system. What is truly worth emulating is its engineering trade-offs: placing configuration on the Host side, using same-origin routes for local media, and keeping a separate archive folder ordered by address outside of memory, ensuring nothing is lost on restart and shortcuts and playback states have fallbacks.
If you just want to change the background and don’t want to maintain a bunch of CSS yourself, this plugin can be used directly; if you want to go further, the route table at /plugin-skin and cordis.patch.yml are the complete entry points for implementation.
- Community Directory: https://www.skillhub.cn/plugins/Avan0203/dsh-skin
- Repository: https://github.com/Avan0203/dsh-skin