{ description = "sims status bar (companion to fenster WM)."; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/24.11"; unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; utils.url = "github:numtide/flake-utils"; fabric.url = "github:Fabric-Development/fabric"; home-manager.url = "github:nix-community/home-manager"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, nixpkgs, unstable, utils, fabric, ... }: utils.lib.eachDefaultSystem ( system: let # Dependencies want from nixpkgs unstable as an overlay unstable-overlay = final: prev: { basedpyright = unstable.legacyPackages.${system}.basedpyright; }; # Fabric overlay fabric-overlay = fabric.overlays.${system}.default; # Apply both overlays pkgs = (nixpkgs.legacyPackages.${system}.extend fabric-overlay).extend unstable-overlay; in { formatter = pkgs.nixfmt-rfc-style; devShells.default = pkgs.callPackage ./nix/shell.nix { inherit pkgs; }; packages = rec { default = pkgs.callPackage ./nix/derivation.nix { inherit (pkgs) lib python3Packages; }; sims = default; }; apps.default = { type = "app"; program = "${self.packages.${system}.default}/bin/sims"; }; } ) // { homeManagerModules = { sims = { config, lib, pkgs, ... }: let cfg = config.services.sims; settingsFormat = pkgs.formats.yaml { }; in { options.services.sims = { enable = lib.mkEnableOption "sims status bar"; package = lib.mkOption { type = lib.types.package; default = self.packages.${pkgs.system}.default; description = "The sims package to use."; }; settings = lib.mkOption { type = lib.types.submodule { options = { vinyl = { enable = lib.mkOption { type = lib.types.bool; default = false; }; }; battery = { enable = lib.mkOption { type = lib.types.bool; default = false; }; }; height = lib.mkOption { type = lib.types.int; default = 40; description = "Height of the status bar in pixels"; }; logLevel = lib.mkOption { type = lib.types.enum [ "TRACE" "DEBUG" "INFO" "SUCCESS" "WARNING" "ERROR" "CRITICAL" ]; default = "WARNING"; description = "Log level for the status bar (loguru levels: TRACE, DEBUG, INFO, SUCCESS, WARNING, ERROR, CRITICAL)"; }; window_title = { enable = lib.mkOption { type = lib.types.bool; default = true; description = "Whether to show the window title in the center of the bar"; }; }; stylix = lib.mkOption { type = lib.types.attrsOf lib.types.anything; default = { enable = false; }; description = "Stylix configuration passed from the stylix module"; }; calendar = { enable = lib.mkOption { type = lib.types.bool; default = true; description = "Whether to enable the calendar widget"; }; khal_path = lib.mkOption { type = lib.types.str; default = "khal"; description = "Path to the khal binary"; }; }; notmuch = { enable = lib.mkOption { type = lib.types.bool; default = true; description = "Whether to enable the notmuch email widget"; }; notmuch_path = lib.mkOption { type = lib.types.str; default = "notmuch"; description = "Path to the notmuch binary"; }; emacsclient_command = lib.mkOption { type = lib.types.str; default = "emacsclient"; description = "Path to the emacsclient binary"; }; debt_query = lib.mkOption { type = lib.types.str; default = "tag:unread and date:..1w"; description = "notmuch query whose count drives the mail-debt severity color on the bar widget"; }; debt_warn_at = lib.mkOption { type = lib.types.int; default = 1; description = "Debt count at which the widget switches to the warn (orange) color"; }; debt_alarm_at = lib.mkOption { type = lib.types.int; default = 6; description = "Debt count at which the widget switches to the alarm (red) color"; }; }; screenrec = { enable = lib.mkOption { type = lib.types.bool; default = false; description = "Whether to enable the screenrec widget and menu"; }; output_dir = lib.mkOption { type = lib.types.str; default = "~/Videos/wl-screenrec"; description = "Directory to save recordings into"; }; }; power = { lock_command = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ "waylock" ]; description = "argv for the Lock action in the power menu"; }; }; notifications = { enable = lib.mkOption { type = lib.types.bool; default = false; description = "Whether to enable the notification toast service. Owns org.freedesktop.Notifications, so other notification daemons (mako, dunst, swaync) must be disabled."; }; anchor = lib.mkOption { type = lib.types.str; default = "top center"; description = "Layer-shell anchor for the toast stack"; }; margin = lib.mkOption { type = lib.types.str; default = "8px"; description = "Layer-shell margin for the toast stack"; }; width = lib.mkOption { type = lib.types.int; default = 360; description = "Width of each notification toast in pixels"; }; timeout_ms = lib.mkOption { type = lib.types.int; default = 10000; description = "Auto-close timeout for notifications in milliseconds"; }; history_size = lib.mkOption { type = lib.types.int; default = 50; description = "How many past notifications the in-memory center keeps"; }; image_max_px = lib.mkOption { type = lib.types.int; default = 128; description = "Max edge in pixels for stored notification thumbnails"; }; center_width = lib.mkOption { type = lib.types.int; default = 380; description = "Width of the notification center side rail in pixels"; }; }; }; }; default = { vinyl.enable = false; battery.enable = false; height = 40; logLevel = "WARNING"; window_title.enable = true; stylix.enable = false; calendar = { enable = true; khal_path = "khal"; }; notmuch = { enable = true; notmuch_path = "notmuch"; emacsclient_command = "emacsclient"; debt_query = "tag:unread and date:..1w"; debt_warn_at = 1; debt_alarm_at = 6; }; screenrec = { enable = false; output_dir = "~/Videos/wl-screenrec"; }; power = { lock_command = [ "waylock" ]; }; notifications = { enable = false; anchor = "top center"; margin = "8px"; width = 360; timeout_ms = 10000; history_size = 50; image_max_px = 128; center_width = 380; }; }; }; }; config = lib.mkIf config.services.sims.enable { systemd.user.services.sims = let configFile = settingsFormat.generate "config.yaml" cfg.settings; in { Unit = { Description = "sims status bar"; After = [ "graphical-session.target" ]; }; Service = { ExecStart = "${config.services.sims.package}/bin/sims --config ${configFile}"; Restart = "on-failure"; }; Install = { WantedBy = [ "default.target" ]; }; }; }; }; stylix-sims = import ./nix/stylix/hm.nix; }; }; }