wallswitch 0.65.3

randomly selects wallpapers for multiple monitors
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416

# wallswitch

Random Wallpaper for Multiple Monitors

```
#-----------#-----------# ... ... #-----------#
|           |           |         |           |
| Monitor 1 | Monitor 2 |         | Monitor n |
|           |           |         |           |
#-----------#-----------# ... ... #-----------#
```

### Description

`wallswitch` randomly selects and processes wallpapers for multiple monitors.

It is designed to be fast, and lightweight, performing all image stitching, cropping, scaling, and fractal generation in-process using pure Rust.

### Example Wallpapers (with Julia Fractal Overlays)

Below are 3 examples of generated wallpapers after applying the procedural Julia set fractal overlay effect.
Click on the thumbnails below to view the images in 1920x1080 resolution:

<table align="center" width="100%">
  <tr>
    <td align="center" width="33.3%">
      <a href="examples/wallswitch_monitor_0.jpg" target="_blank">
        <img src="examples/wallswitch_monitor_0.jpg" alt="Julia Fractal Overlay Example 1" width="100%"/>
      </a>
      <br/>
      <em>Example 1</em>
    </td>
    <td align="center" width="33.3%">
      <a href="examples/wallswitch_monitor_1.jpg" target="_blank">
        <img src="examples/wallswitch_monitor_1.jpg" alt="Julia Fractal Overlay Example 2" width="100%"/>
      </a>
      <br/>
      <em>Example 2</em>
    </td>
    <td align="center" width="33.3%">
      <a href="examples/wallswitch_monitor_2.jpg" target="_blank">
        <img src="examples/wallswitch_monitor_2.jpg" alt="Julia Fractal Overlay Example 3" width="100%"/>
      </a>
      <br/>
      <em>Example 3</em>
    </td>
  </tr>
</table>

### Features

* **Multi-Picture Composition**: Dynamically combines up to N different wallpapers per monitor across all supported desktop environments.
* **Smart Caching & Visual Deduplication**:
    * Uses BLAKE3 hashing to index files.
    * Automatically skips visual duplicates (same image, different filename).
    * Smart cache checks modification times (mtime) for instant startup.
* **Procedural Overlay Effects**: Adds customizable mathematical overlays over your wallpapers. Configured via `-e / --effect <none|julia|mandelbrot|newton|nova|star|aurora|fractal|random>`:
    * **Julia Sets (`julia`)**: Detailed, randomized 360-degree rotated fractals. Uses continuous potential smooth coloring to prevent color-banding, and contrast-preserving dynamic halo blending to keep shapes visible on both light and dark backgrounds.
      * *Generator function: `f(z) = z^2 + c`, where `c` is a fixed constant and the initial `z` varies.*
    * **Mandelbrot Set (`mandelbrot`)**: Renders structural details and high-period cardioid bulb swirls.
      * *Generator function: `z(n+1) = z(n)^2 + c`, where the initial `z` is zero and `c` varies.*
    * **Newton-Raphson Basins (`newton`)**: Renders geometric, kaleidoscope-like mandala structures representing root-finding convergence fields across complex space boundaries.
      * *Generator function: `z(n+1) = z(n) - lambda * f(z(n)) / f'(z(n))` on the polynomial `f(z) = z^p - 1`.*
    * **Nova Julia (`nova`)**: Generates flowing, fluid-like plumes resembling liquid mercury, cosmic nebulae, or dynamic plasma current paths.
      * *Generator function: `z(n+1) = z(n) - R * (z(n)^p - 1) / (p * z(n)^(p-1)) + c`.*
    * **Starfield / Bokeh (`star`)**: Projects glowing, circular stars and light orbs of varying sizes, intensities, and neon colors with smooth Gaussian light falloffs.
      * *Generator function: `I(d) = I_0 * exp(-d^2 / (2 * sigma^2))`.*
    * **Cosmic Aurora (`aurora`)**: Generates glowing atmospheric wave filaments using multi-frequency wave mathematics.
      * *Generator function: `alpha = 0.25 * (sin(d_u * x) + cos(d_v * y) + sin(d_w * x + rho) + cos(sqrt(u^2 + v^2) * d_w4))`.*
    * **Fractal Mode (`fractal`)**: Randomly selects between Julia or Mandelbrot fractal overlays for the cycle.
    * **Polynomial Mode (`polynomial`)**: Randomly selects between Newton-Raphson Basins or Nova Julia fractal overlays for the cycle.
    * **Randomized Mode (`random`)**: Automatically decides on a random overlay effect independently for each physical display.
