1
Fork 0

Hyprpaper module

This commit is contained in:
Matei Adriel 2023-06-09 13:17:34 +02:00
parent 8e2bbdcca5
commit 2533fa1c43
No known key found for this signature in database
21 changed files with 363 additions and 107 deletions

View file

@ -17,7 +17,7 @@ function M.config()
mind.setup({ mind.setup({
persistence = { persistence = {
state_path = "~/Mind/mind.json", state_path = "~/Projects/Mind/mind.json",
data_dir = "~/Mind/data", data_dir = "~/Mind/data",
}, },
ui = { ui = {

View file

@ -5,10 +5,10 @@ Check out [tethys](../tethys.nix) for example imports
## File structure ## File structure
| Directory | Description | | Directory | Description |
| -------------------- | --------------------------------------------- | | -------------------------------- | -------------------------------------------- |
| [cli](./cli) | Configuration for terminal stuff | | [cli](./cli) | Configuration for terminal stuff |
| [desktop](./desktop) | Desktop apps usable on both wayland and xorg | | [desktop](./desktop) | Desktop apps usable on both wayland and xorg |
| [xorg](./xorg) | Xorg only stuff | | [xorg](./xorg) | Xorg only stuff |
| [wayland](./wayland) | Wayland only stuff | | [wayland](./wayland) | Wayland only stuff |
| [neovim](./neovim) | Neovim (to be expanded in the future ) | | [neovim](./neovim) | Neovim (to be expanded in the future ) |
| [games](./games) | Similar to [desktop](./desktop) but for games | | [persistence](./persistence.nix) | For impermanence settings |

View file

@ -1,4 +1,4 @@
{ pkgs, inputs, ... }: { config, pkgs, inputs, ... }:
let let
# {{{ Global extensions # {{{ Global extensions
extensions = with inputs.firefox-addons.packages.${pkgs.system}; [ extensions = with inputs.firefox-addons.packages.${pkgs.system}; [
@ -227,12 +227,14 @@ in
# Tell apps firefox is the default browser using an env var. # Tell apps firefox is the default browser using an env var.
home.sessionVariables.BROWSER = "firefox"; home.sessionVariables.BROWSER = "firefox";
# }}} # }}}
# {{{ Persistence # {{{ Persistence
home.persistence."/persist/home/adrielus".directories = [ satellite.persistence.at.state.apps.Firefox.directories = [
".cache/mozilla/firefox" # Non important cache
".mozilla/firefox" # More important stuff ".mozilla/firefox" # More important stuff
]; ];
satellite.persistence.at.cache.apps.Firefox.directories = [
"${config.xdg.cacheHome}/mozilla/firefox" # Non important cache
];
# }}} # }}}
} }

View file

@ -1,14 +0,0 @@
{ pkgs, config, ... }: {
home.packages = [
pkgs.qbittorrent
];
satellite.persistence.at.state.apps.QBittorrent.directories = [
"${config.xdg.configHome}/qBittorrent" # Config options
];
satellite.persistence.at.cache.apps.QBittorrent.directories = [
# TODO: investigate which subdirectories/files I actually want to keep
"${config.xdg.dataHome}/qBittorrent" # Torrent files, logs, etc
];
}

View file

@ -1,9 +0,0 @@
{ pkgs, config, ... }: {
home.packages = [
pkgs.signal-desktop # Signal client
];
satellite.persistence.at.state.apps.Signal.directories = [
"${config.xdg.configHome}/Signal" # Why tf does signal store it's state here 💀
];
}

View file

@ -1,3 +0,0 @@
{
imports = [ ./wine.nix ./lutris.nix ./steam.nix ];
}

View file

@ -1,15 +0,0 @@
{ pkgs, config, ... }:
{
home.packages = [
pkgs.lutris
];
home.persistence."/persist/home/adrielus".directories = [
("Lutris/.config/lutris") # General config data
".cache/lutris/banners" # Game banners
".cache/lutris/coverart" # Game cover art
# Aparently IO intensive stuff like games prefer symlinks?
{ directory = "Games/Lutris"; method = "symlink"; } # Lutris games
];
}

View file

@ -1,20 +0,0 @@
# Although steam is installed globally by nixos,
# there's some extra settings we make for a specific user!
{
home.persistence."/persist/home/adrielus" = {
files = [
".steam/registry.vdf" # It seems like auto-login does not work without this
];
directories = [
# TODO: perhaps this should leave in it's own file?
".factorio"
# A couple of games don't play well with bindfs
{
directory = ".local/share/Steam";
method = "symlink";
}
];
};
}

View file

@ -1,6 +0,0 @@
# TODO(imperanence): handle persistence
{ pkgs, ... }: {
home.packages = [
pkgs.wine
];
}

View file

@ -0,0 +1,98 @@
{ config, ... }: {
# {{{ XDG dirs
# The lack of "~/Desktop" and "~/Downloads" is intentional!
satellite.persistence.at.data.apps.main.directories = [
config.xdg.userDirs.documents
config.xdg.userDirs.pictures
config.xdg.userDirs.music
config.xdg.userDirs.videos
"Projects"
];
# }}}
# {{{ OpenTabletDriver
satellite.persistence.at.state.apps.OpenTabletDriver.directories = [
#"${config.xdg.configHome}/OpenTabletDriver"
];
# }}}
# {{{ Rust
satellite.persistence.at.cache.apps.Rust.directories = [
#".cargo"
#".rustup"
];
# }}}
# {{{ Purescript
satellite.persistence.at.cache.apps.Purescript.directories = [
#"${config.xdg.cacheHome}/spago"
];
# }}}
# {{{ Nodejs
satellite.persistence.at.cache.apps.Node.directories = [
#"${config.xdg.cacheHome}/yarn"
#"${config.xdg.dataHome}/pnpm"
];
# }}}
# {{{ Shell stuff
satellite.persistence.at.cache.apps.Shell.directories = [
#"${config.xdg.dataHome}/fish"
#"${config.xdg.dataHome}/z" # The z fish plugin
#"${config.xdg.dataHome}/direnv/allow"
#".tmux"
];
# }}}
# {{{ Neovim
satellite.persistence.at.cache.apps.Neovim.directories = [
# "${config.xdg.dataHome}/nvim"
];
# }}}
# {{{ SSH
satellite.persistence.at.state.apps.Ssh.directories = [
# ".ssh"
];
# }}}
# {{{ QBittorrent
satellite.persistence.at.state.apps.QBittorrent.directories = [
"${config.xdg.configHome}/qBittorrent" # Config options
];
satellite.persistence.at.cache.apps.QBittorrent.directories = [
# TODO: investigate which subdirectories/files I actually want to keep
"${config.xdg.dataHome}/qBittorrent" # Torrent files, logs, etc
];
# }}}
# {{{ Signal
satellite.persistence.at.state.apps.Signal.directories = [
"${config.xdg.configHome}/Signal" # Why tf does signal store it's state here 💀
];
# }}}
# {{{ Steam
satellite.persistence.at.state.apps.Steam = {
files = [
".steam/registry.vdf" # It seems like auto-login does not work without this
];
directories = [
".factorio" # TODO: perhaps this should leave in it's own file?
# A couple of games don't play well with bindfs
{
directory = "${config.xdg.dataHome}/Steam";
method = "symlink";
}
];
};
# }}}
# {{{ Lutris
# TODO: there might be more to cache in .cache/lutris
satellite.persistence.at.state.apps.Lutris.directories = [
"${config.xdg.configHome}/lutris" # General config data
"${config.xdg.cacheHome}/lutris/banners" # Game banners
"${config.xdg.cacheHome}/lutris/coverart" # Game cover art
# Aparently IO intensive stuff like games prefer symlinks?
{ directory = "Games/Lutris"; method = "symlink"; } # Lutris games
];
# }}}
# {{{ Wine
satellite.persistence.at.state.apps.Wine.directories = [ ".wine" ];
# }}}
}

View file

@ -1,11 +1,34 @@
{ pkgs, inputs, ... }: { { pkgs, lib, config, inputs, ... }:
let
enabledMonitors = lib.filter (m: m.enabled) config.monitors;
hyprland-monitors = lib.concatStringsSep "\n" (lib.forEach enabledMonitors (m: ''
monitor=${m.name},${toString m.width}x${toString m.height}@${toString m.refreshRate},${toString m.x}x${toString m.y},1
${lib.optionalString (m.workspace != null) "workspace=${m.name},${m.workspace}"}
''));
in
{
imports = [ ../default.nix ]; imports = [ ../default.nix ];
home.packages = [ inputs.hyprland-contrib.packages.${pkgs.system}.grimblast ]; home.packages = [ inputs.hyprland-contrib.packages.${pkgs.system}.grimblast pkgs.hyprpaper ];
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
enable = true; enable = true;
recommendedEnvironment = true; recommendedEnvironment = true;
extraConfig = builtins.readFile ./hyprland.conf; extraConfig = ''
${builtins.readFile ./hyprland.conf}
${hyprland-monitors}
'';
};
services.hyprpaper = {
enable = true;
preload = [ config.stylix.image ];
wallpapers = [
{ image = config.stylix.image; }
] ++ lib.forEach enabledMonitors ({ name, ... }: {
monitor = name;
image = config.stylix.image;
});
}; };
} }

View file

@ -1,4 +1,5 @@
# Monitors # Fallback rule for monitors.
# More specific rules defined in the .nix file.
# https://wiki.hyprland.org/Configuring/Monitors/ # https://wiki.hyprland.org/Configuring/Monitors/
monitor=,preferred,auto,1 monitor=,preferred,auto,1

View file

@ -10,6 +10,7 @@ let
../features/cli ../features/cli
../features/neovim ../features/neovim
../features/persistence.nix
../../common ../../common
]; ];
# }}} # }}}
@ -62,10 +63,10 @@ in
# Set the xdg env vars # Set the xdg env vars
xdg.enable = true; xdg.enable = true;
# {{{ Create xdg user directories # {{{ Xdg user directories
xdg.userDirs = { xdg.userDirs = {
enable = lib.mkDefault true; enable = lib.mkDefault true;
createDirectories = lib.mkDefault true; createDirectories = lib.mkDefault false;
extraConfig.XDG_SCREENSHOTS_DIR = "${config.xdg.userDirs.pictures}/Screenshots"; extraConfig.XDG_SCREENSHOTS_DIR = "${config.xdg.userDirs.pictures}/Screenshots";
}; };
# }}} # }}}

View file

@ -3,14 +3,11 @@
./global ./global
./features/desktop/discord.nix ./features/desktop/discord.nix
./features/desktop/signal.nix
./features/desktop/qbittorrent.nix
./features/desktop/zathura.nix ./features/desktop/zathura.nix
./features/desktop/firefox ./features/desktop/firefox
./features/xorg/xmonad.nix ./features/xorg/xmonad.nix
./features/wayland/hyprland ./features/wayland/hyprland
./features/games
]; ];
# Arbitrary extra packages # Arbitrary extra packages
@ -25,9 +22,13 @@
libreoffice # Free office suite libreoffice # Free office suite
lmms # Music software lmms # Music software
kicad # PCB editing kicad # PCB editing
plover.dev # steno engine
qbittorrent # Torrent client
signal-desktop # Signal client
wine # Windows compat layer or whatever
lutris # Game launcher
# google-chrome # Not my primary browser, but sometimes needed in webdev # google-chrome # Not my primary browser, but sometimes needed in webdev
# obs-studio # video recorder # obs-studio # video recorder
plover.dev # steno engine
# Clis # Clis
agenix # Secret encryption agenix # Secret encryption
@ -46,12 +47,19 @@
# Actual data/media (eg: projects, images, videos, etc) # Actual data/media (eg: projects, images, videos, etc)
at.data.path = "/persist/data"; at.data.path = "/persist/data";
at.data.prefixDirectories = false;
# App state I want to keep # App state I want to keep
at.state.path = "/persist/state"; at.state.path = "/persist/state";
# App state which I should be able to delete at any point # App state which I should be able to delete at any point
at.cache.path = "/persist/cache"; at.cache.path = "/persist/local/cache";
}; };
}; };
monitors = [{
name = "eDP-1";
width = 1920;
height = 1080;
}];
} }

