Add gSlapper video wallpaper plugin (#152)
* feat: add gSlapper wallpaper plugin * docs: clarify gSlapper installation and testing * docs: state Noctalia v5 requirement * docs: use generated plugin thumbnail * fix: keep gSlapper videos playing by default
This commit is contained in:
@@ -0,0 +1,118 @@
|
|||||||
|
# gSlapper Wallpaper
|
||||||
|
|
||||||
|
Choose images and video wallpapers from one picker. Apply one file to every
|
||||||
|
detected output or select a different file for each connector.
|
||||||
|
|
||||||
|
> Requires Noctalia v5 and plugin API 19. Noctalia v4 uses a different QML
|
||||||
|
> plugin format and will not list or load this source.
|
||||||
|
|
||||||
|
Video playback uses [gSlapper](https://github.com/Nomadcxx/gSlapper) instead of
|
||||||
|
mpvpaper. gSlapper uses GStreamer rather than libmpv; its README documents lower
|
||||||
|
CPU, memory, and GPU use than mpvpaper. Tests cover Niri, Hyprland, and Sway.
|
||||||
|
|
||||||
|
## Plugin
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| ID | `nomadcxx/gslapper` |
|
||||||
|
| Entries | Bar widget: `wallpaper`; panel: `picker`; service: `service` |
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- `find` indexes the wallpaper roots
|
||||||
|
- [gSlapper](https://github.com/Nomadcxx/gSlapper) 1.5.2 or newer provides the
|
||||||
|
`gslapper` command and renders video wallpapers
|
||||||
|
- `gst-launch-1.0` creates image and video previews
|
||||||
|
- `pkill` cleans up a plugin-owned process if its socket stops responding
|
||||||
|
- `socat` sends gSlapper IPC commands
|
||||||
|
|
||||||
|
Arch Linux provides `gst-launch-1.0` in `gstreamer`. Debian and Ubuntu provide
|
||||||
|
it in `gstreamer1.0-tools`. Preview generation can fail without blocking image
|
||||||
|
selection or video playback.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Add the canonical repository as a custom plugin source:
|
||||||
|
|
||||||
|
1. Open **Settings → Plugins → Sources**.
|
||||||
|
2. Choose **Add custom repository**.
|
||||||
|
3. Enter `https://github.com/Nomadcxx/noctalia-gslapper`.
|
||||||
|
4. Open **Settings → Plugins → Install** and select **gSlapper Wallpaper**.
|
||||||
|
|
||||||
|
Or install it from a shell:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
noctalia msg plugins source add gslapper git https://github.com/Nomadcxx/noctalia-gslapper
|
||||||
|
noctalia msg plugins enable nomadcxx/gslapper
|
||||||
|
```
|
||||||
|
|
||||||
|
Choose this source or the Noctalia community source. If you add both, Noctalia
|
||||||
|
uses the copy from the last user source. Remove the other source with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
noctalia msg plugins source remove <source-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
In Noctalia Settings, open your existing bar, choose a widget section, select
|
||||||
|
Add Widget, then add **gSlapper Wallpaper**. You can remove Noctalia's
|
||||||
|
Wallpaper widget if you want one wallpaper button.
|
||||||
|
|
||||||
|
Left-click the gSlapper widget to open the picker. Select **All outputs** or a
|
||||||
|
connector such as `eDP-1` or `DP-1`, then choose an image or video. The All
|
||||||
|
view can pause assigned videos or restore every output.
|
||||||
|
|
||||||
|
Toggle the picker from a shell:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
noctalia msg panel-toggle nomadcxx/gslapper:picker
|
||||||
|
```
|
||||||
|
|
||||||
|
The service indexes your image and video roots when Noctalia starts. It creates
|
||||||
|
224 by 126 JPEG previews in the plugin data directory. The picker shows 24
|
||||||
|
media files per page in a four-column grid and lists child folders in a
|
||||||
|
separate selector.
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
| Setting | Default | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Video directory | `~/Videos/Wallpapers` | Root for video wallpapers. Noctalia's wallpaper directory supplies images. |
|
||||||
|
| Video scale | `fill` | Uses gSlapper's fill, stretch, original, or panscan scaling mode. |
|
||||||
|
| When hidden | `none` | Keeps playing unless you select Auto Pause or Auto Stop. |
|
||||||
|
| Loop videos | On | Restarts video playback at the end. |
|
||||||
|
| FPS cap | `30` | Caps video wallpaper playback at 30, 60, or 100 FPS. |
|
||||||
|
| Fade between videos | Off | Enables gSlapper's fade transition. |
|
||||||
|
| Fade duration | `0.5` seconds | Sets the transition duration when you enable fading. |
|
||||||
|
| Additional GStreamer options | Empty | Appends options to gSlapper's GStreamer option list. |
|
||||||
|
| Widget glyph | `wallpaper-selector` | Changes the icon shown in the bar. |
|
||||||
|
|
||||||
|
The service restarts active video wallpapers after you change a playback
|
||||||
|
setting.
|
||||||
|
|
||||||
|
## Self-check
|
||||||
|
|
||||||
|
Run the built-in model and trust-boundary checks with:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
noctalia msg plugin nomadcxx/gslapper:service all self-test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The plugin starts one `gslapper` process and one Unix socket under
|
||||||
|
`$XDG_RUNTIME_DIR/noctalia-gslapper/` for each output with a video.
|
||||||
|
- The plugin stores assignments, its self-check report, its media index, and
|
||||||
|
cached preview JPEGs in Noctalia's plugin data directory. It makes no network
|
||||||
|
requests.
|
||||||
|
- The picker skips filenames that do not use UTF-8.
|
||||||
|
- Static images use Noctalia's wallpaper renderer. For video assignments, the
|
||||||
|
plugin disables Noctalia's wallpaper surface on that output while gSlapper
|
||||||
|
owns it, then restores the native surface when you select **Restore**.
|
||||||
|
- Use **Restore all** before disabling or reloading the plugin. This stops its
|
||||||
|
processes, removes its sockets, and re-enables Noctalia's wallpaper surfaces.
|
||||||
|
- The current plugin API does not report static wallpaper changes made outside
|
||||||
|
this plugin, so its saved image assignment can become stale.
|
||||||
|
- Assignments follow connector names, not monitor serial numbers. Review them
|
||||||
|
after GPU, dock, or cabling changes that rename outputs.
|
||||||
+1002
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,111 @@
|
|||||||
|
id = "nomadcxx/gslapper"
|
||||||
|
name = "gSlapper Wallpaper"
|
||||||
|
version = "0.1.1"
|
||||||
|
plugin_api = 19
|
||||||
|
author = "Nomadcxx"
|
||||||
|
license = "MIT"
|
||||||
|
dependencies = ["find", "gslapper", "gst-launch-1.0", "pkill", "socat"]
|
||||||
|
tags = ["bar", "panel", "service", "video", "wallpaper"]
|
||||||
|
icon = "wallpaper-selector"
|
||||||
|
description = "Choose an image or video wallpaper for each output."
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "video_directory"
|
||||||
|
type = "folder"
|
||||||
|
label_key = "settings.video_directory.label"
|
||||||
|
description_key = "settings.video_directory.description"
|
||||||
|
default = "~/Videos/Wallpapers"
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "scale"
|
||||||
|
type = "select"
|
||||||
|
label_key = "settings.scale.label"
|
||||||
|
description_key = "settings.scale.description"
|
||||||
|
default = "fill"
|
||||||
|
options = [
|
||||||
|
{ value = "fill", label_key = "settings.scale.options.fill" },
|
||||||
|
{ value = "stretch", label_key = "settings.scale.options.stretch" },
|
||||||
|
{ value = "original", label_key = "settings.scale.options.original" },
|
||||||
|
{ value = "panscan", label_key = "settings.scale.options.panscan" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "hidden_behavior"
|
||||||
|
type = "select"
|
||||||
|
label_key = "settings.hidden_behavior.label"
|
||||||
|
description_key = "settings.hidden_behavior.description"
|
||||||
|
default = "none"
|
||||||
|
options = [
|
||||||
|
{ value = "none", label_key = "settings.hidden_behavior.options.none" },
|
||||||
|
{ value = "auto-pause", label_key = "settings.hidden_behavior.options.auto_pause" },
|
||||||
|
{ value = "auto-stop", label_key = "settings.hidden_behavior.options.auto_stop" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "loop"
|
||||||
|
type = "bool"
|
||||||
|
label_key = "settings.loop.label"
|
||||||
|
description_key = "settings.loop.description"
|
||||||
|
default = true
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "fps_cap"
|
||||||
|
type = "select"
|
||||||
|
label_key = "settings.fps_cap.label"
|
||||||
|
description_key = "settings.fps_cap.description"
|
||||||
|
default = "30"
|
||||||
|
options = [
|
||||||
|
{ value = "30", label_key = "settings.fps_cap.options.fps_30" },
|
||||||
|
{ value = "60", label_key = "settings.fps_cap.options.fps_60" },
|
||||||
|
{ value = "100", label_key = "settings.fps_cap.options.fps_100" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "fade"
|
||||||
|
type = "bool"
|
||||||
|
label_key = "settings.fade.label"
|
||||||
|
description_key = "settings.fade.description"
|
||||||
|
default = false
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "fade_duration"
|
||||||
|
type = "double"
|
||||||
|
label_key = "settings.fade_duration.label"
|
||||||
|
description_key = "settings.fade_duration.description"
|
||||||
|
default = 0.5
|
||||||
|
min = 0.1
|
||||||
|
max = 5.0
|
||||||
|
step = 0.1
|
||||||
|
visible_when = { key = "fade", values = ["true"] }
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "gst_options"
|
||||||
|
type = "string"
|
||||||
|
label_key = "settings.gst_options.label"
|
||||||
|
description_key = "settings.gst_options.description"
|
||||||
|
default = ""
|
||||||
|
advanced = true
|
||||||
|
|
||||||
|
[[setting]]
|
||||||
|
key = "glyph"
|
||||||
|
type = "glyph"
|
||||||
|
label_key = "settings.glyph.label"
|
||||||
|
description_key = "settings.glyph.description"
|
||||||
|
default = "wallpaper-selector"
|
||||||
|
|
||||||
|
[[service]]
|
||||||
|
id = "service"
|
||||||
|
entry = "service.luau"
|
||||||
|
|
||||||
|
[[panel]]
|
||||||
|
id = "picker"
|
||||||
|
entry = "panel.luau"
|
||||||
|
width = 980
|
||||||
|
height = 1100
|
||||||
|
placement = "attached"
|
||||||
|
position = "auto"
|
||||||
|
keyboard_focus = "exclusive"
|
||||||
|
|
||||||
|
[[widget]]
|
||||||
|
id = "wallpaper"
|
||||||
|
entry = "widget.luau"
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
@@ -0,0 +1,102 @@
|
|||||||
|
{
|
||||||
|
"panel": {
|
||||||
|
"title": "Wallpaper",
|
||||||
|
"media_count": "{count} items",
|
||||||
|
"thumbnail_unavailable": "Video preview unavailable",
|
||||||
|
"settings": "Settings",
|
||||||
|
"close": "Close",
|
||||||
|
"search": "Search wallpapers",
|
||||||
|
"all_outputs": "All outputs",
|
||||||
|
"filter_all": "All",
|
||||||
|
"filter_images": "Images",
|
||||||
|
"filter_videos": "Videos",
|
||||||
|
"folders": "Folders",
|
||||||
|
"up": "Up",
|
||||||
|
"checking_dependencies": "Checking video support…",
|
||||||
|
"scanning": "Indexing wallpaper library…",
|
||||||
|
"preparing_library": "Preparing wallpaper library…",
|
||||||
|
"generating_previews": "Generating previews · {count} / {total}",
|
||||||
|
"video_unavailable": "Video wallpapers are unavailable",
|
||||||
|
"video_badge": "VIDEO",
|
||||||
|
"partial_badge": "{count} / {total}",
|
||||||
|
"mixed_summary": "{outputs} outputs · {videos} video · {images} image",
|
||||||
|
"pause_videos": "Pause videos",
|
||||||
|
"resume_videos": "Resume videos",
|
||||||
|
"restore_all": "Restore all",
|
||||||
|
"pause": "Pause",
|
||||||
|
"resume": "Resume",
|
||||||
|
"restore": "Restore",
|
||||||
|
"status_static": "Static",
|
||||||
|
"status_starting": "Starting",
|
||||||
|
"status_playing": "Playing",
|
||||||
|
"status_paused": "Paused",
|
||||||
|
"status_error": "Error",
|
||||||
|
"applying": "Applying wallpaper…",
|
||||||
|
"navigation_blocked": "The selected directory is outside its wallpaper root.",
|
||||||
|
"directory_unreadable": "Directory unavailable",
|
||||||
|
"directory_empty": "No supported wallpapers in this directory",
|
||||||
|
"no_search_results": "No wallpapers match your search",
|
||||||
|
"page": "{page} / {pages}"
|
||||||
|
},
|
||||||
|
"widget": {
|
||||||
|
"tooltip": "Choose wallpaper"
|
||||||
|
},
|
||||||
|
"service": {
|
||||||
|
"self_test_passed": "Self-test passed.",
|
||||||
|
"self_test_failed": "Self-test failed."
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"video_directory": {
|
||||||
|
"label": "Video directory",
|
||||||
|
"description": "Directory containing video wallpapers."
|
||||||
|
},
|
||||||
|
"scale": {
|
||||||
|
"label": "Video scale",
|
||||||
|
"description": "How videos fit the output.",
|
||||||
|
"options": {
|
||||||
|
"fill": "Fill",
|
||||||
|
"stretch": "Stretch",
|
||||||
|
"original": "Original",
|
||||||
|
"panscan": "Panscan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hidden_behavior": {
|
||||||
|
"label": "When hidden",
|
||||||
|
"description": "Playback control when the wallpaper is hidden.",
|
||||||
|
"options": {
|
||||||
|
"none": "None",
|
||||||
|
"auto_pause": "Auto Pause",
|
||||||
|
"auto_stop": "Auto Stop"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"loop": {
|
||||||
|
"label": "Loop videos",
|
||||||
|
"description": "Restart a video when it reaches the end."
|
||||||
|
},
|
||||||
|
"fps_cap": {
|
||||||
|
"label": "FPS cap",
|
||||||
|
"description": "Maximum video wallpaper frame rate.",
|
||||||
|
"options": {
|
||||||
|
"fps_30": "30",
|
||||||
|
"fps_60": "60",
|
||||||
|
"fps_100": "100"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fade": {
|
||||||
|
"label": "Fade between videos",
|
||||||
|
"description": "Use a fade when changing media."
|
||||||
|
},
|
||||||
|
"fade_duration": {
|
||||||
|
"label": "Fade duration",
|
||||||
|
"description": "Fade duration in seconds."
|
||||||
|
},
|
||||||
|
"gst_options": {
|
||||||
|
"label": "Additional GStreamer options",
|
||||||
|
"description": "Extra options passed to gSlapper's GStreamer pipeline."
|
||||||
|
},
|
||||||
|
"glyph": {
|
||||||
|
"label": "Widget glyph",
|
||||||
|
"description": "Glyph shown in the bar."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
--!nonstrict
|
||||||
|
|
||||||
|
local PANEL_ID = "nomadcxx/gslapper:picker"
|
||||||
|
|
||||||
|
local function render()
|
||||||
|
barWidget.setGlyph(noctalia.getConfig("glyph") or "wallpaper-selector")
|
||||||
|
barWidget.setTooltip(noctalia.tr("widget.tooltip"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function onClick()
|
||||||
|
noctalia.togglePanel(PANEL_ID)
|
||||||
|
end
|
||||||
|
|
||||||
|
function onConfigChanged()
|
||||||
|
render()
|
||||||
|
end
|
||||||
|
|
||||||
|
render()
|
||||||
Reference in New Issue
Block a user