Compare commits
8 Commits
b5ea96bb8b
...
v2.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
d39e36e096
|
|||
| cf73b12996 | |||
| 9a6fa483a5 | |||
| 5db3650184 | |||
| 0524f26f97 | |||
|
740411f194
|
|||
| 1a2daec165 | |||
| 524b53b7b2 |
@@ -1,4 +1,4 @@
|
|||||||
name: CI/CD
|
name: Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -6,8 +6,8 @@ on:
|
|||||||
- 'v*'
|
- 'v*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build-arch:
|
||||||
name: Package
|
name: Build ArchLinux Package
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Code
|
- name: Checkout Code
|
||||||
@@ -34,6 +34,7 @@ jobs:
|
|||||||
license=('MIT')
|
license=('MIT')
|
||||||
depends=('qt6-base' 'qt6-declarative' 'gcc-libs' 'glibc')
|
depends=('qt6-base' 'qt6-declarative' 'gcc-libs' 'glibc')
|
||||||
makedepends=('cmake')
|
makedepends=('cmake')
|
||||||
|
options=('!debug')
|
||||||
source=("${pkgname}-${pkgver}.tar.gz::https://git.uyani.de/Uyanide/WallReel/archive/v${pkgver}.tar.gz")
|
source=("${pkgname}-${pkgver}.tar.gz::https://git.uyani.de/Uyanide/WallReel/archive/v${pkgver}.tar.gz")
|
||||||
sha256sums=('INSERT_SHA256_HERE')
|
sha256sums=('INSERT_SHA256_HERE')
|
||||||
|
|
||||||
@@ -78,27 +79,27 @@ jobs:
|
|||||||
tar -cf - *.pkg.tar.zst PKGBUILD SRCINFO.txt >&3
|
tar -cf - *.pkg.tar.zst PKGBUILD SRCINFO.txt >&3
|
||||||
" | tar -xf -
|
" | tar -xf -
|
||||||
|
|
||||||
- name: Upload Artifacts
|
- name: Upload Arch Artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: release-artifacts
|
name: arch-artifacts
|
||||||
path: |
|
path: |
|
||||||
*.pkg.tar.zst
|
*.pkg.tar.zst
|
||||||
PKGBUILD
|
PKGBUILD
|
||||||
SRCINFO.txt
|
SRCINFO.txt
|
||||||
|
|
||||||
release:
|
publish-gitea:
|
||||||
name: Publish
|
name: Publish to Gitea Release
|
||||||
needs: build
|
needs: [build-arch]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Extract Version
|
- name: Extract Version
|
||||||
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
|
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Download Artifacts
|
- name: Download Arch Artifacts
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: release-artifacts
|
name: arch-artifacts
|
||||||
path: .
|
path: .
|
||||||
|
|
||||||
- name: Publish to Gitea Release
|
- name: Publish to Gitea Release
|
||||||
@@ -111,6 +112,20 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
publish-aur:
|
||||||
|
name: Publish to AUR
|
||||||
|
needs: [build-arch]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Extract Version
|
||||||
|
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Download Arch Artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: arch-artifacts
|
||||||
|
path: .
|
||||||
|
|
||||||
- name: Publish to AUR
|
- name: Publish to AUR
|
||||||
env:
|
env:
|
||||||
AUR_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
AUR_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
project(WallReel VERSION 2.0.1 LANGUAGES CXX)
|
project(WallReel VERSION 2.2.0 LANGUAGES CXX)
|
||||||
|
|
||||||
set(EXECUTABLE_NAME "wallreel")
|
set(EXECUTABLE_NAME "wallreel")
|
||||||
set(CORELIB_NAME "wallreel-core")
|
set(CORELIB_NAME "wallreel-core")
|
||||||
|
|||||||
@@ -117,12 +117,11 @@ Configures system commands to execute on specific events mapping to your window
|
|||||||
| :-------------------- | :--------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| :-------------------- | :--------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `previewDebounceTime` | Integer | `300` | Debounce time (ms) for triggering the preview action. |
|
| `previewDebounceTime` | Integer | `300` | Debounce time (ms) for triggering the preview action. |
|
||||||
| `printSelected` | Boolean | `true` | Print selected wallpaper path to stdout on confirm. |
|
| `printSelected` | Boolean | `true` | Print selected wallpaper path to stdout on confirm. |
|
||||||
| `printPreview` | Boolean | `false` | Print previewed wallpaper path to stdout on preview. |
|
|
||||||
| `onSelected` | String | `""` | Command to execute when a wallpaper is confirmed. |
|
| `onSelected` | String | `""` | Command to execute when a wallpaper is confirmed. |
|
||||||
| `onPreview` | String | `""` | Command to execute when a wallpaper is previewed. |
|
| `onPreview` | String | `""` | Command to execute when a wallpaper is previewed. |
|
||||||
| `saveState` | Array of Objects | `[]` | Commands to fetch system states before changing wallpapers. Each object defines: `key`, `fallback` (fallback value), `command` (stdout mapping), and `timeout` (ms). |
|
| `saveState` | Array of Objects | `[]` | Commands to fetch system states before changing wallpapers. Each object defines: `key`, `fallback` (fallback value), `command` (stdout mapping), and `timeout` (ms). |
|
||||||
| `onRestore` | String | `""` | Command to execute on restore. Extracted states from `saveState` can be injected using `{{ key }}`. |
|
| `onRestore` | String | `""` | Command to execute on restore. Extracted states from `saveState` can be injected using `{{ key }}`. |
|
||||||
| `quitOnSelected` | Boolean | `false` | Quit the application after a selection is made. |
|
| `quitOnSelected` | Boolean | `true` | Quit the application after a selection is made. |
|
||||||
| `restoreOnClose` | Boolean | `true` | Run `onRestore` command if the application is closed without making a final selection. |
|
| `restoreOnClose` | Boolean | `true` | Run `onRestore` command if the application is closed without making a final selection. |
|
||||||
|
|
||||||
Available placeholders for `onSelected`, `onPreview` commands:
|
Available placeholders for `onSelected`, `onPreview` commands:
|
||||||
|
|||||||
+10
-10
@@ -1,6 +1,6 @@
|
|||||||
.\" Automatically generated by Pandoc 3.5
|
.\" Automatically generated by Pandoc 3.9.0.2
|
||||||
.\"
|
.\"
|
||||||
.TH "WALLREEL" "1" "2026\-03\-24" "WallReel 2.0.1" "User Commands"
|
.TH "WALLREEL" "1" "2026\-03\-24" "WallReel 2.0.2" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
wallreel \- Choose and set desktop wallpapers with customizable themes
|
wallreel \- Choose and set desktop wallpapers with customizable themes
|
||||||
and actions
|
and actions
|
||||||
@@ -42,20 +42,20 @@ In this mode, the configuration is still parsed.
|
|||||||
Action placeholders are resolved from the selected image and any
|
Action placeholders are resolved from the selected image and any
|
||||||
captured state values.
|
captured state values.
|
||||||
.SH BEHAVIOR NOTES
|
.SH BEHAVIOR NOTES
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
CLI options are generally optional; configuration is the preferred
|
CLI options are generally optional; configuration is the preferred
|
||||||
customization path.
|
customization path.
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
Some options are mutually exclusive (for example \f[CR]\-\-verbose\f[R]
|
Some options are mutually exclusive (for example \f[CR]\-\-verbose\f[R]
|
||||||
and \f[CR]\-\-quiet\f[R]).
|
and \f[CR]\-\-quiet\f[R]).
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
With \f[CR]\-\-apply\f[R], WallReel executes configured selection
|
With \f[CR]\-\-apply\f[R], WallReel executes configured selection
|
||||||
actions without opening the UI.
|
actions without opening the UI.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
\f[CR]\[ti]/.config/wallreel/config.json\f[R] : Default configuration
|
\f[CR]\(ti/.config/wallreel/config.json\f[R] : Default configuration
|
||||||
file location.
|
file location.
|
||||||
.PP
|
.PP
|
||||||
\f[CR]\[ti]/.cache/wallreel/\f[R] : Runtime cache location.
|
\f[CR]\(ti/.cache/wallreel/\f[R] : Runtime cache location.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
Run with default configuration:
|
Run with default configuration:
|
||||||
.IP
|
.IP
|
||||||
@@ -66,19 +66,19 @@ wallreel
|
|||||||
Use a custom configuration file:
|
Use a custom configuration file:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.EX
|
||||||
wallreel \-\-config\-file \[ti]/.config/wallreel/config.json
|
wallreel \-\-config\-file \(ti/.config/wallreel/config.json
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Append additional search directories:
|
Append additional search directories:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.EX
|
||||||
wallreel \-\-append\-dir \[ti]/Pictures/Wallpapers \-\-append\-dir \[ti]/Art
|
wallreel \-\-append\-dir \(ti/Pictures/Wallpapers \-\-append\-dir \(ti/Art
|
||||||
.EE
|
.EE
|
||||||
.PP
|
.PP
|
||||||
Apply a wallpaper and exit:
|
Apply a wallpaper and exit:
|
||||||
.IP
|
.IP
|
||||||
.EX
|
.EX
|
||||||
wallreel \-\-apply \[ti]/Pictures/wallpaper.jpg
|
wallreel \-\-apply \(ti/Pictures/wallpaper.jpg
|
||||||
.EE
|
.EE
|
||||||
.SH EXIT STATUS
|
.SH EXIT STATUS
|
||||||
Returns \f[CR]0\f[R] on success.
|
Returns \f[CR]0\f[R] on success.
|
||||||
|
|||||||
+61
-64
@@ -1,22 +1,22 @@
|
|||||||
.\" Automatically generated by Pandoc 3.5
|
.\" Automatically generated by Pandoc 3.9.0.2
|
||||||
.\"
|
.\"
|
||||||
.TH "WALLREEL" "5" "2026\-03\-24" "WallReel 2.0.1" "File Formats Manual"
|
.TH "WALLREEL" "5" "2026\-03\-24" "WallReel 2.0.2" "File Formats Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
wallreel\-config \- configuration format for wallreel
|
wallreel\-config \- configuration format for wallreel
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
\f[CR]\[ti]/.config/wallreel/config.json\f[R]
|
\f[CR]\(ti/.config/wallreel/config.json\f[R]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
WallReel reads configuration from a JSON document.
|
WallReel reads configuration from a JSON document.
|
||||||
The root object is divided into five sections:
|
The root object is divided into five sections:
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]wallpaper\f[R]
|
\f[CR]wallpaper\f[R]
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]theme\f[R]
|
\f[CR]theme\f[R]
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]action\f[R]
|
\f[CR]action\f[R]
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]style\f[R]
|
\f[CR]style\f[R]
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]cache\f[R]
|
\f[CR]cache\f[R]
|
||||||
.PP
|
.PP
|
||||||
For complete machine\-readable validation details, refer to
|
For complete machine\-readable validation details, refer to
|
||||||
@@ -25,7 +25,7 @@ For complete machine\-readable validation details, refer to
|
|||||||
Defines where WallReel looks for images and what to exclude.
|
Defines where WallReel looks for images and what to exclude.
|
||||||
.PP
|
.PP
|
||||||
If both \f[CR]paths\f[R] and \f[CR]dirs\f[R] are empty or omitted,
|
If both \f[CR]paths\f[R] and \f[CR]dirs\f[R] are empty or omitted,
|
||||||
WallReel defaults to recursively scanning the user\[aq]s Pictures
|
WallReel defaults to recursively scanning the user\(aqs Pictures
|
||||||
directory and treating all supported image files as wallpaper
|
directory and treating all supported image files as wallpaper
|
||||||
candidates.
|
candidates.
|
||||||
.PP
|
.PP
|
||||||
@@ -36,9 +36,9 @@ to specific image files.
|
|||||||
to scan for images.
|
to scan for images.
|
||||||
.PP
|
.PP
|
||||||
Each item has:
|
Each item has:
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]path\f[R] (string)
|
\f[CR]path\f[R] (string)
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]recursive\f[R] (boolean)
|
\f[CR]recursive\f[R] (boolean)
|
||||||
.PP
|
.PP
|
||||||
\f[CR]excludes\f[R] (array of string, default: \f[CR][]\f[R]) : Exclude
|
\f[CR]excludes\f[R] (array of string, default: \f[CR][]\f[R]) : Exclude
|
||||||
@@ -54,16 +54,16 @@ the primary color.
|
|||||||
palette definitions.
|
palette definitions.
|
||||||
.PP
|
.PP
|
||||||
Each palette has:
|
Each palette has:
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]name\f[R] (string)
|
\f[CR]name\f[R] (string)
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]colors\f[R] (array)
|
\f[CR]colors\f[R] (array)
|
||||||
.PP
|
.PP
|
||||||
Each color item has:
|
Each color item has:
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]name\f[R] (string)
|
\f[CR]name\f[R] (string)
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]value\f[R] (hex string, for example \f[CR]\[dq]#89b4fa\[dq]\f[R])
|
\f[CR]value\f[R] (hex string, for example \f[CR]\(dq#89b4fa\(dq\f[R])
|
||||||
.SH ACTION SECTION
|
.SH ACTION SECTION
|
||||||
Configures commands executed for preview, selection, and restore
|
Configures commands executed for preview, selection, and restore
|
||||||
behavior.
|
behavior.
|
||||||
@@ -74,33 +74,30 @@ Debounce interval in milliseconds for preview actions.
|
|||||||
\f[CR]printSelected\f[R] (boolean, default: \f[CR]true\f[R]) : Print
|
\f[CR]printSelected\f[R] (boolean, default: \f[CR]true\f[R]) : Print
|
||||||
selected wallpaper path to stdout on confirmation.
|
selected wallpaper path to stdout on confirmation.
|
||||||
.PP
|
.PP
|
||||||
\f[CR]printPreview\f[R] (boolean, default: \f[CR]false\f[R]) : Print
|
\f[CR]onSelected\f[R] (string, default: \f[CR]\(dq\(dq\f[R]) : Command
|
||||||
previewed wallpaper path to stdout on preview.
|
|
||||||
.PP
|
|
||||||
\f[CR]onSelected\f[R] (string, default: \f[CR]\[dq]\[dq]\f[R]) : Command
|
|
||||||
executed when a wallpaper is confirmed.
|
executed when a wallpaper is confirmed.
|
||||||
.PP
|
.PP
|
||||||
\f[CR]onPreview\f[R] (string, default: \f[CR]\[dq]\[dq]\f[R]) : Command
|
\f[CR]onPreview\f[R] (string, default: \f[CR]\(dq\(dq\f[R]) : Command
|
||||||
executed when a wallpaper is previewed.
|
executed when a wallpaper is previewed.
|
||||||
.PP
|
.PP
|
||||||
\f[CR]saveState\f[R] (array of object, default: \f[CR][]\f[R]) :
|
\f[CR]saveState\f[R] (array of object, default: \f[CR][]\f[R]) :
|
||||||
Commands for capturing system values before changing wallpaper.
|
Commands for capturing system values before changing wallpaper.
|
||||||
.PP
|
.PP
|
||||||
Each item has:
|
Each item has:
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]key\f[R] (placeholder key)
|
\f[CR]key\f[R] (placeholder key)
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]fallback\f[R] (default value)
|
\f[CR]fallback\f[R] (default value)
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]command\f[R] (stdout\-mapped command)
|
\f[CR]command\f[R] (stdout\-mapped command)
|
||||||
.IP \[bu] 2
|
.IP \(bu 2
|
||||||
\f[CR]timeout\f[R] (milliseconds)
|
\f[CR]timeout\f[R] (milliseconds)
|
||||||
.PP
|
.PP
|
||||||
\f[CR]onRestore\f[R] (string, default: \f[CR]\[dq]\[dq]\f[R]) : Command
|
\f[CR]onRestore\f[R] (string, default: \f[CR]\(dq\(dq\f[R]) : Command
|
||||||
executed on restore.
|
executed on restore.
|
||||||
Saved state keys are usable as placeholders.
|
Saved state keys are usable as placeholders.
|
||||||
.PP
|
.PP
|
||||||
\f[CR]quitOnSelected\f[R] (boolean, default: \f[CR]false\f[R]) : Exit
|
\f[CR]quitOnSelected\f[R] (boolean, default: \f[CR]true\f[R]) : Exit
|
||||||
application immediately after confirming a selection.
|
application immediately after confirming a selection.
|
||||||
.PP
|
.PP
|
||||||
\f[CR]restoreOnClose\f[R] (boolean, default: \f[CR]true\f[R]) : Run
|
\f[CR]restoreOnClose\f[R] (boolean, default: \f[CR]true\f[R]) : Run
|
||||||
@@ -117,13 +114,13 @@ The following placeholders are available in \f[CR]onSelected\f[R],
|
|||||||
wallpaper.
|
wallpaper.
|
||||||
.PP
|
.PP
|
||||||
\f[CR]{{ palette }}\f[R] : Selected palette name
|
\f[CR]{{ palette }}\f[R] : Selected palette name
|
||||||
(\f[CR]\[dq]null\[dq]\f[R] if none).
|
(\f[CR]\(dqnull\(dq\f[R] if none).
|
||||||
.PP
|
.PP
|
||||||
\f[CR]{{ colorName }}\f[R] : Chosen primary color name
|
\f[CR]{{ colorName }}\f[R] : Chosen primary color name
|
||||||
(\f[CR]\[dq]null\[dq]\f[R] if none).
|
(\f[CR]\(dqnull\(dq\f[R] if none).
|
||||||
.PP
|
.PP
|
||||||
\f[CR]{{ colorHex }}\f[R] : Chosen primary color hex
|
\f[CR]{{ colorHex }}\f[R] : Chosen primary color hex
|
||||||
(\f[CR]\[dq]null\[dq]\f[R] if none).
|
(\f[CR]\(dqnull\(dq\f[R] if none).
|
||||||
.PP
|
.PP
|
||||||
\f[CR]{{ domColorHex }}\f[R] : Dominant color hex extracted from the
|
\f[CR]{{ domColorHex }}\f[R] : Dominant color hex extracted from the
|
||||||
wallpaper.
|
wallpaper.
|
||||||
@@ -162,54 +159,54 @@ Older entries are evicted.
|
|||||||
.IP
|
.IP
|
||||||
.EX
|
.EX
|
||||||
{
|
{
|
||||||
\[dq]$schema\[dq]: \[dq]https://raw.githubusercontent.com/Uyanide/WallReel/refs/heads/master/config.schema.json\[dq],
|
\(dq$schema\(dq: \(dqhttps://raw.githubusercontent.com/Uyanide/WallReel/refs/heads/master/config.schema.json\(dq,
|
||||||
\[dq]wallpaper\[dq]: {
|
\(dqwallpaper\(dq: {
|
||||||
\[dq]paths\[dq]: [\[dq]/home/user/Pictures/favorite.jpg\[dq]],
|
\(dqpaths\(dq: [\(dq/home/user/Pictures/favorite.jpg\(dq],
|
||||||
\[dq]dirs\[dq]: [
|
\(dqdirs\(dq: [
|
||||||
{
|
{
|
||||||
\[dq]path\[dq]: \[dq]/home/user/Pictures/Wallpapers\[dq],
|
\(dqpath\(dq: \(dq/home/user/Pictures/Wallpapers\(dq,
|
||||||
\[dq]recursive\[dq]: \f[B]true\f[R]
|
\(dqrecursive\(dq: \f[B]true\f[R]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
\[dq]excludes\[dq]: [\[dq]\[rs]\[rs].gif$\[dq]]
|
\(dqexcludes\(dq: [\(dq\(rs\(rs.gif$\(dq]
|
||||||
},
|
},
|
||||||
\[dq]theme\[dq]: {
|
\(dqtheme\(dq: {
|
||||||
\[dq]palettes\[dq]: [
|
\(dqpalettes\(dq: [
|
||||||
{
|
{
|
||||||
\[dq]name\[dq]: \[dq]Dark\[dq],
|
\(dqname\(dq: \(dqDark\(dq,
|
||||||
\[dq]colors\[dq]: [
|
\(dqcolors\(dq: [
|
||||||
{ \[dq]name\[dq]: \[dq]blue\[dq], \[dq]value\[dq]: \[dq]#89b4fa\[dq] },
|
{ \(dqname\(dq: \(dqblue\(dq, \(dqvalue\(dq: \(dq#89b4fa\(dq },
|
||||||
{ \[dq]name\[dq]: \[dq]red\[dq], \[dq]value\[dq]: \[dq]#f38ba8\[dq] }
|
{ \(dqname\(dq: \(dqred\(dq, \(dqvalue\(dq: \(dq#f38ba8\(dq }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
\[dq]action\[dq]: {
|
\(dqaction\(dq: {
|
||||||
\[dq]previewDebounceTime\[dq]: 500,
|
\(dqpreviewDebounceTime\(dq: 500,
|
||||||
\[dq]quitOnSelected\[dq]: \f[B]true\f[R],
|
\(dqquitOnSelected\(dq: \f[B]true\f[R],
|
||||||
\[dq]onPreview\[dq]: \[dq]swww img {{ path }}\[dq],
|
\(dqonPreview\(dq: \(dqswww img {{ path }}\(dq,
|
||||||
\[dq]onSelected\[dq]: \[dq]cp {{ path }} \[ti]/.config/wallpaper/current/ && swww img {{ path }}\[dq],
|
\(dqonSelected\(dq: \(dqcp {{ path }} \(ti/.config/wallpaper/current/ && swww img {{ path }}\(dq,
|
||||||
\[dq]saveState\[dq]: [
|
\(dqsaveState\(dq: [
|
||||||
{
|
{
|
||||||
\[dq]key\[dq]: \[dq]current_wp\[dq],
|
\(dqkey\(dq: \(dqcurrent_wp\(dq,
|
||||||
\[dq]fallback\[dq]: \[dq]/home/user/Pictures/default.jpg\[dq],
|
\(dqfallback\(dq: \(dq/home/user/Pictures/default.jpg\(dq,
|
||||||
\[dq]command\[dq]: \[dq]find \[ti]/.config/wallpaper/current \-type f | head \-n 1\[dq],
|
\(dqcommand\(dq: \(dqfind \(ti/.config/wallpaper/current \-type f | head \-n 1\(dq,
|
||||||
\[dq]timeout\[dq]: 1000
|
\(dqtimeout\(dq: 1000
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
\[dq]onRestore\[dq]: \[dq]swww img {{ current_wp }}\[dq]
|
\(dqonRestore\(dq: \(dqswww img {{ current_wp }}\(dq
|
||||||
},
|
},
|
||||||
\[dq]style\[dq]: {
|
\(dqstyle\(dq: {
|
||||||
\[dq]image_width\[dq]: 640,
|
\(dqimage_width\(dq: 640,
|
||||||
\[dq]image_height\[dq]: 400,
|
\(dqimage_height\(dq: 400,
|
||||||
\[dq]image_focus_scale\[dq]: 1.2,
|
\(dqimage_focus_scale\(dq: 1.2,
|
||||||
\[dq]window_width\[dq]: 1280,
|
\(dqwindow_width\(dq: 1280,
|
||||||
\[dq]window_height\[dq]: 720
|
\(dqwindow_height\(dq: 720
|
||||||
},
|
},
|
||||||
\[dq]cache\[dq]: {
|
\(dqcache\(dq: {
|
||||||
\[dq]saveSortMethod\[dq]: \f[B]true\f[R],
|
\(dqsaveSortMethod\(dq: \f[B]true\f[R],
|
||||||
\[dq]savePalette\[dq]: \f[B]true\f[R],
|
\(dqsavePalette\(dq: \f[B]true\f[R],
|
||||||
\[dq]maxImageEntries\[dq]: 300
|
\(dqmaxImageEntries\(dq: 300
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.EE
|
.EE
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
//
|
//
|
||||||
// action.previewDebounceTime number 300 Debounce time for preview action in milliseconds
|
// action.previewDebounceTime number 300 Debounce time for preview action in milliseconds
|
||||||
// action.printSelected boolean true Whether to print the selected wallpaper path to stdout on confirm
|
// action.printSelected boolean true Whether to print the selected wallpaper path to stdout on confirm
|
||||||
// action.printPreview boolean false Whether to print the previewed wallpaper path to stdout on preview
|
|
||||||
// action.onSelected string "" Command to execute on confirmation
|
// action.onSelected string "" Command to execute on confirmation
|
||||||
// action.onPreview string "" Command to execute on preview
|
// action.onPreview string "" Command to execute on preview
|
||||||
// action.saveState array [] Useful for restore command
|
// action.saveState array [] Useful for restore command
|
||||||
@@ -36,7 +35,7 @@
|
|||||||
// action.saveState[].command string "" Command that outputs(to stdout) the value to save when executed
|
// action.saveState[].command string "" Command that outputs(to stdout) the value to save when executed
|
||||||
// action.saveState[].timeout number 3000 Timeout for executing "command" in milliseconds. 0 or negative means no timeout
|
// action.saveState[].timeout number 3000 Timeout for executing "command" in milliseconds. 0 or negative means no timeout
|
||||||
// action.onRestore string "" Command to execute on restore ({{ key }} -> value defined or obtained in saveState)
|
// action.onRestore string "" Command to execute on restore ({{ key }} -> value defined or obtained in saveState)
|
||||||
// action.quitOnSelected boolean false Whether to quit the application after confirming a wallpaper
|
// action.quitOnSelected boolean true Whether to quit the application after confirming a wallpaper
|
||||||
// action.restoreOnClose boolean true Whether to run the restore command after closing the application without confirming a wallpaper
|
// action.restoreOnClose boolean true Whether to run the restore command after closing the application without confirming a wallpaper
|
||||||
//
|
//
|
||||||
// style.image_width number 320 Width of each image
|
// style.image_width number 320 Width of each image
|
||||||
@@ -126,8 +125,7 @@ struct ActionConfigItems {
|
|||||||
QString onRestore;
|
QString onRestore;
|
||||||
int previewDebounceTime = 300; // milliseconds
|
int previewDebounceTime = 300; // milliseconds
|
||||||
bool printSelected = true;
|
bool printSelected = true;
|
||||||
bool printPreview = false;
|
bool quitOnSelected = true;
|
||||||
bool quitOnSelected = false;
|
|
||||||
bool restoreOnClose = true;
|
bool restoreOnClose = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ Manager::Manager(
|
|||||||
const QDir& picturesDir,
|
const QDir& picturesDir,
|
||||||
const QStringList& searchDirs,
|
const QStringList& searchDirs,
|
||||||
const QString& configPath,
|
const QString& configPath,
|
||||||
|
bool disableActions,
|
||||||
QObject* parent)
|
QObject* parent)
|
||||||
: QObject(parent), m_configDir(configDir) {
|
: QObject(parent), m_configDir(configDir), m_disableActions(disableActions) {
|
||||||
connect(this, &Manager::stateCaptured, this, [this]() {
|
connect(this, &Manager::stateCaptured, this, [this]() {
|
||||||
m_stateCaptured = true;
|
m_stateCaptured = true;
|
||||||
WR_INFO("State capture completed");
|
WR_INFO("State capture completed");
|
||||||
@@ -53,9 +54,6 @@ Manager::Manager(
|
|||||||
WR_INFO(QString("No search directories specified, using Pictures directory: %1").arg(picturesPath));
|
WR_INFO(QString("No search directories specified, using Pictures directory: %1").arg(picturesPath));
|
||||||
m_wallpaperConfig.dirs.append({picturesPath, true});
|
m_wallpaperConfig.dirs.append({picturesPath, true});
|
||||||
}
|
}
|
||||||
|
|
||||||
WR_DEBUG("Loading wallpapers ...");
|
|
||||||
_loadWallpapers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::~Manager() {
|
Manager::~Manager() {
|
||||||
@@ -202,12 +200,6 @@ void Manager::_loadActionConfig(const QJsonObject& root) {
|
|||||||
m_actionConfig.printSelected = val.toBool();
|
m_actionConfig.printSelected = val.toBool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (config.contains("printPreview")) {
|
|
||||||
const auto& val = config["printPreview"];
|
|
||||||
if (val.isBool()) {
|
|
||||||
m_actionConfig.printPreview = val.toBool();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (config.contains("saveState") && config["saveState"].isArray()) {
|
if (config.contains("saveState") && config["saveState"].isArray()) {
|
||||||
const QJsonArray& arr = config["saveState"].toArray();
|
const QJsonArray& arr = config["saveState"].toArray();
|
||||||
for (const auto& item : arr) {
|
for (const auto& item : arr) {
|
||||||
@@ -329,7 +321,7 @@ void Manager::_loadCacheConfig(const QJsonObject& root) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::_loadWallpapers() {
|
void Manager::scanWallpapers() {
|
||||||
m_wallpapers.clear();
|
m_wallpapers.clear();
|
||||||
|
|
||||||
// Add paths first using a set to avoid duplicates
|
// Add paths first using a set to avoid duplicates
|
||||||
@@ -398,6 +390,13 @@ void Manager::captureState() {
|
|||||||
if (m_stateCaptured) {
|
if (m_stateCaptured) {
|
||||||
WR_DEBUG("State already captured, skipping capture");
|
WR_DEBUG("State already captured, skipping capture");
|
||||||
emit stateCaptured();
|
emit stateCaptured();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_disableActions) {
|
||||||
|
WR_DEBUG("Actions are disabled, skipping state capture");
|
||||||
|
emit stateCaptured();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pendingCaptures > 0) {
|
if (m_pendingCaptures > 0) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class Manager : public QObject {
|
|||||||
* @param searchDirs Additional directories to search for wallpapers (not recursive)
|
* @param searchDirs Additional directories to search for wallpapers (not recursive)
|
||||||
* @param configPath Optional path to a specific configuration file (overrides the default config path)
|
* @param configPath Optional path to a specific configuration file (overrides the default config path)
|
||||||
* @param picturesDir The pictures directory (default location for user wallpapers)
|
* @param picturesDir The pictures directory (default location for user wallpapers)
|
||||||
|
* @param disableActions Whether to disable actions
|
||||||
* @param parent QObject parent
|
* @param parent QObject parent
|
||||||
*
|
*
|
||||||
* @note The constructor will load the configuration and scan for wallpapers immediately.
|
* @note The constructor will load the configuration and scan for wallpapers immediately.
|
||||||
@@ -36,6 +37,7 @@ class Manager : public QObject {
|
|||||||
const QDir& picturesDir,
|
const QDir& picturesDir,
|
||||||
const QStringList& searchDirs = {},
|
const QStringList& searchDirs = {},
|
||||||
const QString& configPath = "",
|
const QString& configPath = "",
|
||||||
|
bool disableActions = false,
|
||||||
QObject* parent = nullptr);
|
QObject* parent = nullptr);
|
||||||
|
|
||||||
~Manager();
|
~Manager();
|
||||||
@@ -70,6 +72,8 @@ class Manager : public QObject {
|
|||||||
*/
|
*/
|
||||||
Q_INVOKABLE void captureState();
|
Q_INVOKABLE void captureState();
|
||||||
|
|
||||||
|
void scanWallpapers();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stateCaptured();
|
void stateCaptured();
|
||||||
|
|
||||||
@@ -81,13 +85,13 @@ class Manager : public QObject {
|
|||||||
void _loadActionConfig(const QJsonObject& config);
|
void _loadActionConfig(const QJsonObject& config);
|
||||||
void _loadStyleConfig(const QJsonObject& config);
|
void _loadStyleConfig(const QJsonObject& config);
|
||||||
void _loadCacheConfig(const QJsonObject& config);
|
void _loadCacheConfig(const QJsonObject& config);
|
||||||
// Load wallpapers
|
|
||||||
void _loadWallpapers();
|
|
||||||
// Callback for state capture results
|
// Callback for state capture results
|
||||||
void _onCaptureResult(const QString& key, const QString& value);
|
void _onCaptureResult(const QString& key, const QString& value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QDir m_configDir;
|
const QDir m_configDir;
|
||||||
|
bool m_disableActions = false;
|
||||||
|
|
||||||
WallpaperConfigItems m_wallpaperConfig;
|
WallpaperConfigItems m_wallpaperConfig;
|
||||||
ThemeConfigItems m_themeConfig;
|
ThemeConfigItems m_themeConfig;
|
||||||
ActionConfigItems m_actionConfig;
|
ActionConfigItems m_actionConfig;
|
||||||
|
|||||||
@@ -9,10 +9,12 @@
|
|||||||
WALLREEL_DECLARE_SENDER("ImageManager")
|
WALLREEL_DECLARE_SENDER("ImageManager")
|
||||||
|
|
||||||
WallReel::Core::Image::Manager::Manager(
|
WallReel::Core::Image::Manager::Manager(
|
||||||
|
Config::Manager& configMgr,
|
||||||
Cache::Manager& cacheMgr,
|
Cache::Manager& cacheMgr,
|
||||||
const QSize& thumbnailSize,
|
const QSize& thumbnailSize,
|
||||||
QObject* parent)
|
QObject* parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
|
m_configMgr(configMgr),
|
||||||
m_cacheMgr(cacheMgr),
|
m_cacheMgr(cacheMgr),
|
||||||
m_thumbnailSize(thumbnailSize) {
|
m_thumbnailSize(thumbnailSize) {
|
||||||
m_dataModel = new Model(this);
|
m_dataModel = new Model(this);
|
||||||
@@ -38,6 +40,21 @@ WallReel::Core::Image::Manager::~Manager() {
|
|||||||
m_watcher.waitForFinished();
|
m_watcher.waitForFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WallReel::Core::Image::Manager::loadAndProcess() {
|
||||||
|
if (m_isLoading) {
|
||||||
|
WR_WARN("Already loading images. Ignoring new load request.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_isLoading = true;
|
||||||
|
emit isLoadingChanged();
|
||||||
|
|
||||||
|
_clearData();
|
||||||
|
|
||||||
|
m_configMgr.scanWallpapers();
|
||||||
|
const auto paths = m_configMgr.getWallpapers();
|
||||||
|
return _process(paths);
|
||||||
|
}
|
||||||
|
|
||||||
void WallReel::Core::Image::Manager::loadAndProcess(const QStringList& paths) {
|
void WallReel::Core::Image::Manager::loadAndProcess(const QStringList& paths) {
|
||||||
if (m_isLoading) {
|
if (m_isLoading) {
|
||||||
WR_WARN("Already loading images. Ignoring new load request.");
|
WR_WARN("Already loading images. Ignoring new load request.");
|
||||||
@@ -48,6 +65,10 @@ void WallReel::Core::Image::Manager::loadAndProcess(const QStringList& paths) {
|
|||||||
|
|
||||||
_clearData();
|
_clearData();
|
||||||
|
|
||||||
|
return _process(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WallReel::Core::Image::Manager::_process(const QStringList& paths) {
|
||||||
m_processedCount = 0;
|
m_processedCount = 0;
|
||||||
m_progressUpdateTimer.start(s_ProgressUpdateIntervalMs);
|
m_progressUpdateTimer.start(s_ProgressUpdateIntervalMs);
|
||||||
// These are all small objects so capturing by value should be fine
|
// These are all small objects so capturing by value should be fine
|
||||||
@@ -75,6 +96,7 @@ void WallReel::Core::Image::Manager::stop() {
|
|||||||
|
|
||||||
void WallReel::Core::Image::Manager::_clearData() {
|
void WallReel::Core::Image::Manager::_clearData() {
|
||||||
m_dataModel->clearData();
|
m_dataModel->clearData();
|
||||||
|
m_dataMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WallReel::Core::Image::Manager::_onProgressValueChanged(int value) {
|
void WallReel::Core::Image::Manager::_onProgressValueChanged(int value) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#include "Cache/manager.hpp"
|
#include "Cache/manager.hpp"
|
||||||
|
#include "Config/manager.hpp"
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
#include "model.hpp"
|
#include "model.hpp"
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ class Manager : public QObject {
|
|||||||
// Constructor / Destructor
|
// Constructor / Destructor
|
||||||
|
|
||||||
Manager(
|
Manager(
|
||||||
|
Config::Manager& configMgr,
|
||||||
Cache::Manager& cacheMgr,
|
Cache::Manager& cacheMgr,
|
||||||
const QSize& thumbnailSize,
|
const QSize& thumbnailSize,
|
||||||
QObject* parent = nullptr);
|
QObject* parent = nullptr);
|
||||||
@@ -32,6 +34,8 @@ class Manager : public QObject {
|
|||||||
|
|
||||||
int processedCount() const { return m_processedCount.load(std::memory_order_relaxed); }
|
int processedCount() const { return m_processedCount.load(std::memory_order_relaxed); }
|
||||||
|
|
||||||
|
// Total count of processing items, NOT the count of items in the model
|
||||||
|
// (Why did I name this method like this? idk)
|
||||||
int totalCount() const { return m_watcher.progressMaximum(); }
|
int totalCount() const { return m_watcher.progressMaximum(); }
|
||||||
|
|
||||||
void setSortType(Config::SortType type) { m_proxyModel->setSortType(type); }
|
void setSortType(Config::SortType type) { m_proxyModel->setSortType(type); }
|
||||||
@@ -46,6 +50,8 @@ class Manager : public QObject {
|
|||||||
|
|
||||||
QString searchText() const { return m_proxyModel->getSearchText(); }
|
QString searchText() const { return m_proxyModel->getSearchText(); }
|
||||||
|
|
||||||
|
void loadAndProcess();
|
||||||
|
|
||||||
void loadAndProcess(const QStringList& paths);
|
void loadAndProcess(const QStringList& paths);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
@@ -59,6 +65,7 @@ class Manager : public QObject {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void _clearData();
|
void _clearData();
|
||||||
|
void _process(const QStringList& paths);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Properties
|
// Properties
|
||||||
@@ -75,6 +82,7 @@ class Manager : public QObject {
|
|||||||
ProxyModel* m_proxyModel;
|
ProxyModel* m_proxyModel;
|
||||||
QHash<QString, Data*> m_dataMap;
|
QHash<QString, Data*> m_dataMap;
|
||||||
|
|
||||||
|
Config::Manager& m_configMgr;
|
||||||
Cache::Manager& m_cacheMgr;
|
Cache::Manager& m_cacheMgr;
|
||||||
QSize m_thumbnailSize;
|
QSize m_thumbnailSize;
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,13 @@ class Bootstrap {
|
|||||||
friend class Carousel;
|
friend class Carousel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Bootstrap(const AppOptions& options) {
|
Bootstrap(const AppOptions& options) : options(options) {
|
||||||
configMgr = new Config::Manager(
|
configMgr = new Config::Manager(
|
||||||
Utils::getConfigDir(),
|
Utils::getConfigDir(),
|
||||||
Utils::getPicturesDir(),
|
Utils::getPicturesDir(),
|
||||||
options.appendDirs,
|
options.appendDirs,
|
||||||
options.configPath);
|
options.configPath,
|
||||||
|
options.disableActions);
|
||||||
|
|
||||||
cacheMgr = new Cache::Manager(
|
cacheMgr = new Cache::Manager(
|
||||||
Utils::getCacheDir(),
|
Utils::getCacheDir(),
|
||||||
@@ -35,6 +36,7 @@ class Bootstrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
imageMgr = new Image::Manager(
|
imageMgr = new Image::Manager(
|
||||||
|
*configMgr,
|
||||||
*cacheMgr,
|
*cacheMgr,
|
||||||
configMgr->getFocusImageSize());
|
configMgr->getFocusImageSize());
|
||||||
|
|
||||||
@@ -54,10 +56,15 @@ class Bootstrap {
|
|||||||
void start() {
|
void start() {
|
||||||
cacheMgr->evictOldEntries();
|
cacheMgr->evictOldEntries();
|
||||||
configMgr->captureState();
|
configMgr->captureState();
|
||||||
imageMgr->loadAndProcess(configMgr->getWallpapers());
|
imageMgr->loadAndProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool apply(const QString& path) {
|
bool apply(const QString& path) {
|
||||||
|
if (options.disableActions) {
|
||||||
|
Logger::warn("Bootstrap", "Actions are disabled, cannot apply wallpaper");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
bool successFlag = false;
|
bool successFlag = false;
|
||||||
|
|
||||||
@@ -122,6 +129,7 @@ class Bootstrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const AppOptions& options;
|
||||||
Cache::Manager* cacheMgr{};
|
Cache::Manager* cacheMgr{};
|
||||||
Config::Manager* configMgr{};
|
Config::Manager* configMgr{};
|
||||||
Image::Manager* imageMgr{};
|
Image::Manager* imageMgr{};
|
||||||
|
|||||||
@@ -171,6 +171,10 @@ class Carousel : public QObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void requestReload() {
|
||||||
|
m_imageMgr->loadAndProcess();
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void currentImageIdChanged();
|
void currentImageIdChanged();
|
||||||
void currentIndexChanged();
|
void currentIndexChanged();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "manager.hpp"
|
#include "manager.hpp"
|
||||||
|
|
||||||
|
#include "Utils/misc.hpp"
|
||||||
#include "Utils/texttemplate.hpp"
|
#include "Utils/texttemplate.hpp"
|
||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
|
|
||||||
@@ -61,6 +62,8 @@ void Manager::selectWallpaper(const QString& id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utils::printPath(data->getFullPath());
|
||||||
|
|
||||||
const auto command = _renderCommand(m_actionConfig.onSelected, _generateVariables(*data));
|
const auto command = _renderCommand(m_actionConfig.onSelected, _generateVariables(*data));
|
||||||
m_wallpaperService->select(command);
|
m_wallpaperService->select(command);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,6 +179,24 @@ inline QDir getPicturesDir() {
|
|||||||
return QDir(picturesDir);
|
return QDir(picturesDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void printPath(const QString& path, std::FILE* out = stdout) {
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray bytes = QFile::encodeName(path);
|
||||||
|
|
||||||
|
const size_t n = static_cast<size_t>(bytes.size());
|
||||||
|
if (std::fwrite(bytes.constData(), 1, n, out) != n) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (std::fputc('\n', out) == EOF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::fflush(out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace WallReel::Core::Utils
|
} // namespace WallReel::Core::Utils
|
||||||
|
|
||||||
#endif // WALLREEL_MISC_HPP
|
#endif // WALLREEL_MISC_HPP
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ qt_add_qml_module(${UILIB_NAME}_Modules
|
|||||||
Modules/ColorControl.qml
|
Modules/ColorControl.qml
|
||||||
Modules/TopBar.qml
|
Modules/TopBar.qml
|
||||||
Modules/BottomBar.qml
|
Modules/BottomBar.qml
|
||||||
|
Modules/ReloadButton.qml
|
||||||
)
|
)
|
||||||
qt_add_qml_module(${UILIB_NAME}_Components
|
qt_add_qml_module(${UILIB_NAME}_Components
|
||||||
STATIC
|
STATIC
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
ToolButton {
|
||||||
|
id: reloadBtn
|
||||||
|
|
||||||
|
property bool isLoading: false
|
||||||
|
|
||||||
|
icon.name: "view-refresh"
|
||||||
|
icon.width: 16
|
||||||
|
icon.height: 16
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.delay: 600
|
||||||
|
ToolTip.text: "Reload from disk"
|
||||||
|
enabled: !isLoading
|
||||||
|
}
|
||||||
@@ -14,10 +14,12 @@ Item {
|
|||||||
property alias availableSortTypes: sortCtrl.availableSortTypes
|
property alias availableSortTypes: sortCtrl.availableSortTypes
|
||||||
property alias selectedSortType: sortCtrl.selectedSortType
|
property alias selectedSortType: sortCtrl.selectedSortType
|
||||||
property alias isSortDescending: sortCtrl.isDescending
|
property alias isSortDescending: sortCtrl.isDescending
|
||||||
|
property alias isLoading: reloadBtn.isLoading
|
||||||
|
|
||||||
signal sortTypeSelected(string sortType)
|
signal sortTypeSelected(string sortType)
|
||||||
signal sortDescendingToggled(bool descending)
|
signal sortDescendingToggled(bool descending)
|
||||||
signal searchDismissed()
|
signal searchDismissed()
|
||||||
|
signal reloadRequested()
|
||||||
|
|
||||||
function requestSearchFocus() {
|
function requestSearchFocus() {
|
||||||
searchBar.requestFocus();
|
searchBar.requestFocus();
|
||||||
@@ -63,6 +65,13 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReloadButton {
|
||||||
|
id: reloadBtn
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
onClicked: root.reloadRequested()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ Item {
|
|||||||
root.forceActiveFocus();
|
root.forceActiveFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onReloadRequested() {
|
||||||
|
CarouselProvider.requestReload();
|
||||||
|
}
|
||||||
|
|
||||||
target: topBar
|
target: topBar
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +52,7 @@ Item {
|
|||||||
title: carousel.currentImageName
|
title: carousel.currentImageName
|
||||||
availableSortTypes: CarouselProvider.availableSortTypes
|
availableSortTypes: CarouselProvider.availableSortTypes
|
||||||
isSortDescending: CarouselProvider.sortDescending
|
isSortDescending: CarouselProvider.sortDescending
|
||||||
|
isLoading: CarouselProvider.isLoading
|
||||||
onSortTypeSelected: (t) => {
|
onSortTypeSelected: (t) => {
|
||||||
return CarouselProvider.setSortType(t);
|
return CarouselProvider.setSortType(t);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -96,11 +96,6 @@
|
|||||||
"default": true,
|
"default": true,
|
||||||
"description": "Whether to print the selected wallpaper path to stdout on confirm"
|
"description": "Whether to print the selected wallpaper path to stdout on confirm"
|
||||||
},
|
},
|
||||||
"printPreview": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Whether to print the previewed wallpaper path to stdout on preview"
|
|
||||||
},
|
|
||||||
"onSelected": {
|
"onSelected": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"default": "",
|
||||||
@@ -148,7 +143,7 @@
|
|||||||
},
|
},
|
||||||
"quitOnSelected": {
|
"quitOnSelected": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": true,
|
||||||
"description": "Whether to quit the application after confirming a wallpaper"
|
"description": "Whether to quit the application after confirming a wallpaper"
|
||||||
},
|
},
|
||||||
"restoreOnClose": {
|
"restoreOnClose": {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
title: WALLREEL
|
title: WALLREEL
|
||||||
section: 1
|
section: 1
|
||||||
header: User Commands
|
header: User Commands
|
||||||
footer: WallReel 2.0.1
|
footer: WallReel 2.0.2
|
||||||
date: 2026-03-24
|
date: 2026-03-24
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+2
-5
@@ -2,7 +2,7 @@
|
|||||||
title: WALLREEL
|
title: WALLREEL
|
||||||
section: 5
|
section: 5
|
||||||
header: File Formats Manual
|
header: File Formats Manual
|
||||||
footer: WallReel 2.0.1
|
footer: WallReel 2.0.2
|
||||||
date: 2026-03-24
|
date: 2026-03-24
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -79,9 +79,6 @@ Configures commands executed for preview, selection, and restore behavior.
|
|||||||
`printSelected` (boolean, default: `true`)
|
`printSelected` (boolean, default: `true`)
|
||||||
: Print selected wallpaper path to stdout on confirmation.
|
: Print selected wallpaper path to stdout on confirmation.
|
||||||
|
|
||||||
`printPreview` (boolean, default: `false`)
|
|
||||||
: Print previewed wallpaper path to stdout on preview.
|
|
||||||
|
|
||||||
`onSelected` (string, default: `""`)
|
`onSelected` (string, default: `""`)
|
||||||
: Command executed when a wallpaper is confirmed.
|
: Command executed when a wallpaper is confirmed.
|
||||||
|
|
||||||
@@ -101,7 +98,7 @@ Each item has:
|
|||||||
`onRestore` (string, default: `""`)
|
`onRestore` (string, default: `""`)
|
||||||
: Command executed on restore. Saved state keys are usable as placeholders.
|
: Command executed on restore. Saved state keys are usable as placeholders.
|
||||||
|
|
||||||
`quitOnSelected` (boolean, default: `false`)
|
`quitOnSelected` (boolean, default: `true`)
|
||||||
: Exit application immediately after confirming a selection.
|
: Exit application immediately after confirming a selection.
|
||||||
|
|
||||||
`restoreOnClose` (boolean, default: `true`)
|
`restoreOnClose` (boolean, default: `true`)
|
||||||
|
|||||||
Reference in New Issue
Block a user