View file

@ -34,8 +34,8 @@ in
let mkKey = type: path: extra: { inherit type path; } // extra; let mkKey = type: path: extra: { inherit type path; } // extra;
in in
[ [
(mkKey "ed25519" "/persist/etc/ssh/ssh_host_ed25519_key" { }) (mkKey "ed25519" "/persist/state/etc/ssh/ssh_host_ed25519_key" { })
(mkKey "rsa" "/persist/etc/ssh/ssh_host_rsa_key" { bits = 4096; }) (mkKey "rsa" "/persist/state/etc/ssh/ssh_host_rsa_key" { bits = 4096; })
]; ];
}; };

View file

@ -33,19 +33,19 @@
}; };
# Imperative # Imperative
allowAuxiliaryImperativeNetworks = true; # allowAuxiliaryImperativeNetworks = true;
userControlled = { # userControlled = {
enable = true; # enable = true;
group = "network"; # group = "network";
}; # };
}; };
# Ensure group exists # Ensure group exists
users.groups.network = { }; users.groups.network = { };
# TODO: figure out why this does not work!
# Persist imperative config # Persist imperative config
# environment.persistence."/persist".files = [ environment.persistence."/persist/state".files = [
# TODO: investigate why this doesn't work
# "/etc/wpa_supplicant.conf" # "/etc/wpa_supplicant.conf"
# ]; ];
} }

