diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 62524cb..06dc541 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,58 +1,34 @@ # by https://github.com/danth/stylix/blob/master/.github/workflows/docs.yml name: Docs - on: push: branches: - main - jobs: build: name: Build - permissions: contents: read - - runs-on: ubuntu-latest - + runs-on: nixos-latest steps: - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - extra-conf: | - extra-experimental-features = nix-command flakes pipe-operators - - - name: Set up cache - uses: DeterminateSystems/magic-nix-cache-action@main - + - name: Nix Config + run: | + mkdir -p $HOME/.config + mkdir -p $HOME/.config/nix + echo experimental-features = nix-command flakes pipe-operators >> $HOME/.config/nix/nix.conf + echo access-tokens = github.com=${{ secrets.GITHUBTOKEN }} >> $HOME/.config/nix/nix.conf + nix profile install nixpkgs#nodejs - name: Build docs - run: nix -L build github:${{ github.repository }}/${{ github.sha }}#docs --no-write-lock-file - + run: nix -L build git+https://git.dashie.org/${{ forgejo.repository }}.git?rev=${{ forgejo.sha }}#docs --no-write-lock-file - name: Prepare docs for upload run: cp -r --dereference --no-preserve=mode,ownership result/ public/ - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + # - name: Upload artifact + # uses: https://data.forgejo.org/forgejo/upload-artifact@v4 + # with: + # path: public/ + - name: Publish Page + uses: https://data.forgejo.org/actions/git-pages@v2 with: - path: public/ - - deploy: - name: Deploy - - needs: build - - permissions: - pages: write - id-token: write - - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - - runs-on: ubuntu-latest - - steps: - - name: Deploy docs to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 + site: https://username.pages.dashie.org/reponame/ + token: ${{ forge.token }} + source: public/ diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 7037e7f..e92ddfd 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1,13 +1,11 @@ # inspired by https://github.com/danth/stylix/blob/master/.github/workflows/docs.yml -name: Rust-build +name: PR check on: - push: - branches: ["main"] pull_request: branches: ["main"] jobs: build: - name: Build + name: check permissions: contents: read runs-on: ubuntu-latest @@ -17,7 +15,7 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} extra-conf: | - extra-experimental-features = nix-command flakes + extra-experimental-features = nix-command flakes pipe-operators - name: Set up cache uses: DeterminateSystems/magic-nix-cache-action@main - name: action @@ -30,4 +28,8 @@ jobs: name: dashnix authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - name: Linter check - run: nix -L build github:${{ github.repository }}/${{ github.sha }} --no-write-lock-file + run: nix run --no-write-lock-file github:${{ github.repository }}/${{ github.sha }}#lint -- check + - name: Format check + run: nix run --no-write-lock-file github:${{ github.repository }}/${{ github.sha }}#format -- --check . + - name: Build docs + run: nix -L build github:${{ github.repository }}/${{ github.sha }}#docs --no-write-lock-file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 84bda95..1984fb1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,29 +1,29 @@ -# by https://github.com/danth/stylix/blob/master/.github/workflows/docs.yml -name: Release -on: - release: - types: [created] -jobs: - build: - name: Release - permissions: - contents: read - runs-on: ubuntu-latest - steps: - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - extra-conf: | - extra-experimental-features = nix-command flakes pipe-operators - - name: Set up cache - uses: DeterminateSystems/magic-nix-cache-action@main - - name: Build ISO - run: nix build github:${{ github.repository }}/${{ github.sha }}#iso --no-write-lock-file - - name: Prepare ISO for upload - run: | - cp -r --dereference --no-preserve=mode,ownership result/ public/ - - name: upload ISO - uses: softprops/action-gh-release@v1 - with: - path: path/ +# by https://github.com/danth/stylix/blob/master/.github/workflows/docs.yml +name: Release +on: + release: + types: [created] +jobs: + build: + name: Release + permissions: write-all + runs-on: ubuntu-latest + steps: + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + extra-conf: | + extra-experimental-features = nix-command flakes pipe-operators + - name: Set up cache + uses: DeterminateSystems/magic-nix-cache-action@main + - name: Build ISO + run: nix build github:${{ github.repository }}/${{ github.sha }}#iso --no-write-lock-file + - name: Prepare ISO for upload + run: | + cp -r --dereference --no-preserve=mode,ownership result/iso/DashNix.iso DashNix.iso + - name: upload ISO + uses: softprops/action-gh-release@v1 + with: + files: | + DashNix.iso diff --git a/.gitignore b/.gitignore index a931378..f610716 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ result/* result +flake.lock diff --git a/base/common_hardware.nix b/base/common_hardware.nix index 5af3cba..9f7ccf1 100644 --- a/base/common_hardware.nix +++ b/base/common_hardware.nix @@ -101,10 +101,6 @@ in { builders-use-substitutes = mkDashDefault true; - substituters = [ - "https://chaotic-nyx.cachix.org/" - ]; - trusted-substituters = [ "https://hyprland.cachix.org" "https://anyrun.cachix.org" @@ -115,6 +111,7 @@ in { "https://oxicalc.cachix.org" "https://hyprdock.cachix.org" "https://reset.cachix.org" + "https://dashvim.cachix.org" ]; trusted-public-keys = [ @@ -127,7 +124,7 @@ in { "oxicalc.cachix.org-1:qF3krFc20tgSmtR/kt6Ku/T5QiG824z79qU5eRCSBTQ=" "hyprdock.cachix.org-1:HaROK3fBvFWIMHZau3Vq1TLwUoJE8yRbGLk0lEGzv3Y=" "reset.cachix.org-1:LfpnUUdG7QM/eOkN7NtA+3+4Ar/UBeYB+3WH+GjP9Xo=" - "chaotic-nyx.cachix.org-1:HfnXSw4pj95iI/n17rIDy40agHj12WfF+Gqk6SonIT8=" + "dashvim.cachix.org-1:uLRdxp1WOWHnsZZtu3SwUWZRsvC7SXo0Gyk3tIefuL0=" ]; experimental-features = mkDashDefault "nix-command flakes pipe-operators"; @@ -162,6 +159,8 @@ in { "vboxusers" "video" "audio" + "scanner" + "lp" ]; packages = with pkgs; [ home-manager diff --git a/docs/src/README.md b/docs/src/README.md index 6233312..3658e00 100644 --- a/docs/src/README.md +++ b/docs/src/README.md @@ -23,6 +23,40 @@ dashNix = { You can then configure your systems in your flake outputs with a provided library command: +Please note that overriding inputs will invalidate the cache configuration, this means you will have to add this manually: + +```nix + builders-use-substitutes = true; + + extra-substituters = [ + "https://hyprland.cachix.org" + "https://anyrun.cachix.org" + "https://cache.garnix.io" + "https://oxipaste.cachix.org" + "https://oxinoti.cachix.org" + "https://oxishut.cachix.org" + "https://oxidash.cachix.org" + "https://oxicalc.cachix.org" + "https://hyprdock.cachix.org" + "https://reset.cachix.org" + "https://dashvim.cachix.org" + ]; + + extra-trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + "anyrun.cachix.org-1:pqBobmOjI7nKlsUMV25u9QHa9btJK65/C8vnO3p346s=" + "cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g=" + "oxipaste.cachix.org-1:n/oA3N3Z+LJP7eIWOwuoLd9QnPyZXqFjLgkahjsdDGc=" + "oxinoti.cachix.org-1:dvSoJl2Pjo5HMaNngdBbSaixK9BSf2N8gzjP2MdGvfc=" + "oxishut.cachix.org-1:axyAGF3XMh1IyMAW4UMbQCdMNovDH0KH6hqLLRJH8jU=" + "oxidash.cachix.org-1:5K2FNHp7AS8VF7LmQkJAUG/dm6UHCz4ngshBVbjFX30=" + "oxicalc.cachix.org-1:qF3krFc20tgSmtR/kt6Ku/T5QiG824z79qU5eRCSBTQ=" + "hyprdock.cachix.org-1:HaROK3fBvFWIMHZau3Vq1TLwUoJE8yRbGLk0lEGzv3Y=" + "reset.cachix.org-1:LfpnUUdG7QM/eOkN7NtA+3+4Ar/UBeYB+3WH+GjP9Xo=" + "dashvim.cachix.org-1:uLRdxp1WOWHnsZZtu3SwUWZRsvC7SXo0Gyk3tIefuL0=" + ]; +``` + ```nix nixosConfigurations = inputs.dashNix.dashNixLib.buildSystems { root = ./.; }; ``` @@ -74,26 +108,20 @@ Here is a minimal required configuration.nix (the TODOs mention a required chang # default disk config has root home boot and swap partition, overwrite if you want something different sops.enable = false; nextcloud.enable = false; - hypr.hyprland = { - # TODO monitor configuration for hyprland (hyprland is default) - # should be something like DP-1 - defaultMonitor = "YOURMONITOR"; - # width x height @ refreshrate - defaultMonitorMode = "1920x1080@60"; - # scale for your main monitor - defaultMonitorScale = "1"; - # additional configruation can be done as well - # customConfig = { - # monitor = [ - # # default - # "${config.mods.hypr.hyprland.defaultMonitor},${config.mods.hypr.hyprland.defaultMonitorMode},0x0,${config.mods.hypr.hyprland.defaultMonitorScale}" - # # second example monitor - # "DP-2,3440x1440@180,auto,1" - # # all others - # ",highrr,auto,1" - # ]; - # } - }; + wm.monitors = [ + # Example + # { + # name = "DP-1"; + # resolutionX = 3440; + # resolutionY = 1440; + # refreshrate = 180; + # positionX = 2560; + # positionY = 0; + # scale = 1; + # transform = "0"; + # vrr = false; + # } + ]; gpu.nvidia.enable = true; kdeConnect.enable = true; # login manager: @@ -102,29 +130,29 @@ Here is a minimal required configuration.nix (the TODOs mention a required chang # sddm = { }; # gdm = { }; drives = { - # default assumes ROOT, BOOT, HOME and SWAP labaled drives exist - # for an example without HOME see below - # defaultDrives.enable = false; - # extraDrives = [ - # { - # name = "boot"; - # drive = { - # device = "/dev/disk/by-label/BOOT"; - # fsType = "vfat"; - # options = [ "rw" "fmask=0022" "dmask=0022" "noatime" ]; - # }; - # } - # { - # name = ""; - # drive = { - # device = "/dev/disk/by-label/ROOT"; - # fsType = "ext4"; - # options = [ "noatime" "nodiratime" "discard" ]; - # }; - # } - # ]; - # You can also use disko to format your disks on installation. - # Please refer to the Documentation about the drives module for an example. + # default assumes ROOT, BOOT, HOME and SWAP labaled drives exist + # for an example without HOME see below + # defaultDrives.enable = false; + # extraDrives = [ + # { + # name = "boot"; + # drive = { + # device = "/dev/disk/by-label/BOOT"; + # fsType = "vfat"; + # options = [ "rw" "fmask=0022" "dmask=0022" "noatime" ]; + # }; + # } + # { + # name = ""; + # drive = { + # device = "/dev/disk/by-label/ROOT"; + # fsType = "ext4"; + # options = [ "noatime" "nodiratime" "discard" ]; + # }; + # } + # ]; + # You can also use disko to format your disks on installation. + # Please refer to the Documentation about the drives module for an example. }; }; } @@ -134,68 +162,78 @@ Here is a minimal required configuration.nix (the TODOs mention a required chang After logging in the first time, your password will be set to "firstlogin", please change this to whatever you like. -## Nixos and Home-manager Modules +## Configuring pkgs -You can add additional modules or remove all of them by overriding parameters to the buildSystems command: +While DashNix offers a default pkgs config, you may want to permit an unsecure packages, +add additional modules/inputs, or add an overlay to them. +You can configure both stable and unstable pkgs the following way: + +Please note that modules and inputs are merged together to ensure functionality. ```nix -nixosConfigurations = - let - additionalMods = { - nixos = [ - # your modules - ]; home = [ - # your modules - ]; - } - # passing this parameter will override the existing modules - mods = { - nixos = []; - home = []; - } - in - inputs.dashNix.dashNixLib.buildSystems { root = ./.; inherit mods additionalMods; }; +currentSystem = "x86_64-linux"; +permittedPackages = [ + "some package" +]; +config = { + system = currentSystem; + config = { + allowUnfree = true; + permittedInsecurePackages = permittedPackages; + }; + inputs = { + # Some inputs + } + mods = { + home = [ + # Some home manager module + ]; + nixos = [ + # Some nixos module + ]; +} +}; +unstableBundle = { + pkgs = inputs.unstable; + inherit config mods; +}; +inputs.dashNix.dashNixLib.buildSystems { + root = ./.; + inherit unstableBundle; +} ``` -## Additional Inputs - -Just like modules, you can add additional inputs to your configuration. - -```nix -nixosConfigurations = - let - additionalInputs = { - something.url = "yoururl" - } - in - inputs.dashNix.dashNixLib.buildSystems { root = ./.; inherit additionalInputs; }; -``` +With this you could also change your input to something different should you wish to do so. +Note that overriding inputs via the flake still works, +this way however ensures you can also configure the inputs. ## Stable/Unstable Sometimes you want to differentiate between systems that are stable and unstable, e.g. for servers and desktops/laptops. This can be done with the overridePkgs flag for the lib function: +(overridePkgs simply inverts the default bundle that is used for the nix standard library as well as NixOS itself) + ```nix - nixosConfigurations = - inputs.dashNix.dashNixLib.buildSystems { - root = ./stable; - inherit additionalInputs; - overridePkgs = true; - } - // inputs.dashNix.dashNixLib.buildSystems { - root = ./unstable; - inherit additionalInputs; - }; +nixosConfigurations = + inputs.dashNix.dashNixLib.buildSystems { + root = ./stable; + inherit stableBundle; + overridePkgs = true; + } + // inputs.dashNix.dashNixLib.buildSystems { + inherit unstableBundle; + root = ./unstable; + }; ``` You can now place your systems in the respective directories. Keep in mind that the hosts directory will still need to exist in each variant. E.g. stable/hosts/yourserver and unstable/hosts/yourdesktop -# Installation +# Installation via ISO -You can find a custom ISO on my NextCloud server: [Link](https://cloud.dashie.org/s/z7G3zS9SXeEt2ERD). +You can find a custom ISO in the releases: [Link](https://github.com/Xetibo/DashNix/releases). With this, you will receive the example config in /iso/example alongside the gnome desktop environment, as well as a few tools like gnome-disks, Neovim, Vscodium, a browser etc. @@ -214,19 +252,30 @@ Then configure as you please and choose a command below depending on your disk i Installation via manual configuration: ```sh -sudo nixos-install --flake # --root +sudo nixos-install --flake # --root --option experimental-features "nix-command flakes pipe-operators" #example -#nixos-install --flake ~/config#globi --root /mnt +#nixos-install --flake ~/config#globi --root /mnt --option experimental-features "nix-command flakes pipe-operators" ``` Installation via disko: ```sh -sudo disko-install --flake # --disk +sudo disko-install --flake # --disk --option experimental-features "nix-command flakes pipe-operators" #example -#disko-install -- --flake ~/config#globi --disk main /dev/nvme0n1 +#disko-install -- --flake ~/config#globi --disk main /dev/nvme0n1 --option experimental-features "nix-command flakes pipe-operators" ``` +# Installation via flake + +If you already have nix installed, you can instead just copy the default config onto your system and install DashNix with it. +To create the example config for a base to start with, you can just run this flake with the mkFlake command: + +```sh +nix run github:Xetibo/DashNix#mkFlake +``` + +This command will put the default configuration into $HOME/gits/nixos + # Modules This configuration features several modules that can be used as preconfigured "recipies". @@ -234,6 +283,7 @@ These modules attempt to combine the home-manager and nixos packages/options to For package lists, please check the individual modules, as the lists can be long. - Hyprland: Installs and configures Hyprland with various additional packages +- Niri: Installs and configures Niri with various additional packages - acpid : Enables the acpid daemon - base packages : A list of system packages to be installed by default - bluetooth : Configures/enables bluetooth and installs tools for bluetooth @@ -276,3 +326,4 @@ For package lists, please check the individual modules, as the lists can be long - [chermnyx](https://github.com/chermnyx) for providing a base for zen configuration - [voronind-com](https://github.com/voronind-com) for providing the darkreader configuration - [Nix-Artwork](https://github.com/NixOS/nixos-artwork/tree/master/logo) for the Nix/NixOS logo (Tim Cuthbertson (@timbertson)) +- [xddxdd](https://github.com/xddxdd) for the CachyOS-Kernel flake diff --git a/example/flake.nix b/example/flake.nix index 0d1e083..01ec944 100644 --- a/example/flake.nix +++ b/example/flake.nix @@ -31,7 +31,7 @@ "https://oxicalc.cachix.org" "https://hyprdock.cachix.org" "https://reset.cachix.org" - "https://chaotic-nyx.cachix.org/" + "https://dashvim.cachix.org" ]; extra-trusted-public-keys = [ @@ -45,7 +45,7 @@ "oxicalc.cachix.org-1:qF3krFc20tgSmtR/kt6Ku/T5QiG824z79qU5eRCSBTQ=" "hyprdock.cachix.org-1:HaROK3fBvFWIMHZau3Vq1TLwUoJE8yRbGLk0lEGzv3Y=" "reset.cachix.org-1:LfpnUUdG7QM/eOkN7NtA+3+4Ar/UBeYB+3WH+GjP9Xo=" - "chaotic-nyx.cachix.org-1:HfnXSw4pj95iI/n17rIDy40agHj12WfF+Gqk6SonIT8=" + "dashvim.cachix.org-1:uLRdxp1WOWHnsZZtu3SwUWZRsvC7SXo0Gyk3tIefuL0=" ]; }; } diff --git a/example/hosts/example/configuration.nix b/example/hosts/example/configuration.nix index 3567918..dbe8cd0 100644 --- a/example/hosts/example/configuration.nix +++ b/example/hosts/example/configuration.nix @@ -4,13 +4,13 @@ # variables for system conf = { # TODO your username - username = "YOURNAME"; + username = "exampleName"; # TODO only needed when you use intel -> amd is default # cpu = "intel"; # TODO your xkb layout - locale = "something.UTF-8"; + locale = "en_US.UTF-8"; # TODO your timezone - timezone = "CONTINENT/CITY"; + timezone = "Europe/Zurich"; }; # modules @@ -18,26 +18,20 @@ # default disk config has root home boot and swap partition, overwrite if you want something different sops.enable = false; nextcloud.enable = false; - hypr.hyprland = { - # TODO monitor configuration for hyprland (hyprland is default) - # should be something like DP-1 - defaultMonitor = "YOURMONITOR"; - # width x height @ refreshrate - defaultMonitorMode = "1920x1080@60"; - # scale for your main monitor - defaultMonitorScale = "1"; - # additional configruation can be done as well - # customConfig = { - # monitor = [ - # # default - # "${config.mods.hypr.hyprland.defaultMonitor},${config.mods.hypr.hyprland.defaultMonitorMode},0x0,${config.mods.hypr.hyprland.defaultMonitorScale}" - # # second example monitor - # "DP-2,3440x1440@180,auto,1" - # # all others - # ",highrr,auto,1" - # ]; + wm.monitors = [ + # Example + # { + # name = "DP-1"; + # resolutionX = 3440; + # resolutionY = 1440; + # refreshrate = 180; + # positionX = 2560; + # positionY = 0; + # scale = 1; + # transform = "0"; + # vrr = false; # } - }; + ]; gpu.nvidia.enable = true; kdeConnect.enable = true; # login manager: diff --git a/flake.nix b/flake.nix index 8536734..be1d5c2 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,7 @@ url = "github:nix-community/lanzaboote/v0.4.2"; inputs.nixpkgs.follows = "unstable"; }; - statix.url = "github:oppiliappan/statix"; + statix.url = "github:oppiliappan/statix?ref=master"; # Darkreader requires es20, hence a stable pin pkgsDarkreader.url = "github:NixOs/nixpkgs/nixos-24.11"; @@ -18,10 +18,11 @@ url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "unstable"; }; + cachy.url = "github:xddxdd/nix-cachyos-kernel?rev=bb7b8aa687464f24dcd452354d9621331d6b0737"; sops-nix.url = "github:Mic92/sops-nix"; - hyprland.url = "git+https://github.com/hyprwm/Hyprland?submodules=1"; + hyprland.url = "github:hyprwm/Hyprland"; ironbar = { url = "github:JakeStanger/ironbar"; @@ -42,62 +43,41 @@ oxipaste.url = "github:Xetibo/OxiPaste"; oxirun.url = "github:Xetibo/OxiRun"; dashvim.url = "github:Xetibo/DashVim"; - # For now until merged into Xetibo + hyprdock.url = "github:Xetibo/hyprdock"; reset.url = "github:Xetibo/ReSet"; reset-plugins.url = "github:Xetibo/ReSet-Plugins"; superfreq.url = "github:NotAShelf/superfreq"; - # absolute insanity - chaoticNyx.url = "github:chaotic-cx/nyx/nyxpkgs-unstable"; + compose.url = "github:garnix-io/nixos-compose"; }; outputs = {self, ...} @ inputs: let currentSystem = "x86_64-linux"; permittedPackages = [ "olm-3.2.16" - # well done dotnet... - # this is just for omnisharp - "dotnet-core-combined" - "dotnet-wrapped-combined" - "dotnet-combined" - "dotnet-sdk-6.0.428" - "dotnet-sdk-wrapped-6.0.428" - "dotnet-sdk-6.0.136" - "dotnet-sdk-wrapped-6.0.136" - "dotnet-sdk-7.0.120" - "dotnet-sdk-wrapped-7.0.120" - "dotnet-sdk-7.0.410" - "dotnet-sdk-wrapped-7.0.410" - "jitsi-meet-1.0.8043" - "nextcloud-27.1.11" ]; - stable = import ./lib/importPkgs.nix { - inherit inputs permittedPackages currentSystem; - pkgs = inputs.stable; - }; - unstable = import ./lib/importPkgs.nix { - inherit inputs permittedPackages currentSystem; - pkgs = inputs.unstable; - }; - pkgsDarkreader = import ./lib/importPkgs.nix { - inherit inputs permittedPackages currentSystem; - pkgs = inputs.pkgsDarkreader; - }; + importPkgsFn = import ./lib/importPkgs.nix; + defaultConfigureFn = pkgs: + importPkgsFn { + inherit inputs currentSystem permittedPackages pkgs; + }; + stable = defaultConfigureFn inputs.stable; + unstable = defaultConfigureFn inputs.unstable; + pkgsDarkreader = defaultConfigureFn inputs.pkgsDarkreader; in rec { dashNixLib = import ./lib { inherit self inputs unstable - stable + permittedPackages ; dashNixAdditionalProps = { inherit pkgsDarkreader; }; system = currentSystem; - inherit (inputs.unstable) lib; }; docs = import ./docs { inherit inputs; @@ -106,12 +86,28 @@ inherit (inputs.unstable) lib; inherit (dashNixLib) buildSystems; }; - lint = unstable.statix; + lint = inputs.statix.packages.${currentSystem}.default; format = unstable.alejandra; dashNixInputs = inputs; stablePkgs = stable; unstablePkgs = unstable; modules = ./modules; iso = dashNixLib.buildIso.config.system.build.isoImage; + nixosConfigurations = dashNixLib.buildSystems {root = ./example/.;}; + + mkFlake = stablePkgs.writeShellApplication { + name = "Create example config"; + text = + /* + bash + */ + '' + mkdir -p ~/gits/nixos + mkdir -p ~/gits/backup_nixos + + mv ~/gits/nixos/* ~/gits/backup_nixos/ + cp -r ${./example}/* ~/gits/nixos/ + ''; + }; }; } diff --git a/home/common.nix b/home/common.nix index 1a3ccf3..fe2fa53 100644 --- a/home/common.nix +++ b/home/common.nix @@ -2,6 +2,7 @@ mkDashDefault, config, lib, + pkgs, ... }: let username = config.conf.username; diff --git a/home/default.nix b/home/default.nix index ee4f804..afc0ab3 100644 --- a/home/default.nix +++ b/home/default.nix @@ -1,13 +1,11 @@ { mkDashDefault, - additionalHomeConfig, - additionalHomeMods, - additionalInputs, dashNixAdditionalProps, config, homeMods, inputs, lib, + additionalHomeConfig, mod, pkgs, root, @@ -42,7 +40,6 @@ inherit inputs root - additionalInputs alternativePkgs system stable @@ -62,9 +59,8 @@ ../lib/foxwrappers.nix ] ++ homeMods - ++ additionalHomeMods - ++ lib.optional (builtins.pathExists mod) mod - ++ lib.optional (builtins.pathExists additionalHomeConfig) additionalHomeConfig; + ++ lib.optional (builtins.pathExists additionalHomeConfig) additionalHomeConfig + ++ lib.optional (builtins.pathExists mod) mod; }; }; } diff --git a/iso/configuration.nix b/iso/configuration.nix index 8bfcc1e..9272a65 100644 --- a/iso/configuration.nix +++ b/iso/configuration.nix @@ -1,58 +1,77 @@ { pkgs, - lib, modulesPath, + lib, self, inputs, ... }: let system = "x86_64-linux"; in { - imports = ["${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"]; + imports = ["${modulesPath}/installer/cd-dvd/iso-image.nix"]; nixpkgs.hostPlatform = { inherit system; }; environment.systemPackages = with pkgs; [ - neovim + inputs.dashvim.packages.${system}.minimal disko git - vesktop - vscodium firefox kitty gnome-disk-utility inputs.disko.packages.${system}.disko-install ]; + networking = { wireless.enable = false; networkmanager.enable = true; }; + nix.settings.experimental-features = [ "nix-command" "flakes" "pipe-operators" ]; - # gnome is a good default that works with every gpu and doesn't require knowledge about custom keybinds. - services = { - xserver = { + users.users.nixos = { + isNormalUser = true; + password = "nixos"; + extraGroups = ["wheel"]; + }; + + image.baseName = lib.mkForce "DashNix"; + + programs = { + hyprland = { enable = true; - displayManager = { - gdm.enable = true; - }; - desktopManager = { - gnome.enable = true; - }; + withUWSM = true; + xwayland.enable = false; }; + uwsm.enable = true; + }; + + fonts.packages = [pkgs.adwaita-fonts]; + i18n.defaultLocale = "en_US.UTF-8"; + + services = { displayManager.autoLogin = { enable = true; user = "nixos"; }; + greetd = { + enable = true; + settings = { + terminal.vt = 1; + default_session = { + command = "${lib.getExe pkgs.hyprland}"; + user = "nixos"; + }; + }; + }; }; isoImage = { - isoName = lib.mkForce "DashNix.iso"; makeEfiBootable = true; makeUsbBootable = true; contents = [ @@ -62,4 +81,6 @@ in { } ]; }; + + system.stateVersion = "25.11"; } diff --git a/lib/default.nix b/lib/default.nix index 30d34ec..d8a7402 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,13 +1,188 @@ { inputs, - lib, unstable, self, - stable, system, + permittedPackages, dashNixAdditionalProps ? {}, ... -}: { +}: let + defaultConfig = { + config = { + allowUnfree = true; + permittedInsecurePackages = permittedPackages; + }; + overlays = [ + inputs.cachy.overlays.default + inputs.nur.overlays.default + ]; + inherit system; + }; + mkPkgs = { + pkgs, + config, + }: let + overlays = + if (config ? overlays) + then config.overlays + else []; + comnbinedConfig = config // {overlays = overlays ++ defaultConfig.overlays;}; + in + import pkgs comnbinedConfig; +in rec { + mkNixos = { + root, + inputLib, + lib, + stablePkgs, + unstablePkgs, + stableMods, + unstableMods, + overridePkgs, + ... + }: + builtins.listToAttrs ( + map + (name: { + inherit name; + value = let + mod = root + /hosts/${name}/configuration.nix; + additionalNixosConfig = root + /hosts/${name}/hardware.nix; + additionalHomeConfig = root + /hosts/${name}/home.nix; + args = { + inherit + self + inputs + mod + additionalHomeConfig + system + root + dashNixAdditionalProps + lib + ; + stable = stablePkgs; + unstable = unstablePkgs; + pkgs = lib.mkForce ( + if overridePkgs + then stablePkgs + else unstablePkgs + ); + alternativePkgs = + if overridePkgs + then unstablePkgs + else stablePkgs; + hostName = name; + homeMods = + if overridePkgs + then unstableMods.home + else stableMods.home; + mkDashDefault = import ./override.nix {inherit lib;}; + }; + nixosMods = + if overridePkgs + then unstableMods.nixos + else stableMods.nixos; + in + inputLib.nixosSystem { + modules = + [ + {_module.args = args;} + mod + ] + ++ nixosMods + ++ lib.optional (builtins.pathExists additionalNixosConfig) additionalNixosConfig + ++ lib.optional (builtins.pathExists mod) mod; + }; + }) + ( + lib.lists.remove "" ( + lib.attrsets.mapAttrsToList (name: fType: + if fType == "directory" + then name + else "") ( + builtins.readDir (root + /hosts) + ) + ) + ) + ); + + mkHome = { + root, + lib, + stablePkgs, + unstablePkgs, + stableMods, + unstableMods, + overridePkgs, + ... + }: + builtins.listToAttrs ( + map + (name: { + inherit name; + value = let + mod = root + /homes/${name}/configuration.nix; + additionalHomeConfig = root + /homes/${name}/home.nix; + args = { + inherit + self + inputs + mod + additionalHomeConfig + system + root + dashNixAdditionalProps + lib + ; + stable = stablePkgs; + unstable = unstablePkgs; + pkgs = lib.mkForce ( + if overridePkgs + then stablePkgs + else unstablePkgs + ); + alternativePkgs = + if overridePkgs + then unstablePkgs + else stablePkgs; + userName = name; + mkDashDefault = import ./override.nix {inherit lib;}; + }; + homeMods = + if overridePkgs + then unstableMods.home + else stableMods.home; + in + inputs.home-manager.lib.homeManagerConfiguration + { + inherit (args) pkgs; + modules = + [ + {_module.args = args;} + mod + ] + ++ homeMods + ++ [ + ../home/common.nix + ../home/themes + ../home/sync.nix + ./foxwrappers.nix + ] + ++ lib.optional (builtins.pathExists mod) mod; + }; + }) + ( + lib.lists.remove "" ( + lib.attrsets.mapAttrsToList (name: fType: + if fType == "directory" + then name + else "") ( + builtins.readDir (root + /homes) + ) + ) + ) + ); + /* * # buildSystems @@ -36,107 +211,75 @@ # ); # in - buildSystems = { + buildFunc = func: { root, - additionalMods ? { - nixos = []; - home = []; - }, - mods ? { - nixos = [ - inputs.lanzaboote.nixosModules.lanzaboote - inputs.nixos-wsl.nixosModules.default - inputs.home-manager.nixosModules.home-manager - inputs.stylix.nixosModules.stylix - inputs.disko.nixosModules.disko - inputs.superfreq.nixosModules.default - inputs.sops-nix.nixosModules.sops - ../base - ../home - ../modules - inputs.chaoticNyx.nixosModules.default - ]; - home = [ - inputs.anyrun.homeManagerModules.default - inputs.ironbar.homeManagerModules.default - inputs.oxicalc.homeManagerModules.default - inputs.oxishut.homeManagerModules.default - inputs.oxinoti.homeManagerModules.default - inputs.oxidash.homeManagerModules.default - inputs.oxipaste.homeManagerModules.default - inputs.oxirun.homeManagerModules.default - inputs.hyprdock.homeManagerModules.default - inputs.hyprland.homeManagerModules.default - inputs.reset.homeManagerModules.default - inputs.sops-nix.homeManagerModules.sops - inputs.dashvim.homeManagerModules.dashvim - inputs.chaoticNyx.homeManagerModules.default - ../modules - ]; - }, - additionalInputs ? {}, + unstableBundle ? {}, + stableBundle ? {}, overridePkgs ? false, ... - }: - builtins.listToAttrs ( - map - (name: { - inherit name; - value = let - mod = root + /hosts/${name}/configuration.nix; - additionalNixosConfig = root + /hosts/${name}/hardware.nix; - additionalHomeConfig = root + /hosts/${name}/home.nix; - args = { - inherit - self - inputs - mod - additionalHomeConfig - system - root - stable - unstable - additionalInputs - dashNixAdditionalProps - ; - pkgs = lib.mkForce ( - if overridePkgs - then stable - else unstable - ); - alternativePkgs = - if overridePkgs - then unstable - else stable; - hostName = name; - homeMods = mods.home; - additionalHomeMods = additionalMods.home; - mkDashDefault = import ./override.nix {inherit lib;}; - }; - in - inputs.unstable.lib.nixosSystem { - modules = - [ - {_module.args = args;} - mod - ] - ++ mods.nixos - ++ additionalMods.nixos - ++ inputs.unstable.lib.optional (builtins.pathExists additionalNixosConfig) additionalNixosConfig - ++ inputs.unstable.lib.optional (builtins.pathExists mod) mod; - }; - }) - ( - lib.lists.remove "" ( - lib.attrsets.mapAttrsToList (name: fType: - if fType == "directory" - then name - else "") ( - builtins.readDir (root + /hosts) - ) - ) - ) - ); + }: let + defaultNixosMods = inputs: [ + inputs.lanzaboote.nixosModules.lanzaboote + inputs.nixos-wsl.nixosModules.default + inputs.home-manager.nixosModules.home-manager + inputs.stylix.nixosModules.stylix + inputs.disko.nixosModules.disko + inputs.superfreq.nixosModules.default + inputs.sops-nix.nixosModules.sops + ../base + ../home + ../modules + ]; + + defaultHomeMods = inputs: [ + inputs.anyrun.homeManagerModules.default + inputs.ironbar.homeManagerModules.default + inputs.oxicalc.homeManagerModules.default + inputs.oxishut.homeManagerModules.default + inputs.oxinoti.homeManagerModules.default + inputs.oxidash.homeManagerModules.default + inputs.oxipaste.homeManagerModules.default + inputs.oxirun.homeManagerModules.default + inputs.hyprdock.homeManagerModules.default + inputs.hyprland.homeManagerModules.default + inputs.reset.homeManagerModules.default + inputs.sops-nix.homeManagerModules.sops + inputs.dashvim.homeManagerModules.dashvim + ../modules + ]; + + unstableInput = unstableBundle.pkgs or inputs.unstable; + stableInput = stableBundle.pkgs or inputs.stable; + unstableConfig = unstableBundle.config or defaultConfig; + stableConfig = stableBundle.config or defaultConfig; + unstableInputs = (unstableBundle.inputs or {}) // inputs; + stableInputs = (stableBundle.inputs or {}) // inputs; + unstableMods = { + home = (defaultHomeMods unstableInputs) ++ (unstableBundle.mods.home or []); + nixos = (defaultNixosMods unstableInputs) ++ (unstableBundle.mods.nixos or []); + }; + stableMods = { + home = (defaultHomeMods stableInputs) ++ (stableBundle.mods.home or []); + nixos = (defaultNixosMods stableInputs) ++ (stableBundle.mods.nixos or []); + }; + + unstablePkgs = mkPkgs { + pkgs = unstableInput; + config = unstableConfig; + }; + stablePkgs = mkPkgs { + pkgs = stableInput; + config = stableConfig; + }; + inputLib = unstableInput.lib; + inherit (unstablePkgs) lib; + in + func { + inherit lib inputLib stablePkgs unstablePkgs stableMods unstableMods stableInputs unstableInputs root overridePkgs; + }; + + buildSystems = buildFunc mkNixos; + buildHome = buildFunc mkHome; buildIso = inputs.unstable.lib.nixosSystem { specialArgs = { diff --git a/lib/importPkgs.nix b/lib/importPkgs.nix index 77e1299..cfcd413 100644 --- a/lib/importPkgs.nix +++ b/lib/importPkgs.nix @@ -12,6 +12,6 @@ import pkgs { }; overlays = [ inputs.nur.overlays.default - inputs.chaoticNyx.overlays.cache-friendly + inputs.cachy.overlays.default ]; } diff --git a/lib/wm.nix b/lib/wm.nix new file mode 100644 index 0000000..416956a --- /dev/null +++ b/lib/wm.nix @@ -0,0 +1,446 @@ +let + browserName = config: + if (builtins.isString config.mods.homePackages.browser) + then config.mods.homePackages.browser + else if config.mods.homePackages.browser ? meta && config.mods.homePackages.browser.meta ? mainProgram + then config.mods.homePackages.browser.meta.mainProgram + else config.mods.homePackages.browser.pname; + mkSimpleBind = modKeys: key: command: args: { + inherit modKeys key command args; + }; + mkRepeatSimpleBind = modKeys: key: command: args: { + inherit modKeys key command args; + meta.hyprland.repeat = true; + }; + mkSimpleCustomBind = modKeys: key: niri: hyprland: args: { + inherit modKeys key args; + command = { + inherit niri hyprland; + }; + }; + mkRepeatCustomBind = modKeys: key: niri: hyprland: args: { + inherit modKeys key args; + command = { + inherit niri hyprland; + }; + meta.hyprland.repeat = true; + }; + mkBindWithDesc = modKeys: key: command: args: desc: + { + meta.niri.desc = desc; + } + // mkSimpleBind modKeys key command args; +in { + defaultWindowRules = { + niri = [ + '' + match app-id=r#"^org\.keepassxc\.KeePassXC$"# + match app-id=r#"^org\.gnome\.World\.Secrets$"# + + block-out-from "screen-capture" + '' + '' + match app-id=r#"^steam$"# + open-on-workspace "0" + '' + '' + geometry-corner-radius 12 + clip-to-geometry true + '' + ]; + hyprland = [ + # window rules + "match:class OxiCalc, float on" + "match:class winecfg.exe, float on" + "match:class copyq, float on" + "match:class swappy, center on" + "match:class steam, workspace 10 silent" + ]; + }; + + defaultStartup = config: { + all = [ + "systemctl --user import-environment" + "dbus-update-activation-environment --systemd --all" + "hyprctl setcursor ${config.mods.stylix.cursor.name} ${toString config.mods.stylix.cursor.size}" + # ensures the systemd service knows what "hyprctl" is :) + ( + if config.mods.gaming.gamemode + then "systemctl try-restart gamemoded.service --user" + else "" + ) + + # other programs + "${browserName config}" + ( + if config.mods.oxi.hyprdock.enable + then "hyprdock --server" + else "" + ) + ( + if config.mods.hypr.hyprpaper.enable + then "hyprpaper" + else "" + ) + ( + if config.mods.hypr.hyprland.useIronbar + then "ironbar" + else "" + ) + ( + if config.mods.oxi.oxipaste.enable + then "oxipaste_daemon" + else "" + ) + ( + if config.mods.oxi.oxinoti.enable + then "oxinoti" + else "" + ) + ]; + niri = [ + "XDG_CURRENT_DESKTOP=Niri" + "XDG_SESSION_DESKTOP=Niri" + "XDG_SESSION_TYPE=wayland" + ]; + hyprland = [ + "XDG_CURRENT_DESKTOP=Hyprland" + "XDG_SESSION_DESKTOP=Hyprland" + "XDG_SESSION_TYPE=wayland" + ]; + }; + + defaultEnv = config: { + all = { + GTK_CSD = "0"; + TERM = "kitty /bin/fish"; + HYPRCURSOR_THEME = config.mods.stylix.cursor.name; + HYPRCURSOR_SIZE = toString config.mods.stylix.cursor.size; + XCURSOR_THEME = config.mods.stylix.cursor.name; + XCURSOR_SIZE = toString config.mods.stylix.cursor.size; + QT_QPA_PLATFORM = "wayland"; + QT_QPA_PLATFORMTHEME = "qt5ct"; + QT_WAYLAND_FORCE_DPI = "96"; + QT_AUTO_SCREEN_SCALE_FACTOR = "0"; + QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; + QT_SCALE_FACTOR = "1"; + EDITOR = "neovide --novsync --nofork"; + + LIBVA_DRIVER_NAME = + if config.mods.gpu.nvidia.enable + then "nvidia" + else ""; + GBM_BACKEND = + if config.mods.gpu.nvidia.enable + then "nvidia-drm" + else ""; + __GLX_VENDOR_LIBRARY_NAME = + if config.mods.gpu.nvidia.enable + then "nvidia" + else ""; + }; + niri = {}; + hyprland = {}; + }; + + defaultBinds = config: [ + (mkSimpleBind ["Mod"] "1" "focusWorkspace" ["1"]) + (mkSimpleBind ["Mod"] "2" "focusWorkspace" ["2"]) + (mkSimpleBind ["Mod"] "3" "focusWorkspace" ["3"]) + (mkSimpleBind ["Mod"] "4" "focusWorkspace" ["4"]) + (mkSimpleBind ["Mod"] "5" "focusWorkspace" ["5"]) + (mkSimpleBind ["Mod"] "6" "focusWorkspace" ["6"]) + (mkSimpleBind ["Mod"] "7" "focusWorkspace" ["7"]) + (mkSimpleBind ["Mod"] "8" "focusWorkspace" ["8"]) + (mkSimpleBind ["Mod"] "9" "focusWorkspace" ["9"]) + (mkSimpleBind ["Mod"] "0" "focusWorkspace" ["10"]) + (mkSimpleBind ["Mod" "Shift"] "1" "moveToWorkspace" ["1"]) + (mkSimpleBind ["Mod" "Shift"] "2" "moveToWorkspace" ["2"]) + (mkSimpleBind ["Mod" "Shift"] "3" "moveToWorkspace" ["3"]) + (mkSimpleBind ["Mod" "Shift"] "4" "moveToWorkspace" ["4"]) + (mkSimpleBind ["Mod" "Shift"] "5" "moveToWorkspace" ["5"]) + (mkSimpleBind ["Mod" "Shift"] "6" "moveToWorkspace" ["6"]) + (mkSimpleBind ["Mod" "Shift"] "7" "moveToWorkspace" ["7"]) + (mkSimpleBind ["Mod" "Shift"] "8" "moveToWorkspace" ["8"]) + (mkSimpleBind ["Mod" "Shift"] "9" "moveToWorkspace" ["9"]) + (mkSimpleBind ["Mod" "Shift"] "0" "moveToWorkspace" ["10"]) + (mkSimpleBind ["Mod"] "B" "toggleFullscreen" []) + (mkSimpleBind ["Mod"] "V" "toggleFloating" []) + (mkSimpleBind ["Mod" "Shift"] "M" "quit" []) + (mkSimpleBind ["Mod"] "Left" "moveWindowLeft" []) + (mkSimpleBind ["Mod"] "Down" "moveWindowDown" []) + (mkSimpleBind ["Mod"] "Up" "moveWindowUp" []) + (mkSimpleBind ["Mod"] "Right" "moveWindowRight" []) + + (mkRepeatSimpleBind ["Mod"] "J" "moveFocusLeft" []) + (mkRepeatSimpleBind ["Mod"] "K" "moveFocusDown" []) + (mkRepeatSimpleBind ["Mod"] "L" "moveFocusUp" []) + (mkRepeatSimpleBind ["Mod"] "semicolon" "moveFocusRight" []) + + (mkBindWithDesc ["Mod"] "Q" "killActive" [] "Kill active window") + + (mkBindWithDesc ["Mod"] "N" "spawn" ["neovide"] "Open Neovide") + (mkBindWithDesc ["Mod"] "T" "spawn-sh" ["kitty" "-1"] "Open Kitty") + (mkBindWithDesc ["Mod" "Shift"] "L" "spawn" ["hyprlock"] "Lock screen") + + ( + if config.mods.yazi.enable + then mkBindWithDesc ["Mod"] "E" "spawn-sh" ["EDITOR='neovide --no-fork' kitty yazi"] "Open Yazi" + else {} + ) + ( + if config.mods.anyrun.enable + then mkBindWithDesc ["Mod"] "R" "spawn" ["anyrun"] "Open Anyrun" + else {} + ) + ( + if config.mods.oxi.oxirun.enable + then mkBindWithDesc ["Mod"] "R" "spawn" ["oxirun"] "Open OxiRun" + else {} + ) + ( + if config.mods.oxi.oxidash.enable + then mkBindWithDesc ["Mod"] "M" "spawn" ["oxidash"] "Open OxiDash" + else {} + ) + ( + if config.mods.oxi.oxicalc.enable + then mkBindWithDesc ["Mod"] "G" "spawn" ["oxicalc"] "Open Oxicalc" + else {} + ) + ( + if config.mods.oxi.oxishut.enable + then mkBindWithDesc ["Mod"] "D" "spawn" ["oxishut"] "Open OxiShut" + else {} + ) + ( + if config.mods.oxi.oxipaste.enable + then mkBindWithDesc ["Mod"] "A" "spawn" ["oxipaste"] "Open Oxipaste" + else {} + ) + ( + if config.mods.oxi.hyprdock.enable + then mkBindWithDesc ["Mod" "Shift"] "P" "spawn" ["hyprdock --gui"] "Open Hyprdock" + else {} + ) + ( + if config.mods.hypr.hyprlock.enable + then mkBindWithDesc ["Mod" "Shift" "Alt"] "L" "spawn-sh" ["playerctl -a pause & hyprlock & systemctl suspend"] "Lock and suspend" + else {} + ) + ( + if config.mods.hypr.hyprlock.enable + then mkBindWithDesc ["Mod" "Shift" "Alt"] "K" "spawn-sh" ["playerctl -a pause & hyprlock & systemctl hibernate"] "Lock and hibernate" + else {} + ) + + (mkBindWithDesc ["Mod"] "F" "spawn" ["${browserName config}"] "Open Browser") + ( + if + ( + browserName config == "firefox" || browserName config == "zen" + ) + then mkBindWithDesc ["Mod" "Shift"] "F" "spawn" ["${browserName config} -p special"] "Open Browser Special Profile" + else {} + ) + + (mkBindWithDesc ["Mod"] "S" "spawn-sh" [''grim -g "$(slurp)" - | wl-copy''] "Take Screenshot") + (mkBindWithDesc ["Mod" "Shift"] "S" "spawn-sh" [''grim -g "$(slurp)" - | satty -f -''] "Take Screenshot and edit") + + ( + if config.mods.scripts.audioControl + then { + key = "XF86AudioMute"; + command = "spawn-sh"; + args = ["audioControl mute"]; + meta.niri = { + allowWhileLocked = true; + desc = "Mute Audio"; + }; + } + else {} + ) + ( + if config.mods.scripts.audioControl + then { + key = "XF86AudioRaiseVolume"; + command = "spawn-sh"; + args = ["audioControl +5%"]; + meta.niri = { + allowWhileLocked = true; + desc = "Raise Audio Volume"; + }; + } + else {} + ) + ( + if config.mods.scripts.audioControl + then { + key = "XF86AudioLowerVolume"; + command = "spawn-sh"; + args = ["audioControl -5%"]; + meta.niri = { + allowWhileLocked = true; + desc = "Lower Audio Volume"; + }; + } + else {} + ) + { + key = "XF86AudioPlay"; + command = "spawn-sh"; + args = ["playerctl play-pause"]; + meta.niri = { + allowWhileLocked = true; + desc = "Play/Pause"; + }; + } + { + key = "XF86AudioNext"; + command = "spawn-sh"; + args = ["playerctl next"]; + meta.niri = { + allowWhileLocked = true; + desc = "Next Song"; + }; + } + { + key = "XF86AudioPrev"; + command = "spawn-sh"; + args = ["playerctl previous"]; + meta.niri = { + allowWhileLocked = true; + desc = "Previous Song"; + }; + } + ( + if config.mods.scripts.changeBrightness + then { + key = "XF86MonBrightnessDown"; + command = "spawn-sh"; + args = ["changeBrightness -10%"]; + meta.niri = { + allowWhileLocked = true; + desc = "Lower Brigthness"; + }; + } + else {} + ) + ( + if config.mods.scripts.changeBrightness + then { + key = "XF86MonBrightnessUp"; + command = "spawn-sh"; + args = ["changeBrightness +10%"]; + meta.niri = { + allowWhileLocked = true; + desc = "Raise Brigthness"; + }; + } + else {} + ) + + # Niri only keybinds + (mkSimpleCustomBind ["Mod"] "BracketLeft" "consume-or-expel-window-left" null []) + (mkSimpleCustomBind ["Mod"] "BracketRight" "consume-or-expel-window-right" null []) + (mkSimpleCustomBind ["Mod"] "Comma" "consume-window-into-column" null []) + (mkSimpleCustomBind ["Mod"] "Period" "expel-window-from-column" null []) + (mkSimpleCustomBind ["Mod"] "Y" "switch-preset-column-width" null []) + (mkSimpleCustomBind ["Mod"] "Tab" "focus-workspace-previous" null []) + (mkSimpleCustomBind ["Mod" "Shift"] "V" "switch-focus-between-floating-and-tiling" null []) + (mkSimpleCustomBind ["Mod" "Shift"] "B" "expand-column-to-available-width" null []) + (mkSimpleCustomBind ["Mod"] "U" "set-column-width" null ["-10%"]) + (mkSimpleCustomBind ["Mod"] "P" "set-column-width" null ["+10%"]) + (mkSimpleCustomBind ["Mod"] "O" "set-column-width" null ["50%"]) + (mkSimpleCustomBind ["Mod" "Shift"] "Minus" "set-window-height" null ["-10%"]) + (mkSimpleCustomBind ["Mod" "Shift"] "Equal" "set-window-height" null ["+10%"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "1" "move-column-to-workspace" null ["1"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "2" "move-column-to-workspace" null ["2"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "3" "move-column-to-workspace" null ["3"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "4" "move-column-to-workspace" null ["4"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "5" "move-column-to-workspace" null ["5"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "6" "move-column-to-workspace" null ["6"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "7" "move-column-to-workspace" null ["7"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "8" "move-column-to-workspace" null ["8"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "9" "move-column-to-workspace" null ["9"]) + (mkSimpleCustomBind ["Mod" "Ctrl"] "0" "move-column-to-workspace" null ["10"]) + (mkSimpleCustomBind ["Mod" "Shift"] "J" "focus-monitor-left" null []) + (mkSimpleCustomBind ["Mod" "Shift"] "semicolon" "focus-monitor-right" null []) + (mkSimpleCustomBind ["Mod" "Ctrl"] "J" "move-column-to-monitor-left" null []) + (mkSimpleCustomBind ["Mod" "Ctrl"] "semicolon" "move-column-to-monitor-right" null []) + (mkSimpleCustomBind ["Mod" "Shift"] "Slash" "show-hotkey-overlay" null []) + { + modKeys = ["Mod"]; + key = "W"; + command.niri = "toggle-overview"; + meta.niri = { + desc = "Overview"; + repeat = false; + }; + } + { + modKeys = ["Mod"]; + key = "Escape"; + command.niri = "toggle-keyboard-shortcuts-inhibit"; + meta.niri = { + allowInhibit = false; + }; + } + { + modKeys = ["Mod"]; + key = "WheelScrollUp"; + command.niri = "focus-workspace-up"; + meta.niri.cooldown = 150; + } + { + modKeys = ["Mod"]; + key = "WheelScrollDown"; + command.niri = "focus-workspace-down"; + meta.niri.cooldown = 150; + } + { + modKeys = ["Mod"]; + key = "WheelScrollRight"; + command.niri = "focus-column-right"; + meta.niri.cooldown = 150; + } + { + modKeys = ["Mod"]; + key = "WheelScrollLeft"; + command.niri = "focus-column-left"; + meta.niri.cooldown = 150; + } + + # Hyprland only keybinds + (mkSimpleCustomBind ["Mod"] "C" null "togglesplit" []) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "1" null "movetoworkspacesilent" ["1"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "2" null "movetoworkspacesilent" ["2"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "3" null "movetoworkspacesilent" ["3"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "4" null "movetoworkspacesilent" ["4"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "5" null "movetoworkspacesilent" ["5"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "6" null "movetoworkspacesilent" ["6"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "7" null "movetoworkspacesilent" ["7"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "8" null "movetoworkspacesilent" ["8"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "9" null "movetoworkspacesilent" ["9"]) + (mkSimpleCustomBind ["Mod" "SHIFT" "ALT"] "0" null "movetoworkspacesilent" ["10"]) + (mkRepeatCustomBind ["Mod"] "U" null "resizeactive" ["-20" "0"]) + (mkRepeatCustomBind ["Mod"] "P" null "resizeactive" ["20" "0"]) + (mkRepeatCustomBind ["Mod"] "O" null "resizeactive" ["0" "-20"]) + (mkRepeatCustomBind ["Mod"] "I" null "resizeactive" ["0" "20"]) + (mkSimpleCustomBind ["Mod" "ALT"] "J" null "layoutmsg" ["preselect" "l"]) + (mkSimpleCustomBind ["Mod" "ALT"] "K" null "layoutmsg" ["preselect" "d"]) + (mkSimpleCustomBind ["Mod" "ALT"] "L" null "layoutmsg" ["preselect" "u"]) + (mkSimpleCustomBind ["Mod" "ALT"] "semicolon" null "layoutmsg" ["preselect" "r"]) + (mkSimpleCustomBind ["Mod" "ALT"] "H" null "layoutmsg" ["preselect" "n"]) + ( + if config.mods.hypr.hyprland.hyprspaceEnable + then { + modKeys = ["Mod"]; + key = "W"; + command.hyprland = "overview:toggle"; + args = []; + } + else {} + ) + ]; +} diff --git a/modules/programs/basePackages.nix b/modules/programs/basePackages.nix index fa10da8..1d1b2b9 100644 --- a/modules/programs/basePackages.nix +++ b/modules/programs/basePackages.nix @@ -87,7 +87,6 @@ if config.mods.basePackages.enable then { - preload.enable = mkDashDefault true; upower.enable = mkDashDefault true; dbus = { enable = mkDashDefault true; diff --git a/modules/programs/browser/zen.nix b/modules/programs/browser/zen.nix index d3a9b0a..db32900 100644 --- a/modules/programs/browser/zen.nix +++ b/modules/programs/browser/zen.nix @@ -121,7 +121,7 @@ in { }; }; config = lib.mkIf (config.mods.browser.zen.enable || config.mods.homePackages.browser == "zen") ( - lib.optionalAttrs (options ? home.packages) { + (lib.optionalAttrs (options ? home.packages) { programs.zen-browser = { enable = true; package = @@ -149,7 +149,9 @@ in { }; profiles = builtins.listToAttrs config.mods.browser.zen.profiles; }; + }) + // (lib.optionalAttrs (options ? stylix.targets.zen-browser) { stylix.targets.zen-browser.profileNames = lib.map (profile: profile.name) config.mods.browser.zen.profiles; - } + }) ); } diff --git a/modules/programs/clam.nix b/modules/programs/clam.nix new file mode 100644 index 0000000..e212529 --- /dev/null +++ b/modules/programs/clam.nix @@ -0,0 +1,60 @@ +{ + lib, + config, + options, + pkgs, + ... +}: { + options.mods.clam = { + enable = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = "Enables the clamav program and its daemon"; + }; + scanner = { + enable = lib.mkOption { + default = false; + example = true; + type = lib.types.bool; + description = "Enables the clamav scanner"; + }; + interval = lib.mkOption { + type = lib.types.str; + default = "*-*-* 04:00:00"; + description = '' + How often clamdscan is invoked. + By default this runs using 10 cores at most, be sure to run it at a time of low traffic. + ''; + }; + scanDirectories = lib.mkOption { + type = with lib.types; listOf str; + default = [ + "/home" + "/var/lib" + "/tmp" + "/etc" + "/var/tmp" + ]; + description = ''List of directories to scan''; + }; + }; + }; + config = lib.mkIf config.mods.clam.enable ( + lib.optionalAttrs (options ? services.clamav) { + services.clamav = { + daemon.enable = true; + updater.enable = true; + scanner = { + inherit (config.mods.clam.scanner) enable; + inherit (config.mods.clam.scanner) interval; + inherit (config.mods.clam.scanner) scanDirectories; + }; + }; + environment.systemPackages = [ + pkgs.clamav + ]; + } + // lib.optionalAttrs (options ? home.packages) {home.packages = with pkgs; [clamtk];} + ); +} diff --git a/modules/programs/coding.nix b/modules/programs/coding.nix index 7c79fa9..5a22205 100644 --- a/modules/programs/coding.nix +++ b/modules/programs/coding.nix @@ -4,6 +4,8 @@ config, pkgs, options, + inputs, + system, ... }: let font_family = "${config.mods.stylix.fonts.monospace.name}"; @@ -511,6 +513,7 @@ in { d-spy tmux tmate + inputs.compose.packages.${system}.default ]; in lib.mkIf config.mods.coding.enable ( diff --git a/modules/programs/default.nix b/modules/programs/default.nix index ebc1ff4..08a4a2d 100644 --- a/modules/programs/default.nix +++ b/modules/programs/default.nix @@ -5,6 +5,7 @@ ./basePackages.nix ./bluetooth.nix ./browser + ./clam.nix ./coding.nix ./containers.nix ./drives.nix @@ -30,6 +31,7 @@ ./mime.nix ./ncspot.nix ./nextcloud.nix + ./niri.nix ./onedrive.nix ./oxi ./piper.nix @@ -46,6 +48,7 @@ ./sway.nix ./teams.nix ./virtmanager.nix + ./wm.nix ./xkb.nix ./xone.nix ./yazi diff --git a/modules/programs/fastfetch.nix b/modules/programs/fastfetch.nix index f73b2cd..9953d84 100644 --- a/modules/programs/fastfetch.nix +++ b/modules/programs/fastfetch.nix @@ -1,5 +1,4 @@ { - mkDashDefault, pkgs, lib, options, diff --git a/modules/programs/fish.nix b/modules/programs/fish.nix index 2f18036..1d8c8c8 100644 --- a/modules/programs/fish.nix +++ b/modules/programs/fish.nix @@ -56,6 +56,7 @@ in { abbr --add ls 'lsd' abbr --add :q 'exit' abbr --add gh 'git push origin' + abbr --add gu 'git push upstream' abbr --add gl 'git pull origin' abbr --add gm 'git commit -m' abbr --add ga "git add -A" @@ -69,7 +70,7 @@ in { abbr --add cat 'bat' abbr --add find 'fd' abbr --add rm 'rip' - abbr --add cp 'fcp' + abbr --add cp 'cpz' abbr --add cd 'z' abbr --add y 'yazi' diff --git a/modules/programs/gaming.nix b/modules/programs/gaming.nix index 0b2e228..6c3eb0a 100644 --- a/modules/programs/gaming.nix +++ b/modules/programs/gaming.nix @@ -19,7 +19,8 @@ gamescope gamemode steam - lutris + # TODO broken + # lutris wineWowPackages.stable adwsteamgtk heroic @@ -33,10 +34,14 @@ description = "Install gaming related packages"; }; kernel = lib.mkOption { - default = true; - example = false; + default = false; + example = true; type = lib.types.bool; - description = "Whether to use the CachyOS kernel"; + description = '' + Whether to use the CachyOS kernel. + WARNING: This is a manual compiled kernel! + (Please also ensure you use your own input hash for the source as the compilation can often fail due to temporary broken changes.) + ''; }; steam = lib.mkOption { default = true; @@ -74,19 +79,50 @@ type = lib.types.int; description = "Your gpu device.(Physical id of lshw)"; }; + scheduler = lib.mkOption { + default = "scx_rustland"; + example = "scx_rusty"; + type = with lib.types; + nullOr (enum [ + "scx_bpfland" + "scx_chaos" + "scx_cosmos" + "scx_central" + "scx_flash" + "scx_flatcg" + "scx_lavd" + "scx_layered" + "scx_mitosis" + "scx_nest" + "scx_p2dq" + "scx_pair" + "scx_prev" + "scx_qmap" + "scx_rlfifo" + "scx_rustland" + "scx_rusty" + "scx_sdt" + "scx_simple" + "scx_tickless" + "scx_userland" + "scx_wd40" + ]); + description = "Scheduler to use, null disables this"; + }; }; config = lib.mkIf config.mods.gaming.enable ( lib.optionalAttrs (options ? environment.systemPackages) { environment.systemPackages = config.mods.gaming.tools; - boot.kernelPackages = lib.mkForce pkgs.linuxPackages_cachyos; - # TODO Re-enable when fixed - #services.scx.enable = true; + boot.kernelPackages = lib.mkForce pkgs.cachyosKernels.linuxPackages-cachyos-latest; + services.scx = lib.mkIf (config.mods.gaming.scheduler != null) { + enable = true; + inherit (config.mods.gaming) scheduler; + }; programs = { steam.enable = mkDashDefault config.mods.gaming.steam; gamemode.enable = true; gamemode = { - enableRenice = mkDashDefault true; settings = { general = { desiredgov = mkDashDefault "performance"; diff --git a/modules/programs/git.nix b/modules/programs/git.nix index bfcb334..57c1623 100644 --- a/modules/programs/git.nix +++ b/modules/programs/git.nix @@ -50,9 +50,14 @@ config = lib.optionalAttrs (options ? programs.git && options ? home.file) { programs.git = { enable = true; - userName = config.mods.git.username; - userEmail = config.mods.git.email; - extraConfig = config.mods.git.additionalConfig; + settings = + { + user = { + name = config.mods.git.username; + inherit (config.mods.git) email; + }; + } + // config.mods.git.additionalConfig; }; home.file.".ssh/config".text = config.mods.git.sshConfig; }; diff --git a/modules/programs/gpu.nix b/modules/programs/gpu.nix index 8fd8959..023b462 100644 --- a/modules/programs/gpu.nix +++ b/modules/programs/gpu.nix @@ -87,12 +87,11 @@ pkgs.intel-media-driver) (lib.mkIf config.mods.gpu.vapi.enable pkgs.libvdpau-va-gl) (lib.mkIf config.mods.gpu.vapi.enable pkgs.libva) - (lib.mkIf config.mods.gpu.vapi.enable pkgs.vaapiVdpau) + (lib.mkIf config.mods.gpu.vapi.enable pkgs.libva-vdpau-driver) (lib.mkIf (config.mods.gpu.intelgpu.enable || config.mods.gpu.amdgpu.enable) pkgs.mesa) ]; rocmPackages = [ - # TODO broken - #pkgs.rocmPackages.clr.icd + pkgs.rocmPackages.clr.icd pkgs.mesa pkgs.mesa.opencl pkgs.vulkan-loader diff --git a/modules/programs/greetd.nix b/modules/programs/greetd.nix index d632b6f..fe3e455 100644 --- a/modules/programs/greetd.nix +++ b/modules/programs/greetd.nix @@ -5,6 +5,7 @@ inputs, pkgs, options, + system, ... }: { options.mods = { @@ -18,7 +19,10 @@ ''; }; monitor = lib.mkOption { - default = "${config.mods.hypr.hyprland.defaultMonitor}"; + default = + if config.mods.wm.monitors != [] + then (builtins.elemAt config.mods.wm.monitors 0).name + else ""; example = "eDP-1"; type = lib.types.str; description = '' @@ -27,7 +31,10 @@ ''; }; scale = lib.mkOption { - default = "${config.mods.hypr.hyprland.defaultMonitorScale}"; + default = + if config.mods.wm.monitors != [] + then builtins.toString (builtins.elemAt config.mods.wm.monitors 0).scale + else ""; example = "1.5"; type = lib.types.str; description = '' @@ -37,16 +44,23 @@ }; greeterCommand = lib.mkOption { default = "${ - lib.getExe pkgs.hyprland + lib.getExe inputs.hyprland.packages.${system}.hyprland } --config /etc/greetd/hyprgreet.conf"; example = "${ lib.getExe pkgs.cage - } -s -- ${lib.getExe pkgs.greetd.regreet}"; + } -s -- ${lib.getExe pkgs.regreet}"; type = lib.types.str; description = "The compositor/greeter command to run"; }; resolution = lib.mkOption { - default = "${config.mods.hypr.hyprland.defaultMonitorMode}"; + default = + if config.mods.wm.monitors != [] + then let + resX = builtins.toString (builtins.elemAt config.mods.wm.monitors 0).resolutionX; + resY = builtins.toString (builtins.elemAt config.mods.wm.monitors 0).resolutionY; + refresh = builtins.toString (builtins.elemAt config.mods.wm.monitors 0).refreshrate; + in "${resX}x${resY}@${refresh}" + else ""; example = "3440x1440@180"; type = lib.types.str; description = '' @@ -55,12 +69,13 @@ }; environments = lib.mkOption { default = [ - inputs.hyprland.packages.${config.conf.system}.hyprland + (lib.mkIf config.mods.hypr.hyprland.enable inputs.hyprland.packages.${config.conf.system}.hyprland) + (lib.mkIf config.mods.niri.enable pkgs.niri) ]; # no idea if these are written correctly example = [ pkgs.niri - pkgs.river + pkgs.river-classic pkgs.swayfx ]; type = with lib.types; listOf package; @@ -82,7 +97,7 @@ }; config = let - username = config.conf.username; + inherit (config.conf) username; in lib.mkIf config.mods.greetd.enable ( lib.optionalAttrs (options ? environment) { @@ -116,6 +131,8 @@ misc { disable_splash_rendering = false disable_hyprland_logo = true + disable_xdg_env_checks = true + disable_scale_notification = true } env=STATE_DIR,var/cache/regreet diff --git a/modules/programs/homePackages.nix b/modules/programs/homePackages.nix index eabd176..6a995f0 100644 --- a/modules/programs/homePackages.nix +++ b/modules/programs/homePackages.nix @@ -102,11 +102,11 @@ (lib.mkIf config.mods.homePackages.orcaSlicer orca-slicer) (lib.mkIf config.mods.homePackages.vesktop vesktop) (lib.mkIf config.mods.homePackages.nextcloudClient nextcloud-client) - (lib.mkIf (!isNull config.mods.homePackages.matrixClient) config.mods.homePackages.matrixClient) - (lib.mkIf (!isNull config.mods.homePackages.mailClient) config.mods.homePackages.mailClient) + (lib.mkIf (config.mods.homePackages.matrixClient != null) config.mods.homePackages.matrixClient) + (lib.mkIf (config.mods.homePackages.mailClient != null) config.mods.homePackages.mailClient) (lib.mkIf ( # NOTE: This should be package, but nix doesn't have that.... - builtins.isAttrs config.mods.homePackages.browser && !isNull config.mods.homePackages.browser + builtins.isAttrs config.mods.homePackages.browser && config.mods.homePackages.browser != null ) config.mods.homePackages.browser) adw-gtk3 @@ -128,11 +128,11 @@ nh nix-index playerctl - poppler_utils + poppler-utils pulseaudio libsForQt5.qt5ct - qt6ct - fcp + qt6Packages.qt6ct + fuc ripgrep rm-improved system-config-printer diff --git a/modules/programs/hypr/hyprland.nix b/modules/programs/hypr/hyprland.nix index cc79adf..442b964 100644 --- a/modules/programs/hypr/hyprland.nix +++ b/modules/programs/hypr/hyprland.nix @@ -6,12 +6,7 @@ pkgs, ... }: let - browserName = - if (builtins.isString config.mods.homePackages.browser) - then config.mods.homePackages.browser - else if config.mods.homePackages.browser ? meta && config.mods.homePackages.browser.meta ? mainProgram - then config.mods.homePackages.browser.meta.mainProgram - else config.mods.homePackages.browser.pname; + defaultWmConf = import ../../../lib/wm.nix; in { options.mods.hypr.hyprland = { enable = lib.mkOption { @@ -22,64 +17,12 @@ in { Enable Hyprland ''; }; - defaultMonitor = lib.mkOption { - default = ""; - example = "eDP-1"; - type = lib.types.str; - description = '' - main monitor - ''; - }; - defaultMonitorMode = lib.mkOption { - default = ""; - example = "3440x1440@180"; - type = lib.types.str; - description = '' - main monitor mode: width x height @ refreshrate - ''; - }; - defaultMonitorScale = lib.mkOption { - default = "1"; - example = "1.5"; - type = lib.types.str; - description = '' - main monitor scaling - ''; - }; - monitor = lib.mkOption { - default = [ - # main monitor - "${config.mods.hypr.hyprland.defaultMonitor},${config.mods.hypr.hyprland.defaultMonitorMode},0x0,${config.mods.hypr.hyprland.defaultMonitorScale}" - # all others - ]; - example = ["DP-1,3440x1440@180,2560x0,1,vrr,0"]; - type = with lib.types; listOf str; - description = '' - The monitor configuration for hyprland. - ''; - }; - workspace = lib.mkOption { - default = []; - example = ["2,monitor:DP-1, default:true"]; - type = with lib.types; listOf str; - description = '' - The workspace configuration for hyprland. - ''; - }; noAtomic = lib.mkOption { default = false; example = true; type = lib.types.bool; description = '' - Use tearing - ''; - }; - extraAutostart = lib.mkOption { - default = []; - example = ["your application"]; - type = lib.types.listOf lib.types.str; - description = '' - Extra exec_once. + Use tearing (Warning, can be buggy) ''; }; useIronbar = lib.mkOption { @@ -90,14 +33,6 @@ in { Whether to use ironbar in hyprland. ''; }; - ironbarSingleMonitor = lib.mkOption { - default = true; - example = false; - type = lib.types.bool; - description = '' - Whether to use ironbar on a single monitor. - ''; - }; useDefaultConfig = lib.mkOption { default = true; example = false; @@ -160,9 +95,152 @@ in { hyprpicker ]; - wayland.windowManager.hyprland = { + wayland.windowManager.hyprland = let + mkWorkspace = workspaces: + builtins.map (workspace: let + default = + if workspace.default + then ",default:true" + else ""; + in "${workspace.name},monitor:${workspace.monitor}${default}") + workspaces; + mkTransform = transform: + if transform == "0" + then 0 + else if transform == "90" + then 1 + else if transform == "180" + then 2 + else if transform == "270" + then 3 + else 4; + mkVrr = vrr: + if vrr + then "1" + else "0"; + mkMonitors = monitors: + builtins.map ( + monitor: "${monitor.name},${builtins.toString monitor.resolutionX}x${builtins.toString monitor.resolutionY}@${builtins.toString monitor.refreshrate},${builtins.toString monitor.positionX}x${builtins.toString monitor.positionY},${builtins.toString monitor.scale}, transform,${builtins.toString (mkTransform monitor.transform)}, vrr,${mkVrr monitor.vrr}" + ) + monitors; + + mkMods = bind: let + mods = bind.modKeys or []; + in + builtins.map (mod: + if mod == "Mod" + then (lib.strings.toUpper config.mods.wm.modKey) + " " + else lib.strings.toUpper mod) + mods + |> lib.strings.concatStringsSep ""; + mkArgs = args: + if args != [] + then (lib.strings.concatStringsSep " " args) + else ""; + shouldRepeat = bind: bind ? meta && bind.meta ? hyprland && bind.meta.hyprland ? repeat && bind.meta.hyprland.repeat == true; + + defaultBinds = cfg: + if cfg.mods.wm.useDefaultBinds + then defaultWmConf.defaultBinds cfg + else []; + + mkEBinds = cfg: let + binds = cfg.mods.wm.binds ++ defaultBinds cfg; + in + binds + |> builtins.filter (bind: bind ? command && shouldRepeat bind && !(hasInvalidCustomCommand bind)) + |> builtins.map ( + bind: "${mkMods bind},${bind.key},${mkCommand bind}" + ); + mkBinds = cfg: let + binds = cfg.mods.wm.binds ++ defaultBinds cfg; + in + binds + |> builtins.filter (bind: bind ? command && !(shouldRepeat bind) && !(hasInvalidCustomCommand bind)) + |> builtins.map ( + bind: "${mkMods bind},${bind.key},${mkCommand bind}" + ); + mkCommand = bind: let + args = bind.args or []; + in + if bind.command == "quit" + then "exit" + else if bind.command == "killActive" + then "killactive" + else if bind.command == "moveWindowRight" + then "movewindow,r" + else if bind.command == "moveWindowDown" + then "movewindow,d" + else if bind.command == "moveWindowLeft" + then "movewindow,l" + else if bind.command == "moveWindowUp" + then "movewindow,u" + else if bind.command == "moveFocusUp" + then "movefocus,u" + else if bind.command == "moveFocusRight" + then "movefocus,r" + else if bind.command == "moveFocusDown" + then "movefocus,d" + else if bind.command == "moveFocusLeft" + then "movefocus,l" + else if bind.command == "toggleFloating" + then "togglefloating" + else if bind.command == "toggleFullscreen" + then "fullscreen" + else if bind.command == "focusWorkspace" + then "workspace" + "," + mkArgs args + else if bind.command == "moveToWorkspace" + then "movetoworkspace" + "," + mkArgs args + else if bind.command == "spawn" + then "exec" + "," + mkArgs args + else if bind.command == "spawn-sh" + then "exec" + "," + mkArgs args + else bind.command.hyprland + "," + mkArgs args; + hasInvalidCustomCommand = bind: !(builtins.isString bind.command) && bind.command.hyprland or null == null; + + mkEnv = config: let + defaultEnv = + if config.mods.wm.useDefaultEnv + then defaultWmConf.defaultEnv config + else { + all = {}; + hyprland = {}; + }; + userEnv = + if config.mods.wm.env ? all + then config.mods.wm.env.all // config.mods.wm.env.hyprland + else config.mods.wm.env; + env = userEnv // defaultEnv.all // defaultEnv.hyprland; + in + lib.attrsets.mapAttrsToList ( + name: value: "${name},${value}" + ) + env; + mkAutoStart = config: let + defaultStartup = + if config.mods.wm.useDefaultStartup + then defaultWmConf.defaultStartup config + else { + all = []; + hyprland = []; + }; + userStartup = + if config.mods.wm.startup ? all + then config.mods.wm.startup.all ++ config.mods.wm.startup.hyprland + else config.mods.wm.startup; + autoStart = userStartup ++ defaultStartup.all ++ defaultStartup.hyprland; + in + autoStart; + mkWindowRule = config: let + defaultWindowRules = + if config.mods.wm.useDefaultWindowRules + then defaultWmConf.defaultWindowRules.hyprland + else []; + in + # defaultWindowRules ++ config.mods.wm.windowRules.hyprland; + defaultWindowRules; + in { enable = true; - package = mkDashDefault pkgs.hyprland; plugins = [ (lib.mkIf config.mods.hypr.hyprland.hyprspaceEnable pkgs.hyprlandPlugins.hyprspace) @@ -174,124 +252,13 @@ in { lib.mkMerge [ { - "$mod" = mkDashDefault "SUPER"; + "$mod" = mkDashDefault config.mods.wm.modKey; bindm = [ "$mod, mouse:272, movewindow" "$mod, mouse:273, resizeactive" ]; - bind = [ - # screenshots - ''$mod SUPER,S,exec,grim -g "$(slurp)" - | wl-copy'' - ''$mod SUPERSHIFT,S,exec,grim -g "$(slurp)" - | satty -f -'' - - # regular programs - "$mod SUPER,F,exec,${browserName}" - (lib.mkIf ( - browserName == "firefox" || browserName == "zen" - ) "$mod SUPERSHIFT,F,exec,${browserName} -p special") - "$mod SUPER,T,exec,kitty -1" - "$mod SUPER,E,exec,nautilus -w" - (lib.mkIf config.mods.yazi.enable "$mod SUPER,Y,exec, EDITOR='neovide --no-fork' kitty yazi") - "$mod SUPER,N,exec,neovide" - (lib.mkIf config.mods.anyrun.enable "$mod SUPER,R,exec,anyrun") - (lib.mkIf config.mods.oxi.oxirun.enable "$mod SUPER,R,exec,oxirun") - (lib.mkIf config.mods.oxi.oxidash.enable "$mod SUPER,M,exec,oxidash") - (lib.mkIf config.mods.oxi.oxicalc.enable "$mod SUPER,G,exec,oxicalc") - (lib.mkIf config.mods.oxi.oxishut.enable "$mod SUPER,D,exec,oxishut") - (lib.mkIf config.mods.oxi.oxipaste.enable "$mod SUPER,A,exec,oxipaste") - (lib.mkIf config.mods.oxi.hyprdock.enable "$mod SUPERSHIFT,P,exec,hyprdock --gui") - (lib.mkIf config.mods.hypr.hyprlock.enable "$mod SUPERSHIFT,L,exec, playerctl -a pause & hyprlock & systemctl suspend") - (lib.mkIf config.mods.hypr.hyprlock.enable "$mod SUPERSHIFT,K,exec, playerctl -a pause & hyprlock & systemctl hibernate") - - # media keys - (lib.mkIf config.mods.scripts.audioControl ",XF86AudioMute,exec, audioControl mute") - (lib.mkIf config.mods.scripts.audioControl ",XF86AudioLowerVolume,exec, audioControl sink -5%") - (lib.mkIf config.mods.scripts.audioControl ",XF86AudioRaiseVolume,exec, audioControl sink +5%") - ",XF86AudioPlay,exec, playerctl play-pause" - ",XF86AudioNext,exec, playerctl next" - ",XF86AudioPrev,exec, playerctl previous" - (lib.mkIf config.mods.scripts.changeBrightness ",XF86MonBrightnessDown,exec, changeBrightness 10%-") - (lib.mkIf config.mods.scripts.changeBrightness ",XF86MonBrightnessUp,exec, changeBrightness +10%") - - # hyprland keybinds - # misc - "$mod SUPER,V,togglefloating," - "$mod SUPER,B,fullscreen," - "$mod SUPER,C,togglesplit" - "$mod SUPER,Q,killactive," - "$mod SUPERSHIFTALT,M,exit," - "$mod SUPERSHIFT,W,togglespecialworkspace" - - # move - "$mod SUPER,left,movewindow,l" - "$mod SUPER,right,movewindow,r" - "$mod SUPER,up,movewindow,u" - "$mod SUPER,down,movewindow,d" - - # workspaces - "$mod SUPER,1,workspace,1" - "$mod SUPER,2,workspace,2" - "$mod SUPER,3,workspace,3" - "$mod SUPER,4,workspace,4" - "$mod SUPER,5,workspace,5" - "$mod SUPER,6,workspace,6" - "$mod SUPER,7,workspace,7" - "$mod SUPER,8,workspace,8" - "$mod SUPER,9,workspace,9" - "$mod SUPER,0,workspace,10" - - # move to workspace - "$mod SUPERSHIFT,1,movetoworkspace,1" - "$mod SUPERSHIFT,2,movetoworkspace,2" - "$mod SUPERSHIFT,3,movetoworkspace,3" - "$mod SUPERSHIFT,4,movetoworkspace,4" - "$mod SUPERSHIFT,5,movetoworkspace,5" - "$mod SUPERSHIFT,6,movetoworkspace,6" - "$mod SUPERSHIFT,7,movetoworkspace,7" - "$mod SUPERSHIFT,8,movetoworkspace,8" - "$mod SUPERSHIFT,9,movetoworkspace,9" - "$mod SUPERSHIFT,0,movetoworkspace,10" - - # move to workspace silent - "$mod SUPERSHIFTALT,1,movetoworkspacesilent,1" - "$mod SUPERSHIFTALT,2,movetoworkspacesilent,2" - "$mod SUPERSHIFTALT,3,movetoworkspacesilent,3" - "$mod SUPERSHIFTALT,4,movetoworkspacesilent,4" - "$mod SUPERSHIFTALT,5,movetoworkspacesilent,5" - "$mod SUPERSHIFTALT,6,movetoworkspacesilent,6" - "$mod SUPERSHIFTALT,7,movetoworkspacesilent,7" - "$mod SUPERSHIFTALT,8,movetoworkspacesilent,8" - "$mod SUPERSHIFTALT,9,movetoworkspacesilent,9" - "$mod SUPERSHIFTALT,0,movetoworkspacesilent,10" - - # preselection - "$mod SUPERALT,j,layoutmsg,preselect l" - "$mod SUPERALT,k,layoutmsg,preselect d" - "$mod SUPERALT,l,layoutmsg,preselect u" - "$mod SUPERALT,semicolon,layoutmsg,preselect r" - "$mod SUPERALT,h,layoutmsg,preselect n" - ]; - - binde = [ - # hyprland keybinds - # focus - "$mod SUPER,J,movefocus,l" - "$mod SUPER,semicolon,movefocus,r" - "$mod SUPER,L,movefocus,u" - "$mod SUPER,K,movefocus,d" - - # resize - "$mod SUPER,U,resizeactive,-20 0" - "$mod SUPER,P,resizeactive,20 0" - "$mod SUPER,O,resizeactive,0 -20" - "$mod SUPER,I,resizeactive,0 20" - - (lib.mkIf config.mods.hypr.hyprland.hyprspaceEnable - "SUPER, W, overview:toggle") - ]; - general = { gaps_out = mkDashDefault "3,5,5,5"; border_size = mkDashDefault 3; @@ -343,6 +310,8 @@ in { enable_swallow = mkDashDefault true; disable_splash_rendering = mkDashDefault true; disable_hyprland_logo = mkDashDefault true; + disable_xdg_env_checks = mkDashDefault true; + disable_scale_notification = mkDashDefault true; swallow_regex = mkDashDefault "^(.*)(kitty)(.*)$"; initial_workspace_tracking = mkDashDefault 1; # just doesn't work @@ -360,74 +329,23 @@ in { sync_gsettings_theme = mkDashDefault false; }; - gestures = { - workspace_swipe = mkDashDefault true; - }; - - monitor = mkDashDefault config.mods.hypr.hyprland.monitor; - workspace = mkDashDefault config.mods.hypr.hyprland.workspace; - - env = [ - "GTK_CSD,0" - ''TERM,"kitty /bin/fish"'' - "XDG_CURRENT_DESKTOP=Hyprland" - "XDG_SESSION_TYPE=wayland" - "XDG_SESSION_DESKTOP=Hyprland" - "HYPRCURSOR_THEME,${config.mods.stylix.cursor.name}" - "HYPRCURSOR_SIZE,${toString config.mods.stylix.cursor.size}" - "XCURSOR_THEME,${config.mods.stylix.cursor.name}" - "XCURSOR_SIZE,${toString config.mods.stylix.cursor.size}" - "QT_QPA_PLATFORM,wayland" - "QT_QPA_PLATFORMTHEME,qt5ct" - "QT_WAYLAND_FORCE_DPI,96" - "QT_AUTO_SCREEN_SCALE_FACTOR,0" - "QT_WAYLAND_DISABLE_WINDOWDECORATION,1" - "QT_SCALE_FACTOR,1" - ''EDITOR,"neovide --novsync --nofork"'' - - (lib.mkIf config.mods.gpu.nvidia.enable "LIBVA_DRIVER_NAME,nvidia") - (lib.mkIf config.mods.gpu.nvidia.enable "XDG_SESSION_TYPE,wayland") - (lib.mkIf config.mods.gpu.nvidia.enable "GBM_BACKEND,nvidia-drm") - (lib.mkIf config.mods.gpu.nvidia.enable "__GLX_VENDOR_LIBRARY_NAME,nvidia") + gesture = [ + "3, horizontal, workspace" ]; layerrule = [ # layer rules # mainly to disable animations within slurp and grim - "noanim, selection" + "match:namespace selection, no_anim on" ]; - windowrule = [ - # window rules - "float,class:^(.*)(OxiCalc)(.*)$" - "float,class:^(.*)(winecfg.exe)(.*)$" - "float,class:^(.*)(copyq)(.*)$" - "center,class:^(.*)(swappy)(.*)$" - "workspace 10 silent,class:^(.*)(steam)(.*)$" - - # Otherwise neovide will ignore tiling - "suppressevent fullscreen maximize,class:^(.*)(neovide)(.*)$" - ]; - - exec-once = - [ - # environment - "systemctl --user import-environment" - "dbus-update-activation-environment --systemd --all" - "hyprctl setcursor ${config.mods.stylix.cursor.name} ${toString config.mods.stylix.cursor.size}" - # ensures the systemd service knows what "hyprctl" is :) - (lib.mkIf config.mods.gaming.gamemode "systemctl try-restart gamemoded.service --user") - - # other programs - "${browserName}" - (lib.mkIf config.mods.oxi.hyprdock.enable "hyprdock --server") - (lib.mkIf config.mods.hypr.hyprpaper.enable "hyprpaper") - (lib.mkIf config.mods.hypr.hyprland.useIronbar "ironbar") - (lib.mkIf config.mods.oxi.oxipaste.enable "oxipaste_daemon") - (lib.mkIf config.mods.oxi.oxinoti.enable "oxinoti") - ] - ++ config.mods.hypr.hyprland.extraAutostart; - + workspace = mkWorkspace config.mods.wm.workspaces; + monitor = mkMonitors config.mods.wm.monitors; + env = mkEnv config; + bind = mkBinds config; + binde = mkEBinds config; + windowrule = mkWindowRule config; + exec-once = mkAutoStart config; plugin = config.mods.hypr.hyprland.pluginConfig; } config.mods.hypr.hyprland.customConfig diff --git a/modules/programs/hypr/hyprlock.nix b/modules/programs/hypr/hyprlock.nix index 30ea707..c152b22 100644 --- a/modules/programs/hypr/hyprlock.nix +++ b/modules/programs/hypr/hyprlock.nix @@ -24,14 +24,22 @@ input-field = [ { - monitor = "${config.mods.hypr.hyprland.defaultMonitor}"; + monitor = "${ + if config.mods.wm.monitors != [] + then (builtins.elemAt config.mods.wm.monitors 0).name + else "" + }"; placeholder_text = "password or something"; } ]; label = [ { - monitor = "${config.mods.hypr.hyprland.defaultMonitor}"; + monitor = "${ + if config.mods.wm.monitors != [] + then (builtins.elemAt config.mods.wm.monitors 0).name + else "" + }"; text = "$TIME"; font_size = 50; position = "0, 200"; diff --git a/modules/programs/ironbar.nix b/modules/programs/ironbar.nix index ed3fa08..b955d51 100644 --- a/modules/programs/ironbar.nix +++ b/modules/programs/ironbar.nix @@ -1,22 +1,27 @@ { - mkDashDefault, lib, config, pkgs, inputs, options, + mkDashDefault, ... }: let - username = config.conf.username; + inherit (config.conf) username; base16 = pkgs.callPackage inputs.base16.lib {}; scheme = base16.mkSchemeAttrs config.stylix.base16Scheme; ironbarDefaultConfig = useBatteryModule: { end = [ (lib.mkIf useBatteryModule { - type = "upower"; + type = "battery"; class = "battery"; icon_size = 0; + format = "{percentage}%"; + thresholds = { + warning = 20; + critical = 5; + }; }) { class = "music"; @@ -183,8 +188,15 @@ ]; }; monitorConfig = useBatteryModule: - if config.mods.hypr.hyprland.ironbarSingleMonitor - then {monitors.${config.mods.hypr.hyprland.defaultMonitor} = ironbarDefaultConfig useBatteryModule;} + if config.mods.ironbar.ironbarSingleMonitor + then { + monitors.${ + if config.mods.wm.monitors != [] + then (builtins.elemAt config.mods.wm.monitors 0).name + else "" + } = + ironbarDefaultConfig useBatteryModule; + } else ironbarDefaultConfig useBatteryModule; in { options.mods = { @@ -195,6 +207,14 @@ in { type = lib.types.bool; description = "Enables ironbar"; }; + ironbarSingleMonitor = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = '' + Whether to use ironbar on a single monitor. + ''; + }; useDefaultConfig = lib.mkOption { default = true; example = false; @@ -256,6 +276,7 @@ in { @import url("/home/${username}/.config/gtk-3.0/gtk.css"); @define-color primary #${scheme.base0D}; + @define-color warning #${scheme.base0F}; @define-color muted-text #${scheme.base05}; @define-color background #${scheme.base00}; @define-color secondary-background #${scheme.base02}; @@ -405,13 +426,17 @@ in { color: @primary; } + .workspaces .item:not(.visible) { + color: @warning; + } + .workspaces .item.focused { background-color: @primary; color: @background; } - /* upower */ - .upower { + /* battery */ + .battery { font-size: 13px; padding: 0px 4px 0px 0px; margin: 2px 0px 2px 0px; @@ -419,21 +444,21 @@ in { color: @primary; } - .upower .icon { + .battery .icon { opacity: 0.0; } - .upower .label { + .battery .label { margin: 2px 0px 0px -8px; color: @primary; } - .upower:hover { + .battery:hover { background-color: @secondary-background; border-radius: 5px; } - .popup-upower { + .popup-battery { background-color: @background; color: @primary; border-radius: 8px; diff --git a/modules/programs/media.nix b/modules/programs/media.nix index f05500d..c37d62b 100644 --- a/modules/programs/media.nix +++ b/modules/programs/media.nix @@ -39,7 +39,7 @@ filePickerPortal = lib.mkOption { default = "Term"; example = "Gnome"; - type = with lib.types; oneOf [(enum ["Gnome" "Kde" "Lxqt" "Gtk" "Term" "Default"]) string]; + type = with lib.types; oneOf [(enum ["Gnome" "Kde" "Lxqt" "Gtk" "Term" "Default"]) str]; description = '' The file picker portal to use (set with shana). Default removes the config, allowing you to set it yourself. @@ -87,14 +87,14 @@ # audio control playerctl # images - imv + eog # videos mpv # pdf zathura evince libreoffice-fresh - onlyoffice-bin + onlyoffice-desktopeditors pdftk pdfpc polylux2pdfpc diff --git a/modules/programs/mime.nix b/modules/programs/mime.nix index 03d04d8..4da7aff 100644 --- a/modules/programs/mime.nix +++ b/modules/programs/mime.nix @@ -85,7 +85,7 @@ in { description = "Applications used for handling browser mime types"; }; imageApplications = lib.mkOption { - default = ["imv"]; + default = ["eog"]; example = []; type = with lib.types; listOf str; description = "Applications used for handling image mime types"; diff --git a/modules/programs/niri.nix b/modules/programs/niri.nix new file mode 100644 index 0000000..0531829 --- /dev/null +++ b/modules/programs/niri.nix @@ -0,0 +1,392 @@ +{ + mkDashDefault, + config, + lib, + options, + pkgs, + ... +}: let + defaultWmConf = import ../../lib/wm.nix; +in { + options.mods.niri = { + enable = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = '' + Enable Niri + ''; + }; + useDefaultConfig = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = '' + Use preconfigured Niri config. + ''; + }; + customConfig = lib.mkOption { + default = ''''; + example = ''''; + type = lib.types.lines; + description = '' + Custom Niri configuration. + Will be merged with default configuration if enabled. + ''; + }; + }; + + config = lib.mkIf config.mods.niri.enable ( + lib.optionalAttrs (options ? wayland.windowManager.hyprland) { + # TODO deduplicate and abstract away base window management config + # install Niri related packages + home.packages = with pkgs; [ + xorg.xprop + grim + slurp + satty + xdg-desktop-portal-gtk + xdg-desktop-portal-gnome + kdePackages.xdg-desktop-portal-kde + xdg-desktop-portal-shana + copyq + wl-clipboard + + niri + xwayland-satellite + ]; + + xdg.configFile."niri/config.kdl" = let + mkNiriMod = mods: + builtins.map (mod: + if mod == "Mod" + then config.mods.wm.modKey + "+" + else "${mod}" + "+") + mods + |> lib.strings.concatStringsSep ""; + mkNiriArg = args: + if args != [] + then let + concatCommand = lib.strings.concatStringsSep " " args; + validCommand = builtins.replaceStrings [''"''] [''\"''] concatCommand; + in "\"${validCommand}\"" + else ""; + mkNiriCommand = bind: let + args = bind.args or []; + in + if bind.command == "quit" + then "quit;" + else if bind.command == "killActive" + then "close-window;" + else if bind.command == "moveFocusTop" + then "focus-window-up;" + else if bind.command == "focusWorkspace" + then "focus-workspace" + " " + mkNiriArg args + ";" + else if bind.command == "moveWindowRight" + then "move-column-right-or-to-monitor-right;" + else if bind.command == "moveWindowDown" + then "move-window-down;" + else if bind.command == "moveWindowLeft" + then "move-column-left-or-to-monitor-left;" + else if bind.command == "moveWindowUp" + then "move-window-up;" + else if bind.command == "moveFocusUp" + then "focus-window-up;" + else if bind.command == "moveFocusRight" + then "focus-column-or-monitor-right;" + else if bind.command == "moveFocusDown" + then "focus-window-down;" + else if bind.command == "moveFocusLeft" + then "focus-column-or-monitor-left;" + else if bind.command == "toggleFloating" + then "toggle-window-floating;" + else if bind.command == "toggleFullscreen" + then "fullscreen-window;" + else if bind.command == "moveToWorkspace" + then "move-window-to-workspace" + " " + mkNiriArg args + ";" + else if bind.command == "spawn" + then "spawn" + " " + mkNiriArg args + ";" + else if bind.command == "spawn-sh" + then "spawn-sh" + " " + mkNiriArg args + ";" + else if bind.command.niri != null + then bind.command.niri + " " + mkNiriArg args + ";" + else ""; + + mkNiriBinds = cfg: + '' binds { + '' + + ( + ( + builtins.map ( + bind: + /* + kdl + */ + if bind ? key && bind ? command + then '' + ${mkNiriMod (bind.modKeys or [])}${bind.key} ${ + if + bind ? meta + && bind.meta ? niri + then + ( + if + bind.meta.niri ? desc + && bind.meta.niri.desc != "" + then "hotkey-overlay-title=\"" + bind.meta.niri.desc + "\"" + else "" + ) + + " " + + ( + if + bind.meta.niri ? repeat + && bind.meta.niri.repeat + then "repeat=true" + else "repeat=false" + ) + + " " + + ( + if + bind.meta.niri ? allowWhileLocked + && bind.meta.niri.allowWhileLocked + then "allow-when-locked=true" + else "" + ) + + " " + + ( + if + bind.meta.niri ? allowInhibit + && bind.meta.niri.allowInhibit + then "allow-inhibiting=true" + else "allow-inhibiting=false" + ) + else "" + } { ${ + mkNiriCommand bind + } } + '' + else '''' + ) + (( + cfg.mods.wm.binds + ++ ( + if cfg.mods.wm.useDefaultBinds + then defaultWmConf.defaultBinds cfg + else [] + ) + ) + |> builtins.filter (bind: !(hasInvalidCustomCommand bind))) + ) + |> lib.strings.concatLines + ) + + '' + } + ''; + mkVrr = vrr: + if vrr + then "true" + else "false"; + mkNiriMonitors = cfg: + (builtins.map ( + monitor: + # TODO vrr + /* + kdl + */ + '' + output "${monitor.name}" { + variable-refresh-rate on-demand=${mkVrr monitor.vrr} + mode "${builtins.toString monitor.resolutionX}x${builtins.toString monitor.resolutionY}@${builtins.toString monitor.refreshrate}" + scale ${builtins.toString monitor.scale} + transform "${ + if (monitor.transform == "0") + then "normal" + else monitor.transform + }" + position x=${builtins.toString monitor.positionX} y=${builtins.toString monitor.positionY} + } + '' + ) + cfg.mods.wm.monitors) + |> lib.strings.concatLines; + mkNiriWorkspaces = cfg: + (builtins.map ( + workspace: + /* + kdl + */ + '' + workspace "${workspace.name}" { + open-on-output "${workspace.monitor}" + } + '' + ) + cfg.mods.wm.workspaces) + |> lib.strings.concatLines; + mkNiriWindowRules = cfg: ( + ( + builtins.map ( + rule: + /* + kdl + */ + '' + window-rule { + ${rule} + } + '' + ) + ( + cfg.mods.wm.windowRules.niri + ++ ( + if cfg.mods.wm.useDefaultWindowRules + then defaultWmConf.defaultWindowRules.niri + else [] + ) + ) + ) + |> lib.strings.concatLines + ); + hasInvalidCustomCommand = bind: !(bind ? command) || (!(builtins.isString bind.command) && bind.command.niri or null == null); + mkNiriEnv = config: let + defaultEnv = + if config.mods.wm.useDefaultEnv + then defaultWmConf.defaultEnv config + else { + all = {}; + niri = {}; + }; + userEnv = + if config.mods.wm.env ? all + then config.mods.wm.env.all // config.mods.wm.env.niri + else config.mods.wm.env; + env = + userEnv + // defaultEnv.all + // defaultEnv.niri; + in + '' + environment { + '' + + ( + lib.attrsets.mapAttrsToList ( + name: value: "${name} \"${value}\"" + ) + env + |> lib.strings.concatLines + ) + + '' + } + ''; + mkNiriAutoStart = config: let + defaultStartup = + if config.mods.wm.useDefaultStartup + then defaultWmConf.defaultStartup config + else { + all = {}; + niri = {}; + }; + userStartup = + if config.mods.wm.startup ? all + then config.mods.wm.startup.all ++ config.mods.wm.startup.niri + else config.mods.wm.startup; + autoStart = userStartup ++ defaultStartup.all ++ defaultStartup.niri; + in + (builtins.map (value: "spawn-at-startup \"${value}\"") + autoStart) + |> lib.strings.concatLines; + defaultConfig = + /* + kdl + */ + '' + input { + keyboard { + xkb { + layout "enIntUmlaut" + } + repeat-delay 200 + repeat-rate 25 + numlock + } + + touchpad { + tap + natural-scroll + } + + mouse { + accel-speed 0.2 + accel-profile "flat" + } + + focus-follows-mouse max-scroll-amount="25%" + } + + layout { + // Set gaps around windows in logical pixels. + gaps 10 + center-focused-column "never" + always-center-single-column + + preset-column-widths { + proportion 0.33333 + proportion 0.5 + proportion 1.0 + } + + default-column-width { proportion 0.5; } + focus-ring { + width 3 + inactive-color "#505050" + active-gradient from="#ff0000" to="#00ff00" angle=45 + } + + border { + off + } + + // You can enable drop shadows for windows. + shadow { + on + softness 30 + spread 5 + offset x=0 y=5 + color "#0007" + } + } + + ${ + if config.mods.gpu.nvidia.enable + then '' + debug { + wait-for-frame-completion-before-queueing + } + '' + else '''' + } + + // Autostart + + hotkey-overlay { + skip-at-startup + } + + prefer-no-csd + '' + + mkNiriMonitors config + + mkNiriBinds config + + mkNiriWorkspaces config + + mkNiriWindowRules config + + mkNiriEnv config + + mkNiriAutoStart config; + in + mkDashDefault { + text = + if config.mods.niri.useDefaultConfig + then defaultConfig + config.mods.niri.customConfig + else config.mods.niri.customConfig; + }; + } + ); +} diff --git a/modules/programs/oxi/default.nix b/modules/programs/oxi/default.nix index 99de567..83c4f23 100644 --- a/modules/programs/oxi/default.nix +++ b/modules/programs/oxi/default.nix @@ -54,8 +54,8 @@ lib.optionalAttrs (options ? home.packages) { programs = { hyprdock = { - enable = config.mods.oxi.hyprdock.enable; - settings = config.mods.oxi.hyprdock.settings; + inherit (config.mods.oxi.hyprdock) enable; + inherit (config.mods.oxi.hyprdock) settings; }; oxicalc.enable = lib.mkIf config.mods.oxi.oxicalc.enable true; ReSet = lib.mkIf config.mods.oxi.ReSet.enable { @@ -74,8 +74,8 @@ }; }; } - // lib.optionalAttrs (options ? services.logind) { - services.logind.lidSwitchExternalPower = "ignore"; + // lib.optionalAttrs (options ? services.logind && options ? services.logind.settings) { + services.logind.settings.Login.HandleLidSwitchExternalPower = "ignore"; } ); } diff --git a/modules/programs/printing.nix b/modules/programs/printing.nix index 848ffef..98bbe4f 100644 --- a/modules/programs/printing.nix +++ b/modules/programs/printing.nix @@ -16,6 +16,10 @@ config = lib.mkIf config.mods.printing.enable ( lib.optionalAttrs (options ? services.printing) { # Enable CUPS to print documents. + environment.systemPackages = with pkgs; [ + simple-scan + ]; + hardware.sane.enable = true; services = { printing = { enable = true; diff --git a/modules/programs/stylix.nix b/modules/programs/stylix.nix index 124cc64..dd11e8c 100644 --- a/modules/programs/stylix.nix +++ b/modules/programs/stylix.nix @@ -91,7 +91,7 @@ in { }; emoji = { - package = pkgs.noto-fonts-emoji; + package = pkgs.noto-fonts-color-emoji; name = "Noto Color Emoji"; }; }; diff --git a/modules/programs/virtmanager.nix b/modules/programs/virtmanager.nix index bf81b93..de38848 100644 --- a/modules/programs/virtmanager.nix +++ b/modules/programs/virtmanager.nix @@ -44,8 +44,6 @@ in { qemu = { package = mkDashDefault pkgs.qemu_kvm; swtpm.enable = mkDashDefault true; - ovmf.enable = mkDashDefault true; - ovmf.packages = [pkgs.OVMFFull.fd]; }; }; spiceUSBRedirection.enable = mkDashDefault true; diff --git a/modules/programs/wm.nix b/modules/programs/wm.nix new file mode 100644 index 0000000..0f794d3 --- /dev/null +++ b/modules/programs/wm.nix @@ -0,0 +1,403 @@ +{lib, ...}: let + wmWorkspace = with lib.types; { + options = { + name = lib.mkOption { + default = ""; + example = "1"; + type = str; + description = "Name of the workspace"; + }; + default = lib.mkOption { + default = false; + example = true; + type = bool; + description = "Whether the workspace is the default workspace. (Currently doesn't do anything on niri)"; + }; + monitor = lib.mkOption { + default = ""; + example = "DP-1"; + type = str; + description = "Name of the monitor to bind the workspace to"; + }; + }; + }; + + wmOptions = with lib.types; { + options = { + name = lib.mkOption { + default = "DP-1"; + example = "DP-1"; + type = str; + description = "Name of the monitor"; + }; + resolutionX = lib.mkOption { + default = 1920; + example = 2560; + type = number; + description = "ResolutionX of the monitor"; + }; + resolutionY = lib.mkOption { + default = 1080; + example = 1440; + type = number; + description = "ResolutionY of the monitor"; + }; + refreshrate = lib.mkOption { + default = 60; + example = 144; + type = number; + description = "Refreshrate of the monitor"; + }; + positionX = lib.mkOption { + default = 0; + example = 1920; + type = number; + description = "PositionX of the monitor"; + }; + positionY = lib.mkOption { + default = 0; + example = 1080; + type = number; + description = "PositionY of the monitor"; + }; + scale = lib.mkOption { + default = 1; + example = 2; + type = number; + description = "Scale of the monitor"; + }; + transform = lib.mkOption { + default = "0"; + example = "90"; + type = enum ["0" "90" "180" "270" "360"]; + description = "Transform of the monitor"; + }; + vrr = lib.mkOption { + default = false; + example = true; + type = bool; + description = "VRR status of the monitor"; + }; + }; + }; + + modKeys = lib.types.enum ["Mod" "Super" "Alt" "Shift" "Ctrl"]; + + customCommand = with lib.types; { + options = { + niri = lib.mkOption { + default = null; + example = "kitty"; + type = either null str; + description = "Command to use in niri"; + }; + hyprland = lib.mkOption { + default = null; + example = "kitty"; + type = either null str; + description = "Command to use in hyprland"; + }; + }; + }; + + envOptions = with lib.types; { + options = { + all = lib.mkOption { + default = {}; + example = {}; + type = attrsOf str; + description = "General Env"; + }; + niri = lib.mkOption { + default = {}; + example = {}; + type = attrsOf str; + description = "Niri Env"; + }; + hyprland = lib.mkOption { + default = {}; + example = {}; + type = attrsOf str; + description = "Hyprland Env"; + }; + }; + }; + + startupOptions = with lib.types; { + options = { + all = lib.mkOption { + default = []; + example = []; + type = listOf str; + description = "General Startup commands"; + }; + niri = lib.mkOption { + default = []; + example = []; + type = listOf str; + description = "Niri Startup commands"; + }; + hyprland = lib.mkOption { + default = []; + example = []; + type = listOf str; + description = "Hyprland Startup commands"; + }; + }; + }; + + windowRuleOptions = with lib.types; { + options = { + niri = lib.mkOption { + default = []; + example = []; + type = listOf lines; + description = "Niri window rules"; + }; + hyprland = lib.mkOption { + default = []; + example = []; + type = listOf str; + description = "Hyprland window rules"; + }; + }; + }; + + bindOptions = with lib.types; { + options = { + modKeys = lib.mkOption { + default = []; + example = ["Mod"]; + type = listOf modKeys; + description = "List of modifier keys"; + }; + key = lib.mkOption { + default = ""; + example = "Q"; + type = str; + description = "Key to bind"; + }; + command = lib.mkOption { + default = ""; + example = "killActive"; + type = either (submodule customCommand) (enum [ + "spawn" + "spawn-sh" + "quit" + "killActive" + "moveFocusUp" + "moveFocusRight" + "moveFocusDown" + "moveFocusLeft" + "moveWindowUp" + "moveWindowRight" + "moveWindowDown" + "moveWindowLeft" + "focusWorkspace" + "moveToWorkspace" + "toggleFloating" + "toggleFullscreen" + ]); + description = "Command to execute"; + }; + args = lib.mkOption { + default = []; + example = []; + type = listOf str; + description = "Additional arguments for the command"; + }; + meta = lib.mkOption { + default = {}; + example = {}; + type = submodule { + options = { + niri = lib.mkOption { + default = {}; + type = submodule { + options = { + desc = lib.mkOption { + default = ""; + type = str; + description = "Description for Hotkey overview"; + }; + repeat = lib.mkOption { + type = bool; + default = true; + description = "Whether to repeat the keybind on hold"; + }; + allowInhibit = lib.mkOption { + type = bool; + default = true; + description = "Whether to allow inhibiting"; + }; + allowWhileLocked = lib.mkOption { + type = bool; + default = false; + description = "Whether to allow while locked"; + }; + cooldown = lib.mkOption { + type = number; + default = 0; + description = "Cooldown on bind"; + }; + }; + }; + description = "Niri meta for keybinds"; + }; + hyprland = lib.mkOption { + default = {}; + type = submodule { + options = { + repeat = lib.mkOption { + type = bool; + default = true; + description = "Whether to repeat the keybind on hold"; + }; + }; + }; + description = "Niri meta for keybinds"; + }; + }; + }; + description = "Custom metadata per bind. Note, only supported environments are taken into account."; + }; + }; + }; +in { + options.mods.wm = { + modKey = lib.mkOption { + default = "Super"; + example = "Alt"; + type = modKeys; + description = "Mod key"; + }; + + env = lib.mkOption { + default = {}; + example = { + all = { + EDITOR = "Neovim"; + }; + niri = { + EDITOR = "Emacs"; + }; + }; + type = with lib.types; either (submodule envOptions) (attrsOf str); + description = "Environment configuration"; + }; + + useDefaultEnv = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = "Whether to use default env variables"; + }; + + startup = lib.mkOption { + default = []; + example = { + all = ["oxinoti"]; + niri = ["someniricommand"]; + hyprland = ["somehyprlandcommand"]; + }; + type = with lib.types; either (submodule startupOptions) (listOf str); + description = "Start commands"; + }; + + useDefaultStartup = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = "Whether to use default autostart commands"; + }; + + useDefaultWindowRules = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = "Whether to use default window rules"; + }; + + windowRules = lib.mkOption { + default = {}; + example = { + niri = [ + '' + match app-id=r#"^org\.keepassxc\.KeePassXC$"# + match app-id=r#"^org\.gnome\.World\.Secrets$"# + + block-out-from "screen-capture" + '' + '' + match app-id=r#"^steam$"# + open-on-workspace "0" + '' + ]; + }; + type = lib.types.submodule windowRuleOptions; + description = "Window rules"; + }; + + workspaces = lib.mkOption { + default = []; + example = [ + { + name = "chat"; + monitor = "DP-1"; + } + ]; + type = + lib.types.listOf (lib.types.submodule wmWorkspace); + description = "Workspace configuration"; + }; + + monitors = lib.mkOption { + default = []; + example = [ + { + name = "DP-1"; + resolutionX = 1920; + resolutionY = 1080; + refreshrate = 144; + positionX = 0; + positionY = 0; + scale = 1; + transform = "0"; + vrr = false; + } + ]; + type = + lib.types.listOf (lib.types.submodule wmOptions); + description = "Monitor configuration"; + }; + + useDefaultBinds = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = "Whether to use default keybinds"; + }; + + binds = lib.mkOption { + default = []; + example = [ + { + modKeys = ["Mod"]; + key = "Q"; + command = "killActive"; + args = []; + meta = { + niri = { + desc = "Kill the active window"; + repeat = false; + }; + hyprland = {}; + }; + } + ]; + type = + lib.types.listOf (lib.types.submodule bindOptions); + description = "Bind configuration"; + }; + }; +} diff --git a/modules/programs/yazi/default.nix b/modules/programs/yazi/default.nix index c9bd08b..d890a81 100644 --- a/modules/programs/yazi/default.nix +++ b/modules/programs/yazi/default.nix @@ -38,7 +38,7 @@ }; plugins = lib.mkOption { default = { - inherit (pkgs.yaziPlugins) piper diff gitui; + inherit (pkgs.yaziPlugins) piper diff gitui wl-clipboard; }; example = {}; type = with lib.types; attrsOf anything; @@ -55,7 +55,7 @@ inherit (conf) enable; settings = conf.settings // config.mods.yazi.additionalKeymap; keymap = conf.keymap // config.mods.yazi.additionalConfig; - plugins = config.mods.yazi.plugins; + inherit (config.mods.yazi) plugins; }; } ); diff --git a/modules/programs/yazi/yazi.nix b/modules/programs/yazi/yazi.nix index bed1c03..22e3169 100644 --- a/modules/programs/yazi/yazi.nix +++ b/modules/programs/yazi/yazi.nix @@ -31,7 +31,7 @@ ]; image = [ { - run = ''imv "$@"''; + run = ''eog "$@"''; orphan = true; display_name = "Open"; } @@ -102,6 +102,11 @@ }; keymap = { mgr.keymap = [ + { + on = ""; + run = "backspace"; + desc = "Delete the character before the cursor"; + } { on = [""]; run = "escape"; @@ -763,6 +768,11 @@ ]; input.keymap = [ + { + on = ""; + run = "backspace"; + desc = "Delete the character before the cursor"; + } { on = [""]; run = "close";