{ config, lib, inputs, pkgs, ... }: let cfg = config.david.programs.noctalia; inherit (inputs.niri-flake.lib.kdl) node leaf flag plain ; spawn = leaf "spawn"; noctalia = args: (spawn ( [ "noctalia-shell" "ipc" "call" ] ++ args )); layer-rule = plain "layer-rule"; match = leaf "match"; in { options = { david.programs.noctalia = { enable = lib.mkEnableOption "noctalia"; niriExtraConfig = lib.mkOption { type = inputs.niri-flake.lib.kdl.types.kdl-document; default = [ (leaf "spawn-at-startup" [ (lib.getExe config.programs.noctalia-shell.package) ]) (plain "binds" [ (plain "Mod+V" [ (noctalia [ "launcher" "clipboard" ]) ]) (plain "Mod+Shift+P" [ (noctalia [ "lockScreen" "lock" ]) ]) (plain "Mod+Space" [ (noctalia [ "launcher" "toggle" ]) ]) (node "XF86AudioRaiseVolume" [ { allow-when-locked = true; } ] [ (noctalia [ "volume" "increase" ]) ] ) (node "XF86AudioLowerVolume" [ { allow-when-locked = true; } ] [ (noctalia [ "volume" "decrease" ]) ] ) (node "XF86AudioMute" [ { allow-when-locked = true; } ] [ (noctalia [ "volume" "muteOutput" ]) ] ) (node "XF86AudioMicMute" [ { allow-when-locked = true; } ] [ (noctalia [ "volume" "muteInput" ]) ] ) ]) (layer-rule [ (match [ { namespace = "^noctalia-wallpaper-.*$"; } ]) (leaf "place-within-backdrop" [ true ]) ]) (layer-rule [ (match [ { namespace = "^noctalia-notifications-.*$"; } ]) (leaf "block-out-from" [ "screen-capture" ]) ]) (plain "layout" [ (plain "focus-ring" [ (leaf "active-gradient" [ { from = "#8288fcff"; to = "#8288fc00"; angle = 45; "in" = "oklch"; } ]) ]) ]) ]; apply = configuration: config.david.programs.niri.configHelper.validated-config-for ( inputs.niri-flake.lib.kdl.serialize.nodes configuration ); }; }; }; config = lib.mkIf cfg.enable { stylix.targets.noctalia-shell.enable = false; home.packages = [ pkgs.app2unit pkgs.gpu-screen-recorder ]; programs.noctalia-shell = { enable = true; plugins = builtins.fromJSON (builtins.readFile ./plugins.json); pluginSettings = let enabledPlugins = with lib; flip pipe [ (filterAttrs (_name: settings: settings.enabled or false)) builtins.attrNames ] config.programs.noctalia-shell.plugins.states; staticSettings = lib.genAttrs enabledPlugins ( name: let pluginSettingPath = ./plugin + "/${name}.json"; in if lib.pathIsRegularFile pluginSettingPath then builtins.fromJSON (builtins.readFile pluginSettingPath) else { } ); in lib.recursiveUpdate staticSettings { screen-recorder.directory = "${config.xdg.userDirs.videos}/records"; }; settings = lib.recursiveUpdate (builtins.fromJSON (builtins.readFile ./settings.json)) { general.avatarImage = "${config.home.homeDirectory}/.face"; wallpaper.directory = "${config.home.homeDirectory}/${config.david.wallpaper.path}"; }; }; }; }