[Wayland] setting the wallpaper from a systemd unit
cmacrae opened this issue ยท 7 comments
Hey @xyproto ๐ Thanks very much for wallutils ๐
I'm trying to set up a systemd user service unit/timer combo to change the wallpaper in my sway session (testing every minute at the moment).
I'm doing so on NixOS using a collection of the following:
- systemd user service unit (
wallpaper.service
)
[Unit]
Description=Change the wallpaper every minute
PartOf=graphical-session.target
[Service]
Environment="LOCALE_ARCHIVE=<snip>/lib/locale/locale-archive"
Environment="PATH=<snip>"
ExecStart=<snip>/bin/setrandom -v <snip>/share/backgrounds/elementary
Note: I've redacted the long Nix paths here, replaced with <snip>
for legibility
- systemd user service timer (
wallpaper.timer
)
[Unit]
[Timer]
OnCalendar=*:0/1
- Reaching the
sway-session.target
with the final line of my sway config:
exec "systemctl --user import-environment; systemctl --user start sway-session.target"
According to sway's documentation for systemd integration, this last part should copy in the user environment for user
scope systemd constructs to use. And indeed it does - checking the output of systemctl --user show-environment
has everything from my shell's output of env
.
The problem
Sadly it seems setrandom
isn't able to set the wallpaper, complaining with the following in its output (from the triggered unit):
Setting background image to: <snip>/share/backgrounds/elementary/Jonas Nilsson Lee.j>
Found no working method for setting the desktop wallpaper.
So, I was just wondering if you might be able to shed some light on this ๐
What would setrandom
need to be able to talk to the active compositor? Does it expect any environment variables or sockets?
To clarify, the command works perfectly from the shell once in the session, and also as an initial exec_always
in my sway's config (to set it at start/reload).
Many thanks in advance for any help on this! ๐ค
For anyone interested that may stumble across this, here's the part of my NixOS configuration that handles this:
systemd.user = {
targets.sway-session = {
description = "sway compositor session";
documentation = ["man:systemd.special(7)"];
bindsTo = ["graphical-session.target"];
wants = ["graphical-session-pre.target"];
after = ["graphical-session-pre.target"];
};
services.wallpaper = {
description = "Change the wallpaper every 1 minutes";
wantedBy = ["sway-session.target"];
partOf = ["graphical-session.target"];
startAt = "*:0/1";
serviceConfig = {
ExecStart = ''
${pkgs.wallutils}/bin/setrandom -v ${pkgs.pantheon.elementary-wallpapers}/share/backgrounds/elementary
'';
};
};
};
This will (once it's working!) randomly set a wallpaper from the pantheon.elementary-wallpapers
package ๐
Hi, yes, currently setwallpaper
and setrandom
will look for certain environment variables and then try to communicate with the window manager as it is running. Setting the wallpaper in advance, before the window manager is running, would also be interesting!
A flag could be added to setwallpaper
and setrandom
to achieve this.
Thanks for reporting!
Thanks for your swift response ๐
Well, actually, in the above scenario, the windowmanager is actually running. The systemd unit set to trigger is executed only once the sway-session.target
is reached (executed at the end of sway's config: exec "systemctl --user import-environment; systemctl --user start sway-session.target"
).
That said, I decided to try and implement this as a native feature of setrandom
, with an -interval
flag. So you could do: setrandom -interval 30m path/to/wallpapers
I've written the code, but can't build because I don't know where to get all the Wayland header files from ๐
If you have advice on where I can get all the headers for Wayland from, I'd appreciate it ๐
I pulled down the source, but I seem to be missing some header files after running ./autogen.sh
and make
from the Wayland repo, I still seem to be missing some:
ฯ wallutils/cmd/setrandom on_interval โ โฏ go build -v
github.com/xyproto/wallutils
# github.com/xyproto/wallutils
In file included from ./wayinfo.h:8,
from ../../wayinfo.go:4:
./wayland-client.h:40:10: fatal error: wayland-client-protocol.h: No such file or directory
#include "wayland-client-protocol.h"
^~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
Once I've got it building, I'll submit a PR and you can see what you think about the feature :)
Hi, sorry for the late reply. On my system, /usr/include/wayland-client-protocol.h
comes with the wayland
package (currently at version 1.17.0). This is on Arch Linux.
On NixOS, I assume that wayland-client-protocol.h
either comes with the wayland
or wayland-protocols
package, but I have no easy way to check this (that I could find, at least).
Did this work out?