View file

@ -25,7 +25,6 @@
# {{{ A few ad-hoc hardware settings # {{{ A few ad-hoc hardware settings
hardware.opengl.enable = true; hardware.opengl.enable = true;
# TODO: persistence of config
hardware.opentabletdriver.enable = true; hardware.opentabletdriver.enable = true;
# }}} # }}}
# {{{ A few ad-hoc programs # {{{ A few ad-hoc programs

View file

@ -2,9 +2,17 @@
{ {
# example = import ./example.nix; # example = import ./example.nix;
discord = import ./discord.nix;
# Personal things
firefox = import ./firefox; firefox = import ./firefox;
satellite-dev = import ./satellite-dev.nix; satellite-dev = import ./satellite-dev.nix;
satellite-persistence = import ./persistence.nix; satellite-persistence = import ./persistence.nix;
monitors = import ./monitors.nix;
# Should upstream
discord = import ./discord.nix;
hyprpaper = import ./hyprpaper.nix;
# Temporary
wofi = import ./wofi.nix; wofi = import ./wofi.nix;
} }

View file

@ -0,0 +1,106 @@
# TODO: add maintainers and upstream into home-manager
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.hyprpaper;
mkWallpaper = { mode, image, monitor, ... }:
let
monitorString = lib.optionalString (monitor != null) monitor;
modeString = lib.optionalString (mode == "contain") "contain:";
in
"wallpaper=${monitorString},${modeString}${image}";
in
{
options.services.hyprpaper = {
enable = mkEnableOption "hyprpaper";
package = mkOption {
type = types.package;
default = pkgs.hyprpaper;
defaultText = "pkgs.hyprpaper";
description = ''
hyprpaper derivation to use.
'';
};
systemdTarget = mkOption {
type = types.str;
default = "graphical-session.target";
description = ''
Systemd target to bind to.
'';
};
preload = mkOption {
type = types.listOf (types.oneOf [ types.str types.path ]);
default = [ ];
example = [ "~/background.png" ];
description = "List of images to preload";
};
wallpapers = mkOption {
type = types.listOf (types.submodule (_: {
options = {
monitor = mkOption {
type = types.nullOr types.str;
default = null;
example = "eDP-1";
description = ''
Monitor to use for the wallpaper.
Either leave empty as a wildcard,
type the name of the monitor, or
include the monitor's description
prefixed with `desc:`.
'';
};
image = mkOption {
type = types.oneOf [ types.str types.path ];
default = null;
example = "~/background.png";
description = "Image to use as wallpaper";
};
mode = mkOption {
type = lib.types.enum [ "cover" "contain" ];
default = "cover";
example = "contain";
description = "The way to display the wallpaper";
};
};
}));
default = [ ];
description = "List of wallpapers to set";
};
};
config = mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.hyprpaper" pkgs
lib.platforms.linux)
];
xdg.configFile."hypr/hyprpaper.conf".text = ''
${lib.concatStringsSep "\n" (lib.forEach cfg.preload (image: "preload=${image}"))}
${lib.concatStringsSep "\n" (lib.forEach cfg.wallpapers mkWallpaper)}
'';
systemd.user.services.hyprpaper = {
Unit = {
Description = "Wayland wallpaper service";
PartOf = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${cfg.package}/bin/hyprpaper";
};
Install = {
WantedBy = [ cfg.systemdTarget ];
};
};
};
}

