inputs: { config, lib, pkgs, ... }: with lib; let cfg = config.ezpcusr; in { imports = [ inputs.niri.homeModules.niri inputs.noctalia.homeModules.default inputs.system76-scheduler-niri.homeModules.default ]; options.ezpcusr = { enable = mkEnableOption "Enable simple PC user config"; 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 = 600; description = "Time until your screen locks"; }; offTime = mkOption { type = types.int; default = 900; description = "Time until your screen turns off"; }; }; }; }; bluetooth = mkOption { type = types.bool; default = false; description = "If this PC has bluetooth support"; }; }; config = lib.mkIf cfg.enable { services.system76-scheduler-niri.enable = true; services.hypridle = { enable = lib.mkDefault true; settings = { general = { lock_cmd = "noctalia msg session lock"; before_sleep_cmd = "loginctl lock-session"; after_sleep_cmd = "hyperctl dispatch dpms on"; }; listener = [ { timeout = cfg.screensaver.lockTime; on-timeout = "loginctl lock-session"; } { timeout = cfg.screensaver.offTime; on-timeout = "hyperctl dispatch dpms off"; } ]; }; }; # xdg.portal = { # config.niri = { # default = [ "gnome" "gtk" ]; # # "org.freedesktop.impl.portal.Access" = "gtk"; # # "org.freedesktop.impl.portal.Notification" = "gtk"; # # "org.freedesktop.impl.portal.Secret" = "gnome-keyring"; # # "org.freedesktop.impl.portal.FileChooser" = "gtk"; # }; # extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; # }; systemd.user.services.noctalia-shell = { Unit = { Description = "Noctalia shell service"; PartOf = [config.wayland.systemd.target]; Before = [config.wayland.systemd.target]; }; Install.WantedBy = [config.wayland.systemd.target]; Service = { ExecStart = "${inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default}/bin/noctalia"; Restart = "on-failure"; RestartSec = 5; }; }; programs.niri = { enable = true; package = pkgs.niri-unstable; settings = { blur = { passes = 2; offset = 3.0; noise = 0.03; saturation = 1.0; }; layer-rules = [ { matches = [{ namespace = "^noctalia-(bar-[^\"]+|notification|dock|panel|attached-panel|osd)$"; }]; background-effect.xray = false; } { matches = [{ namespace = "^noctalia-backdrop"; }]; place-within-backdrop = true; } ]; window-rules = [ { draw-border-with-background = false; geometry-corner-radius = { bottom-left = 8.0; bottom-right = 8.0; top-left = 8.0; top-right = 8.0; }; clip-to-geometry = true; } { background-effect = { blur = true; xray = false; }; } ]; prefer-no-csd = true; xwayland-satellite = { enable = true; path = lib.getExe pkgs.xwayland-satellite-unstable; }; # spawn-at-startup = [ # {argv = ["noctalia"];} # ]; clipboard.disable-primary = true; input = { focus-follows-mouse.enable = true; touchpad = { click-method = "clickfinger"; natural-scroll = false; }; }; binds = { "Mod+Return".action.spawn = "${config.programs.foot.package}/bin/foot"; "Mod+q".action = config.lib.niri.actions.close-window; # "$mod, F, fullscreen, 0" # "$mod SHIFT, F, fullscreen, 1" # "$mod, Space, togglefloating" # "$mod SHIFT, SPACE, exec, hyprctl switchxkblayout all next" "Mod+d".action.spawn = ["noctalia" "msg" "panel-open" "launcher"]; "Print".action.spawn-sh = "grim - | satty -f -"; "Mod+c".action.spawn = ["noctalia" "msg" "panel-open" "clipboard"]; "Mod+e".action.spawn = ["noctalia" "msg" "panel-open" "launcher" "/emo"]; "Mod+Minus".action.spawn = ["noctalia" "msg" "volume-down"]; "Mod+Equal".action.spawn = ["noctalia" "msg" "volume-up"]; "XF86AudioLowerVolume".action.spawn = ["noctalia" "msg" "volume-down"]; "XF86AudioRaiseVolume".action.spawn = ["noctalia" "msg" "volume-up"]; "XF86AudioMute".action.spawn = ["noctalia" "msg" "volume-mute"]; "XF86AudioMicMute".action.spawn = ["noctalia" "msg" "mic-mute"]; "XF86MonBrightnessDown".action.spawn = ["noctalia" "msg" "brightness-down"]; "XF86MonBrightnessUp".action.spawn = ["noctalia" "msg" "brightness-up"]; "Mod+Semicolon".action.spawn = ["noctalia" "msg" "brightness-down"]; "Mod+Apostrophe".action.spawn = ["noctalia" "msg" "brightness-up"]; # Previous/next but change the shuffle/random state before action (and change back afterwards) "Mod+Shift+Bracketright".action.spawn-sh = "${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl next && ${pkgs.playerctl}/bin/playerctl shuffle Toggle"; "Mod+Shift+bracketleft".action.spawn-sh = "${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl previous && ${pkgs.playerctl}/bin/playerctl shuffle Toggle"; "Shift+XF86AudioNext".action.spawn-sh = "${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl next && ${pkgs.playerctl}/bin/playerctl shuffle Toggle"; "Shift+XF86AudioPrev".action.spawn-sh = "${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl pref && ${pkgs.playerctl}/bin/playerctl shuffle Toggle"; # Previous/next "Mod+Bracketright".action.spawn = ["noctalia" "msg" "media" "next"]; "Mod+Bracketleft".action.spawn = ["noctalia" "msg" "media" "previous"]; "XF86AudioNext".action.spawn = ["noctalia" "msg" "media" "next"]; "XF86AudioPrev".action.spawn = ["noctalia" "msg" "media" "previous"]; # Seek forward/back "Mod+Control+bracketleft".action.spawn = ["noctalia" "msg" "media" "seekRelative" "-5"]; "Mod+Control+bracketright".action.spawn = ["noctalia" "msg" "media" "seekRelative" "5"]; "Control+XF86AudioPrev".action.spawn = ["noctalia" "msg" "media" "seekRelative" "-5"]; "Control+XF86AudioNext".action.spawn = ["noctalia" "msg" "media" "seekRelative" "5"]; # Toggle play/pause "XF86AudioPlay".action.spawn = ["noctalia" "msg" "media" "toggle"]; "XF86AudioPause".action.spawn = ["noctalia" "msg" "media" "toggle"]; "Mod+Backslash".action.spawn = ["noctalia" "msg" "media" "toggle"]; "Control+Alt+l".action.spawn = ["noctalia" "msg" "session" "lock"]; "Mod+Shift+Slash".action = config.lib.niri.actions.show-hotkey-overlay; "Mod+Left".action = config.lib.niri.actions.focus-column-left; "Mod+Right".action = config.lib.niri.actions.focus-column-right; # "Mod+Shift+Left".action = config.lib.niri.actions.move-column-left; # "Mod+Shift+Right".action = config.lib.niri.actions.move-column-right; "Mod+Shift+Left".action = config.lib.niri.actions.consume-or-expel-window-left; "Mod+Shift+Right".action = config.lib.niri.actions.consume-or-expel-window-right; "Mod+Down".action = config.lib.niri.actions.focus-window-or-workspace-down; "Mod+Up".action = config.lib.niri.actions.focus-window-or-workspace-up; "Mod+Shift+Down".action = config.lib.niri.actions.move-window-down-or-to-workspace-down; "Mod+Shift+Up".action = config.lib.niri.actions.move-window-up-or-to-workspace-up; "Mod+Space".action = config.lib.niri.actions.toggle-window-floating; "Mod+F".action = config.lib.niri.actions.fullscreen-window; "Mod+M".action = config.lib.niri.actions.maximize-column; "Mod+O".action = config.lib.niri.actions.toggle-overview; "Mod+Control+Right".action = config.lib.niri.actions.focus-monitor-right; "Mod+Control+Left".action = config.lib.niri.actions.focus-monitor-left; "Mod+Control+Up".action = config.lib.niri.actions.focus-monitor-up; "Mod+Control+Down".action = config.lib.niri.actions.focus-monitor-down; "Mod+Control+Shift+Right".action = config.lib.niri.actions.move-window-to-monitor-right; "Mod+Control+Shift+Left".action = config.lib.niri.actions.move-window-to-monitor-left; "Mod+Control+Shift+Up".action = config.lib.niri.actions.move-window-to-monitor-up; "Mod+Control+Shift+Down".action = config.lib.niri.actions.move-window-to-monitor-down; } // ( # workspaces # binds $mod + [shift +] {1..9} to [move to] workspace {1..9} lib.listToAttrs ( builtins.concatLists (builtins.genList ( i: let ws = i + 1; in [ { name = "Mod+${toString i}"; value = {action.focus-workspace = i;}; } { name = "Mod+Shift+${toString i}"; value = {action.move-window-to-workspace = i;}; } ] ) 9) ) ); }; }; programs.noctalia = { enable = true; settings = { dock.enabled = false; shell = { time_format = "{:%-I:%M %p}"; setup_wizard_enabled = false; telemetry_enabled = false; external_ip_enabled = false; niri_overview_type_to_launch_enabled = true; animation.speed = 2.0; panel = { transparency_mode = "glass"; }; }; desktop_widgets = { enabled = true; }; location = { auto_locate = true; }; widget = { media = { max_length = 400; title_scroll = "always"; }; audio_visualizer = { show_when_idle = true; }; }; bar.main = { floating = false; background_opacity = config.stylix.opacity.desktop; start = ["workspaces" "active_window"]; center = ["media" "spacer" "clock" "spacer" "audio_visualizer"]; end = ["tray" "notifications" "battery" "power_profile" "volume" "network" "bluetooth" "control-center"]; }; }; }; programs.librewolf.enable = true; services.mpris-proxy.enable = lib.mkDefault true; services.playerctld.enable = lib.mkDefault true; programs.foot.enable = true; 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; [ brightnessctl nautilus # gnome portal file chooser wl-clipboard wtype ydotool keyutils maim slop xhost sway-contrib.grimshot grim inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default ]; programs.satty = { enable = true; settings.general = { fullscreen = true; initial-tool = "crop"; early-exit = true; copy-command = "wl-copy"; save-after-copy = true; actions-on-enter = ["save-to-clipboard"]; actions-on-escape = ["exit"]; output-filename = "${config.home.homeDirectory}/Media/Screenshots/satty-%F_%T.png"; }; }; services.cliphist.enable = true; }; }