Skip to content

Instantly share code, notes, and snippets.

@Ramblurr
Created March 27, 2024 07:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ramblurr/0463c3ba20948ce7b84203c699264a59 to your computer and use it in GitHub Desktop.
Save Ramblurr/0463c3ba20948ce7b84203c699264a59 to your computer and use it in GitHub Desktop.
nixfmt breaking this file
# Source: https://github.com/b3nj5m1n/dotfiles/blob/1da98eb2745ea4b0e4b789c38a037080bbf8347f/nix/modules/nixos/dynamic-wallpaper.nix#L8
# (C) https://github.com/b3nj5m1n
# License: AGPL v3
{
pkgs,
config,
lib,
...
}:
with lib; let
cfg = config.services.dynamic-wallpaper;
in {
imports = [
];
options.services.dynamic-wallpaper = {
enable = mkEnableOption "dynamic wallpaper service";
noResize = mkEnableOption "Do not resize the image. If the image is smaller than the screen's size, it will be padded with the value of `fill_color`.";
fillColor = mkOption {
description = "Which color to fill the padding with when not resizing";
type = types.str;
default = "000000";
};
filter = mkOption {
description = "Filter to use when scaling images. Available options are Nearest, Bilinear, CatmullRom, Mitchell, Lanczos3.";
type = types.str;
default = "Lanczos3";
};
sync = mkEnableOption "Sync the animations' frames between monitors";
transitionType = mkOption {
description = "Type of transition. Available options are simple, left, right, top, bottom, wipe, wave, grow, center, any, outer, random.";
type = types.str;
default = "any";
};
transitionStep = mkOption {
description = "How fast the transition approaches the new image. 255 switches immediately.";
type = types.int;
default = 90;
};
transitionDuration = mkOption {
description = "How many seconds the transition takes to complete.";
type = types.int;
default = 3;
};
transitionFps = mkOption {
description = "Frame rate for the transition effect.";
type = types.int;
default = 144;
};
transitionAngle = mkOption {
description = "Angle in degrees used in the wipe and wave transition type. 0 is right to left, 90 top to bottom, 270 bottom to top.";
type = types.int;
default = 30;
};
transitionPosition = mkOption {
description = "Controls the center of the cricle in grow and outer transition type.
Position values can be given in both percentage values and pixel values:
float values are interpreted as percentages and integer values as pixel
values eg: 0.5,0.5 means 50% of the screen width and 50% of the screen height
200,400 means 200 pixels from the left and 400 pixels from the bottom
the value can also be an alias which will set the position accordingly):
'center' | 'top' | 'left' | 'right' | 'bottom' | 'top-left' | 'top-right' |
'bottom-left' | 'bottom-right'";
type = types.str;
default = "center";
};
transitionBezier = mkOption {
description = "Bezier curve used for transition.";
type = types.str;
default = ".54,0,.34,.99";
};
transitionWaveProperties = mkOption {
description = "Controls the width and height of each wave in the wave transition type.";
type = types.str;
default = "20,20";
};
};
config = {
environment.systemPackages = with pkgs; [
swww
];
# Service for starting the swww daemon
systemd.user.services."swww-daemon" = mkIf cfg.enable {
unitConfig = {
"Description" = "Solution to Wayland Wallpaper Woes";
"Requires" = "graphical-session.target";
"PartOf" = "graphical-session.target";
"After" = "graphical-session.target";
};
serviceConfig = {
Type = "notify";
ExecStart = "${pkgs.swww}/bin/swww init --no-daemon";
NotifyAccess = "all";
};
wantedBy = [
"graphical-session.target"
];
path = [pkgs.swww];
};
# Service which sets the current wallpaper to the wallpaper corresponding to the current hour
# systemctl --user start dynamic-wallpaper@default.service # Use settings specified by this module
# systemctl --user start dynamic-wallpaper@skip.service # Skip transition and immediately set the image as background
systemd.user.services."dynamic-wallpaper@" = mkIf cfg.enable {
unitConfig = {
"Description" = "Change the wallpaper periodically";
"Requires" = "swww-daemon.service";
"PartOf" = "swww-daemon.service";
"After" = "swww-daemon.service";
};
script = let
flags = builtins.concatStringsSep " " (
builtins.filter (x: x != "") [
"${
if cfg.noResize
then "--no-resize"
else ""
}"
"${
if cfg.noResize
then "--fill-color ${cfg.fillColor}"
else ""
}"
"--filter ${cfg.filter}"
"${
if cfg.sync
then "--sync"
else ""
}"
"--transition-type ${cfg.transitionType}"
"--transition-step ${toString cfg.transitionStep}"
"--transition-duration ${toString cfg.transitionDuration}"
"--transition-fps ${toString cfg.transitionFps}"
"--transition-angle ${toString cfg.transitionAngle}"
"--transition-pos ${cfg.transitionPosition}"
"--transition-bezier ${cfg.transitionBezier}"
"${
if cfg.transitionType == "wave"
then "--transition-wave ${cfg.transitionWaveProperties}"
else ""
}"
]
);
command = "${pkgs.swww}/bin/swww img";
in ''
set -eu
hour="$(date +%k | xargs)" # xargs removes leading whitespace
# Set the directory where the images are stored
pickup_directory="$HOME/.config/hypr/wallpaper"
# Pick a random image from the directory using shuf
selected_image=$(find "$pickup_directory" -not -type d -print0 | shuf -n 1 -z | tr -d '\0')
if [ "$1" = "skip" ]; then
${command} --transition-duration 0 "$selected_image"
else
${command} ${flags} "$selected_image"
fi
'';
scriptArgs = "%i";
serviceConfig = {
Type = "oneshot";
};
};
# Run the dynamic-wallpaper service every hour
systemd.user.timers."dynamic-wallpaper" = {
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "3h";
RandomizedDelaySec = "300";
OnUnitActiveSec = "3h";
Unit = "dynamic-wallpaper@default.service";
};
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment