{ flake, flakeInputs, userName, pkgs, customUtils, lib, config, sources, ... }@inputs: with lib; let cfg = config.home-manager.users.${userName}; emacsScratch = pkgs.stdenv.mkDerivation (sources.emacs-scratch_el // rec { phases = [ "installPhase" ]; installPhase = '' mkdir -p $out/share/emacs/site-lisp cp $src/scratch.el $out/share/emacs/site-lisp/default.el ''; }); muteScript = pkgs.stdenv.mkDerivation { name = "mute"; src = ./scripts/mute.zsh; buildInputs = with pkgs; [ makeWrapper ]; phases = [ "installPhase" ]; installPhase = '' mkdir -p $out/bin install -m 0755 $src $out/bin/mute wrapProgram $out/bin/mute \ --prefix PATH : ${pkgs.zsh}/bin \ --prefix PATH : ${pkgs.findutils}/bin \ --prefix PATH : ${pkgs.util-linux}/bin \ --prefix PATH : ${pkgs.coreutils}/bin \ --prefix PATH : ${pkgs.pulseaudio}/bin ''; }; wrapElectron = { package, bin ? package.meta.mainProgram or package.pname or (pkgs.lib.strings.nameFromURL package.name "-"), outBin ? bin, sandbox ? true }: pkgs.symlinkJoin { name = "${package.name}-wrapped"; buildInputs = with pkgs; [ makeWrapper ]; paths = [ package ]; inherit bin outBin; postBuild = '' hidden=$out/bin/."$(basename "$bin")"-wrapped while [ -e "$hidden" ]; do hidden="''${hidden}_" done mv "$out/bin/$bin" "$hidden" makeWrapper "$hidden" "$out/bin/$outBin" \ ${optionalString (!sandbox) "--add-flags '--no-sandbox'"} ''; }; wrappedChrome = wrapElectron { package = pkgs.google-chrome; outBin = "google-chrome"; }; wrappedZulip = wrapElectron { package = pkgs.zulip; bin = "zulip"; outBin = "zulip"; }; wrappedElementDesktop = wrapElectron { package = pkgs.element-desktop; bin = "element-desktop"; }; wrappedRocketChatDesktop = wrapElectron { package = pkgs.rocketchat-desktop; bin = "rocketchat-desktop"; outBin = "rocketchat"; }; wrappedYTMDesktop = wrapElectron { package = pkgs.ytmdesktop; sandbox = false; }; wrappedKeepassxc = pkgs.symlinkJoin { inherit (pkgs.keepassxc) name; paths = with pkgs; [ keepassxc (pkgs.writeTextFile { name = "org.keepassxc.KeePassXC"; destination = "/share/dbus-1/services/org.keepassxc.KeePassXC.MainWindow.service"; text = '' [D-BUS Service] Name=org.keepassxc.KeePassXC.MainWindow Exec=${pkgs.coreutils}/bin/false SystemdService=keepassxc.service ''; }) (pkgs.writeTextFile { name = "org.freedesktop.secrets"; destination = "/share/dbus-1/services/org.freedesktop.secrets.service"; text = '' [D-BUS Service] Name=org.freedesktop.secrets Exec=${pkgs.coreutils}/bin/false SystemdService=keepassxc.service ''; }) ]; }; nvidiaOffloadScript = pkgs.writeShellScriptBin "nvidia-offload" '' export __NV_PRIME_RENDER_OFFLOAD=1 export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0 export __GLX_VENDOR_LIBRARY_NAME=nvidia export __VK_LAYER_NV_optimus=NVIDIA_only exec -a "$1" "$@" ''; lockCommand = pkgs.writeShellScript "gtklock" '' set -x export PATH="${lib.makeBinPath [cfg.programs.wpaperd.package pkgs.jq pkgs.coreutils pkgs.gtklock pkgs.imagemagick pkgs.findutils pkgs.dbus pkgs.systemd]}:$PATH" dbus-send --session --dest=org.keepassxc.KeePassXC.MainWindow /keepassxc org.keepassxc.KeePassXC.MainWindow.lockAllDatabases systemctl --user --no-block stop gpg-agent.service tmpDir=$(mktemp -d --tmpdir="$RUNTIME_DIRECTORY" "gtklock.$(date -uIs).XXXXXXXX") args=() cp --no-preserve=mode ${pkgs.writeText "gtklock.css" '' #window-box { padding: 64px; /* border: 1px solid black; */ border-radius: 4px; box-shadow: rgba(0, 0, 0, 0.8) 0px 4px 12px; /* background-color: white; */ background-color: rgba(0, 0, 0, 0.5); } ''} "$tmpDir"/style.css monitors=() while IFS= read -r entry; do path=$(jq -r ".path" <<<"$entry") [[ -z "$path" || ! -f "$path" ]] && continue display=$(jq -r ".display" <<<"$entry") monitors+=("$display") # ln -s "$path" "$tmpDir"/"$display"."''${path##*.}" magick "$path" -filter Gaussian -resize 6.25% -define filter:sigma=2.5 -resize 1600% "$tmpDir"/"$display"."''${path##*.}" & done < <(wpaperctl all-wallpapers -j | jq -c ".[]") wait for monitor in "''${monitors[@]}"; do path=$(find "$tmpDir" -name "$monitor"'.*') cat >>"$tmpDir"/style.css </dev/null" ProxyJump remote.cip.ifi.lmu.de Match host *.mathinst.loc,*.cipmath.loc,*.math.lmu.de IdentityFile ~/.ssh/gkleen@mathinst.loc HostKeyAlgorithms +ssh-rsa PubkeyAcceptedAlgorithms +ssh-rsa ConnectTimeout 30 PasswordAuthentication yes KbdInteractiveAuthentication yes UpdateHostKeys yes GlobalKnownHostsFile ${pkgs.writeText "ssh_known_hosts" '' @cert-authority *.mathinst.loc,*.math.lmu.de,*.cipmath.loc ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBUTFpVCdETCXiDSDl7YGbR1J4BLTsoBzjDtflHJGO/z ssh-pki@mgmt01 ''} Match host *.mathinst.loc,*.math.lmu.de !host ssh.math.lmu.de !exec "nc -z -w 1 %h %p &>/dev/null" # ProxyCommand ${pkgs.socat}/bin/socat - SOCKS4A:127.0.0.1:%h:%p,socksport=8118 ProxyJump ssh.math.lmu.de Match host *.cipmath.loc !host cip04.cipmath.loc,mgmt-cls01.cipmath.loc !exec "nc -z -w 1 %h %p &>/dev/null" ProxyJump cip04 Match host *.ifi.lmu.de,*.math.lmu.de AddressFamily inet Match host *.mgmt.yggdrasil ProxyJump vidhar Host * ''; }; emacs = { enable = true; package = pkgs.emacs29-pgtk; extraPackages = epkgs: with epkgs; [ evil evil-dvorak undo-tree magit haskell-mode nix-mode yaml-mode json-mode shakespeare-mode smart-mode-line highlight-parentheses highlight-symbol ag sass-mode lua-mode fira-code-mode use-package wanderlust # notmuch use-package-ensure-system-package git-gutter emacsScratch edit-server mediawiki editorconfig typescript-mode markdown-mode nftables-mode rustic lsp-mode lsp-ui direnv company projectile tomorrow-night-paradise-theme ]; overrides = self: super: { tomorrow-night-paradise-theme = super.trivialBuild { inherit (sources.tomorrow-night-paradise-theme) pname version src; }; }; }; firefox = { enable = true; profiles.default = { settings = { # "layout.css.devPixelsPerPx" = "0.5833"; "browser.tabs.drawInTitlebar" = false; "toolkit.legacyUserProfileCustomizations.stylesheets" = true; "dom.security.https_only_mode" = true; }; }; }; zathura.enable = true; imv.enable = true; mpv.config = { demuxer-max-bytes = 1073741824; demuxer-max-back-bytes = 268435456; # gpu-api = "vulkan"; }; zsh.initExtra = "source ${./zshrc}"; zsh.dirHashes = let flakeHashes = mapAttrs' (n: v: nameValuePair (inputNames.${n} or n) (toString v)) flakeInputs; inputNames = { "nixpkgs" = "nixos"; }; in flakeHashes // { u2w = "$HOME/projects/uni2work"; docs = "$HOME/documents"; dl = "$HOME/Downloads"; scrot = "$HOME/screenshots"; flk = "$HOME/projects/machines"; rz = "$HOME/projects/rz"; pro = "$HOME/projects/pro"; }; obs-studio = { enable = true; plugins = with pkgs; []; }; gh = { enable = true; settings = { editor = "${config.home-manager.users.${userName}.programs.emacs.package}/bin/emacsclient"; gitProtocol = "ssh"; }; }; kitty = { enable = true; font = { package = pkgs.fira; name = "FiraMono Nerd Font"; size = 10; }; settings = { enable_audio_bell = false; update_check_interval = 0; strip_trailing_spaces = "smart"; focus_follows_mouse = true; visual_bell_duration = "0.1"; visual_bell_color = "#26240d"; tab_bar_style = "powerline"; tab_powerline_style = "slanted"; # notify_on_cmd_finish = "invisible 120"; }; }; waybar = { enable = true; systemd = { enable = true; target = "hyprland-session.target"; }; settings = let windowRewrites = { "(.*) — Mozilla Firefox" = "$1"; "(.*) - Mozilla Thunderbird" = "$1"; "(.*) - mpv" = "$1"; }; iconSize = 14; in [ { layer = "top"; position = "top"; height = 14; output = "eDP-1"; modules-left = [ "hyprland/workspaces" ]; modules-center = [ "hyprland/window" ]; modules-right = [ "custom/weather" "custom/keymap" "clock" "privacy" "tray" "pulseaudio" "backlight" "battery" "idle_inhibitor" ]; "custom/weather" = { format = "{}"; tooltip = true; interval = 3600; exec = "${lib.getExe pkgs.wttrbar} --hide-conditions --custom-indicator \"{ICON} {FeelsLikeC}°\""; return-type = "json"; }; "custom/keymap" = { format = "{}"; tooltip = true; return-type = "json"; exec = pkgs.writers.writePython3 "keymap" {} '' import os import socket import re import subprocess import json def output(keymap): short = keymap if keymap == "English (programmer Dvorak)": short = "dvp" elif keymap == "English (US)": short = "us" print(json.dumps({'text': short, 'tooltip': keymap}, separators=(',', ':')), flush=True) # noqa: E501 r = subprocess.run(["hyprctl", "devices", "-j"], check=True, stdout=subprocess.PIPE, text=True) # noqa: E501 for keyboard in json.loads(r.stdout)['keyboards']: if keyboard['name'] != "at-translated-set-2-keyboard": continue output(keyboard['active_keymap']) sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(os.environ["XDG_RUNTIME_DIR"] + "/hypr/" + os.environ["HYPRLAND_INSTANCE_SIGNATURE"] + "/.socket2.sock") # noqa: E501 expected = re.compile(r'^activelayout>>at-translated-set-2-keyboard,(?P.+)$') # noqa: E501 for line in sock.makefile(buffering=1, encoding='utf-8'): if match := expected.match(line): output(match.group("keymap")) ''; on-click = "hyprctl switchxkblayout at-translated-set-2-keyboard next"; }; "hyprland/workspaces" = { all-outputs = true; }; "hyprland/window" = { separate-outputs = true; icon = true; icon-size = iconSize; rewrite = windowRewrites; }; clock = { interval = 1; # timezone = "Europe/Berlin"; format = "W{:%V-%u %F %H:%M:%S%Ez}"; tooltip-format = "{calendar}"; calendar = { mode = "year"; mode-mon-col = 3; weeks-pos = "left"; on-scroll = 1; format = { months = "{}"; days = "{}"; weeks = "{}"; weekdays = "{}"; today = "{}"; }; }; }; battery = { format = "{icon}"; states = { warning = 30; critical = 15; }; format-icons = ["󰂎" "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; format-charging = "󰂄"; format-plugged = "󰚥"; tooltip-format = "{capacity}% {timeTo}"; interval = 20; }; tray = { icon-size = 16; # show-passive-items = true; spacing = 1; }; privacy = { icon-spacing = 6; icon-size = 11; modules = [ { type = "screenshare"; } { type = "audio-in"; } ]; }; idle_inhibitor = { format = "{icon}"; icon-size = 16; format-icons = { activated = "󰈈"; deactivated = "󰈉"; }; }; backlight = { format = "{icon}"; tooltip-format = "{percent}%"; format-icons = ["󰃚" "󰃛" "󰃜" "󰃝" "󰃞" "󰃟" "󰃠"]; on-scroll-up = "lightctl -d up"; on-scroll-down = "lightctl -d down"; }; pulseaudio = { format = "{icon}"; icon-size = 16; tooltip-format = "{volume}% {desc}"; format-icons = ["󰕿" "󰖀" "󰕾"]; format-muted = "󰝟"; ignored-sinks = ["Easy Effects Sink"]; on-scroll-up = "volumectl -d -u up"; on-scroll-down = "volumectl -d -u down"; on-click = "volumectl -d toggle-mute"; }; } { layer = "top"; position = "top"; height = 14; output = "!eDP-1"; modules-left = [ "hyprland/workspaces" ]; modules-center = [ "hyprland/window" ]; modules-right = [ "clock" ]; "hyprland/workspaces" = { all-outputs = false; }; "hyprland/window" = { separate-outputs = true; icon = true; icon-size = iconSize; rewrite = windowRewrites; }; clock = { interval = 1; # timezone = "Europe/Berlin"; format = "{:%H:%M}"; tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}"; }; } ]; style = '' @define-color white #ffffff; @define-color grey #555555; @define-color blue #1a8fff; @define-color green #23fd00; @define-color orange #f28a21; @define-color red #f2201f; * { border: none; font-family: "Fira Sans Nerd Font"; font-size: 10pt; min-height: 0; } window#waybar { background-color: rgba(0, 0, 0, 0.66); color: @white; } .modules-left { margin-left: 9px; } .modules-right { margin-right: 9px; } .module { margin: 0 5px; } #workspaces button { color: @white; } #workspaces button.empty { color: @grey; } #workspaces button.visible { color: @blue; } #workspaces button.active { color: @green; } #workspaces button.urgent { color: @red; } #custom-weather, #custom-keymap { color: @grey; } #tray { margin: 0 2px; } #battery, #idle_inhibitor, #backlight, #pulseaudio { color: @grey; } #battery, #pulseaudio { margin: 0 5px 0 2px; } #backlight { margin: 0 9px 0 3px; } #battery.discharging { color: @white; } #battery.warning { color: @orange; } #battery.critical { color: @red; } #battery.charging { color: @white; } #idle_inhibitor.activated { color: @white; } #idle_inhibitor { padding-top: 1px; margin: 0 9px 0 2px; } #privacy { color: @red; margin: -1px 2px 0px 5px; } #clock { margin-right: 5px; } ''; }; wpaperd = { enable = true; settings.default = { path = "~/.wallpapers"; duration = "8h"; mode = "center"; }; }; fuzzel = { enable = true; settings = { main = { terminal = lib.getExe pkgs.kitty; layer = "overlay"; icon-theme = "Paper"; font = "Fira Sans"; }; colors = { background = "000000aa"; text = "cdd6f4ff"; match = "94e2d5ff"; selection = "585b70ff"; selection-match = "94e2d5ff"; selection-text = "cdd6f4ff"; border = "b4befeff"; }; dmenu = { exit-immediately-if-empty = true; }; }; }; }; services = { dunst = { settings = import ./dunst-settings.nix inputs; iconTheme = { package = pkgs.paper-icon-theme; name = "Paper"; }; enable = true; }; emacs = { enable = true; socketActivation.enable = true; client = { enable = true; arguments = mkForce ["-a" "\"\""]; }; }; gpg-agent = { enable = true; enableSshSupport = true; extraConfig = '' pinentry-program ${pkgs.pinentry-gtk2}/bin/pinentry grab ''; }; xembed-sni-proxy.enable = true; udiskie = { enable = true; automount = false; settings = { program_options = { file_manager = ""; }; notification_actions = { device_mounted = []; }; }; }; network-manager-applet.enable = true; blueman-applet.enable = true; unison = { enable = true; pairs = { documents = { roots = ["${cfg.home.homeDirectory}/documents" "ssh://unison.vidhar/documents"]; stateDirectory = "${cfg.xdg.dataHome}/documents.unison"; commandOptions = { auto = "true"; batch = "true"; log = "false"; repeat = "watch"; sshcmd = "${pkgs.openssh}/bin/ssh"; ui = "text"; }; }; }; }; easyeffects = { enable = true; }; etesync-dav = { enable = true; serverUrl = "https://etesync.yggdrasil.li"; }; swayidle = { enable = true; events = [ { event = "before-sleep"; command = "${lockCommand} -d"; } { event = "after-resume"; command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms on"; } { event = "lock"; command = "${lockCommand} -d"; } ]; timeouts = [ { timeout = 300; command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms off"; resumeCommand = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms on"; } { timeout = 330; command = "${lockCommand} -d"; } ]; extraArgs = [ "idlehint" "30" ]; }; poweralertd.enable = true; avizo = { enable = true; settings.default = { time = "1.0"; background = "rgba(0, 0, 0, 0.8)"; border-color = "rgba(0, 0, 0, 1)"; bar-fg-color = "rgba(160, 160, 160, 1)"; bar-bg-color = "rgba(32, 32, 32, 0.96)"; # y-offset = "0.25"; }; }; }; home.pointerCursor = { package = pkgs.vanilla-dmz; name = "Vanilla-DMZ-AA"; size = 32; x11 = { enable = true; defaultCursor = "left_ptr"; }; gtk.enable = true; }; gtk = { enable = true; font = { package = pkgs.fira; name = "Fira Sans"; size = 10; }; theme = { package = pkgs.equilux-theme; name = "Equilux-compact"; }; iconTheme = { package = pkgs.paper-icon-theme; name = "Paper-Mono-Dark"; }; }; xsession.preferStatusNotifierItems = true; xresources.properties = import ./xresources.nix; home = { packages = with pkgs; [ fira fira-code powerline-fonts nerdfonts pavucontrol wrappedKeepassxc wl-clipboard-rs mumble pulseaudio-ctl pamixer libnotify screen-message wrappedYTMDesktop qt5ct playerctl evince thunderbird zoom-us steam steam-run wireshark virt-manager rclone cached-nix-shell worktime fira-code-symbols libreoffice xournalpp google-chrome nixos-shell virt-viewer freerdp gnome-icon-theme paper-icon-theme sshpassSecret weechat element-desktop matrix-synapse-tools.synadm flakeInputs.deploy-rs.packages.${config.nixpkgs.system}.deploy-rs sieve-connect gimp inkscape udiskie glab nitrokey-app pynitrokey gtklock wlrctl nvidiaOffloadScript ]; file = { ".emacs".source = ./emacs.el; ".backup-munin".source = ./backup-patterns; ".mozilla/firefox/default/chrome/userChrome.css".source = ./firefox-chrome.css; ".mozilla/firefox/default/chrome/userContent.css".source = ./firefox-content.css; ".local/share/etesync-dav/CACHEDIR.TAG".text = '' Signature: 8a477f597d28d172789f06886806bc55 ''; ".cups/client.conf".text = '' ServerName cups.mathinst.loc ''; }; sessionVariables = { # GDK_SCALE = 96.0 / 282.0; # QT_AUTO_SCREEN_SCALE_FACTOR = 1; QT_QPA_PLATFORMTHEME = "qt5ct"; LIBVIRT_DEFAULT_URI = "qemu:///system"; STACK_XDG = 1; }; extraProfileCommands = '' export XDG_DATA_DIRS="${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}''${XDG_DATA_DIRS:+:''${XDG_DATA_DIRS}}" ''; }; xdg.configFile = { "dunst/dunstrc.d" = { source = ./dunstrc.d; recursive = true; onChange = '' ${pkgs.systemd}/bin/systemctl --user try-restart dunst ''; }; "wireplumber" = { source = ./wireplumber; recursive = true; onChange = '' ${pkgs.systemd}/bin/systemctl --user try-restart wireplumber ''; }; "stack/config.yaml" = { source = (pkgs.formats.yaml {}).generate "config.yaml" { recommend-stack-upgrade = false; }; }; "gtklock/config.ini" = { source = (pkgs.formats.ini {}).generate "config.ini" { main = { idle-hide = true; follow-focus = true; start-hidden = true; }; }; }; "qalculate/qalc.cfg" = { source = (pkgs.formats.ini {}).generate "qalc.cfg" { General = { dot_as_separator = 0; }; }; }; }; xdg.dataFile = { "pandoc/abbreviations" = { source = pkgs.runCommand "pandoc-abbreviations" { buildInputs = [ pkgs.pandoc pkgs.coreutils ]; } (let germanAbbrevs = pkgs.fetchFromGitHub { owner = "jfilter"; repo = "german-abbreviations"; rev = "8eb9dae93b6f05d7c53374cd217ab2dc89558e0c"; sha256 = "SaD3tSqzen6Y3SPICe6/9vhe4iMHlArZ3kFQaEk7Hps="; }; in '' cat \ <(pandoc --print-default-data-file=abbreviations) \ <(grep -E '^[^ ]+\.$' ${germanAbbrevs}/german_abbreviations.txt) \ ${pkgs.writeText "abbrevs.txt" '' i.A. d.h. D.h. gdw. ''} \ | sort | uniq >$out ''); }; "dbus-1/services/org.keepassxc.KeePassXC.service".source = "${wrappedKeepassxc}/share/dbus-1/services/org.keepassxc.KeePassXC.service"; "dbus-1/services/org.freedesktop.secrets.service.service".source = "${wrappedKeepassxc}/share/dbus-1/services/org.freedesktop.secrets.service.service"; "emoji-data/list.txt".source = pkgs.stdenv.mkDerivation { inherit (sources.emoji-data) pname src; version = lib.removePrefix "v" sources.emoji-data.version; buildInputs = with pkgs; [ jq (ruby.withPackages (ps: with ps; [ nokogiri rspec racc rubocop rubocop-performance rspec-core rspec-expectations rspec-mocks diff-lcs parallel parser rainbow regexp_parser rubocop-ast ruby-progressbar unicode-display_width rspec-support optimist ast ])) ]; LC_ALL = "C.UTF-8"; patches = [ (pkgs.writeText "nix.patch" '' diff --git a/Makefile b/Makefile index 896cb50..c7b6db8 100644 --- a/Makefile +++ b/Makefile @@ -21,10 +21,10 @@ data: cldr: @[ ! -d cldr/.git ] && git submodule update --init cldr -data/all.json: compile.rb $(wildcard lib/*.rb) $(INPUT_FILES) | cldr data check-ruby gems +data/all.json: compile.rb $(wildcard lib/*.rb) $(INPUT_FILES) | data @ruby compile.rb > "$@" -data/%.txt: views/%.txt.jq data/all.json | data check-jq +data/%.txt: views/%.txt.jq data/all.json | data @jq -r -f "$<" < data/all.json > "$@" data/%.json: views/%.json.jq data/all.json | data check-jq '') ]; postPatch = '' cp ${pkgs.writeText "list.txt.jq" '' .categories[] | # Collect category + subcategory combos .name as $cat | reduce .subcategories[] as $sub ( []; # Build an array of all emojis in this subcategory . + ( $sub.emojis | map( # emoji: name (keyword, keyword, keyword) "\(.characters): \(.name // .tts_descriptions.en // "") (\(.keywords.en // [] | join(", ")))" ) ) ) | # Merge into a single string join("\n") ''} views/list.txt.jq ''; buildFlagsArray = ["data/list.txt"]; installPhase = '' cp data/list.txt $out ''; }; }; xdg.mimeApps = { enable = true; defaultApplications = let filters = { }; doFilter = n: v: (filters.${n} or id) (filter (d: d != "emacs.desktop") v); in mapAttrs doFilter (cfg.lib.xdg.mimeAssociations [ cfg.programs.zathura.package cfg.programs.imv.package cfg.programs.emacs.package cfg.programs.firefox.package ]) // { "x-scheme-handler/mailto" = "thunderbird.desktop"; }; }; xdg.desktopEntries = { element-lmu = { name = "Element (LMU)"; exec = "element-desktop --profile=lmu %u"; icon = "element"; genericName = "Matrix Client"; categories = [ "Network" "InstantMessaging" "Chat" ]; settings = { StartupWMClass = "Element"; }; }; }; fonts = { fontconfig.enable = true; lmu-hausschrift.enable = true; }; systemd.user = import ./systemd.nix inputs; dconf.settings = { "org/gnome/desktop/interface" = { color-scheme = "prefer-dark"; }; }; wayland.windowManager.hyprland = { enable = true; settings = import ./hyprland.nix inputs; }; }; }; }