swww icon indicating copy to clipboard operation
swww copied to clipboard

Storing cached image in ~/.cache/swww instead of its location

Open nydragon opened this issue 9 months ago • 5 comments

Given the following systemd service for swww-daemon, where I restrict accessible locations to /run/user and ~/.cache/swww, having the cache be the location of the file, instead of the actual file, breaks swww-daemon, because it cannot access those locations.

systemd.user.services.swww = {
  Install.WantedBy = ["graphical-session.target"];
  Unit.After = ["graphical-session.target"];

  Service =
    {
      Type = "simple";
      ExecStart = "${getExe' pkgs.swww "swww-daemon"}";
      Restart = "on-failure";
      BindPaths = "/run/user /home/${config.home.username}/.cache/swww";
      TemporaryFileSystem = "/home /run/user /root";
      ProtectProc = "noaccess";
      RestrictNamespaces = true;
      CapabilityBoundingSet = "";
      PrivateUsers = true;
      RestrictAddressFamilies = "AF_UNIX";
    }
};

A workaround would be wrapping swww img in a copy of the file to the cache directory (which works great), but I still wanted to express that use-case.

nydragon avatar May 29 '25 13:05 nydragon

~/.cache/swww is actually supposed to be a directory. It has several files in it.

Other than that, I don't understand the problem. Are you restricting access to ~/.cache/swww? But, why does that not work? Why does wrapping swww img work? I don't really know how systemd services work very well, so I am afraid you might have to explain it more thoroughly for me to get it 😅

LGFae avatar May 30 '25 13:05 LGFae

Thanks for checking this out!

You're right, the only directories that the swww-daemon has access to in my example are /run/user/, for the socket, and ~/.cache/swww/ for cache. Since for the cache swww is storing the path of the image in .cache/swww/<output-name> instead of the actual image, the daemon will not have access to it.

I am working around this issue by wrapping swww img in a function that copies the image into ~/.cache/swww/ before running swww img:

function set-wp;
  cp -v "$argv[1]" ~/.cache/swww/image
  swww img  ~/.cache/swww/image
end

Because of this, swww-daemon can restore the set wallpaper when it is restarted.

Another nice side effect for storing the image in the cache folder, would be to avoid breaking the cache when the original file is deleted.

nydragon avatar May 30 '25 16:05 nydragon

I see! I get it now. The only problem this might create is that some people tend to use very large gifs (like, 100MB+), and this would cause some load on their disks.

If I did just a symlink instead of copying the files, would this work? (I know it would still die if the original file is deleted, but I can live with that for now).

If not, we can still make a command line argument whether to copy the file over to the cache.

LGFae avatar May 30 '25 16:05 LGFae

A symlink would unfortunately not work because it would just link to an empty location, since the entirety of /home is replaced with a tmpfs for swww-daemon, however a flag would be a good alternative! Thank you

nydragon avatar May 30 '25 18:05 nydragon

I ran into the same issue myself while hardening the service, so it would be pretty useful to add that functionality. For me it's perfectly fine if it is behind a feature flag or even a build option. :)

cardboardcpu avatar Jun 12 '25 22:06 cardboardcpu