View file

@ -0,0 +1,50 @@
# Taken from [misterio's config](https://github.com/Misterio77/nix-config/blob/main/modules/home-manager/monitors.nix)
# This is meant to provide a wm-independent way of specifying the monitor configuration of each machine.
{ lib, ... }:
{
options.monitors = lib.mkOption {
type = lib.types.listOf (lib.types.submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
example = "DP-1";
};
width = lib.mkOption {
type = lib.types.int;
example = 1920;
};
height = lib.mkOption {
type = lib.types.int;
example = 1080;
};
refreshRate = lib.mkOption {
type = lib.types.int;
default = 60;
};
x = lib.mkOption {
type = lib.types.int;
default = 0;
};
y = lib.mkOption {
type = lib.types.int;
default = 0;
};
enabled = lib.mkOption {
type = lib.types.bool;
default = true;
};
workspace = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
};
};
});
};
}

View file

@ -18,11 +18,29 @@ in
description = "The location to store the files described in this record"; description = "The location to store the files described in this record";
}; };
prefixDirectories = lib.mkOption {
type = lib.types.bool;
default = true;
example = false;
description = "Whether to enable gnu/stow type prefix directories";
};
apps = lib.mkOption { apps = lib.mkOption {
default = { }; default = { };
description = "The apps to be stores in this persistent location"; description = "The apps to be stores in this persistent location";
type = lib.types.attrsOf (lib.types.submodule (_: { type = lib.types.attrsOf (lib.types.submodule (_: {
options = { options = {
files = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ ".screenrc" ];
description = ''
A list of files in your home directory you want to
link to persistent storage. Allows both absolute paths
and paths relative to the home directory. .
'';
};
directories = lib.mkOption { directories = lib.mkOption {
default = [ ]; default = [ ];
description = "Modified version of home.persistence.*.directories which takes in absolute paths"; description = "Modified version of home.persistence.*.directories which takes in absolute paths";
@ -36,7 +54,7 @@ in
method = lib.mkOption { method = lib.mkOption {
type = lib.types.enum [ "bindfs" "symlink" ]; type = lib.types.enum [ "bindfs" "symlink" ];
default = "bindfs"; default = "symlink";
description = '' description = ''
The linking method that should be used for this The linking method that should be used for this
directory. bindfs is the default and works for most use directory. bindfs is the default and works for most use
@ -60,7 +78,12 @@ in
makeLocation = location: makeLocation = location:
let let
processPath = appName: value: processPath = appName: value:
"${appName}/${lib.strings.removePrefix config.home.homeDirectory (builtins.toString value)}"; let
suffix = "${lib.strings.removePrefix "${config.home.homeDirectory}/" (builtins.toString value)}";
prefix = if location.prefixDirectories then "${appName}/" else "";
in
# lib.debug.traceSeq "\nProcessing path at location ${location.path} and app ${appName} from original path ${value} to ${prefix + suffix}"
(prefix + suffix);
mkDirectory = appName: directory: mkDirectory = appName: directory:
if builtins.isAttrs directory then { if builtins.isAttrs directory then {
@ -70,12 +93,16 @@ in
else processPath appName directory; else processPath appName directory;
mkAppDirectory = appName: app: builtins.map (mkDirectory appName) app.directories; mkAppDirectory = appName: app: builtins.map (mkDirectory appName) app.directories;
mkAppFiles = appName: app: builtins.map (processPath appName) app.files;
in in
lib.attrsets.nameValuePair (location.path + config.home.homeDirectory) { lib.attrsets.nameValuePair (location.path + config.home.homeDirectory) {
removePrefixDirectory = true; removePrefixDirectory = location.prefixDirectories;
allowOther = true; allowOther = true;
directories = lib.lists.flatten directories = lib.lists.flatten
(lib.attrsets.mapAttrsToList mkAppDirectory location.apps); (lib.attrsets.mapAttrsToList mkAppDirectory location.apps);
files = lib.lists.flatten
(lib.attrsets.mapAttrsToList mkAppFiles location.apps);
}; };
in in
lib.mkIf cfg.enable { lib.mkIf cfg.enable {