inputs: { config, lib, pkgs, ... }: with lib; let cfg = config.ezpcusr; lockCommand = pkgs.writeScript "lock.sh" '' ${pkgs.swaylock-effects}/bin/swaylock -f --clock --indicator --screenshots --effect-scale 0.8 --effect-blur 8x3 --effect-vignette 0.2:0.5 --fade-in 0.5 --text-color ${config.ezcolors.base16.base08} --inside-color ${config.ezcolors.base16.base00} --ring-color ${config.ezcolors.base16.base01} --datestr "%Y-%m-%e" --timestr "%I:%M %p" ''; selshot = pkgs.writeScript "selshot.sh" '' #!${pkgs.zsh}/bin/zsh ${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp)" $1 ''; selvid = pkgs.writeScript "selvid.sh" '' #!${pkgs.zsh}/bin/zsh ${pkgs.wf-recorder}/bin/wf-recorder -g "$(${pkgs.slurp}/bin/slurp)" -f $1 ''; getscrloc = pkgs.writeScript "getscrloc.sh" '' #!${pkgs.zsh}/bin/zsh mkdir -p "${cfg.screenshotsPath}" echo "${cfg.screenshotsPath}/$(date +%F_%T).''${1:-png}" ''; scrsaveclip = pkgs.writeScript "scr-save-clip.sh" '' #!${pkgs.zsh}/bin/zsh LOC=$(${getscrloc}) ${selshot} $LOC ${pkgs.wl-clipboard}/bin/wl-copy -t image/png < $LOC ''; scrsaveup = if cfg.uploadScript != null then pkgs.writeScript "scr-save-up.sh" '' #!${pkgs.zsh}/bin/zsh LOC=$(${getscrloc}) ${selshot} $LOC ${cfg.uploadScript} $LOC | xargs echo -n | ${pkgs.wl-clipboard}/bin/wl-copy notify-send "Screenshot Uploaded!" '' else null; scrvidsaveclip = pkgs.writeScript "scr-vid-save-clip.sh" '' #!${pkgs.zsh}/bin/zsh LOC=$(${getscrloc} mp4) ${selvid} $LOC ${pkgs.wl-clipboard}/bin/wl-copy -t video/mp4 < $LOC ''; scrvidsaveup = if cfg.uploadScript != null then pkgs.writeScript "scr-vid-save-up.sh" '' #!${pkgs.zsh}/bin/zsh LOC=$(${getscrloc} mp4) ${selvid} $LOC ${cfg.uploadScript} $LOC | ${pkgs.findutils}/bin/xargs echo -n | ${pkgs.wl-clipboard}/bin/wl-copy notify-send "Screen Recording Uploaded!" '' else null; scrvidstop = pkgs.writeScript "scr-vid-stop.sh" '' #!${pkgs.zsh}/bin/zsh ${pkgs.procps}/bin/pkill -2 wf-recorder ''; ezDrv = pkgs.runCommand "ez-commands" {} ( '' mkdir -p $out/bin ln -s ${selshot} $out/bin/selshot ln -s ${selvid} $out/bin/selvid ln -s ${getscrloc} $out/bin/getscrloc ln -s ${scrsaveclip} $out/bin/scrsaveclip ln -s ${scrvidsaveclip} $out/bin/scrvidsaveclip ln -s ${scrvidstop} $out/bin/scrvidstop '' + ( if cfg.uploadScript != null then '' ln -s ${cfg.uploadScript} $out/bin/upload_file ln -s ${scrsaveup} $out/bin/scrsaveup ln -s ${scrvidsaveup} $out/bin/scrvidsaveup '' else "" ) ); in { options.ezpcusr = { enable = mkEnableOption "Enable simple PC user config"; uploadScript = mkOption { type = types.nullOr types.package; default = null; description = "A path to a script that takes a path to a file and returns a URL"; }; screenshotsPath = mkOption { description = "Path to save screenshots in"; default = "$HOME/Media/Screenshots"; type = types.str; }; screensaver = mkOption { description = "ezpcusr screensaver"; default = {}; type = types.submodule { options = { lockTime = mkOption { type = types.int; default = 300; description = "Time until your screen locks"; }; offTime = mkOption { type = types.int; default = 600; description = "Time until your screen turns off"; }; }; }; }; favIcons = mkOption { description = "Your favourite icons pack"; default = {}; type = types.submodule { options = { name = mkOption { type = types.str; default = "Papirus-Dark"; description = "Name of your icon pack"; }; package = mkOption { type = types.package; default = pkgs.papirus-icon-theme; description = "Package for your icon pack"; }; }; }; }; bluetooth = mkOption { type = types.bool; default = false; description = "If this PC has bluetooth support"; }; battery = mkOption { type = types.bool; default = false; description = "If this PC has a battery"; }; location = mkOption { description = "Your location (used for weather)"; example = "US-12345"; default = ""; type = types.str; }; }; config = lib.mkIf cfg.enable { services.swayidle = { enable = lib.mkDefault true; events = [ { event = "before-sleep"; command = "${lockCommand}"; } { event = "lock"; command = "${lockCommand}"; } ]; timeouts = [ { timeout = cfg.screensaver.lockTime; command = "${lockCommand}"; } { timeout = cfg.screensaver.offTime; command = "${pkgs.sway}/bin/swaymsg 'output * dpms off'"; resumeCommand = "${pkgs.sway}/bin/swaymsg 'output * dpms on'"; } ]; }; wayland.windowManager.sway = { enable = lib.mkDefault true; systemdIntegration = lib.mkDefault true; wrapperFeatures.gtk = lib.mkDefault true; extraConfig = '' exec keyctl link @u @s workspace 1 ''; config = { terminal = lib.mkDefault "${pkgs.kermit-terminal}/bin/kermit"; modifier = lib.mkDefault "Mod4"; keybindings = let modifier = config.wayland.windowManager.sway.config.modifier; alphabet = ["Ctrl" "Alt" "Ctrl+Alt"]; genKeyAttrs = move: lib.listToAttrs ( map ( n: { name = "${modifier}${ if move then "+Shift" else "" }+${builtins.elemAt alphabet ((n - 11) / 10)}+${toString (lib.mod n 10)}"; value = "${ if move then "move container to " else "" }workspace number ${toString n}"; } ) (lib.lists.range 11 (10 * (builtins.length alphabet) + 10)) ); in lib.mkOptionDefault ( let volumeUp = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%"; volumeDown = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%"; in { "${modifier}+q" = "kill"; "Print" = "exec ${scrsaveclip}"; "Shift+Print" = if cfg.uploadScript != null then "exec ${scrsaveup}" else "nop"; "Ctrl+Print" = "exec ${scrvidsaveclip}"; "Ctrl+Alt+Print" = "exec ${scrvidstop}"; "${modifier}+minus" = volumeDown; "${modifier}+equal" = volumeUp; "XF86AudioRaiseVolume" = volumeUp; "XF86AudioLowerVolume" = volumeDown; "XF86AudioMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle"; "XF86AudioMicMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle"; "XF86MonBrightnessDown" = "exec ${pkgs.light}/bin/light -U 10"; "XF86MonBrightnessUp" = "exec ${pkgs.light}/bin/light -A 10"; "${modifier}+semicolon" = "exec ${pkgs.light}/bin/light -U 10"; "${modifier}+apostrophe" = "exec ${pkgs.light}/bin/light -A 10"; # Previous/next but change the shuffle/random state before action (and change back afterwards) "${modifier}+Shift+bracketright" = "exec ${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl next && ${pkgs.playerctl}/bin/playerctl shuffle Toggle"; "${modifier}+Shift+bracketleft" = "exec ${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl previous && ${pkgs.playerctl}/bin/playerctl shuffle Toggle"; "Shift+XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl next && ${pkgs.playerctl}/bin/playerctl shuffle Toggle"; # Previous/next "${modifier}+bracketright" = "exec ${pkgs.playerctl}/bin/playerctl next"; "${modifier}+bracketleft" = "exec ${pkgs.playerctl}/bin/playerctl previous"; "XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl next"; "XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl prev"; # Seek forward/back "${modifier}+Ctrl+bracketright" = "exec ${pkgs.playerctl}/bin/playerctl position 5+"; "${modifier}+Ctrl+bracketleft" = "exec ${pkgs.playerctl}/bin/playerctl position 5-"; "Ctrl+XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl position 5+"; "Ctrl+XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl position 5-"; # Toggle play/pause "XF86AudioPlay" = "exec ${pkgs.playerctl}/bin/playerctl play-pause"; "XF86AudioPause" = "exec ${pkgs.playerctl}/bin/playerctl play-pause"; "${modifier}+backslash" = "exec ${pkgs.playerctl}/bin/playerctl play-pause"; "${modifier}+p" = "exec bash ${inputs.bwmenu}/bwmenu"; "${modifier}+e" = "exec bash ${inputs.bemoji}/bemoji -t"; "${modifier}+0" = "workspace 10"; "${modifier}+Shift+0" = "move container to workspace 10"; "Ctrl+Alt+l" = "exec ${lockCommand}"; } // genKeyAttrs true // genKeyAttrs false ); menu = "${config.programs.rofi.package}/bin/rofi -show drun -show-icons -run-command '${pkgs.sway}/bin/swaymsg exec -- {cmd}'"; bars = []; gaps = { smartGaps = lib.mkDefault true; smartBorders = lib.mkDefault "on"; inner = lib.mkDefault 10; outer = lib.mkDefault 0; }; }; }; programs.firefox.enable = true; programs.waybar = { enable = lib.mkDefault true; systemd = { enable = lib.mkDefault true; target = lib.mkDefault "sway-session.target"; }; settings.mainbar = let weatherCommand = f: "(${pkgs.curl}/bin/curl 'wttr.in/${cfg.location}?format=${f}' || echo 'ERR') | ${pkgs.gnused}/bin/sed 's/^Unknown.*/ERR/' | ${pkgs.coreutils}/bin/tr -s ' '"; in { position = lib.mkDefault "left"; height = lib.mkDefault null; modules-left = ["sway/workspaces" "custom/spacer" "custom/weather-temp" "custom/weather-precip" "custom/weather-wind"]; modules-center = ["clock#1" "clock#2" "custom/spacer" "custom/media" "custom/spacer" "clock#3" "custom/spacer" "clock#4"]; modules-right = ["pulseaudio" "custom/spacer" "memory" "custom/spacer" "cpu"] ++ lib.optionals cfg.battery ["custom/spacer" "battery"] ++ ["custom/spacer" "tray"]; "custom/spacer" = { format = lib.mkDefault "〜"; rotate = lib.mkDefault 90; tooltip = lib.mkDefault false; }; "custom/weather-temp" = { exec = lib.mkDefault (weatherCommand "%c+%t"); on-click = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://weather.com/weather/today/l/85625'"; on-click-right = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://wttr.in/${cfg.location}'"; interval = lib.mkDefault 300; }; "custom/weather-precip" = { exec = lib.mkDefault (weatherCommand "🌧️+%p"); on-click = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://www.lightningmaps.org/'"; on-click-right = "lib.mkDefault ${pkgs.xdg-utils}/bin/xdg-open 'https://wttr.in/${cfg.location}'"; interval = lib.mkDefault 300; }; "custom/weather-wind" = { exec = lib.mkDefault (weatherCommand "🌬️+%w"); on-click = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://www.ventusky.com/"; on-click-right = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://wttr.in/${cfg.location}'"; interval = lib.mkDefault 300; }; "custom/media" = { rotate = lib.mkDefault 90; max-length = lib.mkDefault 60; on-click = lib.mkDefault "${pkgs.playerctl}/bin/playerctl play-pause"; exec = lib.mkDefault "${pkgs.playerctl}/bin/playerctl metadata --format '{{ emoji(status) }} {{ artist }} - {{ title }}' --follow"; }; "sway/workspaces" = { disable-scroll = lib.mkDefault true; }; "clock#1" = { tooltip = lib.mkDefault false; format = lib.mkDefault "{:%a}"; }; "clock#2" = { tooltip = lib.mkDefault false; format = lib.mkDefault "{:%m-%d}"; }; "clock#3" = { tooltip = lib.mkDefault false; format = lib.mkDefault "{:%I:%M %p}"; }; "clock#4" = { tooltip = lib.mkDefault false; timezone = lib.mkDefault "Etc/UTC"; format = lib.mkDefault "{:%H:%M} UTC"; }; pulseaudio = { format = lib.mkDefault "{icon} {volume}%"; format-bluetooth = lib.mkDefault "{icon} {volume}%"; format-muted = lib.mkDefault "MUTE"; format-icons = { headphone = lib.mkDefault ""; default = lib.mkDefault ""; }; on-click = lib.mkDefault "${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle"; on-click-right = lib.mkDefault "${pkgs.pavucontrol}/bin/pavucontrol"; }; memory = { interval = lib.mkDefault 20; format = lib.mkDefault " {}%"; }; cpu = { interval = lib.mkDefault 20; format = lib.mkDefault " {usage}%"; }; battery = { states = { good = lib.mkDefault 90; warning = lib.mkDefault 25; critical = lib.mkDefault 10; }; format = lib.mkDefault "{icon} {capacity}%"; format-icons = ["" "" "" "" "" "" "" "" "" ""]; }; tray = { icon-size = lib.mkDefault 18; spacing = lib.mkDefault 5; }; }; style = '' window#waybar { background: #${config.ezcolors.base16.base01}; color: #${config.ezcolors.base16.base06}; } #custom-spacer { font-size: 15px; color: #${config.ezcolors.base16.base00}; font-weight: bold; } #workspaces, #clock.1, #clock.2, #clock.3, #clock.4, #pulseaudio, #memory, #cpu, #battery, #disk, #tray, #mode, #custom-weather-temp, #custom-weather-precip, #custom-weather-wind, #custom-media { color: #${config.ezcolors.base16.base06}; font-size: ${toString (config.ezfonts.font.size + 1)}px; background: #${config.ezcolors.base16.base00}; padding: 5px 0; } #workspaces { padding: 0 } #clock.1 { padding: 5px 0 0 0; } #clock.2 { padding: 0 0 5px 0; } #custom-weather-temp { padding: 5px 0 0 0; } #custom-weather-precip { padding: 5px 0; } #custom-weather-wind { padding: 0 0 5px 0; } #custom-media.playing { color: #${config.ezcolors.base16.base0A}; } #workspaces button.focused { color: #${config.ezcolors.base16.base0A}; } #workspaces button:hover { background: #${config.ezcolors.base16.base02}; } #pulseaudio { color: #${config.ezcolors.base16.base0B}; } #memory { color: #${config.ezcolors.base16.base0C}; } #cpu { color: #${config.ezcolors.base16.base0D}; } #battery { color: #${config.ezcolors.base16.base0E}; } * { font-family: "${config.ezfonts.font.name}"; border-radius: 0; border-width: 0; border-style: none; margin: 0; padding: 0; } ''; }; programs.mako = { enable = lib.mkDefault true; maxVisible = lib.mkDefault 6; extraConfig = lib.generators.toKeyValue {} { on-button-middle = "dismiss-all"; }; }; systemd.user.services.mako = { Service = { ExecStart = "${pkgs.mako}/bin/mako"; }; Install = { After = ["sway-session.target"]; WantedBy = ["sway-session.target"]; }; }; ezcolors.enable = lib.mkDefault true; ezfonts.enable = lib.mkDefault true; services.blueman-applet.enable = lib.mkDefault cfg.bluetooth; services.mpris-proxy.enable = lib.mkDefault true; services.playerctld.enable = lib.mkDefault true; gtk = { enable = lib.mkDefault true; iconTheme = { package = lib.mkDefault cfg.favIcons.package; name = lib.mkDefault cfg.favIcons.name; }; }; qt = { enable = lib.mkDefault true; platformTheme = lib.mkDefault "gtk"; }; programs.kermit = { enable = lib.mkDefault true; settings = { opacity = lib.mkDefault "0.90"; key = lib.mkDefault "shift"; }; }; xdg.enable = true; xdg.userDirs.enable = true; xdg.configFile."mimeapps.list".force = true; xdg.mimeApps = let applications = { "inode/directory" = "pcmanfm-qt.desktop"; "text/html" = "librewolf.desktop"; "x-scheme-handler/http" = "librewolf.desktop"; "x-scheme-handler/https" = "librewolf.desktop"; "x-scheme-handler/about" = "librewolf.desktop"; "application/zip" = "ark.desktop"; "application/rar" = "ark.desktop"; "application/7z" = "ark.desktop"; "application/*tar" = "ark.desktop"; }; in { enable = true; associations.added = applications; defaultApplications = applications; }; programs.mpv.enable = lib.mkDefault true; fonts.fontconfig.enable = lib.mkDefault true; home.packages = with pkgs; [ wl-clipboard wtype ydotool keyutils # ezpcusr stuff ezDrv # programs pavucontrol ark pcmanfm-qt # CLI tools yt-dlp maim slop xorg.xhost ]; programs.rofi = { enable = lib.mkDefault true; package = pkgs.rofi-wayland; terminal = lib.mkDefault "${pkgs.kermit-terminal}/bin/kermit"; }; }; }