* **Highly Optimized Parallel Processing**: Core rendering routines for procedural calculations and image stitching are fully parallelized. CPU consumption can be throttled dynamically using `--max-threads-percent` (from 10% to 100%) to prevent performance impacts on other system applications.
* **Configurable Filtering**:
    * Dimension Control: Filter images by minimum/maximum width and height.
    * File Size Management: Exclude images based on byte size.
* **Flexible Configuration**:
    * Custom directories and image extensions (AVIF, JPG, PNG, WEBP, TIF, etc.).
    * Monitor-specific settings (orientation and pictures per monitor).
* **Advanced Listing**:
    * Sort your entire collection by size, dimensions, aspect ratio, or date.

### Usage

Standard background loop:
```
wallswitch
```
Run once and exit (useful for login scripts or cron):
```
wallswitch --once
```
Test behavior without applying changes:
```
wallswitch --dry-run
```
Set N different wallpapers per monitor (All desktops):
```
wallswitch -p N
```
Apply a specific Julia Sets overlay on wallpapers:
```
wallswitch -e julia
```

### Configuration

The configuration file is located at:
```
  ~/.config/wallswitch/wallswitch.json
```

Displaying the Configuration:
```
wallswitch -c
```
The default configuration file structure:
```
{
  "desktop": "gnome",
  "directories": [
    "/home/user_name/Figures",
    "/home/user_name/Images",
    "/home/user_name/Pictures",
    "/home/user_name/Wallpapers",
    "/home/user_name/Imagens",
    "/usr/share/backgrounds"
  ],
  "extensions": [
    "avif",
    "jpg",
    "jpeg",
    "png",
    "tif",
    "webp"
  ],
  "interval": 1800,
  "min_dimension": 600,
  "max_dimension": 128000,
  "min_size": 1024,
  "max_size": 1073741824,
  "monitors": [
    {
      "picture_orientation": "Vertical",
      "pictures_per_monitor": 1,
      "resolution": {
        "width": 3840,
        "height": 2160
      }
    },
    {
      "picture_orientation": "Horizontal",
      "pictures_per_monitor": 1,
      "resolution": {
        "width": 3840,
        "height": 2160
      }
    }
  ],
  "monitor_orientation": "Horizontal",
  "path_feh": "/usr/bin/feh",
  "sort": false,
  "effect": "none",
  "effects": {
    "add_presets": true,
    "min_iterations": 600,
    "max_iterations": 1200,
    "julia": [...],
    "mandelbrot": [...],
    "newton": [...],
    "nova": [...]
  },
  "wallpaper": "/home/user_name/.cache/wallswitch/wallswitch.png",
  "transition_type": "random",
  "transition_duration": 2,
  "transition_fps": 60,
  "transition_angle": 45,
  "transition_pos": "center",
  "max_threads_percent": 50
}

```

### Listing and Sorting

List images using `--list <CRITERIA>`.

#### Table sorting options:
  * path: Sort by full system path.
  * name: Sort by filename only.
  * size: Sort by file size (ascending).
  * sizedesc: Sort by file size (descending).
  * width: Sort by image width.
  * height: Sort by image height.
  * area: Sort by total pixels (width x height).
  * ratio: Sort by aspect ratio (e.g., 16:9).
  * time: Sort by last modification date.

