garbg Integration with gar Window Manager
This guide explains how to integrate garbg (wallpaper daemon) with the gar tiling window manager.
Quick Start
1. Start garbg daemon on login
Add to your ~/.config/gar/init.lua:
-- Start garbg daemon on gar startup
gar.exec_once("garbg daemon")
Or if using a shell startup script (~/.xinitrc, ~/.xprofile):
garbg daemon &
2. Set initial wallpaper
In your gar config:
-- Set wallpaper after daemon starts
gar.exec_once("sleep 0.5 && garbg set ~/Pictures/wallpaper.jpg")
-- Or set a slideshow directory
gar.exec_once("sleep 0.5 && garbg set ~/Pictures/wallpapers --random --interval 5m")
Keybindings
Add wallpaper control keybindings to your gar config:
-- Wallpaper navigation
gar.bind("mod+bracketright", function() gar.exec("garbg next") end) -- Mod+]
gar.bind("mod+bracketleft", function() gar.exec("garbg prev") end) -- Mod+[
gar.bind("mod+shift+w", function() gar.exec("garbg random") end) -- Mod+Shift+W
-- Pause/resume slideshow or animation
gar.bind("mod+shift+p", function() gar.exec("garbg toggle") end) -- Mod+Shift+P
Helper Functions
Create reusable functions in your gar config:
-- Wallpaper helper module
garbg = {
next = function() gar.exec("garbg next") end,
prev = function() gar.exec("garbg prev") end,
pause = function() gar.exec("garbg pause") end,
resume = function() gar.exec("garbg resume") end,
toggle = function() gar.exec("garbg toggle") end,
random = function() gar.exec("garbg random") end,
set = function(source, opts)
local cmd = "garbg set '" .. source .. "'"
if opts then
if opts.mode then cmd = cmd .. " --mode " .. opts.mode end
if opts.random then cmd = cmd .. " --random" end
if opts.interval then cmd = cmd .. " --interval " .. opts.interval end
if opts.animate then cmd = cmd .. " --animate" end
end
gar.exec(cmd)
end,
set_monitor = function(monitor, source, mode)
local cmd = "garbg set-monitor " .. monitor .. " '" .. source .. "'"
if mode then cmd = cmd .. " --mode " .. mode end
gar.exec(cmd)
end,
}
-- Usage examples:
-- garbg.set("~/Pictures/wallpapers", { random = true, interval = "5m" })
-- garbg.set_monitor("DP-1", "~/left.jpg")
-- garbg.toggle()
Per-Workspace Wallpapers
garbg automatically subscribes to gar workspace events. Configure per-workspace wallpapers in ~/.config/garbg/config.toml:
[general]
mode = "fill"
[default]
source = "~/Pictures/default.jpg"
[[workspaces]]
id = 1
source = "~/Pictures/workspace1.jpg"
[[workspaces]]
id = 2
source = "~/Pictures/workspace2.jpg"
[[workspaces]]
id = 9
source = "~/Pictures/gaming.jpg"
When you switch workspaces in gar, garbg will automatically change the wallpaper.
Multi-Monitor Setup
Query available monitors
garbg query monitors
Output:
{
"monitors": [
{"name": "DP-1", "width": 2560, "height": 1440, "x": 0, "y": 0, "primary": true},
{"name": "HDMI-1", "width": 1920, "height": 1080, "x": 2560, "y": 180, "primary": false}
]
}
Set per-monitor wallpapers
# Set different wallpapers for each monitor
garbg set-monitor DP-1 ~/Pictures/left.jpg
garbg set-monitor HDMI-1 ~/Pictures/right.jpg
In gar config:
gar.exec_once("sleep 0.5 && garbg set-monitor DP-1 ~/Pictures/main.jpg")
gar.exec_once("sleep 0.5 && garbg set-monitor HDMI-1 ~/Pictures/side.jpg")
Monitor Hotplug
garbg subscribes to monitor events from gar. When a monitor is:
- Added: Wallpaper is automatically applied to the new monitor
- Removed: Monitor state is cleaned up
- Changed: Wallpapers are re-composited at new positions/resolutions
No additional configuration needed - this works automatically when connected to gar.
Animated Wallpapers
Animated GIFs
garbg set ~/Pictures/animated.gif --animate
Video wallpapers (requires video feature)
garbg set ~/Videos/loop.mp4
# Videos are automatically animated (no --animate flag needed)
IPC Commands
All commands can be sent to the daemon via the CLI:
| Command | Description |
|---|---|
garbg set <source> |
Set wallpaper |
garbg set-monitor <name> <source> |
Set per-monitor wallpaper |
garbg next |
Next in slideshow |
garbg prev |
Previous in slideshow |
garbg random |
Random from playlist |
garbg pause |
Pause slideshow/animation |
garbg resume |
Resume slideshow/animation |
garbg toggle |
Toggle pause state |
garbg status |
Get current status (JSON) |
garbg query monitors |
List monitors (JSON) |
garbg query current |
Current wallpaper info (JSON) |
garbg reload |
Reload configuration |
Troubleshooting
garbg not connecting to gar
Check that gar is running and its IPC socket exists:
ls -la $XDG_RUNTIME_DIR/gar.sock
garbg will automatically reconnect with exponential backoff if gar restarts.
Wallpaper not appearing
-
Verify the daemon is running:
pgrep -f "garbg daemon" -
Check daemon logs:
garbg daemon # Run in foreground to see logs -
Verify RandR is working:
garbg query monitors
Animation stuttering
- Reduce max FPS:
garbg set file.gif --animate --max-fps 30 - Ensure no heavy background processes
Example Complete Config
~/.config/gar/init.lua:
-- Start garbg wallpaper daemon
gar.exec_once("garbg daemon")
-- Set initial wallpaper with slideshow
gar.exec_once("sleep 0.5 && garbg set ~/Pictures/wallpapers --random --interval 10m")
-- Wallpaper keybindings
gar.bind("mod+bracketright", function() gar.exec("garbg next") end)
gar.bind("mod+bracketleft", function() gar.exec("garbg prev") end)
gar.bind("mod+shift+w", function() gar.exec("garbg random") end)
gar.bind("mod+shift+p", function() gar.exec("garbg toggle") end)
~/.config/garbg/config.toml:
[general]
mode = "fill"
[animation]
enabled = true
max_fps = 60
[cache]
max_size_mb = 512
[default]
source = "~/Pictures/wallpapers"
[default.slideshow]
enabled = true
interval = "10m"
shuffle = true
[[workspaces]]
id = 1
source = "~/Pictures/main.jpg"
[[workspaces]]
id = 9
source = "~/Pictures/gaming.jpg"
View source
| 1 | # garbg Integration with gar Window Manager |
| 2 | |
| 3 | This guide explains how to integrate garbg (wallpaper daemon) with the gar tiling window manager. |
| 4 | |
| 5 | ## Quick Start |
| 6 | |
| 7 | ### 1. Start garbg daemon on login |
| 8 | |
| 9 | Add to your `~/.config/gar/init.lua`: |
| 10 | |
| 11 | ```lua |
| 12 | -- Start garbg daemon on gar startup |
| 13 | gar.exec_once("garbg daemon") |
| 14 | ``` |
| 15 | |
| 16 | Or if using a shell startup script (`~/.xinitrc`, `~/.xprofile`): |
| 17 | |
| 18 | ```bash |
| 19 | garbg daemon & |
| 20 | ``` |
| 21 | |
| 22 | ### 2. Set initial wallpaper |
| 23 | |
| 24 | In your gar config: |
| 25 | |
| 26 | ```lua |
| 27 | -- Set wallpaper after daemon starts |
| 28 | gar.exec_once("sleep 0.5 && garbg set ~/Pictures/wallpaper.jpg") |
| 29 | |
| 30 | -- Or set a slideshow directory |
| 31 | gar.exec_once("sleep 0.5 && garbg set ~/Pictures/wallpapers --random --interval 5m") |
| 32 | ``` |
| 33 | |
| 34 | ## Keybindings |
| 35 | |
| 36 | Add wallpaper control keybindings to your gar config: |
| 37 | |
| 38 | ```lua |
| 39 | -- Wallpaper navigation |
| 40 | gar.bind("mod+bracketright", function() gar.exec("garbg next") end) -- Mod+] |
| 41 | gar.bind("mod+bracketleft", function() gar.exec("garbg prev") end) -- Mod+[ |
| 42 | gar.bind("mod+shift+w", function() gar.exec("garbg random") end) -- Mod+Shift+W |
| 43 | |
| 44 | -- Pause/resume slideshow or animation |
| 45 | gar.bind("mod+shift+p", function() gar.exec("garbg toggle") end) -- Mod+Shift+P |
| 46 | ``` |
| 47 | |
| 48 | ## Helper Functions |
| 49 | |
| 50 | Create reusable functions in your gar config: |
| 51 | |
| 52 | ```lua |
| 53 | -- Wallpaper helper module |
| 54 | garbg = { |
| 55 | next = function() gar.exec("garbg next") end, |
| 56 | prev = function() gar.exec("garbg prev") end, |
| 57 | pause = function() gar.exec("garbg pause") end, |
| 58 | resume = function() gar.exec("garbg resume") end, |
| 59 | toggle = function() gar.exec("garbg toggle") end, |
| 60 | random = function() gar.exec("garbg random") end, |
| 61 | |
| 62 | set = function(source, opts) |
| 63 | local cmd = "garbg set '" .. source .. "'" |
| 64 | if opts then |
| 65 | if opts.mode then cmd = cmd .. " --mode " .. opts.mode end |
| 66 | if opts.random then cmd = cmd .. " --random" end |
| 67 | if opts.interval then cmd = cmd .. " --interval " .. opts.interval end |
| 68 | if opts.animate then cmd = cmd .. " --animate" end |
| 69 | end |
| 70 | gar.exec(cmd) |
| 71 | end, |
| 72 | |
| 73 | set_monitor = function(monitor, source, mode) |
| 74 | local cmd = "garbg set-monitor " .. monitor .. " '" .. source .. "'" |
| 75 | if mode then cmd = cmd .. " --mode " .. mode end |
| 76 | gar.exec(cmd) |
| 77 | end, |
| 78 | } |
| 79 | |
| 80 | -- Usage examples: |
| 81 | -- garbg.set("~/Pictures/wallpapers", { random = true, interval = "5m" }) |
| 82 | -- garbg.set_monitor("DP-1", "~/left.jpg") |
| 83 | -- garbg.toggle() |
| 84 | ``` |
| 85 | |
| 86 | ## Per-Workspace Wallpapers |
| 87 | |
| 88 | garbg automatically subscribes to gar workspace events. Configure per-workspace wallpapers in `~/.config/garbg/config.toml`: |
| 89 | |
| 90 | ```toml |
| 91 | [general] |
| 92 | mode = "fill" |
| 93 | |
| 94 | [default] |
| 95 | source = "~/Pictures/default.jpg" |
| 96 | |
| 97 | [[workspaces]] |
| 98 | id = 1 |
| 99 | source = "~/Pictures/workspace1.jpg" |
| 100 | |
| 101 | [[workspaces]] |
| 102 | id = 2 |
| 103 | source = "~/Pictures/workspace2.jpg" |
| 104 | |
| 105 | [[workspaces]] |
| 106 | id = 9 |
| 107 | source = "~/Pictures/gaming.jpg" |
| 108 | ``` |
| 109 | |
| 110 | When you switch workspaces in gar, garbg will automatically change the wallpaper. |
| 111 | |
| 112 | ## Multi-Monitor Setup |
| 113 | |
| 114 | ### Query available monitors |
| 115 | |
| 116 | ```bash |
| 117 | garbg query monitors |
| 118 | ``` |
| 119 | |
| 120 | Output: |
| 121 | ```json |
| 122 | { |
| 123 | "monitors": [ |
| 124 | {"name": "DP-1", "width": 2560, "height": 1440, "x": 0, "y": 0, "primary": true}, |
| 125 | {"name": "HDMI-1", "width": 1920, "height": 1080, "x": 2560, "y": 180, "primary": false} |
| 126 | ] |
| 127 | } |
| 128 | ``` |
| 129 | |
| 130 | ### Set per-monitor wallpapers |
| 131 | |
| 132 | ```bash |
| 133 | # Set different wallpapers for each monitor |
| 134 | garbg set-monitor DP-1 ~/Pictures/left.jpg |
| 135 | garbg set-monitor HDMI-1 ~/Pictures/right.jpg |
| 136 | ``` |
| 137 | |
| 138 | In gar config: |
| 139 | ```lua |
| 140 | gar.exec_once("sleep 0.5 && garbg set-monitor DP-1 ~/Pictures/main.jpg") |
| 141 | gar.exec_once("sleep 0.5 && garbg set-monitor HDMI-1 ~/Pictures/side.jpg") |
| 142 | ``` |
| 143 | |
| 144 | ## Monitor Hotplug |
| 145 | |
| 146 | garbg subscribes to monitor events from gar. When a monitor is: |
| 147 | - **Added**: Wallpaper is automatically applied to the new monitor |
| 148 | - **Removed**: Monitor state is cleaned up |
| 149 | - **Changed**: Wallpapers are re-composited at new positions/resolutions |
| 150 | |
| 151 | No additional configuration needed - this works automatically when connected to gar. |
| 152 | |
| 153 | ## Animated Wallpapers |
| 154 | |
| 155 | ### Animated GIFs |
| 156 | |
| 157 | ```bash |
| 158 | garbg set ~/Pictures/animated.gif --animate |
| 159 | ``` |
| 160 | |
| 161 | ### Video wallpapers (requires `video` feature) |
| 162 | |
| 163 | ```bash |
| 164 | garbg set ~/Videos/loop.mp4 |
| 165 | # Videos are automatically animated (no --animate flag needed) |
| 166 | ``` |
| 167 | |
| 168 | ## IPC Commands |
| 169 | |
| 170 | All commands can be sent to the daemon via the CLI: |
| 171 | |
| 172 | | Command | Description | |
| 173 | |---------|-------------| |
| 174 | | `garbg set <source>` | Set wallpaper | |
| 175 | | `garbg set-monitor <name> <source>` | Set per-monitor wallpaper | |
| 176 | | `garbg next` | Next in slideshow | |
| 177 | | `garbg prev` | Previous in slideshow | |
| 178 | | `garbg random` | Random from playlist | |
| 179 | | `garbg pause` | Pause slideshow/animation | |
| 180 | | `garbg resume` | Resume slideshow/animation | |
| 181 | | `garbg toggle` | Toggle pause state | |
| 182 | | `garbg status` | Get current status (JSON) | |
| 183 | | `garbg query monitors` | List monitors (JSON) | |
| 184 | | `garbg query current` | Current wallpaper info (JSON) | |
| 185 | | `garbg reload` | Reload configuration | |
| 186 | |
| 187 | ## Troubleshooting |
| 188 | |
| 189 | ### garbg not connecting to gar |
| 190 | |
| 191 | Check that gar is running and its IPC socket exists: |
| 192 | ```bash |
| 193 | ls -la $XDG_RUNTIME_DIR/gar.sock |
| 194 | ``` |
| 195 | |
| 196 | garbg will automatically reconnect with exponential backoff if gar restarts. |
| 197 | |
| 198 | ### Wallpaper not appearing |
| 199 | |
| 200 | 1. Verify the daemon is running: |
| 201 | ```bash |
| 202 | pgrep -f "garbg daemon" |
| 203 | ``` |
| 204 | |
| 205 | 2. Check daemon logs: |
| 206 | ```bash |
| 207 | garbg daemon # Run in foreground to see logs |
| 208 | ``` |
| 209 | |
| 210 | 3. Verify RandR is working: |
| 211 | ```bash |
| 212 | garbg query monitors |
| 213 | ``` |
| 214 | |
| 215 | ### Animation stuttering |
| 216 | |
| 217 | - Reduce max FPS: `garbg set file.gif --animate --max-fps 30` |
| 218 | - Ensure no heavy background processes |
| 219 | |
| 220 | ## Example Complete Config |
| 221 | |
| 222 | `~/.config/gar/init.lua`: |
| 223 | ```lua |
| 224 | -- Start garbg wallpaper daemon |
| 225 | gar.exec_once("garbg daemon") |
| 226 | |
| 227 | -- Set initial wallpaper with slideshow |
| 228 | gar.exec_once("sleep 0.5 && garbg set ~/Pictures/wallpapers --random --interval 10m") |
| 229 | |
| 230 | -- Wallpaper keybindings |
| 231 | gar.bind("mod+bracketright", function() gar.exec("garbg next") end) |
| 232 | gar.bind("mod+bracketleft", function() gar.exec("garbg prev") end) |
| 233 | gar.bind("mod+shift+w", function() gar.exec("garbg random") end) |
| 234 | gar.bind("mod+shift+p", function() gar.exec("garbg toggle") end) |
| 235 | ``` |
| 236 | |
| 237 | `~/.config/garbg/config.toml`: |
| 238 | ```toml |
| 239 | [general] |
| 240 | mode = "fill" |
| 241 | |
| 242 | [animation] |
| 243 | enabled = true |
| 244 | max_fps = 60 |
| 245 | |
| 246 | [cache] |
| 247 | max_size_mb = 512 |
| 248 | |
| 249 | [default] |
| 250 | source = "~/Pictures/wallpapers" |
| 251 | |
| 252 | [default.slideshow] |
| 253 | enabled = true |
| 254 | interval = "10m" |
| 255 | shuffle = true |
| 256 | |
| 257 | [[workspaces]] |
| 258 | id = 1 |
| 259 | source = "~/Pictures/main.jpg" |
| 260 | |
| 261 | [[workspaces]] |
| 262 | id = 9 |
| 263 | source = "~/Pictures/gaming.jpg" |
| 264 | ``` |