#### JSON state options:
  * processed: List probed images with dimension metadata (JSON).
  * unprocessed: List images pending dimension probing (JSON).
  * cache: Full dump of the metadata cache (JSON).

Example:
```
wallswitch --list ratio
```

### Wallpaper Suggestions

* Get all gnome backgrounds:
```
git clone https://github.com/zebreus/all-gnome-backgrounds.git
```

### Help Messages
```
Run: wallswitch -h
```
```
randomly selects wallpapers for multiple monitors
Usage: wallswitch [OPTIONS]

Options:
  -b, --min-size <MIN_SIZE>
          Set a minimum file size (in bytes) for searching image files
  -B, --max-size <MAX_SIZE>
          Set a maximum file size (in bytes) for searching image files
  -c, --config
          Read the configuration file and exit the program
  -d, --min-dimension <MIN_DIMENSION>
          Set the minimum dimension that the height and width must satisfy
  -D, --max-dimension <MAX_DIMENSION>
          Set the maximum dimension that the height and width must satisfy
  -e, --effect <EFFECT>
          Apply a procedural overlay effect to the selected wallpapers before displaying [possible values: none, julia, mandelbrot, newton, nova, aurora, star, fractal, polynomial, random]
      --effects-add-presets <BOOL>
          Whether custom presets are appended to default ones (true) or replace them (false) [possible values: true, false]
  -n, --effects-min-iterations <MIN_ITERATIONS>
          Set a custom minimum iteration limit for escape-time fractal calculations
  -N, --effects-max-iterations <MAX_ITERATIONS>
          Set a custom maximum iteration limit for escape-time fractal calculations
  -g, --generate <GENERATOR>
          Generate shell completions and exit the program [possible values: bash, elvish, fish, powershell, zsh]
  -i, --interval <INTERVAL>
          Set the interval (in seconds) between each wallpaper displayed
  -l, --list <CRITERIA>
          List all found images and exit
  -m, --monitor <MONITOR>
          Set the number of monitors [default: 2]
  -o, --orientation <MONITOR_ORIENTATION>
          Inform monitor orientation: Horizontal (side-by-side) or Vertical (stacked)
  -1, --once
          Run a single wallpaper update cycle and exit
  -p, --pictures-per-monitor <PICTURES_PER_MONITOR>
          Set number of pictures (or images) per monitor [default: 1]
  -s, --sort
          Sort the images found
  -r, --dry-run
          Run without applying the wallpapers (simulation mode)
      --transition-type <TRANSITION_TYPE>
          Transition type for Wayland compositors using awww (e.g. wipe, wave, fade, random)
      --transition-duration <TRANSITION_DURATION>
          Duration of the transition animation in seconds
      --transition-fps <TRANSITION_FPS>
          Frames per second for transition smoothness
      --transition-angle <TRANSITION_ANGLE>
          Angle used by directional transitions (wipe, wave)
      --transition-pos <TRANSITION_POS>
          Origin position used by grow/outer transitions (e.g. center, top)
  -t, --max-threads-percent <PERCENT>
          Limit the maximum execution threads used by parallel tasks
  -v, --verbose
          Show intermediate runtime messages
  -h, --help
          Print help (see more with '--help')
  -V, --version
          Print version


Config file:
  /.config/wallswitch/wallswitch.json

Effects Configuration (EffectsConfig):
  Alter these parameters inside your 'wallswitch.json' or override them via CLI:

• add-presets: Add custom presets to defaults (default: true).
• min-iterations: Minimum iteration limit for escape-time calculations.
• max-iterations: Maximum iteration limit for escape-time calculations.
• julia / mandelbrot / newton / nova: Custom arrays of mathematical presets.

Examples:
  # Start the automatic background loop using default settings
  wallswitch

  # Run a single wallpaper update cycle and exit (useful for cron jobs)
  wallswitch --once

  # Change wallpaper every 10 minutes (600 seconds)
  wallswitch --interval 600

  # Set 3 different wallpapers per monitor (Gnome desktop only)
  wallswitch --pictures_per_monitor 3

  # Filter images by dimension (min 1080px) and file size (max 5MB)
  wallswitch --min-dimension 1080 --max-size 5242880

  # Apply a specific Julia Sets fractal overlay on wallpapers
  wallswitch --effect julia

  # Override the preset behavior and iterations for fractal calculations
  wallswitch --effect julia --effects-add-presets false --effects-min-iterations 1200

  # Apply random fractal overlays [julia, mandelbrot]
  wallswitch --effect fractal

  # Apply randomized procedural overlays (fractal, star, aurora) on wallpapers
  wallswitch --effect random

  # Dry run mode to see what would be executed without applying changes
  wallswitch --dry-run --verbose

  # Wayland (awww): Use specific transition effects and duration
  wallswitch --transition-type wave --transition-duration 3

  # List all found images sorted by file size
  wallswitch --list size

  # Display all processed images (with dimensions) in JSON format
  wallswitch --list processed

  # Display all images that haven't been probed yet
  wallswitch --list unprocessed

  # Count processed images using jq
  wallswitch -l processed | jq 'length'

  # Limit CPU processing to 20% of total logical cores during rendering
  wallswitch --max-threads-percent 20
```

### Installation and Background Strategies

`wallswitch` can be deployed using two different strategies depending on your operating system and system resource preferences.

#### Strategy A: Systemd User Scheduler (Recommended for Linux)

This approach triggers a single-shot cycle (`wallswitch --once`) at a configured interval.
* **Advantage:** Guarantees 0 MB of RAM usage when idle, as the process terminates immediately after updating the background.
* **Requirements:** Any standard Linux distribution using Systemd (such as Manjaro, Arch, Fedora, Debian/Ubuntu).

To build, install, and configure the Systemd timer automatically (defaults to a 10-minute / 600-second interval):

```
git clone https://github.com/claudiofsr/wallswitch.git
cd wallswitch
make install
```

To customize the rotation interval (e.g., to 5 minutes / 300 seconds):

```
make install INTERVAL=300
```

To cleanly disable and remove the timer and configuration files from your system:

```
make uninstall
```

---

#### Strategy B: Built-in Daemon Mode

This approach runs `wallswitch` as a persistent background loop process.
* **Advantage:** Completely self-contained with zero external scheduler dependencies; ideal for non-Systemd setups, X11/Openbox sessions, or Windows environments.
* **Memory Management:** Highly optimized. It leverages standard drop semantics and conditional `malloc_trim` FFI triggers at the end of each cycle to release unused memory arenas back to the OS kernel, keeping the idle RAM footprint constrained (~58MB to ~140MB depending on the processing of massive 4K/8K assets).

To build and install the standalone binary:

```
cargo b -r && cargo install --path=.
```

To run the persistent background loop (e.g., updating every 5 minutes):

```
wallswitch --interval 300
```

### Desktops

Desktop Specifics:
  * Gnome    : Assembles composite backgrounds in memory, saves the final spanned file, and sets it via 'gsettings'.
  * XFCE     : Assembles composite backgrounds in memory, saves separate monitor backgrounds, and applies them via 'xfconf-query'.
  * Wayland  : Robust detection for Hyprland, Niri, Labwc, Mango.
               Assembles separate monitor backgrounds, and applies them.
               Backend priority: awww -> swaybg -> hyprpaper.
  * X11/Other: Fallback to 'feh'.

### Dependencies

* feh         : Fast viewer for X11/Openbox.
* awww        : Animated daemon for Wayland (highly recommended).
* swaybg      : Reliable static wallpaper tool for Wayland.
* hyprpaper   : Wallpaper utility for Hyprland users.

### License

Copyright (c) 2023, Claudio Fernandes de Souza Rodrigues.

All rights reserved.

Distributed under the BSD-3-Clause License.