├── .github └── workflows │ ├── update-ca-test.yaml │ ├── update-flake-iso.yaml │ ├── update-flake-master.yaml │ └── update-flake-unstable-small.yaml ├── configuration.nix ├── flake.lock ├── flake.nix ├── hardware-configuration-template.nix ├── home-manager.nix ├── iso ├── flake.nix └── livecd.nix ├── lanzaboote.nix ├── modules ├── features │ ├── appimage.nix │ ├── docker.nix │ ├── filesystems.nix │ ├── fwupd.nix │ ├── nix-ld.nix │ ├── pcscd.nix │ └── virtualisation.nix ├── i18n.nix ├── network.nix ├── nix.nix ├── shell.nix ├── ssh.nix └── time.nix ├── nixpkgs.nix ├── packages ├── default.nix └── gaming.nix ├── platform ├── desktop │ ├── default.nix │ ├── gnome │ │ ├── default.nix │ │ └── modules.nix │ ├── hyprland │ │ ├── default.nix │ │ └── modules.nix │ ├── modules.nix │ └── plasma │ │ └── default.nix └── modules │ ├── features │ ├── audio │ │ ├── pipewire.nix │ │ └── pulseaudio.nix │ ├── avahi.nix │ ├── flatpak.nix │ ├── ime │ │ ├── fcitx5.nix │ │ └── ibus.nix │ ├── plymouth.nix │ └── printing.nix │ ├── fonts.nix │ └── hardware │ ├── bluetooth.nix │ ├── gamepad.nix │ └── mobiledevice.nix ├── scripts ├── deploy-flake.sh ├── update-ca-test.sh ├── update-deploy.sh └── update-flake.sh ├── secrets ├── .sops.yaml ├── cert │ ├── ca.pem │ └── default.nix ├── default.nix └── secrets.yaml ├── security.md ├── specific ├── architecture-specific │ └── x86-64 │ │ ├── default.nix │ │ └── modules │ │ └── features │ │ └── binfmt.nix ├── general │ ├── amd │ │ └── virtualisation.nix │ ├── btrfs │ │ ├── autoscrub.nix │ │ ├── docker.nix │ │ └── snapper.nix │ ├── keyboard │ │ └── vamillo.nix │ ├── linux │ │ ├── tpm2.nix │ │ ├── zram.nix │ │ └── zswap.nix │ ├── nvidia │ │ ├── beta.nix │ │ ├── cuda.nix │ │ └── specialisation.nix │ ├── radio │ │ └── rtl-sdr.nix │ ├── ssd │ │ └── trim.nix │ ├── tablet │ │ └── opentabletdriver.nix │ └── zfs │ │ └── docker.nix ├── hardware-specific │ ├── apple-silicon │ │ ├── .gitignore │ │ └── default.nix │ ├── asus-zephyrus-ga401 │ │ ├── default.nix │ │ └── modules │ │ │ └── features │ │ │ ├── gpu-paththrough │ │ │ ├── hooks.nix │ │ │ ├── qemu.d │ │ │ │ ├── win11-hybrid │ │ │ │ │ ├── prepare │ │ │ │ │ │ └── begin │ │ │ │ │ │ │ └── start.sh │ │ │ │ │ └── release │ │ │ │ │ │ └── end │ │ │ │ │ │ └── stop.sh │ │ │ │ ├── win11-kvmfr │ │ │ │ │ ├── prepare │ │ │ │ │ │ └── begin │ │ │ │ │ │ │ └── start.sh │ │ │ │ │ └── release │ │ │ │ │ │ └── end │ │ │ │ │ │ └── stop.sh │ │ │ │ └── win11 │ │ │ │ │ ├── prepare │ │ │ │ │ └── begin │ │ │ │ │ │ └── start.sh │ │ │ │ │ └── release │ │ │ │ │ └── end │ │ │ │ │ └── stop.sh │ │ │ └── specialisation.nix │ │ │ └── libfprint-goodix-521d │ │ │ └── default.nix │ └── lenovo-legion-16ach6h │ │ └── default.nix ├── system-specific │ ├── CAAppleSilicon │ │ ├── default.nix │ │ └── hardware-configuration.nix │ ├── CALaptopG14 │ │ ├── default.nix │ │ ├── hardware-configuration.nix │ │ ├── modules │ │ │ └── features │ │ │ │ └── rathole.nix │ │ └── persistent.nix │ ├── CALaptopR9000P │ │ ├── default.nix │ │ ├── disk-config.nix │ │ ├── hardware-configuration.nix │ │ ├── persistent.nix │ │ └── zfs.nix │ └── _CALaptopR9000P │ │ ├── default.nix │ │ ├── disk-config.nix │ │ ├── hardware-configuration.nix │ │ └── persistent.nix └── user-specific │ ├── default.nix │ └── modules │ ├── features │ ├── looking-glass │ │ ├── config.nix │ │ ├── default.nix │ │ └── kvmfr.nix │ ├── ollama.nix │ └── waydroid.nix │ ├── network │ ├── firewall.nix │ ├── proxy.nix │ └── tailscale.nix │ ├── nix │ ├── access-tokens.nix │ └── remote-builds.nix │ ├── sudo-rs.nix │ └── sudo.nix ├── triple-buffering-v4.patch ├── user ├── default.nix ├── desktop │ ├── default.nix │ ├── gnome │ │ ├── dconf │ │ │ ├── display │ │ │ │ ├── hidpi.nix │ │ │ │ └── vrr.nix │ │ │ ├── fonts.nix │ │ │ └── gnome.nix │ │ ├── default.nix │ │ └── theme.nix │ └── hyprland │ │ ├── config.nix │ │ ├── default.nix │ │ └── waybar │ │ ├── default.nix │ │ └── style.css ├── home.nix ├── packages │ ├── apps.nix │ └── utils.nix ├── programs │ ├── dotnet.nix │ ├── firefox.nix │ ├── git.nix │ ├── gpg.nix │ ├── java.nix │ ├── jetbrains.nix │ ├── kitty.nix │ ├── lazygit.nix │ ├── mangohud.nix │ ├── obs-studio.nix │ ├── shell.nix │ ├── spicetify.nix │ └── vscode.nix ├── services │ ├── lorri.nix │ ├── mpd.nix │ └── syncthing.nix └── settings │ ├── dconf │ └── blackbox.nix │ ├── flatpak.nix │ ├── gtk.nix │ └── i18n.nix └── wayland-text-input-v1-Implement-basic-text-input-v1-.patch /.github/workflows/update-ca-test.yaml: -------------------------------------------------------------------------------- 1 | name: Sync `autoupdate-ca-test` Branch 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - ca-test 8 | 9 | jobs: 10 | sync: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | - name: Config 17 | run: | 18 | git config user.name github-actions 19 | git config user.email github-actions@github.com 20 | - name: Create 21 | run: | 22 | git checkout $(git rev-parse master) 23 | git cherry-pick origin/ca-test 24 | HEAD=$(git rev-parse HEAD) 25 | git checkout -B autoupdate-ca-test 26 | git reset --hard ${HEAD} 27 | - name: Push 28 | run: | 29 | git push origin autoupdate-ca-test -f -------------------------------------------------------------------------------- /.github/workflows/update-flake-iso.yaml: -------------------------------------------------------------------------------- 1 | name: Update flake.lock on `iso` flake 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: '*/15 * * * *' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | update: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | - uses: cachix/install-nix-action@v27 19 | - name: Config 20 | run: | 21 | git config user.name github-actions 22 | git config user.email github-actions@github.com 23 | - name: Update 24 | run: | 25 | git checkout $(git rev-parse master) 26 | cd iso 27 | nix flake update 28 | git commit -m "Update flake.lock" -i flake.lock 29 | HEAD=$(git rev-parse HEAD) 30 | git checkout -B autoupdate-iso 31 | git reset --hard ${HEAD} 32 | - name: Push 33 | run: | 34 | git push origin autoupdate-iso -f -------------------------------------------------------------------------------- /.github/workflows/update-flake-master.yaml: -------------------------------------------------------------------------------- 1 | name: Update flake.lock on `autoupdate-master` Branch 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: '*/15 * * * *' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | update: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | - uses: cachix/install-nix-action@v27 19 | - name: Config 20 | run: | 21 | git config user.name github-actions 22 | git config user.email github-actions@github.com 23 | - name: Update 24 | run: | 25 | git checkout $(git rev-parse master) 26 | nix flake update --override-input nixpkgs github:NixOS/nixpkgs/master 27 | git commit -m "Update flake.lock" -i flake.lock 28 | HEAD=$(git rev-parse HEAD) 29 | git checkout -B autoupdate-master 30 | git reset --hard ${HEAD} 31 | - name: Push 32 | run: | 33 | git push origin autoupdate-master -f -------------------------------------------------------------------------------- /.github/workflows/update-flake-unstable-small.yaml: -------------------------------------------------------------------------------- 1 | name: Update flake.lock on `autoupdate-unstable-small` Branch 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: '*/15 * * * *' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | update: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | - uses: cachix/install-nix-action@v27 19 | - name: Config 20 | run: | 21 | git config user.name github-actions 22 | git config user.email github-actions@github.com 23 | - name: Update 24 | run: | 25 | git checkout $(git rev-parse master) 26 | nix flake update --override-input nixpkgs github:NixOS/nixpkgs/nixos-unstable-small 27 | git commit -m "Update flake.lock" -i flake.lock 28 | HEAD=$(git rev-parse HEAD) 29 | git checkout -B autoupdate-unstable-small 30 | git reset --hard ${HEAD} 31 | - name: Push 32 | run: | 33 | git push origin autoupdate-unstable-small -f -------------------------------------------------------------------------------- /configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page, on 3 | # https://search.nixos.org/options and in the NixOS manual (`nixos-help`). 4 | 5 | { lib, pkgs, ... }: 6 | 7 | { 8 | imports = [ 9 | # modules/basic 10 | ./modules/time.nix 11 | ./modules/i18n.nix 12 | ./modules/network.nix 13 | ./modules/ssh.nix 14 | ./modules/shell.nix 15 | ./modules/nix.nix 16 | # modules/features 17 | ./modules/features/virtualisation.nix 18 | ./modules/features/docker.nix 19 | ./modules/features/filesystems.nix 20 | ./modules/features/fwupd.nix 21 | ./modules/features/pcscd.nix 22 | ./modules/features/appimage.nix 23 | ./modules/features/nix-ld.nix 24 | # secrets 25 | ./secrets 26 | # package 27 | ./packages 28 | ./packages/gaming.nix 29 | # user config 30 | ./user 31 | ]; 32 | 33 | # Use the systemd-boot EFI boot loader. 34 | boot.loader.systemd-boot.enable = true; 35 | boot.loader.systemd-boot.consoleMode = lib.mkDefault "auto"; 36 | boot.loader.efi.canTouchEfiVariables = true; 37 | boot.loader.timeout = 180; 38 | boot.kernelPackages = lib.mkDefault pkgs.linuxPackages_zen; 39 | 40 | # Using Tmpfs for /tmp to speed up the system 41 | # If you have less memory, this can cause Nix builds to fail 42 | boot.tmp.useTmpfs = true; 43 | # You can choose whether to clean /tmp on boot, but this is not necessary for Tmpfs 44 | # boot.tmp.cleanOnBoot = true; 45 | 46 | # Don't allow mutation of users outside of the config. 47 | users.mutableUsers = false; 48 | nixpkgs.overlays = [ 49 | (final: prev: { 50 | mutter = prev.mutter.overrideAttrs (oldAttrs: { 51 | patches = oldAttrs.patches or [ ] ++ [ 52 | ./wayland-text-input-v1-Implement-basic-text-input-v1-.patch 53 | ]; 54 | }); 55 | }) 56 | ]; 57 | 58 | # Copy the NixOS configuration file and link it from the resulting system 59 | # (/run/current-system/configuration.nix). This is useful in case you 60 | # accidentally delete configuration.nix. 61 | # system.copySystemConfiguration = true; 62 | 63 | # This option defines the first version of NixOS you have installed on this particular machine, 64 | # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions. 65 | # 66 | # Most users should NEVER change this value after the initial install, for any reason, 67 | # even if you've upgraded your system to a new NixOS release. 68 | # 69 | # This value does NOT affect the Nixpkgs version your packages and OS are pulled from, 70 | # so changing it will NOT upgrade your system. 71 | # 72 | # This value being lower than the current NixOS release does NOT mean your system is 73 | # out of date, out of support, or vulnerable. 74 | # 75 | # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration, 76 | # and migrated your data accordingly. 77 | # 78 | # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . 79 | system.stateVersion = "24.05"; # Did you read the comment? 80 | 81 | } 82 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "aagl": { 4 | "inputs": { 5 | "flake-compat": "flake-compat", 6 | "nixpkgs": [ 7 | "nixpkgs" 8 | ] 9 | }, 10 | "locked": { 11 | "lastModified": 1740876632, 12 | "narHash": "sha256-u695YUS3R5HI1VQp7feCifWYOn3Gh6yGde1vp5rKqTg=", 13 | "owner": "ezKEa", 14 | "repo": "aagl-gtk-on-nix", 15 | "rev": "5505af25160f16ad26f9107aebee9ea7713b59d9", 16 | "type": "github" 17 | }, 18 | "original": { 19 | "owner": "ezKEa", 20 | "repo": "aagl-gtk-on-nix", 21 | "type": "github" 22 | } 23 | }, 24 | "apple-silicon-support": { 25 | "inputs": { 26 | "flake-compat": "flake-compat_2", 27 | "nixpkgs": [ 28 | "nixpkgs" 29 | ], 30 | "rust-overlay": "rust-overlay" 31 | }, 32 | "locked": { 33 | "lastModified": 1741663108, 34 | "narHash": "sha256-9RaZ3HuOptioE94IQ/nnzC2x5cMaRi6NX8d8ZOqhJ68=", 35 | "owner": "tpwrules", 36 | "repo": "nixos-apple-silicon", 37 | "rev": "4264de082e92e7d7ba7fa2ad5b5b1a8818b5d048", 38 | "type": "github" 39 | }, 40 | "original": { 41 | "owner": "tpwrules", 42 | "repo": "nixos-apple-silicon", 43 | "type": "github" 44 | } 45 | }, 46 | "crane": { 47 | "locked": { 48 | "lastModified": 1741148495, 49 | "narHash": "sha256-EV8KUaIZ2/CdBXlutXrHoZYbWPeB65p5kKZk71gvDRI=", 50 | "owner": "ipetkov", 51 | "repo": "crane", 52 | "rev": "75390a36cd0c2cdd5f1aafd8a9f827d7107f2e53", 53 | "type": "github" 54 | }, 55 | "original": { 56 | "owner": "ipetkov", 57 | "repo": "crane", 58 | "type": "github" 59 | } 60 | }, 61 | "daeuniverse": { 62 | "inputs": { 63 | "flake-parts": "flake-parts", 64 | "nixpkgs": "nixpkgs" 65 | }, 66 | "locked": { 67 | "lastModified": 1741008028, 68 | "narHash": "sha256-Dypah+fVZ30hCRG96hu1Vmi0DHQSv6XKfy8S6kiS2CQ=", 69 | "owner": "daeuniverse", 70 | "repo": "flake.nix", 71 | "rev": "2d2ea1661c89efc9c12781572b95f4bb700f2a4a", 72 | "type": "github" 73 | }, 74 | "original": { 75 | "owner": "daeuniverse", 76 | "repo": "flake.nix", 77 | "type": "github" 78 | } 79 | }, 80 | "disko": { 81 | "inputs": { 82 | "nixpkgs": "nixpkgs_2" 83 | }, 84 | "locked": { 85 | "lastModified": 1741684000, 86 | "narHash": "sha256-NQykaWIrn5zilncefIvW4jPQ76YMXVK/dMTzkSVDmdk=", 87 | "owner": "nix-community", 88 | "repo": "disko", 89 | "rev": "2db1d64fc084b1d15e3871dffc02c62a94ed6ed7", 90 | "type": "github" 91 | }, 92 | "original": { 93 | "owner": "nix-community", 94 | "repo": "disko", 95 | "type": "github" 96 | } 97 | }, 98 | "firefox-gnome-theme": { 99 | "flake": false, 100 | "locked": { 101 | "lastModified": 1741628778, 102 | "narHash": "sha256-RsvHGNTmO2e/eVfgYK7g+eYEdwwh7SbZa+gZkT24MEA=", 103 | "owner": "rafaelmardojai", 104 | "repo": "firefox-gnome-theme", 105 | "rev": "5a81d390bb64afd4e81221749ec4bffcbeb5fa80", 106 | "type": "github" 107 | }, 108 | "original": { 109 | "owner": "rafaelmardojai", 110 | "repo": "firefox-gnome-theme", 111 | "type": "github" 112 | } 113 | }, 114 | "flake-compat": { 115 | "flake": false, 116 | "locked": { 117 | "lastModified": 1733328505, 118 | "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", 119 | "owner": "edolstra", 120 | "repo": "flake-compat", 121 | "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", 122 | "type": "github" 123 | }, 124 | "original": { 125 | "owner": "edolstra", 126 | "repo": "flake-compat", 127 | "type": "github" 128 | } 129 | }, 130 | "flake-compat_2": { 131 | "locked": { 132 | "lastModified": 1688025799, 133 | "narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=", 134 | "owner": "nix-community", 135 | "repo": "flake-compat", 136 | "rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c", 137 | "type": "github" 138 | }, 139 | "original": { 140 | "owner": "nix-community", 141 | "repo": "flake-compat", 142 | "type": "github" 143 | } 144 | }, 145 | "flake-compat_3": { 146 | "flake": false, 147 | "locked": { 148 | "lastModified": 1733328505, 149 | "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", 150 | "owner": "edolstra", 151 | "repo": "flake-compat", 152 | "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", 153 | "type": "github" 154 | }, 155 | "original": { 156 | "owner": "edolstra", 157 | "repo": "flake-compat", 158 | "type": "github" 159 | } 160 | }, 161 | "flake-parts": { 162 | "inputs": { 163 | "nixpkgs-lib": "nixpkgs-lib" 164 | }, 165 | "locked": { 166 | "lastModified": 1738453229, 167 | "narHash": "sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm+zmZ7vxbJdo=", 168 | "owner": "hercules-ci", 169 | "repo": "flake-parts", 170 | "rev": "32ea77a06711b758da0ad9bd6a844c5740a87abd", 171 | "type": "github" 172 | }, 173 | "original": { 174 | "owner": "hercules-ci", 175 | "repo": "flake-parts", 176 | "type": "github" 177 | } 178 | }, 179 | "flake-parts_2": { 180 | "inputs": { 181 | "nixpkgs-lib": [ 182 | "lanzaboote", 183 | "nixpkgs" 184 | ] 185 | }, 186 | "locked": { 187 | "lastModified": 1740872218, 188 | "narHash": "sha256-ZaMw0pdoUKigLpv9HiNDH2Pjnosg7NBYMJlHTIsHEUo=", 189 | "owner": "hercules-ci", 190 | "repo": "flake-parts", 191 | "rev": "3876f6b87db82f33775b1ef5ea343986105db764", 192 | "type": "github" 193 | }, 194 | "original": { 195 | "owner": "hercules-ci", 196 | "repo": "flake-parts", 197 | "type": "github" 198 | } 199 | }, 200 | "flake-parts_3": { 201 | "inputs": { 202 | "nixpkgs-lib": [ 203 | "nur", 204 | "nixpkgs" 205 | ] 206 | }, 207 | "locked": { 208 | "lastModified": 1733312601, 209 | "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", 210 | "owner": "hercules-ci", 211 | "repo": "flake-parts", 212 | "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", 213 | "type": "github" 214 | }, 215 | "original": { 216 | "owner": "hercules-ci", 217 | "repo": "flake-parts", 218 | "type": "github" 219 | } 220 | }, 221 | "flake-programs-sqlite": { 222 | "inputs": { 223 | "nixpkgs": [ 224 | "nixpkgs" 225 | ], 226 | "utils": "utils" 227 | }, 228 | "locked": { 229 | "lastModified": 1741676642, 230 | "narHash": "sha256-hnb4c+6vXIBIKgHXKRzzxIFEHc9CcPZo2gGtcfhL9cU=", 231 | "owner": "wamserma", 232 | "repo": "flake-programs-sqlite", 233 | "rev": "1f3a4e2792ba4f9e5a4aa798141b8707442f7029", 234 | "type": "github" 235 | }, 236 | "original": { 237 | "owner": "wamserma", 238 | "repo": "flake-programs-sqlite", 239 | "type": "github" 240 | } 241 | }, 242 | "flake-utils": { 243 | "inputs": { 244 | "systems": "systems" 245 | }, 246 | "locked": { 247 | "lastModified": 1731533236, 248 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 249 | "owner": "numtide", 250 | "repo": "flake-utils", 251 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 252 | "type": "github" 253 | }, 254 | "original": { 255 | "owner": "numtide", 256 | "repo": "flake-utils", 257 | "type": "github" 258 | } 259 | }, 260 | "gitignore": { 261 | "inputs": { 262 | "nixpkgs": [ 263 | "lanzaboote", 264 | "pre-commit-hooks-nix", 265 | "nixpkgs" 266 | ] 267 | }, 268 | "locked": { 269 | "lastModified": 1709087332, 270 | "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", 271 | "owner": "hercules-ci", 272 | "repo": "gitignore.nix", 273 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 274 | "type": "github" 275 | }, 276 | "original": { 277 | "owner": "hercules-ci", 278 | "repo": "gitignore.nix", 279 | "type": "github" 280 | } 281 | }, 282 | "home-manager": { 283 | "inputs": { 284 | "nixpkgs": [ 285 | "nixpkgs" 286 | ] 287 | }, 288 | "locked": { 289 | "lastModified": 1741635347, 290 | "narHash": "sha256-2aYfV44h18alHXopyfL4D9GsnpE5XlSVkp4MGe586VU=", 291 | "owner": "nix-community", 292 | "repo": "home-manager", 293 | "rev": "7fb8678716c158642ac42f9ff7a18c0800fea551", 294 | "type": "github" 295 | }, 296 | "original": { 297 | "owner": "nix-community", 298 | "repo": "home-manager", 299 | "type": "github" 300 | } 301 | }, 302 | "impermanence": { 303 | "locked": { 304 | "lastModified": 1737831083, 305 | "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", 306 | "owner": "nix-community", 307 | "repo": "impermanence", 308 | "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", 309 | "type": "github" 310 | }, 311 | "original": { 312 | "owner": "nix-community", 313 | "repo": "impermanence", 314 | "type": "github" 315 | } 316 | }, 317 | "lanzaboote": { 318 | "inputs": { 319 | "crane": "crane", 320 | "flake-compat": "flake-compat_3", 321 | "flake-parts": "flake-parts_2", 322 | "nixpkgs": [ 323 | "nixpkgs" 324 | ], 325 | "pre-commit-hooks-nix": "pre-commit-hooks-nix", 326 | "rust-overlay": "rust-overlay_2" 327 | }, 328 | "locked": { 329 | "lastModified": 1741442524, 330 | "narHash": "sha256-tVcxLDLLho8dWcO81Xj/3/ANLdVs0bGyCPyKjp70JWk=", 331 | "owner": "nix-community", 332 | "repo": "lanzaboote", 333 | "rev": "d8099586d9a84308ffedac07880e7f07a0180ff4", 334 | "type": "github" 335 | }, 336 | "original": { 337 | "owner": "nix-community", 338 | "repo": "lanzaboote", 339 | "type": "github" 340 | } 341 | }, 342 | "nix-vscode-extensions": { 343 | "inputs": { 344 | "flake-utils": "flake-utils", 345 | "nixpkgs": [ 346 | "nixpkgs" 347 | ] 348 | }, 349 | "locked": { 350 | "lastModified": 1741693734, 351 | "narHash": "sha256-Df0jzarVCkwJttnITExjsbSN20FOOuenGhpKvOj49hk=", 352 | "owner": "nix-community", 353 | "repo": "nix-vscode-extensions", 354 | "rev": "6d444be7edf281b8df98235d911d176beaa31510", 355 | "type": "github" 356 | }, 357 | "original": { 358 | "owner": "nix-community", 359 | "repo": "nix-vscode-extensions", 360 | "type": "github" 361 | } 362 | }, 363 | "nixos-hardware": { 364 | "locked": { 365 | "lastModified": 1741078299, 366 | "narHash": "sha256-e8/89MEcO0cxJYwYGYScn6UXTPLZuHvrre4ShrIeDVY=", 367 | "owner": "LostAttractor", 368 | "repo": "nixos-hardware", 369 | "rev": "143330d0895df5a65dfe38129ef6b732a137db2e", 370 | "type": "github" 371 | }, 372 | "original": { 373 | "owner": "nixos", 374 | "repo": "nixos-hardware", 375 | "type": "github" 376 | } 377 | }, 378 | "nixos-xivlauncher-rb": { 379 | "inputs": { 380 | "nixpkgs": [ 381 | "nixpkgs" 382 | ] 383 | }, 384 | "locked": { 385 | "lastModified": 1741086523, 386 | "narHash": "sha256-lLAsxAU5W85MERQ4g4kLTN18tlpMAFHk80a+HFRPWYw=", 387 | "owner": "drakon64", 388 | "repo": "nixos-xivlauncher-rb", 389 | "rev": "f2ce0bde73ccfa650bcb95d4663c1bc7f53bee75", 390 | "type": "github" 391 | }, 392 | "original": { 393 | "owner": "drakon64", 394 | "repo": "nixos-xivlauncher-rb", 395 | "type": "github" 396 | } 397 | }, 398 | "nixpkgs": { 399 | "locked": { 400 | "lastModified": 1739866667, 401 | "narHash": "sha256-EO1ygNKZlsAC9avfcwHkKGMsmipUk1Uc0TbrEZpkn64=", 402 | "owner": "NixOS", 403 | "repo": "nixpkgs", 404 | "rev": "73cf49b8ad837ade2de76f87eb53fc85ed5d4680", 405 | "type": "github" 406 | }, 407 | "original": { 408 | "owner": "NixOS", 409 | "ref": "nixos-unstable", 410 | "repo": "nixpkgs", 411 | "type": "github" 412 | } 413 | }, 414 | "nixpkgs-lib": { 415 | "locked": { 416 | "lastModified": 1738452942, 417 | "narHash": "sha256-vJzFZGaCpnmo7I6i416HaBLpC+hvcURh/BQwROcGIp8=", 418 | "type": "tarball", 419 | "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" 420 | }, 421 | "original": { 422 | "type": "tarball", 423 | "url": "https://github.com/NixOS/nixpkgs/archive/072a6db25e947df2f31aab9eccd0ab75d5b2da11.tar.gz" 424 | } 425 | }, 426 | "nixpkgs-stable": { 427 | "locked": { 428 | "lastModified": 1741600792, 429 | "narHash": "sha256-yfDy6chHcM7pXpMF4wycuuV+ILSTG486Z/vLx/Bdi6Y=", 430 | "owner": "nixos", 431 | "repo": "nixpkgs", 432 | "rev": "ebe2788eafd539477f83775ef93c3c7e244421d3", 433 | "type": "github" 434 | }, 435 | "original": { 436 | "owner": "nixos", 437 | "ref": "nixos-24.11", 438 | "repo": "nixpkgs", 439 | "type": "github" 440 | } 441 | }, 442 | "nixpkgs_2": { 443 | "locked": { 444 | "lastModified": 1738136902, 445 | "narHash": "sha256-pUvLijVGARw4u793APze3j6mU1Zwdtz7hGkGGkD87qw=", 446 | "owner": "NixOS", 447 | "repo": "nixpkgs", 448 | "rev": "9a5db3142ce450045840cc8d832b13b8a2018e0c", 449 | "type": "github" 450 | }, 451 | "original": { 452 | "owner": "NixOS", 453 | "ref": "nixpkgs-unstable", 454 | "repo": "nixpkgs", 455 | "type": "github" 456 | } 457 | }, 458 | "nixpkgs_3": { 459 | "locked": { 460 | "lastModified": 1741697595, 461 | "narHash": "sha256-wBm/HJiQ9ihshEGdK75XETxYMxvB+uUlBgGCYzfrR5Q=", 462 | "owner": "LostAttractor", 463 | "repo": "nixpkgs", 464 | "rev": "b74a327280a9b9aaccb8b3102dc9684e02794b8c", 465 | "type": "github" 466 | }, 467 | "original": { 468 | "owner": "nixos", 469 | "ref": "nixos-unstable-small", 470 | "repo": "nixpkgs", 471 | "type": "github" 472 | } 473 | }, 474 | "nur": { 475 | "inputs": { 476 | "flake-parts": "flake-parts_3", 477 | "nixpkgs": [ 478 | "nixpkgs" 479 | ], 480 | "treefmt-nix": "treefmt-nix" 481 | }, 482 | "locked": { 483 | "lastModified": 1741693509, 484 | "narHash": "sha256-emkxnsZstiJWmGACimyAYqIKz2Qz5We5h1oBVDyQjLw=", 485 | "owner": "nix-community", 486 | "repo": "NUR", 487 | "rev": "5479646b2574837f1899da78bdf9a48b75a9fb27", 488 | "type": "github" 489 | }, 490 | "original": { 491 | "owner": "nix-community", 492 | "repo": "NUR", 493 | "type": "github" 494 | } 495 | }, 496 | "pre-commit-hooks-nix": { 497 | "inputs": { 498 | "flake-compat": [ 499 | "lanzaboote", 500 | "flake-compat" 501 | ], 502 | "gitignore": "gitignore", 503 | "nixpkgs": [ 504 | "lanzaboote", 505 | "nixpkgs" 506 | ] 507 | }, 508 | "locked": { 509 | "lastModified": 1740915799, 510 | "narHash": "sha256-JvQvtaphZNmeeV+IpHgNdiNePsIpHD5U/7QN5AeY44A=", 511 | "owner": "cachix", 512 | "repo": "pre-commit-hooks.nix", 513 | "rev": "42b1ba089d2034d910566bf6b40830af6b8ec732", 514 | "type": "github" 515 | }, 516 | "original": { 517 | "owner": "cachix", 518 | "repo": "pre-commit-hooks.nix", 519 | "type": "github" 520 | } 521 | }, 522 | "root": { 523 | "inputs": { 524 | "aagl": "aagl", 525 | "apple-silicon-support": "apple-silicon-support", 526 | "daeuniverse": "daeuniverse", 527 | "disko": "disko", 528 | "firefox-gnome-theme": "firefox-gnome-theme", 529 | "flake-programs-sqlite": "flake-programs-sqlite", 530 | "home-manager": "home-manager", 531 | "impermanence": "impermanence", 532 | "lanzaboote": "lanzaboote", 533 | "nix-vscode-extensions": "nix-vscode-extensions", 534 | "nixos-hardware": "nixos-hardware", 535 | "nixos-xivlauncher-rb": "nixos-xivlauncher-rb", 536 | "nixpkgs": "nixpkgs_3", 537 | "nixpkgs-stable": "nixpkgs-stable", 538 | "nur": "nur", 539 | "sops-nix": "sops-nix", 540 | "spicetify-nix": "spicetify-nix", 541 | "umu": "umu" 542 | } 543 | }, 544 | "rust-overlay": { 545 | "flake": false, 546 | "locked": { 547 | "lastModified": 1686795910, 548 | "narHash": "sha256-jDa40qRZ0GRQtP9EMZdf+uCbvzuLnJglTUI2JoHfWDc=", 549 | "owner": "oxalica", 550 | "repo": "rust-overlay", 551 | "rev": "5c2b97c0a9bc5217fc3dfb1555aae0fb756d99f9", 552 | "type": "github" 553 | }, 554 | "original": { 555 | "owner": "oxalica", 556 | "repo": "rust-overlay", 557 | "type": "github" 558 | } 559 | }, 560 | "rust-overlay_2": { 561 | "inputs": { 562 | "nixpkgs": [ 563 | "lanzaboote", 564 | "nixpkgs" 565 | ] 566 | }, 567 | "locked": { 568 | "lastModified": 1741228283, 569 | "narHash": "sha256-VzqI+k/eoijLQ5am6rDFDAtFAbw8nltXfLBC6SIEJAE=", 570 | "owner": "oxalica", 571 | "repo": "rust-overlay", 572 | "rev": "38e9826bc4296c9daf18bc1e6aa299f3e932a403", 573 | "type": "github" 574 | }, 575 | "original": { 576 | "owner": "oxalica", 577 | "repo": "rust-overlay", 578 | "type": "github" 579 | } 580 | }, 581 | "sops-nix": { 582 | "inputs": { 583 | "nixpkgs": [ 584 | "nixpkgs" 585 | ] 586 | }, 587 | "locked": { 588 | "lastModified": 1741644481, 589 | "narHash": "sha256-E0RrMykMtEv15V3QhpsFutgoSKhL1JBhidn+iZajOyg=", 590 | "owner": "Mic92", 591 | "repo": "sops-nix", 592 | "rev": "e653d71e82575a43fe9d228def8eddb73887b866", 593 | "type": "github" 594 | }, 595 | "original": { 596 | "owner": "Mic92", 597 | "repo": "sops-nix", 598 | "type": "github" 599 | } 600 | }, 601 | "spicetify-nix": { 602 | "inputs": { 603 | "nixpkgs": [ 604 | "nixpkgs" 605 | ], 606 | "systems": "systems_2" 607 | }, 608 | "locked": { 609 | "lastModified": 1741493656, 610 | "narHash": "sha256-1M2mf5pZTlhZXkSI8wKs9GfNb1hllND58zQUYSAe8EA=", 611 | "owner": "Gerg-L", 612 | "repo": "spicetify-nix", 613 | "rev": "a06e502c884307c33dbdf2017fd50ab3592ad868", 614 | "type": "github" 615 | }, 616 | "original": { 617 | "owner": "Gerg-L", 618 | "repo": "spicetify-nix", 619 | "type": "github" 620 | } 621 | }, 622 | "systems": { 623 | "locked": { 624 | "lastModified": 1681028828, 625 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 626 | "owner": "nix-systems", 627 | "repo": "default", 628 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 629 | "type": "github" 630 | }, 631 | "original": { 632 | "owner": "nix-systems", 633 | "repo": "default", 634 | "type": "github" 635 | } 636 | }, 637 | "systems_2": { 638 | "locked": { 639 | "lastModified": 1681028828, 640 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 641 | "owner": "nix-systems", 642 | "repo": "default", 643 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 644 | "type": "github" 645 | }, 646 | "original": { 647 | "owner": "nix-systems", 648 | "repo": "default", 649 | "type": "github" 650 | } 651 | }, 652 | "treefmt-nix": { 653 | "inputs": { 654 | "nixpkgs": [ 655 | "nur", 656 | "nixpkgs" 657 | ] 658 | }, 659 | "locked": { 660 | "lastModified": 1733222881, 661 | "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", 662 | "owner": "numtide", 663 | "repo": "treefmt-nix", 664 | "rev": "49717b5af6f80172275d47a418c9719a31a78b53", 665 | "type": "github" 666 | }, 667 | "original": { 668 | "owner": "numtide", 669 | "repo": "treefmt-nix", 670 | "type": "github" 671 | } 672 | }, 673 | "umu": { 674 | "inputs": { 675 | "nixpkgs": [ 676 | "nixpkgs" 677 | ] 678 | }, 679 | "locked": { 680 | "dir": "packaging/nix", 681 | "lastModified": 1741627943, 682 | "narHash": "sha256-gGeuNkJcHgORz7ohcXuvzf+gw8qh8m4z8xWNlWTnIG4=", 683 | "owner": "Open-Wine-Components", 684 | "repo": "umu-launcher", 685 | "rev": "14530e6644868af5dfd9d8921ad73dba625761f5", 686 | "type": "github" 687 | }, 688 | "original": { 689 | "dir": "packaging/nix", 690 | "owner": "Open-Wine-Components", 691 | "repo": "umu-launcher", 692 | "type": "github" 693 | } 694 | }, 695 | "utils": { 696 | "locked": { 697 | "lastModified": 1678901627, 698 | "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", 699 | "owner": "numtide", 700 | "repo": "flake-utils", 701 | "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", 702 | "type": "github" 703 | }, 704 | "original": { 705 | "owner": "numtide", 706 | "repo": "flake-utils", 707 | "type": "github" 708 | } 709 | } 710 | }, 711 | "root": "root", 712 | "version": 7 713 | } 714 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "ChaosAttractor's NixOS Flake"; 3 | 4 | inputs = { 5 | # Nix Packages 6 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; 7 | nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11"; 8 | # Nix Hardware 9 | nixos-hardware.url = "github:nixos/nixos-hardware"; 10 | # Disko 11 | disko.url = "github:nix-community/disko"; 12 | # Impermanence 13 | impermanence.url = "github:nix-community/impermanence"; 14 | # lanzaboote (Secure boot) 15 | lanzaboote.url = "github:nix-community/lanzaboote"; 16 | lanzaboote.inputs.nixpkgs.follows = "nixpkgs"; 17 | # User Packages 18 | home-manager.url = "github:nix-community/home-manager"; 19 | home-manager.inputs.nixpkgs.follows = "nixpkgs"; 20 | # NUR Packages 21 | nur.url = "github:nix-community/NUR"; 22 | # Apple Silicon Support 23 | apple-silicon-support.url = "github:tpwrules/nixos-apple-silicon"; 24 | apple-silicon-support.inputs.nixpkgs.follows = "nixpkgs"; 25 | # sops-nix 26 | sops-nix.url = "github:Mic92/sops-nix"; 27 | sops-nix.inputs.nixpkgs.follows = "nixpkgs"; 28 | # AAGL 29 | aagl.url = "github:ezKEa/aagl-gtk-on-nix"; 30 | aagl.inputs.nixpkgs.follows = "nixpkgs"; 31 | # Spicetify 32 | spicetify-nix.url = "github:Gerg-L/spicetify-nix"; 33 | spicetify-nix.inputs.nixpkgs.follows = "nixpkgs"; 34 | # daeuniverse 35 | daeuniverse.url = "github:daeuniverse/flake.nix"; 36 | daeuniverse.inputs.nixpkgs.follows = "nixpkgs"; 37 | # xivlauncher-rb 38 | nixos-xivlauncher-rb.url = "github:drakon64/nixos-xivlauncher-rb"; 39 | nixos-xivlauncher-rb.inputs.nixpkgs.follows = "nixpkgs"; 40 | # vscode-extensions 41 | nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions"; 42 | nix-vscode-extensions.inputs.nixpkgs.follows = "nixpkgs"; 43 | # flake-programs-sqlite 44 | flake-programs-sqlite.url = "github:wamserma/flake-programs-sqlite"; 45 | flake-programs-sqlite.inputs.nixpkgs.follows = "nixpkgs"; 46 | # UMU Launcher 47 | umu.url = "github:Open-Wine-Components/umu-launcher?dir=packaging/nix"; 48 | umu.inputs.nixpkgs.follows = "nixpkgs"; 49 | # firefox-gnome-theme 50 | firefox-gnome-theme = { 51 | url = "github:rafaelmardojai/firefox-gnome-theme"; 52 | flake = false; 53 | }; 54 | }; 55 | 56 | outputs = 57 | { nixpkgs, ... }@inputs: 58 | let 59 | user = "lostattractor"; 60 | in 61 | rec { 62 | nixosConfigurations = { 63 | # Zephyrus G14 64 | CALaptopG14 = nixpkgs.lib.nixosSystem rec { 65 | system = "x86_64-linux"; 66 | specialArgs = { 67 | inherit inputs user system; 68 | }; 69 | modules = with inputs; [ 70 | ./configuration.nix 71 | ./nixpkgs.nix 72 | ./platform/desktop 73 | ./specific/system-specific/CALaptopG14 74 | ./specific/hardware-specific/asus-zephyrus-ga401 75 | ./specific/architecture-specific/x86-64 76 | ./specific/user-specific 77 | ./lanzaboote.nix 78 | ./home-manager.nix 79 | nixos-hardware.nixosModules.asus-zephyrus-ga401 80 | impermanence.nixosModules.impermanence 81 | lanzaboote.nixosModules.lanzaboote 82 | home-manager.nixosModules.home-manager 83 | sops-nix.nixosModules.sops 84 | aagl.nixosModules.default 85 | daeuniverse.nixosModules.daed 86 | flake-programs-sqlite.nixosModules.programs-sqlite 87 | { nixpkgs.config.allowUnfree = true; } 88 | ]; 89 | }; 90 | CALaptopR9000P = nixpkgs.lib.nixosSystem rec { 91 | system = "x86_64-linux"; 92 | specialArgs = { 93 | inherit inputs user system; 94 | }; 95 | modules = with inputs; [ 96 | ./configuration.nix 97 | ./nixpkgs.nix 98 | ./platform/desktop 99 | ./specific/system-specific/CALaptopR9000P 100 | ./specific/hardware-specific/lenovo-legion-16ach6h 101 | ./specific/architecture-specific/x86-64 102 | ./specific/user-specific 103 | ./lanzaboote.nix 104 | ./home-manager.nix 105 | disko.nixosModules.disko 106 | nixos-hardware.nixosModules.lenovo-legion-16ach6h # hardware.nvidia.prime.offload.enable may cause xorg crash 107 | impermanence.nixosModules.impermanence 108 | lanzaboote.nixosModules.lanzaboote 109 | home-manager.nixosModules.home-manager 110 | sops-nix.nixosModules.sops 111 | aagl.nixosModules.default 112 | daeuniverse.nixosModules.daed 113 | flake-programs-sqlite.nixosModules.programs-sqlite 114 | { nixpkgs.config.allowUnfree = true; } 115 | ]; 116 | }; 117 | # CAAppleSilicon 118 | CAAppleSilicon = nixpkgs.lib.nixosSystem rec { 119 | system = "aarch64-linux"; 120 | specialArgs = { 121 | inherit inputs user system; 122 | }; 123 | modules = with inputs; [ 124 | ./configuration.nix 125 | ./nixpkgs.nix 126 | ./platform/desktop 127 | ./specific/system-specific/CAAppleSilicon 128 | ./specific/hardware-specific/apple-silicon 129 | ./specific/user-specific 130 | apple-silicon-support.nixosModules.apple-silicon-support 131 | home-manager.nixosModules.home-manager 132 | sops-nix.nixosModules.sops 133 | ]; 134 | }; 135 | }; 136 | hydraJobs.nixosConfigurations = nixpkgs.lib.mapAttrs' ( 137 | name: config: nixpkgs.lib.nameValuePair name config.config.system.build.toplevel 138 | ) nixosConfigurations; 139 | }; 140 | } 141 | -------------------------------------------------------------------------------- /hardware-configuration-template.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | config, 6 | lib, 7 | modulesPath, 8 | ... 9 | }: 10 | 11 | { 12 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; 13 | 14 | boot.initrd.availableKernelModules = [ 15 | "nvme" 16 | "xhci_pci" 17 | "usbhid" 18 | "usb_storage" 19 | "sd_mod" 20 | ]; 21 | boot.initrd.kernelModules = [ ]; 22 | boot.kernelModules = [ "kvm-amd" ]; 23 | boot.extraModulePackages = [ ]; 24 | # https://nixos.org/manual/nixos/stable/options.html#opt-boot.resumeDevice 25 | boot.resumeDevice = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 26 | # https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate#Hibernation_into_swap_file_on_Btrfs 27 | # https://sawyershepherd.org/post/hibernating-to-an-encrypted-swapfile-on-btrfs-with-nixos/ 28 | boot.kernelParams = [ "resume_offset=5514496" ]; 29 | 30 | fileSystems."/" = { 31 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 32 | fsType = "btrfs"; 33 | options = [ 34 | "subvol=root" 35 | "compress=zstd" 36 | ]; 37 | }; 38 | 39 | fileSystems."/home" = { 40 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 41 | fsType = "btrfs"; 42 | options = [ 43 | "subvol=home" 44 | "compress=zstd" 45 | ]; 46 | }; 47 | 48 | fileSystems."/nix" = { 49 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 50 | fsType = "btrfs"; 51 | options = [ 52 | "subvol=nix" 53 | "compress=zstd" 54 | "noatime" 55 | ]; 56 | }; 57 | 58 | fileSystems."/swap" = { 59 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 60 | fsType = "btrfs"; 61 | options = [ 62 | "subvol=swap" 63 | "noatime" 64 | ]; 65 | }; 66 | 67 | fileSystems."/boot" = { 68 | device = "/dev/disk/by-uuid/C784-FC44"; 69 | fsType = "vfat"; 70 | }; 71 | 72 | swapDevices = [ { device = "/swap/swapfile"; } ]; 73 | 74 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 75 | # (the default) this is the recommended approach. When using systemd-networkd it's 76 | # still possible to use this option, but it's recommended to use it in conjunction 77 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 78 | networking.useDHCP = lib.mkDefault true; 79 | # networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true; 80 | 81 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 82 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 83 | } 84 | -------------------------------------------------------------------------------- /home-manager.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | user, 4 | system, 5 | ... 6 | }: 7 | { 8 | home-manager.useGlobalPkgs = true; 9 | home-manager.useUserPackages = true; 10 | home-manager.extraSpecialArgs = { 11 | inherit inputs user system; 12 | }; 13 | home-manager.users.${user} = import ./user/home.nix; 14 | } 15 | -------------------------------------------------------------------------------- /iso/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "ChaosAttractor's NixOS LiveCD Flake"; 3 | 4 | inputs = { 5 | # Nix Packages 6 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; 7 | # User Packages 8 | home-manager.url = "github:nix-community/home-manager"; 9 | home-manager.inputs.nixpkgs.follows = "nixpkgs"; 10 | # NUR Packages 11 | nur.url = "github:nix-community/NUR"; 12 | # Apple Silicon Support 13 | apple-silicon-support.url = "github:tpwrules/nixos-apple-silicon"; 14 | apple-silicon-support.inputs.nixpkgs.follows = "nixpkgs"; 15 | # AAGL 16 | aagl.url = "github:ezKEa/aagl-gtk-on-nix"; 17 | aagl.inputs.nixpkgs.follows = "nixpkgs"; 18 | # Spicetify 19 | spicetify-nix.url = "github:Gerg-L/spicetify-nix"; 20 | spicetify-nix.inputs.nixpkgs.follows = "nixpkgs"; 21 | # daeuniverse 22 | daeuniverse.url = "github:daeuniverse/flake.nix"; 23 | daeuniverse.inputs.nixpkgs.follows = "nixpkgs"; 24 | # xivlauncher-rb 25 | nixos-xivlauncher-rb.url = "github:drakon64/nixos-xivlauncher-rb"; 26 | nixos-xivlauncher-rb.inputs.nixpkgs.follows = "nixpkgs"; 27 | # vscode-extensions 28 | nix-vscode-extensions.url = "github:nix-community/nix-vscode-extensions"; 29 | nix-vscode-extensions.inputs.nixpkgs.follows = "nixpkgs"; 30 | # flake-programs-sqlite 31 | flake-programs-sqlite.url = "github:wamserma/flake-programs-sqlite"; 32 | flake-programs-sqlite.inputs.nixpkgs.follows = "nixpkgs"; 33 | # UMU Launcher 34 | umu.url = "github:Open-Wine-Components/umu-launcher?dir=packaging/nix"; 35 | umu.inputs.nixpkgs.follows = "nixpkgs"; 36 | # firefox-gnome-theme 37 | firefox-gnome-theme = { 38 | url = "github:rafaelmardojai/firefox-gnome-theme"; 39 | flake = false; 40 | }; 41 | }; 42 | 43 | outputs = 44 | { nixpkgs, ... }@inputs: 45 | rec { 46 | nixosConfigurations = { 47 | gnome = nixpkgs.lib.nixosSystem rec { 48 | system = "x86_64-linux"; 49 | specialArgs = { 50 | inherit inputs system; 51 | user = "nixos"; 52 | }; 53 | modules = with inputs; [ 54 | "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-graphical-gnome.nix" 55 | ./livecd.nix 56 | ../nixpkgs.nix 57 | ../platform/desktop/gnome/modules.nix 58 | ../home-manager.nix 59 | home-manager.nixosModules.home-manager 60 | aagl.nixosModules.default 61 | daeuniverse.nixosModules.daed 62 | flake-programs-sqlite.nixosModules.programs-sqlite 63 | { nixpkgs.config.allowUnfree = true; } 64 | ]; 65 | }; 66 | plasma6 = nixpkgs.lib.nixosSystem rec { 67 | system = "x86_64-linux"; 68 | specialArgs = { 69 | inherit inputs system; 70 | user = "nixos"; 71 | }; 72 | modules = with inputs; [ 73 | "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-graphical-plasma6.nix" 74 | ./livecd.nix 75 | ../home-manager.nix 76 | home-manager.nixosModules.home-manager 77 | aagl.nixosModules.default 78 | flake-programs-sqlite.nixosModules.programs-sqlite 79 | daeuniverse.nixosModules.daed 80 | { nixpkgs.config.allowUnfree = true; } 81 | ]; 82 | }; 83 | }; 84 | hydraJobs.iso = nixpkgs.lib.mapAttrs' ( 85 | name: config: nixpkgs.lib.nameValuePair name config.config.system.build.isoImage 86 | ) nixosConfigurations; 87 | }; 88 | } 89 | -------------------------------------------------------------------------------- /iso/livecd.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | imports = [ 3 | # desktop platform modules 4 | ../platform/desktop/modules.nix 5 | # modules/basic 6 | ../modules/time.nix 7 | ../modules/network.nix 8 | ../modules/shell.nix 9 | ../modules/nix.nix 10 | # modules/features 11 | ../modules/features/virtualisation.nix 12 | ../modules/features/docker.nix 13 | ../modules/features/appimage.nix 14 | ../modules/features/nix-ld.nix 15 | # package 16 | ../packages 17 | ../packages/gaming.nix 18 | ]; 19 | 20 | nixpkgs.overlays = [ 21 | (final: prev: { 22 | mutter = prev.mutter.overrideAttrs (oldAttrs: { 23 | patches = oldAttrs.patches or [ ] ++ [ 24 | ../wayland-text-input-v1-Implement-basic-text-input-v1-.patch 25 | ]; 26 | }); 27 | }) 28 | ]; 29 | 30 | isoImage.squashfsCompression = "zstd"; 31 | } 32 | -------------------------------------------------------------------------------- /lanzaboote.nix: -------------------------------------------------------------------------------- 1 | { pkgs, lib, ... }: 2 | { 3 | environment.systemPackages = [ 4 | # For debugging and troubleshooting Secure Boot. 5 | pkgs.sbctl 6 | ]; 7 | 8 | # Lanzaboote currently replaces the systemd-boot module. 9 | # This setting is usually set to true in configuration.nix 10 | # generated at installation time. So we force it to false 11 | # for now. 12 | boot.loader.systemd-boot.enable = lib.mkForce false; 13 | 14 | boot.lanzaboote = { 15 | enable = true; 16 | pkiBundle = "/etc/secureboot"; 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /modules/features/appimage.nix: -------------------------------------------------------------------------------- 1 | _: { programs.appimage.binfmt = true; } 2 | -------------------------------------------------------------------------------- /modules/features/docker.nix: -------------------------------------------------------------------------------- 1 | _: { virtualisation.docker.enable = true; } 2 | -------------------------------------------------------------------------------- /modules/features/filesystems.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | boot.supportedFilesystems = [ 3 | "nfs" 4 | "cifs" 5 | "ntfs" 6 | ]; 7 | } 8 | -------------------------------------------------------------------------------- /modules/features/fwupd.nix: -------------------------------------------------------------------------------- 1 | _: { services.fwupd.enable = true; } 2 | -------------------------------------------------------------------------------- /modules/features/nix-ld.nix: -------------------------------------------------------------------------------- 1 | _: { programs.nix-ld.enable = true; } 2 | -------------------------------------------------------------------------------- /modules/features/pcscd.nix: -------------------------------------------------------------------------------- 1 | _: { services.pcscd.enable = true; } 2 | -------------------------------------------------------------------------------- /modules/features/virtualisation.nix: -------------------------------------------------------------------------------- 1 | # You need kvm-intel / kvm-amd kernel module for virtualisation 2 | { pkgs, ... }: 3 | { 4 | virtualisation = { 5 | libvirtd = { 6 | enable = true; 7 | qemu = { 8 | ovmf.packages = [ pkgs.OVMFFull.fd ]; 9 | swtpm.enable = true; 10 | }; 11 | }; 12 | spiceUSBRedirection.enable = true; 13 | }; 14 | 15 | # https://www.reddit.com/r/NixOS/comments/ulzr88/creating_a_windows_11_vm_on_nixos_secure_boot/ 16 | # https://linustechtips.com/topic/1379063-windows-11-in-virt-manager/ 17 | # https://blog.csdn.net/qq_36393978/article/details/118390233 18 | # https://discourse.nixos.org/t/enable-secure-boot-for-qemu/15718/6 19 | # /etc/ovmf/edk2-x86_64-secure-code.fd 20 | # /etc/ovmf/edk2-i386-vars.fd 21 | } 22 | -------------------------------------------------------------------------------- /modules/i18n.nix: -------------------------------------------------------------------------------- 1 | _: { i18n.supportedLocales = [ "all" ]; } -------------------------------------------------------------------------------- /modules/network.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant. 3 | networking.networkmanager.enable = true; # Easiest to use and most distros use this by default. 4 | } 5 | -------------------------------------------------------------------------------- /modules/nix.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | nix.package = pkgs.nixVersions.latest; 4 | 5 | nix.settings = { 6 | experimental-features = [ 7 | "nix-command" 8 | "flakes" 9 | "ca-derivations" 10 | ]; 11 | trusted-users = [ 12 | "root" 13 | "@wheel" 14 | ]; 15 | # Substituters 16 | substituters = [ 17 | "https://attic.home.lostattractor.net/hydra" 18 | "https://binarycache.home.lostattractor.net" 19 | "https://mirrors.ustc.edu.cn/nix-channels/store" 20 | ]; 21 | trusted-public-keys = [ 22 | "hydra:bCXoAKNbKou4hrnzaH2YB0nvbBPj81PmTklSUSQr5I8=" 23 | "binarycache.home.lostattractor.net:nB258qoytYrdCe2pcI6qJ/M9R0l7Q5l9Bu5ryCbzItc=" 24 | ]; 25 | }; 26 | 27 | # Optimize nix store by using hard-link 28 | nix.settings.auto-optimise-store = true; 29 | 30 | # Automatic GC 31 | nix.gc = { 32 | automatic = true; 33 | dates = "daily"; 34 | options = "--delete-older-than 7d"; 35 | }; 36 | 37 | nix.extraOptions = '' 38 | min-free = ${toString (10 * 1024 * 1024 * 1024)} 39 | max-free = ${toString (20 * 1024 * 1024 * 1024)} 40 | ''; 41 | } 42 | -------------------------------------------------------------------------------- /modules/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | programs.fish.enable = true; 4 | users.defaultUserShell = pkgs.fish; 5 | } 6 | -------------------------------------------------------------------------------- /modules/ssh.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.openssh = { 3 | enable = true; 4 | settings = { 5 | # Require public key authentication 6 | PasswordAuthentication = false; 7 | KbdInteractiveAuthentication = false; 8 | }; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /modules/time.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # Set your time zone. 3 | time.timeZone = "Asia/Shanghai"; 4 | # May cause problems with systemd timer 5 | # time.hardwareClockInLocalTime = true; 6 | } 7 | -------------------------------------------------------------------------------- /nixpkgs.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | { 3 | nixpkgs.config.allowUnfree = true; 4 | 5 | nixpkgs.config.permittedInsecurePackages = [ 6 | "openssl-1.1.1w" # wechat-uos 7 | "electron-27.3.11" 8 | "electron-unwrapped-27.3.11" 9 | "electron-29.4.6" 10 | "jitsi-meet-1.0.8043" 11 | "cinny-4.2.3" 12 | "cinny-unwrapped-4.2.3" 13 | ]; 14 | 15 | nixpkgs.overlays = [ 16 | inputs.nur.overlays.default 17 | inputs.nix-vscode-extensions.overlays.default 18 | 19 | (final: prev: { 20 | chromium = prev.chromium.override { 21 | commandLineArgs = [ 22 | "--wayland-text-input-version=3" 23 | "--enable-features=VaapiVideoDecoder" 24 | ]; 25 | }; 26 | google-chrome = prev.google-chrome.override { 27 | commandLineArgs = [ 28 | "--wayland-text-input-version=3" 29 | "--enable-features=VaapiVideoDecoder" 30 | ]; 31 | }; 32 | brave = prev.brave.override { 33 | commandLineArgs = [ 34 | "--wayland-text-input-version=3" 35 | "--enable-features=VaapiVideoDecoder" 36 | ]; 37 | }; 38 | vscode = prev.vscode.override { commandLineArgs = [ "--wayland-text-input-version=3" ]; }; 39 | qq = prev.qq.override { commandLineArgs = [ "--wayland-text-input-version=3" ]; }; 40 | 41 | signal-desktop = prev.signal-desktop.overrideAttrs (oldAttrs: { 42 | postInstall = 43 | oldAttrs.postInstall or "" 44 | + '' 45 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 46 | --add-flags "--wayland-text-input-version=3" 47 | ''; 48 | }); 49 | 50 | element-desktop = prev.element-desktop.overrideAttrs (oldAttrs: { 51 | postInstall = 52 | oldAttrs.postInstall or "" 53 | + '' 54 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 55 | --add-flags "--wayland-text-input-version=3" 56 | ''; 57 | }); 58 | 59 | discord = 60 | let 61 | binaryName = prev.discord.meta.mainProgram; 62 | in 63 | prev.discord.overrideAttrs (oldAttrs: { 64 | postInstall = 65 | oldAttrs.postInstall or "" 66 | + '' 67 | wrapProgram $out/opt/${binaryName}/${binaryName} \ 68 | --add-flags "--wayland-text-input-version=3" 69 | ''; 70 | }); 71 | 72 | logseq = prev.logseq.overrideAttrs (oldAttrs: { 73 | postFixup = 74 | oldAttrs.postFixup or "" 75 | + '' 76 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 77 | --add-flags "--wayland-text-input-version=3" 78 | ''; 79 | }); 80 | 81 | obsidian = prev.obsidian.overrideAttrs (oldAttrs: { 82 | postInstall = 83 | oldAttrs.postInstall or "" 84 | + '' 85 | wrapProgram $out/bin/${oldAttrs.pname} \ 86 | --add-flags "--wayland-text-input-version=3" 87 | ''; 88 | }); 89 | 90 | marktext = prev.marktext.overrideAttrs (oldAttrs: { 91 | postInstall = 92 | oldAttrs.postInstall or "" 93 | + '' 94 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 95 | --add-flags "--wayland-text-input-version=3" 96 | ''; 97 | }); 98 | 99 | kuro = prev.kuro.overrideAttrs (oldAttrs: { 100 | postInstall = 101 | oldAttrs.postInstall or "" 102 | + '' 103 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 104 | --add-flags "--wayland-text-input-version=3" 105 | ''; 106 | }); 107 | 108 | github-desktop = prev.github-desktop.overrideAttrs (oldAttrs: { 109 | postInstall = 110 | oldAttrs.postInstall or "" 111 | + '' 112 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 113 | --add-flags "--wayland-text-input-version=3" 114 | ''; 115 | }); 116 | 117 | bitwarden = prev.bitwarden.overrideAttrs (oldAttrs: { 118 | postInstall = 119 | oldAttrs.postInstall or "" 120 | + '' 121 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 122 | --add-flags "--wayland-text-input-version=3" 123 | ''; 124 | }); 125 | }) 126 | ]; 127 | } -------------------------------------------------------------------------------- /packages/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | # List packages installed in system profile. To search, run: 4 | # $ nix search wget 5 | environment.systemPackages = with pkgs; [ 6 | # Download Tools 7 | wget 8 | axel 9 | curlHTTP3 10 | # Editor & VCS 11 | git 12 | vim 13 | nano 14 | # Basic Tools 15 | htop 16 | tmux 17 | lsof 18 | # Devices 19 | pciutils 20 | usbutils 21 | smartmontools 22 | # Network 23 | inetutils 24 | bridge-utils 25 | dnsutils 26 | ethtool 27 | trippy 28 | q 29 | dogdns 30 | # Graphics 31 | vulkan-tools 32 | mesa-demos 33 | # Video Codec 34 | libva-utils 35 | # Sensors 36 | lm_sensors 37 | # Rsync 38 | rsync 39 | # Compiler 40 | clang 41 | go 42 | rustup 43 | gcc 44 | gdb 45 | # Runtime 46 | nodejs 47 | yarn 48 | python3 49 | ]; 50 | 51 | # Some programs need SUID wrappers, can be configured further or are 52 | # started in user sessions. 53 | programs.iotop.enable = true; 54 | programs.iftop.enable = true; 55 | programs.bandwhich.enable = true; 56 | programs.mtr.enable = true; 57 | programs.nexttrace.enable = true; 58 | programs.trippy.enable = true; 59 | programs.wireshark.enable = true; 60 | 61 | programs.sharing.enable = true; 62 | 63 | # Android debug bridge 64 | programs.adb.enable = true; 65 | } 66 | -------------------------------------------------------------------------------- /packages/gaming.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs, 3 | pkgs, 4 | config, 5 | ... 6 | }: 7 | { 8 | environment.systemPackages = [ 9 | (inputs.nixos-xivlauncher-rb.packages.x86_64-linux.default.override { 10 | useGameMode = true; 11 | nvngxPath = "${config.hardware.nvidia.package}/lib/nvidia/wine"; 12 | }) 13 | ]; 14 | 15 | programs.steam = { 16 | enable = true; 17 | gamescopeSession.enable = true; 18 | remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play 19 | dedicatedServer.openFirewall = true; # Open ports in the firewall for Source Dedicated Server 20 | extraCompatPackages = with pkgs; [ proton-ge-bin ]; 21 | }; 22 | 23 | programs.gamescope.enable = true; 24 | # programs.gamescope.capSysNice = true; 25 | 26 | programs.gamemode.enable = true; 27 | 28 | nix.settings = inputs.aagl.nixConfig; # Set up Cachix 29 | programs.anime-game-launcher.enable = true; # Adds launcher and /etc/hosts rules 30 | programs.anime-games-launcher.enable = true; 31 | programs.honkers-railway-launcher.enable = true; 32 | programs.honkers-launcher.enable = true; 33 | programs.wavey-launcher.enable = true; 34 | programs.sleepy-launcher.enable = true; 35 | } 36 | -------------------------------------------------------------------------------- /platform/desktop/default.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | { 3 | imports = [ 4 | # Using Gnome by default 5 | ./gnome 6 | # Basic modules for desktop 7 | ./modules.nix 8 | ]; 9 | 10 | specialisation = 11 | lib.mapAttrs 12 | (name: config: { 13 | configuration = { 14 | system.nixos.tags = [ name ]; 15 | disabledModules = [ ./gnome ]; 16 | } // config; 17 | }) 18 | { 19 | "Hyprland" = { 20 | imports = [ ./hyprland ]; 21 | }; 22 | "Plasma" = { 23 | imports = [ ./plasma ]; 24 | }; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /platform/desktop/gnome/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.xserver.enable = true; 3 | services.xserver.displayManager.gdm.enable = true; 4 | services.xserver.desktopManager.gnome.enable = true; 5 | 6 | imports = [ ./modules.nix ]; 7 | } 8 | -------------------------------------------------------------------------------- /platform/desktop/gnome/modules.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | options, 5 | user, 6 | ... 7 | }: 8 | { 9 | config = 10 | { 11 | environment.gnome.excludePackages = with pkgs; [ 12 | gnome-tour 13 | epiphany 14 | ]; 15 | 16 | # Open Firewall for Gnome Remote Display 17 | networking.firewall.allowedTCPPorts = [ 3389 ]; 18 | 19 | # Open Firewall for gsconnect 20 | programs.kdeconnect = { 21 | enable = true; 22 | package = pkgs.gnomeExtensions.gsconnect; 23 | }; 24 | } 25 | // lib.optionalAttrs (options ? home-manager) { 26 | home-manager.users.${user} = import ../../../user/desktop/gnome; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /platform/desktop/hyprland/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | programs.hyprland.enable = true; 3 | xdg.portal.enable = true; 4 | 5 | imports = [ ./modules.nix ]; 6 | } 7 | -------------------------------------------------------------------------------- /platform/desktop/hyprland/modules.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | lib, 4 | options, 5 | user, 6 | ... 7 | }: 8 | { 9 | config = 10 | { 11 | environment.systemPackages = with pkgs; [ adwaita-icon-theme ]; 12 | 13 | services.gvfs.enable = true; 14 | 15 | services.gnome.gnome-keyring.enable = true; 16 | programs.gnupg.agent.pinentryPackage = pkgs.pinentry-gnome3; # need gcr 17 | } 18 | // lib.optionalAttrs (options ? home-manager) { 19 | home-manager.users.${user} = import ../../../user/desktop/hyprland; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /platform/desktop/modules.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | imports = [ 3 | # platform/modules/basic 4 | ../modules/fonts.nix 5 | # platform/modules/hardware 6 | ../modules/hardware/bluetooth.nix 7 | ../modules/hardware/gamepad.nix 8 | ../modules/hardware/mobiledevice.nix 9 | # platform/modules/features 10 | ../modules/features/audio/pipewire.nix 11 | ../modules/features/ime/fcitx5.nix 12 | ../modules/features/avahi.nix 13 | ../modules/features/printing.nix 14 | ../modules/features/flatpak.nix 15 | ]; 16 | } 17 | -------------------------------------------------------------------------------- /platform/desktop/plasma/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.displayManager.sddm.enable = true; 3 | services.displayManager.sddm.wayland.enable = true; 4 | services.desktopManager.plasma6.enable = true; 5 | } 6 | -------------------------------------------------------------------------------- /platform/modules/features/audio/pipewire.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # rtkit is optional but recommended 3 | security.rtkit.enable = true; 4 | # Pipewire 5 | services.pipewire = { 6 | enable = true; 7 | alsa.enable = true; 8 | alsa.support32Bit = true; 9 | pulse.enable = true; 10 | # If you want to use JACK applications, uncomment this 11 | # jack.enable = true; 12 | 13 | wireplumber.enable = true; 14 | 15 | extraConfig.pipewire."echo-cancel" = { 16 | # Echo cancellation 17 | "context.modules" = [ 18 | { 19 | name = "libpipewire-module-echo-cancel"; 20 | args = { 21 | # Monitor mode: Instead of creating a virtual sink into which all 22 | # applications must play, in PipeWire the echo cancellation module can read 23 | # the audio that should be cancelled directly from the current fallback 24 | # audio output 25 | "monitor.mode" = true; 26 | # The audio source / microphone wherein the echo should be cancelled is not 27 | # specified explicitly; the module follows the fallback audio source setting 28 | "source.props" = { 29 | # Name and description of the virtual source where you get the audio 30 | # without echoed speaker output 31 | "node.name" = "source_ec"; 32 | "node.description" = "Echo-cancelled source"; 33 | }; 34 | "aec.args" = { 35 | # Settings for the WebRTC echo cancellation engine 36 | # https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/spa/plugins/aec/aec-webrtc.cpp 37 | # "webrtc.gain_control" = true; 38 | }; 39 | }; 40 | } 41 | ]; 42 | }; 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /platform/modules/features/audio/pulseaudio.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # rtkit is optional but recommended 3 | security.rtkit.enable = true; 4 | # PulseAudio 5 | hardware.pulseaudio.enable = true; 6 | } 7 | -------------------------------------------------------------------------------- /platform/modules/features/avahi.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.avahi = { 3 | enable = true; 4 | nssmdns4 = true; 5 | nssmdns6 = true; 6 | ipv6 = true; 7 | publish = { 8 | enable = true; 9 | domain = true; 10 | addresses = true; 11 | workstation = true; 12 | userServices = true; 13 | hinfo = true; 14 | }; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /platform/modules/features/flatpak.nix: -------------------------------------------------------------------------------- 1 | _: { services.flatpak.enable = true; } 2 | -------------------------------------------------------------------------------- /platform/modules/features/ime/fcitx5.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | i18n.inputMethod = { 4 | enable = true; 5 | type = "fcitx5"; 6 | fcitx5.addons = with pkgs; [ 7 | fcitx5-rime 8 | fcitx5-chinese-addons 9 | ]; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /platform/modules/features/ime/ibus.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | # BUG: 如果不设置 LANG=zh_CN.utf8 可能导致ibus中文输入异常 4 | i18n.inputMethod = { 5 | enable = true; 6 | type = "ibus"; 7 | ibus.engines = with pkgs.ibus-engines; [ rime ]; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /platform/modules/features/plymouth.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # Quiet boot with plymouth - supports LUKS passphrase entry if needed 3 | boot.kernelParams = [ 4 | "quiet" 5 | "rd.systemd.show_status=false" 6 | "rd.udev.log_level=3" 7 | "udev.log_priority=3" 8 | "boot.shell_on_fail" 9 | ]; 10 | boot.consoleLogLevel = 0; 11 | boot.initrd.verbose = false; 12 | boot.plymouth.enable = true; 13 | } 14 | -------------------------------------------------------------------------------- /platform/modules/features/printing.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # Enable CUPS to print documents. 3 | services.printing.enable = true; 4 | } 5 | -------------------------------------------------------------------------------- /platform/modules/fonts.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | fonts = { 4 | packages = with pkgs; [ 5 | # Cantarell 6 | cantarell-fonts 7 | # Noto Fonts 8 | noto-fonts 9 | noto-fonts-color-emoji 10 | # 思源宋体/思源黑体 (CJK Fonts) 11 | # Variable-fonts may cause some apps to not render CJK correctly 12 | noto-fonts-cjk-sans 13 | noto-fonts-cjk-serif 14 | # So also install non-variable version 15 | source-han-sans 16 | source-han-serif 17 | source-han-mono 18 | # Monospace fonts 19 | fira-code 20 | fira-code-symbols 21 | nerd-fonts.fira-code 22 | jetbrains-mono 23 | nerd-fonts.jetbrains-mono 24 | nerd-fonts.droid-sans-mono 25 | # Some unused fonts 26 | # Inter font 27 | # inter 28 | # Source fonts 29 | # source-sans-pro 30 | # source-serif-pro 31 | # source-code-pro 32 | # 文泉驿 33 | # wqy_microhei 34 | # wqy_zenhei 35 | # 更纱黑体 36 | # sarasa-gothic 37 | # hack fonts (monospace) 38 | # hack-font 39 | ]; 40 | fontconfig = { 41 | defaultFonts = { 42 | sansSerif = [ 43 | # Main Sans-Serif Font 44 | "Cantarell" 45 | # CJK Fallback 46 | "Noto Sans SC" 47 | "Noto Sans TC" 48 | "Noto Sans JP" 49 | "Noto Sans KR" 50 | # Unicode Fallback 51 | "DejaVu Sans" 52 | ]; 53 | serif = [ 54 | # Main Serif Font 55 | "Noto Serif" 56 | # CJK Fallback 57 | "Noto Serif SC" 58 | "Noto Serif TC" 59 | "Noto Serif JP" 60 | "Noto Serif KR" 61 | # Unicode Fallback 62 | "DejaVu Serif" 63 | ]; 64 | monospace = [ 65 | # Main Mono Font 66 | "JetBrainsMono" 67 | # CJK Fallback 68 | "Noto Mono SC" 69 | "Noto Mono TC" 70 | "Noto Mono JP" 71 | "Noto Mono KR" 72 | # Unicode Fallback 73 | "DejaVu Sans Mono" 74 | ]; 75 | emoji = [ "Noto Color Emoji" ]; 76 | }; 77 | 78 | subpixel.rgba = "rgb"; 79 | }; 80 | }; 81 | } 82 | -------------------------------------------------------------------------------- /platform/modules/hardware/bluetooth.nix: -------------------------------------------------------------------------------- 1 | _: { hardware.bluetooth.enable = true; } 2 | -------------------------------------------------------------------------------- /platform/modules/hardware/gamepad.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | hardware = { 3 | xone.enable = true; 4 | xpadneo.enable = true; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /platform/modules/hardware/mobiledevice.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | services.usbmuxd.enable = true; 4 | 5 | environment.systemPackages = with pkgs; [ 6 | libimobiledevice 7 | ifuse # optional, to mount using 'ifuse' 8 | ]; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/deploy-flake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$EUID" -ne 0 ] 3 | then echo "Please run as root" 4 | exit 5 | fi 6 | nixos-rebuild switch --flake .# $* --log-format internal-json -v |& nom --json -------------------------------------------------------------------------------- /scripts/update-ca-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | git stash --all 3 | 4 | git checkout $(git rev-parse master) 5 | git cherry-pick origin/ca-test 6 | HEAD=$(git rev-parse HEAD) 7 | git checkout -B ca-test 8 | git reset --hard ${HEAD} 9 | 10 | git stash pop -------------------------------------------------------------------------------- /scripts/update-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$EUID" -ne 0 ] 3 | then echo "Please run as root" 4 | exit 5 | fi 6 | ./scripts/update-flake.sh 7 | ./scripts/deploy-flake.sh $* -------------------------------------------------------------------------------- /scripts/update-flake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | nix flake update -v -------------------------------------------------------------------------------- /secrets/.sops.yaml: -------------------------------------------------------------------------------- 1 | # This example uses YAML anchors which allows reuse of multiple keys 2 | # without having to repeat yourself. 3 | # Also see https://github.com/Mic92/dotfiles/blob/master/nixos/.sops.yaml 4 | # for a more complex example. 5 | keys: 6 | - &admin_lostattractor 57EDCBEDDE7ABA6B44377FF2B96725F36430B3D1 7 | - &device_calaptopg14 age197ftfqlm75q9vlcc5mu6j5a90fh8lfw0cecxvw968xmrkgwjg59qledtwm 8 | creation_rules: 9 | - path_regex: secrets.yaml 10 | key_groups: 11 | - pgp: 12 | - *admin_lostattractor 13 | age: 14 | - *device_calaptopg14 -------------------------------------------------------------------------------- /secrets/cert/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHzCCAaWgAwIBAgIUV4AZwX79HfbqPW6HYzEK/YXEjBswCgYIKoZIzj0EAwMw 3 | TzELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFNoYW5naGFpMREwDwYDVQQHEwhTaGFu 4 | Z2hhaTEaMBgGA1UEAxMRbG9zdGF0dHJhY3Rvci5uZXQwHhcNMjMxMjE2MTY0MDAw 5 | WhcNMjgxMjE0MTY0MDAwWjBPMQswCQYDVQQGEwJDTjERMA8GA1UECBMIU2hhbmdo 6 | YWkxETAPBgNVBAcTCFNoYW5naGFpMRowGAYDVQQDExFsb3N0YXR0cmFjdG9yLm5l 7 | dDB2MBAGByqGSM49AgEGBSuBBAAiA2IABG1OjXZwBAN/8Y6TXVv6NWuUpRsUjJqL 8 | n8J+thUOon6LTZ6bniwU2B4sh6K/3m9glzAygrB87lyqg7lJ9rYHwrmf56KpNKi5 9 | Zz9smYg/jNAUcQTMR98CDBKLk8Ojwh7gVKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8G 10 | A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKKs+Tg5GrlJTZiQsGRxJPo7ZdJsMAoG 11 | CCqGSM49BAMDA2gAMGUCMHw+0I6RK6ciXGocJZ2bASNP7/0bouLV/FR1q98qchx3 12 | DcNGm6V+NjLFAEsxb2MyKwIxANdW0gCWQb/pjuWBSuaOxdWaAfjVvKWf40Vc76bX 13 | mf5JU53a/O7DH+20JcBCj9+UAA== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /secrets/cert/default.nix: -------------------------------------------------------------------------------- 1 | _: { security.pki.certificateFiles = [ ./ca.pem ]; } 2 | -------------------------------------------------------------------------------- /secrets/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | imports = [ ./cert ]; 3 | 4 | sops.defaultSopsFile = ./secrets.yaml; 5 | } 6 | -------------------------------------------------------------------------------- /secrets/secrets.yaml: -------------------------------------------------------------------------------- 1 | rathole: 2 | token: ENC[AES256_GCM,data:HJVkEYhEOoIq7UvYR8HS4Q==,iv:O2x1vOADcr8nmAJjFWxlmAciSJQBwCVVJaq/w8h3Rz4=,tag:t9GED4ECTEmCiL/cz2HqGQ==,type:str] 3 | nix: 4 | access-tokens: 5 | github: ENC[AES256_GCM,data:ymkz5XZEXWTwE77VFVMA6Qy55j2zGtn1l739Q0a53sbwGSCq8U5nog==,iv:XA9fqtSRuVymzkrTjRzpf5w5Uo4ZV90JVph4fURnCW8=,tag:/wO43vI0MaFMn6cQeUGoWQ==,type:str] 6 | sops: 7 | kms: [] 8 | gcp_kms: [] 9 | azure_kv: [] 10 | hc_vault: [] 11 | age: 12 | - recipient: age197ftfqlm75q9vlcc5mu6j5a90fh8lfw0cecxvw968xmrkgwjg59qledtwm 13 | enc: | 14 | -----BEGIN AGE ENCRYPTED FILE----- 15 | YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6UUY3N2dQZGxNOStjRG52 16 | ZkY4MS9tSzRRVzJpQlpaclRlbytxMnA0QTFjCkU0b0Z1Z3dUOGZxU0VJYkhpbkd0 17 | OW16NU4yZTZIZFlOZzMzdStSU2VyMjAKLS0tIFVuMW5qd2QvcVBDZTJqQngyL2g0 18 | ZFY0aVRacDNXWnF2ODNESnp2Q3RXclUKEKq4Hv//t8a4GHuDiTkYgxW1u9cCCmt1 19 | WG/8WYFRbJXNnL4JqBy3cP1EoqfqjqtuJdpy7DkrTwIMgQ3jO1iUTw== 20 | -----END AGE ENCRYPTED FILE----- 21 | lastmodified: "2024-06-15T08:41:28Z" 22 | mac: ENC[AES256_GCM,data:9FxXnBYCXwlPqcP+pVa35TMVyNYJ6/jEOocDdLO+qlPPLmHFEI4DUvbFPCdNEZgshjxjf4VrwVWhjYg0foQzJT4qx/rHh4Y4BnLjndLgQe8fi/t0eT7MapPJoZu+dwO82n7O+faiO9tU25zrkZR0e+/FYz2SGXn+rKHqcjmv6vo=,iv:KTE343pLPtEBd5vFppf5hU8TTGUd+3Dh6NwbEUF20ck=,tag:/9gmnvyrkI/2ncfU6JLe5A==,type:str] 23 | pgp: 24 | - created_at: "2024-04-07T21:29:49Z" 25 | enc: |- 26 | -----BEGIN PGP MESSAGE----- 27 | 28 | hH4DuWcl82Qws9ESAgMEcZwxQx9a5iHzVXg3nq98vMEWP20e+6/BoBK2kpvdEu+e 29 | hIImt8MumpNfA6XCR8/GEO3qWAJLMDBXp7qrm+QcCzBndf5cn1qi9lnldYgkQrjq 30 | E+sOCS3LHqlT7+4NXO090+8Xh+igT/X0JlytR914jBfUaAEJAhAzjOaId59+juld 31 | s6wmdTQv4vxz7yKkKBDvMsOFVmJmTClK487Ce/MCM4oeoVzXWe4M9NT8Uy/JEvXE 32 | T0AfLN9G2PETHAFwEqquJc4Esc5yeqOaaKWqu3poTGRdEICOm7AmDqP3 33 | =UC26 34 | -----END PGP MESSAGE----- 35 | fp: 57EDCBEDDE7ABA6B44377FF2B96725F36430B3D1 36 | unencrypted_suffix: _unencrypted 37 | version: 3.8.1 38 | -------------------------------------------------------------------------------- /security.md: -------------------------------------------------------------------------------- 1 | # WIP 2 | 3 | # Introduction 4 | 5 | The premise of everything in this article is that the link between cpu and tpm cannot be side-channel attacked or the key can be derived through vulnerabilities (like the fTPM vulnerability for AMD's ZEN3 cpus). 6 | 7 | At the same time, side-channel attacks or cold boot attacks on memory links may also be able to steal the keys stored in the TPM. 8 | 9 | # TPM PCRS 10 | 11 | PCR 0~3 is BIOS binary/settings, extended or pluggable devices binary/settings (that can DMA). 12 | 13 | When external device binary is verified, it may not be possible to export the key from the TPM at all. But considering the worst case scenario, IOMMU and Pre boot DMA protection are still necessary to ensure security. 14 | 15 | PCR 4,9,11 will change when nixos-rebuild, but since there is secure boot, this is not a problem. 16 | 17 | So here we verify all values ​​from 0 to 9 except 4, and also verify 12 from 11 to 14 : 18 | 19 | 20 | ```bash 21 | sudo systemd-cryptenroll /dev/nvme0n1p2 --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=0+1+2+3+5+6+7+8+12 22 | ``` 23 | 24 | ## Show all PCRs 25 | 26 | ```bash 27 | systemd-analyze pcrs 28 | 29 | NR NAME SHA256 30 | 0 platform-code 17fd69d452d578af04c65db302d5d2bc04faf1bd691b523be36dea198f09fc9d 31 | 1 platform-config 31016a55db0129c763093ddaf9b2b74ddcd7bb4d4005df5873b0f77666634522 32 | 2 external-code 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 33 | 3 external-config 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 34 | 4 boot-loader-code b0396a197f78233fd587060cc48dfb1e27ce910326c75fdf130996c48f851b85 35 | 5 boot-loader-config dc76310226ff6e715c60aa7484dac85b580170ca6cd89402f47a078180be9fe5 36 | 6 host-platform 3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969 37 | 7 secure-boot-policy e5207fc1b545ae5e1fe575f7f6b4ac5fbe549420414c5a71d6357de6c0c749d6 38 | 8 - 0000000000000000000000000000000000000000000000000000000000000000 39 | 9 kernel-initrd c3ab37e05b8bcd4e28f69618f0096bdce2df782fed71b59fdf1ef7150b7fc422 40 | 10 ima 0000000000000000000000000000000000000000000000000000000000000000 41 | 11 kernel-boot 2009a0c0571b8305f7ba3ed5948b7e10e6d0c7dd8c6c9e0aa0ea766adb55c078 42 | 12 kernel-config 0000000000000000000000000000000000000000000000000000000000000000 43 | 13 sysexts 0000000000000000000000000000000000000000000000000000000000000000 44 | 14 shim-policy 0000000000000000000000000000000000000000000000000000000000000000 45 | 15 system-identity 0000000000000000000000000000000000000000000000000000000000000000 46 | 16 debug 0000000000000000000000000000000000000000000000000000000000000000 47 | 17 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 48 | 18 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 49 | 19 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 50 | 20 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 51 | 21 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 52 | 22 - ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 53 | 23 application-support 0000000000000000000000000000000000000000000000000000000000000000 54 | ``` 55 | 56 | # AppArmor (TODO) 57 | 58 | # Reference 59 | https://wiki.archlinux.org/title/Trusted_Platform_Module -------------------------------------------------------------------------------- /specific/architecture-specific/x86-64/default.nix: -------------------------------------------------------------------------------- 1 | _: { imports = [ ./modules/features/binfmt.nix ]; } 2 | -------------------------------------------------------------------------------- /specific/architecture-specific/x86-64/modules/features/binfmt.nix: -------------------------------------------------------------------------------- 1 | _: { boot.binfmt.emulatedSystems = [ "aarch64-linux" ]; } 2 | -------------------------------------------------------------------------------- /specific/general/amd/virtualisation.nix: -------------------------------------------------------------------------------- 1 | # You need kvm-intel / kvm-amd kernelModule for virtualisation 2 | _: { 3 | # AMD IOMMU is enabled by default 4 | # https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Enabling_IOMMU 5 | boot.extraModprobeConfig = "options kvm_amd nested=1"; # nested virtualization 6 | } 7 | -------------------------------------------------------------------------------- /specific/general/btrfs/autoscrub.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.btrfs.autoScrub = { 3 | enable = true; 4 | interval = "monthly"; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /specific/general/btrfs/docker.nix: -------------------------------------------------------------------------------- 1 | _: { virtualisation.docker.storageDriver = "btrfs"; } 2 | -------------------------------------------------------------------------------- /specific/general/btrfs/snapper.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.snapper = { 3 | configs."home" = { 4 | SUBVOLUME = "/home"; 5 | ALLOW_GROUPS = [ "wheel" ]; 6 | TIMELINE_CREATE = true; 7 | TIMELINE_CLEANUP = true; 8 | TIMELINE_LIMIT_HOURLY = 24; 9 | TIMELINE_LIMIT_DAILY = 7; 10 | TIMELINE_LIMIT_WEEKLY = 3; 11 | TIMELINE_LIMIT_MONTHLY = 0; 12 | TIMELINE_LIMIT_YEARLY = 0; 13 | }; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /specific/general/keyboard/vamillo.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | boot.extraModprobeConfig = '' 3 | options hid_apple fnmode=0 4 | ''; 5 | } 6 | -------------------------------------------------------------------------------- /specific/general/linux/tpm2.nix: -------------------------------------------------------------------------------- 1 | _: 2 | { 3 | # Use systemd-cryptenroll to auto unlock luks partition 4 | boot.initrd.systemd.enable = true; 5 | security.tpm2.enable = true; 6 | security.tpm2.tctiEnvironment.enable = true; 7 | 8 | # security.tpm2.pkcs11.enable = true; 9 | # security.tpm2.pkcs11.package = pkgs.tpm2-pkcs11.override { abrmdSupport = false; }; # Using Kernel RM 10 | 11 | # environment.systemPackages = with pkgs; [ 12 | # (tpm2-tools.override { abrmdSupport = false; }) 13 | # tpm2-tss 14 | # ]; 15 | } -------------------------------------------------------------------------------- /specific/general/linux/zram.nix: -------------------------------------------------------------------------------- 1 | _: { zramSwap.enable = true; } 2 | -------------------------------------------------------------------------------- /specific/general/linux/zswap.nix: -------------------------------------------------------------------------------- 1 | _: 2 | { 3 | boot.kernelParams = [ 4 | "zswap.enabled=1" 5 | "zswap.shrinker_enabled=1" 6 | "zswap.parameters.compressor=lz4" 7 | ]; 8 | } -------------------------------------------------------------------------------- /specific/general/nvidia/beta.nix: -------------------------------------------------------------------------------- 1 | { config, ... }: 2 | { 3 | hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.beta; 4 | } 5 | -------------------------------------------------------------------------------- /specific/general/nvidia/cuda.nix: -------------------------------------------------------------------------------- 1 | _: { nixpkgs.config.cudaSupport = true; } 2 | -------------------------------------------------------------------------------- /specific/general/nvidia/specialisation.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | specialisation."NvidiaSync".configuration = { 3 | system.nixos.tags = [ "Nvidia-Sync-Mode" ]; 4 | 5 | hardware.nvidia.prime = { 6 | offload.enable = false; 7 | sync.enable = true; 8 | }; 9 | }; 10 | 11 | specialisation."NvidiaReverseSync".configuration = { 12 | system.nixos.tags = [ "Nvidia-Reverse-Sync-Mode" ]; 13 | 14 | hardware.nvidia.prime = { 15 | reverseSync.enable = true; 16 | 17 | # Enable if using an external GPU 18 | allowExternalGpu = false; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /specific/general/radio/rtl-sdr.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: { 2 | hardware.rtl-sdr.enable = true; 3 | environment.systemPackages = with pkgs; [ rtl-sdr ]; 4 | } -------------------------------------------------------------------------------- /specific/general/ssd/trim.nix: -------------------------------------------------------------------------------- 1 | _: 2 | { 3 | services.fstrim.enable = true; 4 | } -------------------------------------------------------------------------------- /specific/general/tablet/opentabletdriver.nix: -------------------------------------------------------------------------------- 1 | _: { hardware.opentabletdriver.enable = true; } -------------------------------------------------------------------------------- /specific/general/zfs/docker.nix: -------------------------------------------------------------------------------- 1 | _: { virtualisation.docker.storageDriver = "zfs"; } 2 | -------------------------------------------------------------------------------- /specific/hardware-specific/apple-silicon/.gitignore: -------------------------------------------------------------------------------- 1 | firmware -------------------------------------------------------------------------------- /specific/hardware-specific/apple-silicon/default.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | { 3 | hardware.asahi.useExperimentalGPUDriver = true; 4 | # hardware.asahi.experimentalGPUInstallMode = "overlay"; 5 | 6 | # hardware.asahi.peripheralFirmwareDirectory = ./firmware; 7 | # hardware.asahi.extractPeripheralFirmware = false; 8 | 9 | boot.loader.timeout = lib.mkForce 5; 10 | 11 | boot.loader.efi.canTouchEfiVariables = lib.mkForce false; 12 | } 13 | -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | imports = [ 4 | ../../general/amd/virtualisation.nix 5 | ../../general/nvidia/cuda.nix 6 | ../../general/nvidia/beta.nix 7 | # ../../general/nvidia/specialisation.nix 8 | # ./modules/features/gpu-paththrough/specialisation.nix 9 | ./modules/features/gpu-paththrough/hooks.nix 10 | # ./modules/features/libfprint-goodix-521d 11 | ]; 12 | } 13 | -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/hooks.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | # Load Hooks for Libvirt 4 | systemd.services.libvirtd.preStart = 5 | let 6 | qemuHook = pkgs.writeScript "qemu-hook" '' 7 | #!${pkgs.runtimeShell} 8 | 9 | GUEST_NAME="$1" 10 | HOOK_NAME="$2" 11 | STATE_NAME="$3" 12 | MISC="$\{@:4}" 13 | 14 | BASEDIR="$(dirname $0)" 15 | 16 | HOOKPATH="$BASEDIR/qemu.d/$GUEST_NAME/$HOOK_NAME/$STATE_NAME" 17 | set -e # If a script exits with an error, we should as well. 18 | 19 | if [ -f "$HOOKPATH" ]; then 20 | eval \""$HOOKPATH"\" "$@" 21 | elif [ -d "$HOOKPATH" ]; then 22 | while read file; do 23 | eval \""$file"\" "$@" 24 | done <<< "$(find -L "$HOOKPATH" -maxdepth 1 -type f -executable -print;)" 25 | fi 26 | ''; 27 | in 28 | '' 29 | mkdir -p /var/lib/libvirt/hooks 30 | chmod 755 /var/lib/libvirt/hooks 31 | 32 | # Copy hook files 33 | ln -sf ${qemuHook} /var/lib/libvirt/hooks/qemu 34 | cp -rfT ${./qemu.d} /var/lib/libvirt/hooks/qemu.d 35 | 36 | # Make executable 37 | chmod -R +x /var/lib/libvirt/hooks/qemu.d/ 38 | ''; 39 | } 40 | -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/qemu.d/win11-hybrid/prepare/begin/start.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | set -x 3 | 4 | # Xpad affects the work of the xbox controller and its wireless adapter 5 | # The xpad will shake hands with the handle/wireless adapter when it is plugged in. At this time, 6 | # if you pass the usb device directly to the virtual machine, the xbox handle will not re-handshake with the root of windows, 7 | # which will eventually cause it to fail to work. 8 | # I can't find a way to make the usb device passthrough into the virtual machine from before/when it is plugged in, 9 | # so I suggest you disable this driver if you need to use the gamepad in virtual machine 10 | modprobe -r xpad 11 | 12 | # Stop display manager 13 | systemctl stop display-manager 14 | 15 | sleep 5 16 | 17 | # Unbind VTconsoles: might not be needed 18 | echo 0 > /sys/class/vtconsole/vtcon0/bind 19 | echo 0 > /sys/class/vtconsole/vtcon1/bind 20 | 21 | # Unbind EFI Framebuffer 22 | echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind 23 | 24 | sleep 3 25 | 26 | # Unload NVIDIA kernel modules 27 | modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia 28 | 29 | # Unload AMD kernel module 30 | modprobe -r amdgpu 31 | 32 | # Detach GPU devices from host 33 | # Use your GPU and HDMI Audio PCI host device 34 | virsh nodedev-detach pci_0000_01_00_0 35 | virsh nodedev-detach pci_0000_01_00_1 36 | virsh nodedev-detach pci_0000_04_00_0 37 | virsh nodedev-detach pci_0000_04_00_1 38 | 39 | # Load vfio module 40 | modprobe vfio_pci -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/qemu.d/win11-hybrid/release/end/stop.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | set -x 3 | 4 | # Load Xpad 5 | modprobe xpad 6 | 7 | # Attach GPU devices to host 8 | # Use your GPU and HDMI Audio PCI host device 9 | virsh nodedev-reattach pci_0000_01_00_0 10 | virsh nodedev-reattach pci_0000_01_00_1 11 | virsh nodedev-reattach pci_0000_04_00_0 12 | virsh nodedev-reattach pci_0000_04_00_1 13 | 14 | # Unload vfio module 15 | modprobe -r vfio_pci 16 | 17 | # Load AMD kernel module 18 | modprobe amdgpu 19 | 20 | # Rebind framebuffer to host 21 | echo "efi-framebuffer.0" > /sys/bus/platform/drivers/efi-framebuffer/bind 22 | 23 | # Load NVIDIA kernel modules 24 | modprobe nvidia_drm 25 | modprobe nvidia_modeset 26 | modprobe nvidia_uvm 27 | modprobe nvidia 28 | 29 | # Bind VTconsoles: might not be needed 30 | echo 1 > /sys/class/vtconsole/vtcon0/bind 31 | echo 1 > /sys/class/vtconsole/vtcon1/bind 32 | 33 | # Restart Display Manager 34 | systemctl start display-manager -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/qemu.d/win11-kvmfr/prepare/begin/start.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | set -x 3 | 4 | # Xpad affects the work of the xbox controller and its wireless adapter 5 | # The xpad will shake hands with the handle/wireless adapter when it is plugged in. At this time, 6 | # if you pass the usb device directly to the virtual machine, the xbox handle will not re-handshake with the root of windows, 7 | # which will eventually cause it to fail to work. 8 | # I can't find a way to make the usb device passthrough into the virtual machine from before/when it is plugged in, 9 | # so I suggest you disable this driver if you need to use the gamepad in virtual machine 10 | modprobe -r xpad 11 | 12 | # dGPU PCI slots 13 | pci_slot="01:00" 14 | 15 | # Determine whether the graphics card has been used by VFIO kernel modules 16 | if [ -z "$(lspci -k -s $pci_slot | grep vfio_pci)" ]; then 17 | # Determine whether nvidia kernel modules has been loaded 18 | lsmod_result=$(lsmod | grep nvidia) 19 | if [ -n "$lsmod_result" ]; then 20 | # Stop display manager 21 | systemctl stop display-manager 22 | 23 | sleep 2 24 | 25 | # Unload NVIDIA kernel modules 26 | modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia 27 | 28 | # Unload AMD kernel module 29 | # modprobe -r amdgpu 30 | fi 31 | 32 | # Detach GPU devices from host 33 | # Use your GPU and HDMI Audio PCI host device 34 | virsh nodedev-detach pci_0000_01_00_0 35 | virsh nodedev-detach pci_0000_01_00_1 36 | 37 | # Load vfio module 38 | modprobe vfio_pci 39 | 40 | if [ -n "$lsmod_result" ]; then 41 | # Restart Display Manager 42 | systemctl start display-manager 43 | fi 44 | fi -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/qemu.d/win11-kvmfr/release/end/stop.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | set -x 3 | 4 | # Load Xpad 5 | modprobe xpad 6 | 7 | # Attach GPU devices to host 8 | # Use your GPU and HDMI Audio PCI host device 9 | virsh nodedev-reattach pci_0000_01_00_0 10 | virsh nodedev-reattach pci_0000_01_00_1 11 | 12 | # Unload vfio module 13 | modprobe -r vfio_pci -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/qemu.d/win11/prepare/begin/start.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | set -x 3 | 4 | # Xpad affects the work of the xbox controller and its wireless adapter 5 | # The xpad will shake hands with the handle/wireless adapter when it is plugged in. At this time, 6 | # if you pass the usb device directly to the virtual machine, the xbox handle will not re-handshake with the root of windows, 7 | # which will eventually cause it to fail to work. 8 | # I can't find a way to make the usb device passthrough into the virtual machine from before/when it is plugged in, 9 | # so I suggest you disable this driver if you need to use the gamepad in virtual machine 10 | modprobe -r xpad 11 | 12 | # dGPU PCI slots 13 | pci_slot="01:00" 14 | 15 | # Determine whether the graphics card has been used by VFIO kernel modules 16 | if [ -z "$(lspci -k -s $pci_slot | grep vfio_pci)" ]; then 17 | # Determine whether nvidia kernel modules has been loaded 18 | lsmod_result=$(lsmod | grep nvidia) 19 | if [ -n "$lsmod_result" ]; then 20 | # Stop display manager 21 | systemctl stop display-manager 22 | 23 | sleep 2 24 | 25 | # Unload NVIDIA kernel modules 26 | modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia 27 | 28 | # Unload AMD kernel module 29 | # modprobe -r amdgpu 30 | fi 31 | 32 | # Detach GPU devices from host 33 | # Use your GPU and HDMI Audio PCI host device 34 | virsh nodedev-detach pci_0000_01_00_0 35 | virsh nodedev-detach pci_0000_01_00_1 36 | 37 | # Load vfio module 38 | modprobe vfio_pci 39 | 40 | if [ -n "$lsmod_result" ]; then 41 | # Restart Display Manager 42 | systemctl start display-manager 43 | fi 44 | fi -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/qemu.d/win11/release/end/stop.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | set -x 3 | 4 | # Load Xpad 5 | modprobe xpad 6 | 7 | # Attach GPU devices to host 8 | # Use your GPU and HDMI Audio PCI host device 9 | virsh nodedev-reattach pci_0000_01_00_0 10 | virsh nodedev-reattach pci_0000_01_00_1 11 | 12 | # Unload vfio module 13 | modprobe -r vfio_pci -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/gpu-paththrough/specialisation.nix: -------------------------------------------------------------------------------- 1 | # https://astrid.tech/2022/09/22/0/nixos-gpu-vfio/ 2 | let 3 | # RTX 3060 Laptop 4 | # IOMMU Group 8: 5 | # 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA106M [GeForce RTX 3060 Mobile / Max-Q] [10de:2520] (rev a1) 6 | # 01:00.1 Audio device [0403]: NVIDIA Corporation GA106 High Definition Audio Controller [10de:228e] (rev a1) 7 | gpuIDs = [ 8 | "10de:2520" # Graphics 9 | "10de:228e" # Audio 10 | ]; 11 | in 12 | { lib, ... }: 13 | { 14 | specialisation."GPUPaththrough".configuration = { 15 | system.nixos.tags = [ "Nvidia-GPU-VFIO" ]; 16 | 17 | # The vfio modules before the nvidia modules is very intentional because it lets vfio claim my GPU before nvidia does. 18 | boot.initrd.kernelModules = [ 19 | # vifo 20 | "vfio_pci" 21 | "vfio" 22 | "vfio_iommu_type1" 23 | # Built into kernel at linux 6.2 24 | # "vfio_virqfd" 25 | # If you load nvidia driver in initrd, you need specific vfio load before nvidia driver 26 | # "nvidia" 27 | # "nvidia_modeset" 28 | # "nvidia_uvm" 29 | # "nvidia_drm" 30 | ]; 31 | boot.kernelParams = [ 32 | ("vfio-pci.ids=" + lib.concatStringsSep "," gpuIDs) # vfio devices 33 | ]; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /specific/hardware-specific/asus-zephyrus-ga401/modules/features/libfprint-goodix-521d/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # This module is broken now 3 | services.fprintd.enable = true; 4 | 5 | nixpkgs.overlays = [ 6 | (final: prev: { 7 | libfprint = prev.libfprint.overrideAttrs ( 8 | oldAttrs: with prev; { 9 | pname = "libfprint-goodix-521d"; 10 | version = "unstable"; 11 | 12 | src = fetchFromGitHub { 13 | owner = "lostattractor"; 14 | repo = "libfprint"; 15 | rev = "abf8dffabfcc7373d4562c151d41a6c7e087ee41"; 16 | sha256 = "sha256-TEU/c3IfNL53vvEbA/ZSfq6ZKuo1g3alBIF1957ZVec="; 17 | }; 18 | 19 | buildInputs = oldAttrs.buildInputs or [ ] ++ [ openssl ]; 20 | } 21 | ); 22 | }) 23 | ]; 24 | } 25 | -------------------------------------------------------------------------------- /specific/hardware-specific/lenovo-legion-16ach6h/default.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, ... }: 2 | { 3 | imports = [ 4 | ../../general/amd/virtualisation.nix 5 | ../../general/nvidia/cuda.nix 6 | ../../general/nvidia/beta.nix 7 | ]; 8 | 9 | boot.extraModulePackages = [ config.boot.kernelPackages.lenovo-legion-module ]; 10 | 11 | environment.systemPackages = with pkgs; [ lenovo-legion ]; 12 | } 13 | -------------------------------------------------------------------------------- /specific/system-specific/CAAppleSilicon/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | networking.hostName = "CAAppleSilicon"; # Define hostname. 4 | 5 | imports = [ ./hardware-configuration.nix ]; 6 | } 7 | -------------------------------------------------------------------------------- /specific/system-specific/CAAppleSilicon/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { lib, modulesPath, ... }: 5 | 6 | { 7 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; 8 | 9 | boot.initrd.availableKernelModules = [ "usb_storage" ]; 10 | boot.initrd.kernelModules = [ ]; 11 | boot.kernelModules = [ ]; 12 | boot.extraModulePackages = [ ]; 13 | 14 | fileSystems."/" = { 15 | device = "/dev/disk/by-uuid/11d47676-cf1c-4060-8f4a-aa43c17b1eb8"; 16 | fsType = "btrfs"; 17 | options = [ "subvol=root" ]; 18 | }; 19 | 20 | fileSystems."/home" = { 21 | device = "/dev/disk/by-uuid/11d47676-cf1c-4060-8f4a-aa43c17b1eb8"; 22 | fsType = "btrfs"; 23 | options = [ "subvol=home" ]; 24 | }; 25 | 26 | fileSystems."/nix" = { 27 | device = "/dev/disk/by-uuid/11d47676-cf1c-4060-8f4a-aa43c17b1eb8"; 28 | fsType = "btrfs"; 29 | options = [ "subvol=nix" ]; 30 | }; 31 | 32 | fileSystems."/boot" = { 33 | device = "/dev/disk/by-uuid/6DF2-180F"; 34 | fsType = "vfat"; 35 | }; 36 | 37 | swapDevices = [ ]; 38 | 39 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 40 | # (the default) this is the recommended approach. When using systemd-networkd it's 41 | # still possible to use this option, but it's recommended to use it in conjunction 42 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 43 | networking.useDHCP = lib.mkDefault true; 44 | # networking.interfaces.wlp1s0f0.useDHCP = lib.mkDefault true; 45 | 46 | nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; 47 | powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; 48 | } 49 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopG14/default.nix: -------------------------------------------------------------------------------- 1 | { user, ... }: 2 | { 3 | networking.hostName = "CALaptopG14"; # Define hostname. 4 | 5 | programs.rog-control-center.enable = true; 6 | programs.rog-control-center.autoStart = true; 7 | 8 | # Torchpad is so slow 9 | home-manager.users.${user}.dconf.settings = { 10 | "org/gnome/desktop/peripherals/touchpad" = { 11 | speed = 0.2; 12 | }; 13 | }; 14 | 15 | # Reserve one core to prevent the system from freezing 16 | nix.settings.cores = 15; 17 | 18 | imports = [ 19 | ../../general/btrfs/autoscrub.nix 20 | ../../general/btrfs/snapper.nix 21 | ../../general/btrfs/docker.nix 22 | ../../general/ssd/trim.nix 23 | ../../general/keyboard/vamillo.nix 24 | ../../general/tablet/opentabletdriver.nix 25 | ../../general/radio/rtl-sdr.nix 26 | # Include the results of the hardware scan. 27 | ./hardware-configuration.nix 28 | ../../general/linux/tpm2.nix 29 | ../../general/linux/zswap.nix 30 | # Persistent 31 | ./persistent.nix 32 | # Featrues 33 | ./modules/features/rathole.nix 34 | ]; 35 | } 36 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopG14/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { 5 | config, 6 | lib, 7 | pkgs, 8 | modulesPath, 9 | ... 10 | }: 11 | 12 | { 13 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; 14 | 15 | boot.initrd.availableKernelModules = [ 16 | "nvme" 17 | "xhci_pci" 18 | "usbhid" 19 | ]; 20 | boot.initrd.kernelModules = [ ]; 21 | boot.kernelModules = [ "kvm-amd" ]; 22 | boot.extraModulePackages = [ ]; 23 | 24 | boot.initrd.luks.devices."lvm-encrypted".device = "/dev/disk/by-uuid/468b2786-745a-4937-9123-4f4e5ba58d12"; 25 | 26 | fileSystems."/" = { 27 | device = "tmpfs"; 28 | fsType = "tmpfs"; 29 | options = [ "mode=755" ]; 30 | }; 31 | 32 | fileSystems."/root" = { 33 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 34 | fsType = "btrfs"; 35 | options = [ 36 | "subvol=root" 37 | "compress=zstd" 38 | "discard=async" 39 | ]; 40 | }; 41 | 42 | fileSystems."/home" = { 43 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 44 | fsType = "btrfs"; 45 | options = [ 46 | "subvol=home" 47 | "compress=zstd" 48 | "discard=async" 49 | ]; 50 | }; 51 | 52 | fileSystems."/persistent" = { 53 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 54 | fsType = "btrfs"; 55 | options = [ 56 | "subvol=persistent" 57 | "compress=zstd" 58 | "discard=async" 59 | ]; 60 | neededForBoot = true; 61 | }; 62 | 63 | fileSystems."/nix" = { 64 | device = "/dev/disk/by-uuid/fe8d27b3-11bf-4939-a414-d1d359c26083"; 65 | fsType = "btrfs"; 66 | options = [ 67 | "subvol=nix" 68 | "compress=zstd" 69 | "discard=async" 70 | "noatime" 71 | ]; 72 | }; 73 | 74 | fileSystems."/boot" = { 75 | device = "/dev/disk/by-uuid/C784-FC44"; 76 | fsType = "vfat"; 77 | }; 78 | 79 | swapDevices = [ 80 | { 81 | device = "/dev/disk/by-partuuid/7f8c2111-4cd4-4e92-8ff4-7d53761ece05"; 82 | randomEncryption = { 83 | enable = true; 84 | allowDiscards = true; 85 | }; 86 | discardPolicy = "both"; 87 | } 88 | ]; 89 | 90 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 91 | # (the default) this is the recommended approach. When using systemd-networkd it's 92 | # still possible to use this option, but it's recommended to use it in conjunction 93 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 94 | networking.useDHCP = lib.mkDefault true; 95 | # networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true; 96 | 97 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 98 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 99 | } 100 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopG14/modules/features/rathole.nix: -------------------------------------------------------------------------------- 1 | { config, ... }: 2 | { 3 | services.rathole = { 4 | enable = true; 5 | role = "client"; 6 | credentialsFile = config.sops.templates."rathole".path; 7 | settings.client = { 8 | remote_addr = "lostattractor.net:3344"; 9 | services.CALaptopG14_ssh.local_addr = "127.0.0.1:22"; 10 | }; 11 | }; 12 | 13 | sops.templates."rathole".content = '' 14 | [client.services.CALaptopG14_ssh] 15 | # Must be the same with the server to pass the validation 16 | token = "${config.sops.placeholder."rathole/token"}" 17 | ''; 18 | 19 | sops.secrets."rathole/token" = { }; 20 | } 21 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopG14/persistent.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | environment.persistence."/persistent" = { 3 | hideMounts = true; 4 | 5 | directories = [ 6 | "/etc/secureboot" 7 | "/etc/NetworkManager/system-connections" 8 | "/etc/daed" 9 | "/etc/asusd" 10 | "/var/lib" 11 | "/var/log" 12 | ]; 13 | 14 | files = [ 15 | "/etc/machine-id" 16 | "/etc/ssh/ssh_host_ed25519_key.pub" 17 | "/etc/ssh/ssh_host_ed25519_key" 18 | "/etc/ssh/ssh_host_rsa_key.pub" 19 | "/etc/ssh/ssh_host_rsa_key" 20 | ]; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopR9000P/default.nix: -------------------------------------------------------------------------------- 1 | { user, ... }: 2 | { 3 | networking.hostName = "CALaptopR9000P"; # Define hostname. 4 | 5 | # Reserve one core to prevent the system from freezing 6 | nix.settings.cores = 15; 7 | 8 | # Do less swapping instead of droping page cache (default=60) 9 | # boot.kernel.sysctl."vm.swappiness" = 30; 10 | 11 | # https://nixos.org/manual/nixos/unstable/index.html#sec-gpu-accel-vulkan 12 | # environment.variables.DXVK_FILTER_DEVICE_NAME = "NVIDIA GeForce RTX 3060 Laptop GPU"; 13 | 14 | imports = [ 15 | ../../general/btrfs/autoscrub.nix 16 | ../../general/btrfs/snapper.nix 17 | ../../general/btrfs/docker.nix 18 | ../../general/ssd/trim.nix 19 | ../../general/keyboard/vamillo.nix 20 | ../../general/tablet/opentabletdriver.nix 21 | ../../general/radio/rtl-sdr.nix 22 | # Include the results of the hardware scan. 23 | ./hardware-configuration.nix 24 | ./disk-config.nix 25 | ../../general/linux/tpm2.nix 26 | ../../general/linux/zswap.nix 27 | # Persistent 28 | ./persistent.nix 29 | ]; 30 | } 31 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopR9000P/disk-config.nix: -------------------------------------------------------------------------------- 1 | _: 2 | { 3 | fileSystems."/" = { 4 | device = "tmpfs"; 5 | fsType = "tmpfs"; 6 | options = [ "mode=755" ]; 7 | }; 8 | 9 | fileSystems."/persistent".neededForBoot = true; 10 | 11 | disko.devices.disk.main = { 12 | type = "disk"; 13 | device = "/dev/nvme0n1"; 14 | content = { 15 | type = "gpt"; 16 | partitions = { 17 | ESP = { 18 | size = "512M"; 19 | type = "EF00"; 20 | content = { 21 | type = "filesystem"; 22 | format = "vfat"; 23 | mountpoint = "/boot"; 24 | mountOptions = [ "umask=0077" ]; 25 | }; 26 | }; 27 | luks = { 28 | end = "-32G"; 29 | content = { 30 | type = "luks"; 31 | name = "crypted"; 32 | passwordFile = "/tmp/secret.key"; # Interactive 33 | settings.allowDiscards = true; 34 | content = { 35 | type = "btrfs"; 36 | extraArgs = [ "-f" ]; 37 | subvolumes = { 38 | "/persistent" = { 39 | mountpoint = "/persistent"; 40 | mountOptions = [ "compress=zstd" "discard=async" ]; 41 | }; 42 | "/root" = { 43 | mountpoint = "/root"; 44 | mountOptions = [ "compress=zstd" "discard=async" ]; 45 | }; 46 | "/home" = { 47 | mountpoint = "/home"; 48 | mountOptions = [ "compress=zstd" "discard=async" ]; 49 | }; 50 | "/nix" = { 51 | mountpoint = "/nix"; 52 | mountOptions = [ "compress=zstd" "discard=async" "noatime" ]; 53 | }; 54 | }; 55 | }; 56 | }; 57 | }; 58 | encryptedSwap = { 59 | size = "100%"; 60 | content = { 61 | type = "swap"; 62 | randomEncryption = true; 63 | discardPolicy = "both"; 64 | }; 65 | }; 66 | }; 67 | }; 68 | }; 69 | 70 | services.beesd.filesystems.root = { 71 | spec = "/dev/mapper/crypted"; 72 | hashTableSizeMB = 128; # 128K extent size for 1TB 73 | verbosity = "crit"; 74 | extraOptions = [ "--loadavg-target" "5.0" ]; 75 | }; 76 | } -------------------------------------------------------------------------------- /specific/system-specific/CALaptopR9000P/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; 12 | boot.initrd.kernelModules = [ ]; 13 | boot.kernelModules = [ "kvm-amd" ]; 14 | boot.extraModulePackages = [ ]; 15 | 16 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 17 | # (the default) this is the recommended approach. When using systemd-networkd it's 18 | # still possible to use this option, but it's recommended to use it in conjunction 19 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 20 | networking.useDHCP = lib.mkDefault true; 21 | # networking.interfaces.eno1.useDHCP = lib.mkDefault true; 22 | # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; 23 | 24 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 25 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 26 | } 27 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopR9000P/persistent.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | environment.persistence."/persistent" = { 3 | hideMounts = true; 4 | 5 | directories = [ 6 | "/etc/secureboot" 7 | "/etc/NetworkManager/system-connections" 8 | "/etc/daed" 9 | "/etc/asusd" 10 | "/var/lib" 11 | "/var/log" 12 | ]; 13 | 14 | files = [ 15 | "/etc/machine-id" 16 | "/etc/ssh/ssh_host_ed25519_key.pub" 17 | "/etc/ssh/ssh_host_ed25519_key" 18 | "/etc/ssh/ssh_host_rsa_key.pub" 19 | "/etc/ssh/ssh_host_rsa_key" 20 | ]; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /specific/system-specific/CALaptopR9000P/zfs.nix: -------------------------------------------------------------------------------- 1 | { 2 | config, 3 | lib, 4 | pkgs, 5 | ... 6 | }: 7 | 8 | let 9 | zfsCompatibleKernelPackages = lib.filterAttrs ( 10 | name: kernelPackages: 11 | (builtins.match "linux_[0-9]+_[0-9]+" name) != null 12 | && (builtins.tryEval kernelPackages).success 13 | && (!kernelPackages.${config.boot.zfs.package.kernelModuleAttribute}.meta.broken) 14 | ) pkgs.linuxKernel.packages; 15 | latestKernelPackage = lib.last ( 16 | lib.sort (a: b: (lib.versionOlder a.kernel.version b.kernel.version)) ( 17 | builtins.attrValues zfsCompatibleKernelPackages 18 | ) 19 | ); 20 | in 21 | { 22 | boot = { 23 | # Note this might jump back and forth as kernels are added or removed. 24 | kernelPackages = latestKernelPackage; 25 | supportedFilesystems = [ "zfs" ]; 26 | zfs.package = pkgs.zfs_unstable; 27 | kernelParams = [ 28 | # https://github.com/openzfs/zfs/issues/9910 29 | "init_on_alloc=0" 30 | ]; 31 | }; 32 | 33 | services.zfs = { 34 | autoScrub.enable = true; 35 | autoSnapshot.enable = true; 36 | }; 37 | 38 | networking.hostId = "007f0200"; 39 | } -------------------------------------------------------------------------------- /specific/system-specific/_CALaptopR9000P/default.nix: -------------------------------------------------------------------------------- 1 | { user, ... }: 2 | { 3 | networking.hostName = "CALaptopR9000P"; # Define hostname. 4 | 5 | # Reserve one core to prevent the system from freezing 6 | nix.settings.cores = 15; 7 | 8 | # Do less swapping instead of droping page cache (default=60) 9 | # boot.kernel.sysctl."vm.swappiness" = 30; 10 | 11 | # https://nixos.org/manual/nixos/unstable/index.html#sec-gpu-accel-vulkan 12 | # environment.variables.DXVK_FILTER_DEVICE_NAME = "NVIDIA GeForce RTX 3060 Laptop GPU"; 13 | 14 | imports = [ 15 | ../../general/btrfs/autoscrub.nix 16 | ../../general/btrfs/snapper.nix 17 | ../../general/btrfs/docker.nix 18 | ../../general/ssd/trim.nix 19 | ../../general/keyboard/vamillo.nix 20 | ../../general/tablet/opentabletdriver.nix 21 | # Include the results of the hardware scan. 22 | ./hardware-configuration.nix 23 | ./disk-config.nix 24 | ../../general/linux/tpm2.nix 25 | ../../general/linux/zswap.nix 26 | # Persistent 27 | ./persistent.nix 28 | ]; 29 | } 30 | -------------------------------------------------------------------------------- /specific/system-specific/_CALaptopR9000P/disk-config.nix: -------------------------------------------------------------------------------- 1 | { lib, ... }: 2 | { 3 | fileSystems."/" = { 4 | device = "tmpfs"; 5 | fsType = "tmpfs"; 6 | options = [ "mode=755" ]; 7 | }; 8 | 9 | fileSystems."/persistent".neededForBoot = true; 10 | 11 | disko.devices.disk.main = { 12 | type = "disk"; 13 | device = "/dev/nvme0n1"; 14 | content = { 15 | type = "gpt"; 16 | partitions = { 17 | ESP = { 18 | size = "512M"; 19 | type = "EF00"; 20 | content = { 21 | type = "filesystem"; 22 | format = "vfat"; 23 | mountpoint = "/boot"; 24 | mountOptions = [ "umask=0077" ]; 25 | }; 26 | }; 27 | luks = { 28 | end = "-${lib.toString 32+320}G"; 29 | content = { 30 | type = "luks"; 31 | name = "crypted"; 32 | passwordFile = "/tmp/secret.key"; # Interactive 33 | settings.allowDiscards = true; 34 | content = { 35 | type = "btrfs"; 36 | extraArgs = [ "-f" ]; 37 | subvolumes = { 38 | "/persistent" = { 39 | mountpoint = "/persistent"; 40 | mountOptions = [ "compress=zstd" "discard=async" ]; 41 | }; 42 | "/root" = { 43 | mountpoint = "/root"; 44 | mountOptions = [ "compress=zstd" "discard=async" ]; 45 | }; 46 | "/home" = { 47 | mountpoint = "/home"; 48 | mountOptions = [ "compress=zstd" "discard=async" ]; 49 | }; 50 | "/nix" = { 51 | mountpoint = "/nix"; 52 | mountOptions = [ "compress=zstd" "discard=async" "noatime" ]; 53 | }; 54 | }; 55 | }; 56 | }; 57 | }; 58 | encryptedSwap = { 59 | end = "-320G"; 60 | content = { 61 | type = "swap"; 62 | randomEncryption = true; 63 | discardPolicy = "both"; 64 | }; 65 | }; 66 | }; 67 | }; 68 | }; 69 | 70 | services.beesd.filesystems.root = { 71 | spec = "/dev/mapper/crypted"; 72 | hashTableSizeMB = 128; # 128K extent size for 1TB 73 | verbosity = "crit"; 74 | extraOptions = [ "--loadavg-target" "5.0" ]; 75 | }; 76 | } -------------------------------------------------------------------------------- /specific/system-specific/_CALaptopR9000P/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ]; 12 | boot.initrd.kernelModules = [ ]; 13 | boot.kernelModules = [ "kvm-amd" ]; 14 | boot.extraModulePackages = [ ]; 15 | 16 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 17 | # (the default) this is the recommended approach. When using systemd-networkd it's 18 | # still possible to use this option, but it's recommended to use it in conjunction 19 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 20 | networking.useDHCP = lib.mkDefault true; 21 | # networking.interfaces.eno1.useDHCP = lib.mkDefault true; 22 | # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; 23 | 24 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 25 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 26 | } 27 | -------------------------------------------------------------------------------- /specific/system-specific/_CALaptopR9000P/persistent.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | environment.persistence."/persistent" = { 3 | hideMounts = true; 4 | 5 | directories = [ 6 | "/etc/secureboot" 7 | "/etc/NetworkManager/system-connections" 8 | "/etc/daed" 9 | "/etc/asusd" 10 | "/var/lib" 11 | "/var/log" 12 | ]; 13 | 14 | files = [ 15 | "/etc/machine-id" 16 | "/etc/ssh/ssh_host_ed25519_key.pub" 17 | "/etc/ssh/ssh_host_ed25519_key" 18 | "/etc/ssh/ssh_host_rsa_key.pub" 19 | "/etc/ssh/ssh_host_rsa_key" 20 | ]; 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /specific/user-specific/default.nix: -------------------------------------------------------------------------------- 1 | { ... }: 2 | { 3 | imports = [ 4 | ./modules/sudo.nix 5 | ./modules/nix/access-tokens.nix 6 | ./modules/nix/remote-builds.nix 7 | ./modules/network/firewall.nix 8 | ./modules/network/proxy.nix 9 | ./modules/network/tailscale.nix 10 | ./modules/features/ollama.nix 11 | ./modules/features/waydroid.nix 12 | ./modules/features/looking-glass/kvmfr.nix 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /specific/user-specific/modules/features/looking-glass/config.nix: -------------------------------------------------------------------------------- 1 | { 2 | additional ? "", 3 | ... 4 | }: 5 | let 6 | config = '' 7 | [win] 8 | fullScreen=yes 9 | 10 | [input] 11 | escapeKey=97 12 | 13 | [spice] 14 | captureOnStart=yes 15 | ''; 16 | in 17 | { 18 | environment.etc."looking-glass-client.ini".text = config + additional; 19 | } 20 | -------------------------------------------------------------------------------- /specific/user-specific/modules/features/looking-glass/default.nix: -------------------------------------------------------------------------------- 1 | { user, ... }: 2 | { 3 | imports = [ (import ./config.nix { }) ]; 4 | 5 | systemd.tmpfiles.rules = [ 6 | # Type Path Mode UID GID Age Argument 7 | "f /dev/shm/looking-glass 0660 ${user} kvm -" 8 | ]; 9 | } 10 | -------------------------------------------------------------------------------- /specific/user-specific/modules/features/looking-glass/kvmfr.nix: -------------------------------------------------------------------------------- 1 | { config, user, ... }: 2 | let 3 | additional = '' 4 | [app] 5 | shmFile=/dev/kvmfr0 6 | ''; 7 | in 8 | { 9 | imports = [ (import ./config.nix { inherit additional; }) ]; 10 | 11 | boot = { 12 | kernelModules = [ "kvmfr" ]; 13 | extraModulePackages = with config.boot.kernelPackages; [ kvmfr ]; 14 | extraModprobeConfig = '' 15 | options kvmfr static_size_mb=64 16 | ''; 17 | }; 18 | 19 | services.udev.extraRules = '' 20 | SUBSYSTEM=="kvmfr", OWNER="${user}", GROUP="kvm", MODE="0660" 21 | ''; 22 | 23 | virtualisation.libvirtd.qemu.verbatimConfig = '' 24 | namespaces = [] 25 | cgroup_device_acl = [ 26 | "/dev/null", "/dev/full", "/dev/zero", 27 | "/dev/random", "/dev/urandom", 28 | "/dev/ptmx", "/dev/kvm", 29 | "/dev/kvmfr0" 30 | ] 31 | ''; 32 | } 33 | -------------------------------------------------------------------------------- /specific/user-specific/modules/features/ollama.nix: -------------------------------------------------------------------------------- 1 | _: { services.ollama.enable = true; } 2 | -------------------------------------------------------------------------------- /specific/user-specific/modules/features/waydroid.nix: -------------------------------------------------------------------------------- 1 | _: { virtualisation.waydroid.enable = true; } 2 | -------------------------------------------------------------------------------- /specific/user-specific/modules/network/firewall.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | networking.nftables.enable = true; 3 | 4 | # Firewall Ports 5 | # 3389 RDP TCP 6 | # 15234 Landrop TCP 7 | # 4455 OBS Websocket TCP 8 | # 7000 Uxplay TCP 9 | # 7100 Uxplay TCP 10 | # 6000 Uxplay UDP 11 | # 6001 Uxplay UDP 12 | # 7011 Uxplay UDP 13 | # 51820 Wireguard UDP (Configured via NetworkManager) 14 | 15 | # Open ports in the firewall. 16 | networking.firewall.allowedTCPPorts = [ 17 | 15234 18 | 7000 19 | 7100 20 | 4455 21 | ]; 22 | networking.firewall.allowedUDPPorts = [ 23 | 6000 24 | 6001 25 | 7011 26 | ]; 27 | # Or disable the firewall altogether. 28 | # networking.firewall.enable = false; 29 | } 30 | -------------------------------------------------------------------------------- /specific/user-specific/modules/network/proxy.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # Network Proxy 3 | # networking.proxy.default = "http://user:password@proxy:port/"; 4 | # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; 5 | 6 | # DAED 7 | services.daed.enable = true; 8 | } 9 | -------------------------------------------------------------------------------- /specific/user-specific/modules/network/tailscale.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.tailscale = { 3 | enable = true; 4 | useRoutingFeatures = "client"; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /specific/user-specific/modules/nix/access-tokens.nix: -------------------------------------------------------------------------------- 1 | { config, ... }: 2 | { 3 | nix.extraOptions = '' 4 | !include ${config.sops.templates."nix-access-tokens".path} 5 | ''; 6 | 7 | sops.templates."nix-access-tokens" = { 8 | content = '' 9 | access-tokens = github.com=${config.sops.placeholder."nix/access-tokens/github"} 10 | ''; 11 | group = "wheel"; 12 | mode = "0440"; 13 | }; 14 | 15 | sops.secrets."nix/access-tokens/github" = { }; 16 | } 17 | -------------------------------------------------------------------------------- /specific/user-specific/modules/nix/remote-builds.nix: -------------------------------------------------------------------------------- 1 | _: 2 | let 3 | systems = [ 4 | "x86_64-linux" 5 | "i686-linux" 6 | "aarch64-linux" 7 | ]; 8 | supportedFeatures = [ 9 | "nixos-test" 10 | "benchmark" 11 | "big-parallel" 12 | "kvm" 13 | "nix-command" 14 | "flakes" 15 | "ca-derivations" 16 | ]; 17 | in 18 | { 19 | nix.buildMachines = [ 20 | { 21 | hostName = "nixremote@hydra.home.lostattractor.net"; 22 | # protocol = "ssh-ng"; 23 | systems = systems; 24 | maxJobs = 6; 25 | speedFactor = 4; 26 | supportedFeatures = supportedFeatures; 27 | mandatoryFeatures = [ ]; 28 | publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU9iWjBoTjEwbjBYSUtvS1dEdjg1ZElkVlZPbjNPMlozSUhRdkgxK051Tlogcm9vdEBIeWRyYQo="; 29 | } 30 | { 31 | hostName = "nixremote@nixbuilder1.home.lostattractor.net"; 32 | # protocol = "ssh-ng"; 33 | systems = systems; 34 | maxJobs = 2; 35 | speedFactor = 2; 36 | supportedFeatures = supportedFeatures; 37 | mandatoryFeatures = [ ]; 38 | publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUVaZXpYbzNXZUk3Rm16SThSSlBoOUUxZHZ5LzAxaXV5bUlzRU5LWkhvUkwgcm9vdEBuaXhidWlsZGVyMQo="; 39 | } 40 | ]; 41 | nix.distributedBuilds = true; 42 | # Optional, useful when the builder has a faster internet connection than yours 43 | nix.settings.builders-use-substitutes = true; 44 | 45 | programs.ssh.extraConfig = '' 46 | Host nixbuilder1.home.lostattractor.net 47 | IdentityFile /root/.ssh/nixremote 48 | Host hydra.home.lostattractor.net 49 | IdentityFile /root/.ssh/nixremote 50 | ''; 51 | } 52 | -------------------------------------------------------------------------------- /specific/user-specific/modules/sudo-rs.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # sudo-rs currectly don't support --preserve-env 3 | security.sudo-rs.enable = true; 4 | security.sudo-rs.wheelNeedsPassword = false; 5 | } 6 | -------------------------------------------------------------------------------- /specific/user-specific/modules/sudo.nix: -------------------------------------------------------------------------------- 1 | _: { security.sudo.wheelNeedsPassword = false; } 2 | -------------------------------------------------------------------------------- /user/default.nix: -------------------------------------------------------------------------------- 1 | { user, ... }: 2 | { 3 | users = { 4 | # Don't allow mutation of users outside of the config. 5 | mutableUsers = false; 6 | users.${user} = { 7 | description = "ChaosAttractor"; 8 | isNormalUser = true; 9 | extraGroups = [ 10 | "wheel" 11 | "tss" 12 | "networkmanager" 13 | "docker" 14 | "libvirtd" 15 | "adbusers" 16 | "plugdev" 17 | ]; 18 | # Set passwd directly 19 | initialHashedPassword = "$6$ER3vW7b0o74VUb5S$MhA3IXzTJpJMkfLXZiPjVHQdmHRQX9Axfi2G5nLJIS/Hm98rw7.Pd39JeVDgPrvWUUJZAH8BfSdHLMyJI2zLu/"; 20 | openssh.authorizedKeys.keys = [ 21 | # TPM-Protected Key 22 | "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC5HypvbsI4xvwfd4Uw7D+SV0AevYPS/nCarFwfBwrMHKybbqUJV1cLM1ySZPxXcZD7+3m48Riiwlssh6o7WM/M= openpgp:0xDE4C24F6" 23 | # Generic Key 24 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL2q0QKgzBS1DFGxmMEvzpz1X05GMidvmulyH/pd8zQA lostattractor@gmail.com" 25 | ]; 26 | }; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /user/desktop/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # Enable Wayland for Chromium (CEF) Apps 3 | home.sessionVariables.NIXOS_OZONE_WL = "1"; 4 | # Using vulkan renderer for gtk4 5 | # home.sessionVariables.GSK_RENDERER = "vulkan"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /user/desktop/gnome/dconf/display/hidpi.nix: -------------------------------------------------------------------------------- 1 | _: 2 | 3 | { dconf.settings."org/gnome/mutter".experimental-features = [ "scale-monitor-framebuffer" "xwayland-native-scaling" ]; } 4 | -------------------------------------------------------------------------------- /user/desktop/gnome/dconf/display/vrr.nix: -------------------------------------------------------------------------------- 1 | _: 2 | 3 | { dconf.settings."org/gnome/mutter".experimental-features = [ "variable-refresh-rate" ]; } 4 | -------------------------------------------------------------------------------- /user/desktop/gnome/dconf/fonts.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # Let Gnome use font in fontconfig 3 | dconf.settings = { 4 | "org/gnome/desktop/interface" = { 5 | font-antialiasing = "rgba"; 6 | monospace-font-name = "Monospace 11"; 7 | }; 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /user/desktop/gnome/dconf/gnome.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | dconf.settings = { 3 | "org/gnome/mutter" = { 4 | dynamic-workspaces = true; 5 | edge-tiling = true; 6 | workspaces-only-on-primary = true; 7 | }; 8 | "org/gnome/desktop/peripherals/touchpad" = { 9 | tap-to-click = true; 10 | }; 11 | "org/gnome/desktop/wm/preferences" = { 12 | button-layout = "appmenu:minimize,maximize,close"; 13 | resize-with-right-button = true; 14 | }; 15 | "org/gnome/settings-daemon/plugins/power" = { 16 | sleep-inactive-ac-type = "nothing"; 17 | }; 18 | "org/gnome/desktop/interface" = { 19 | clock-show-weekday = true; 20 | }; 21 | "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = { 22 | binding = "Return"; 23 | command = "ptyxis --new-window"; 24 | name = "Console"; 25 | }; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /user/desktop/gnome/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | home.packages = 4 | (with pkgs; [ 5 | gnome-tweaks 6 | dconf-editor 7 | gnome-sound-recorder 8 | gnome-power-manager 9 | ]) 10 | ++ (with pkgs.gnomeExtensions; [ 11 | appindicator 12 | gsconnect 13 | blur-my-shell 14 | dock-from-dash 15 | caffeine 16 | pano 17 | astra-monitor 18 | miniview 19 | wiggle 20 | kimpanel 21 | # Extensions that no longer in use 22 | # openweather 23 | # tiling-assistant 24 | # burn-my-windows 25 | ]); 26 | 27 | imports = [ 28 | ./dconf/gnome.nix 29 | ./dconf/fonts.nix 30 | ./dconf/display/hidpi.nix 31 | ./dconf/display/vrr.nix 32 | ./theme.nix 33 | ]; 34 | } 35 | -------------------------------------------------------------------------------- /user/desktop/gnome/theme.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | home.pointerCursor = { 4 | package = pkgs.kdePackages.breeze; 5 | name = "breeze_cursors"; 6 | gtk.enable = true; 7 | }; 8 | 9 | qt = { 10 | enable = true; 11 | platformTheme.name = "adwaita"; 12 | style.name = "adwaita-dark"; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /user/desktop/hyprland/config.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | 4 | wayland.windowManager.hyprland = { 5 | enable = true; 6 | settings = { 7 | # See https://wiki.hyprland.org/Configuring/Monitors/ 8 | monitor = [ 9 | "eDP-1,preferred,auto,1.25" 10 | "HDMI-A-1,highrr,auto,auto" 11 | ]; 12 | 13 | # See https://wiki.hyprland.org/Configuring/Keywords/ for more 14 | 15 | # Execute your favorite apps at launch 16 | exec-once = [ 17 | "waybar" 18 | "hyprpaper" 19 | "mako" 20 | "fcitx5" 21 | "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1" 22 | ]; 23 | 24 | # Source a file (multi-file configs) 25 | # source = ~/.config/hypr/myColors.conf 26 | 27 | # Some default env vars. 28 | env = [ "XCURSOR_SIZE,24" ]; 29 | 30 | # No Scaling For XWayland 31 | xwayland.force_zero_scaling = true; 32 | 33 | # For all categories, see https://wiki.hyprland.org/Configuring/Variables/ 34 | 35 | input = { 36 | touchpad = { 37 | natural_scroll = true; 38 | }; 39 | sensitivity = 0; # -1.0 - 1.0, 0 means no modification. 40 | follow_mouse = 2; 41 | }; 42 | 43 | general = { 44 | gaps_in = 5; 45 | gaps_out = 8; 46 | border_size = 2; 47 | "col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg"; 48 | "col.inactive_border" = "rgba(595959aa)"; 49 | 50 | layout = "dwindle"; 51 | 52 | # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on 53 | allow_tearing = false; 54 | }; 55 | 56 | binds = { 57 | workspace_back_and_forth = true; 58 | }; 59 | 60 | group = { 61 | "col.border_active" = "rgba(33ccffee) rgba(00ff99ee) 45deg"; 62 | "col.border_inactive" = "rgba(595959aa)"; 63 | 64 | groupbar = { 65 | render_titles = false; 66 | "col.active" = "rgba(33ccffee) rgba(00ff99ee) 45deg"; 67 | "col.inactive" = "rgba(595959aa)"; 68 | }; 69 | }; 70 | 71 | decoration = { 72 | rounding = 8; 73 | 74 | blur = { 75 | enabled = true; 76 | size = 3; 77 | passes = 1; 78 | }; 79 | 80 | drop_shadow = true; 81 | shadow_range = 4; 82 | shadow_render_power = 3; 83 | "col.shadow" = "rgba(1a1a1aee)"; 84 | }; 85 | 86 | # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more 87 | animations = { 88 | enabled = true; 89 | 90 | bezier = "myBezier, 0.05, 0.9, 0.1, 1.05"; 91 | 92 | animation = [ 93 | "windows, 1, 7, myBezier" 94 | "windowsOut, 1, 7, default, popin 80%" 95 | "border, 1, 10, default" 96 | "borderangle, 1, 8, default" 97 | "fade, 1, 7, default" 98 | "workspaces, 1, 6, default" 99 | "specialWorkspace, 1, 6, default, slidevert" 100 | ]; 101 | }; 102 | 103 | # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more 104 | dwindle = { 105 | pseudotile = true; # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below 106 | preserve_split = true; # you probably want this 107 | }; 108 | 109 | # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more 110 | master = { 111 | new_is_master = true; 112 | }; 113 | 114 | gestures = { 115 | workspace_swipe = true; 116 | workspace_swipe_cancel_ratio = 0.3; 117 | workspace_swipe_forever = true; 118 | }; 119 | 120 | misc = { 121 | force_default_wallpaper = -1; # Set to 0 to disable the anime mascot wallpapers 122 | }; 123 | 124 | # Example per-device config 125 | # See https://wiki.hyprland.org/Configuring/Keywords/#executing for more 126 | "device:epic-mouse-v1" = { 127 | sensitivity = -0.5; 128 | }; 129 | 130 | # Example windowrule v1 131 | # windowrule = float, ^(kitty)$ 132 | # Example windowrule v2 133 | # windowrulev2 = float,class:^(kitty)$,title:^(kitty)$ 134 | # See https://wiki.hyprland.org/Configuring/Window-Rules/ for more 135 | 136 | # See https://wiki.hyprland.org/Configuring/Keywords/ for more 137 | "$mainMod" = "SUPER"; 138 | 139 | # Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more 140 | bind = [ 141 | "$mainMod, R, exec, pkill rofi || rofi -show drun -show-icons" 142 | "$mainMod, RETURN, exec, kitty" 143 | "$mainMod, E, exec, nautilus" 144 | "$mainMod, W, killactive," 145 | "$mainMod, A, fullscreen," 146 | "$mainMod, M, exit," 147 | "$mainMod, V, togglefloating," 148 | "$mainMod, P, pin," 149 | "$mainMod, P, pseudo," # dwindle 150 | "$mainMod, J, togglesplit," # dwindle 151 | 152 | # Toggle Group with mainMod + Z 153 | "$mainMod, Z, togglegroup," 154 | "$mainMod SHIFT, Z, moveoutofgroup," 155 | 156 | # Lock Group with mainMod + X 157 | "$mainMod, X, lockactivegroup, toggle" 158 | 159 | # Cycle through groupped windows with mainMod + TAB 160 | "$mainMod, Grave, changegroupactive, f" 161 | "$mainMod SHIFT, Grave, changegroupactive, b" 162 | 163 | # Cycle currect foucus with mainMod + TAB 164 | "$mainMod, Tab, cyclenext," 165 | "$mainMod, Tab, bringactivetotop," 166 | "$mainMod SHIFT, Tab, cyclenext, prev" 167 | "$mainMod SHIFT, Tab, bringactivetotop," 168 | 169 | # Move focus with mainMod + arrow keys 170 | "$mainMod, left, movefocus, l" 171 | "$mainMod, right, movefocus, r" 172 | "$mainMod, up, movefocus, u" 173 | "$mainMod, down, movefocus, d" 174 | 175 | # Switch workspaces with mainMod + [0-9] 176 | "$mainMod, 1, workspace, 1" 177 | "$mainMod, 2, workspace, 2" 178 | "$mainMod, 3, workspace, 3" 179 | "$mainMod, 4, workspace, 4" 180 | "$mainMod, 5, workspace, 5" 181 | "$mainMod, 6, workspace, 6" 182 | "$mainMod, 7, workspace, 7" 183 | "$mainMod, 8, workspace, 8" 184 | "$mainMod, 9, workspace, 9" 185 | "$mainMod, 0, workspace, 10" 186 | 187 | # Move active window to a workspace with mainMod + SHIFT + [0-9] 188 | "$mainMod SHIFT, 1, movetoworkspace, 1" 189 | "$mainMod SHIFT, 2, movetoworkspace, 2" 190 | "$mainMod SHIFT, 3, movetoworkspace, 3" 191 | "$mainMod SHIFT, 4, movetoworkspace, 4" 192 | "$mainMod SHIFT, 5, movetoworkspace, 5" 193 | "$mainMod SHIFT, 6, movetoworkspace, 6" 194 | "$mainMod SHIFT, 7, movetoworkspace, 7" 195 | "$mainMod SHIFT, 8, movetoworkspace, 8" 196 | "$mainMod SHIFT, 9, movetoworkspace, 9" 197 | "$mainMod SHIFT, 0, movetoworkspace, 10" 198 | 199 | # Example special workspace (scratchpad) 200 | "$mainMod, S, togglespecialworkspace, magic" 201 | "$mainMod SHIFT, S, movetoworkspace, special:magic" 202 | 203 | # Move active window to a workspace silently with mainMod + CTRL + [0-9] 204 | "$mainMod CTRL, 1, movetoworkspacesilent, 1" 205 | "$mainMod CTRL, 2, movetoworkspacesilent, 2" 206 | "$mainMod CTRL, 3, movetoworkspacesilent, 3" 207 | "$mainMod CTRL, 4, movetoworkspacesilent, 4" 208 | "$mainMod CTRL, 5, movetoworkspacesilent, 5" 209 | "$mainMod CTRL, 6, movetoworkspacesilent, 6" 210 | "$mainMod CTRL, 7, movetoworkspacesilent, 7" 211 | "$mainMod CTRL, 8, movetoworkspacesilent, 8" 212 | "$mainMod CTRL, 9, movetoworkspacesilent, 9" 213 | "$mainMod CTRL, 0, movetoworkspacesilent, 10" 214 | 215 | # Scroll through existing workspaces with mainMod + [page up/down] 216 | "$mainMod, page_up, workspace, e-1" 217 | "$mainMod, page_down, workspace, e+1" 218 | "$mainMod SHIFT, page_up, movetoworkspace, e-1" 219 | "$mainMod SHIFT, page_down, movetoworkspace, e+1" 220 | "$mainMod CTRL, page_up, movetoworkspacesilent, e-1" 221 | "$mainMod CTRL, page_down, movetoworkspacesilent, e+1" 222 | 223 | # Scroll through existing workspaces with mainMod + scroll 224 | "$mainMod, mouse_up, workspace, e+1" 225 | "$mainMod, mouse_down, workspace, e-1" 226 | "$mainMod SHIFT, mouse_up, movetoworkspace, e+1" 227 | "$mainMod SHIFT, mouse_down, movetoworkspace, e-1" 228 | "$mainMod CTRL, mouse_up, movetoworkspacesilent, e+1" 229 | "$mainMod CTRL, mouse_down, movetoworkspacesilent, e-1" 230 | ]; 231 | bindm = [ 232 | # Move/resize windows with mainMod + LMB/RMB and dragging 233 | "$mainMod, mouse:272, movewindow" 234 | "$mainMod, mouse:273, resizewindow" 235 | ]; 236 | }; 237 | }; 238 | } 239 | -------------------------------------------------------------------------------- /user/desktop/hyprland/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | home.packages = with pkgs; [ 4 | hyprpaper 5 | rofi-wayland 6 | mako 7 | nautilus 8 | networkmanagerapplet 9 | ]; 10 | 11 | imports = [ 12 | ./config.nix 13 | ./waybar 14 | ]; 15 | } 16 | -------------------------------------------------------------------------------- /user/desktop/hyprland/waybar/default.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | programs.waybar = { 3 | enable = true; 4 | style = builtins.readFile ./style.css; 5 | settings = [ 6 | { 7 | layer = "top"; 8 | modules-left = [ 9 | "custom/launcher" 10 | "hyprland/workspaces" 11 | "temperature" 12 | #"idle_inhibitor" 13 | # "custom/wall" 14 | "mpd" 15 | "custom/cava-internal" 16 | ]; 17 | modules-center = [ "clock" ]; 18 | modules-right = [ 19 | "pulseaudio" 20 | "backlight" 21 | "memory" 22 | "cpu" 23 | "network" 24 | "battery" 25 | # "custom/powermenu" 26 | "tray" 27 | ]; 28 | "custom/launcher" = { 29 | "format" = " "; 30 | "on-click" = "pkill rofi || rofi -show drun -show-icons"; 31 | "tooltip" = false; 32 | }; 33 | # "custom/wall" = { 34 | # "on-click" = "wallpaper_random"; 35 | # "on-click-middle" = "default_wall"; 36 | # "on-click-right" = "killall dynamic_wallpaper || dynamic_wallpaper &"; 37 | # "format" = " 󰠖 "; 38 | # "tooltip" = false; 39 | # }; 40 | "custom/cava-internal" = { 41 | "exec" = "sleep 1s && cava-internal"; 42 | "tooltip" = false; 43 | }; 44 | "hyprland/workspaces" = { 45 | "format" = "{icon}"; 46 | "on-click" = "activate"; 47 | # "on-scroll-up" = "hyprctl dispatch workspace e+1"; 48 | # "on-scroll-down" = "hyprctl dispatch workspace e-1"; 49 | }; 50 | # "idle_inhibitor" = { 51 | # "format" = "{icon}"; 52 | # "format-icons" = { 53 | # "activated" = ""; 54 | # "deactivated" = ""; 55 | # }; 56 | # "tooltip" = false; 57 | # }; 58 | "backlight" = { 59 | "device" = "intel_backlight"; 60 | "on-scroll-up" = "light -A 5"; 61 | "on-scroll-down" = "light -U 5"; 62 | "format" = "{icon} {percent}%"; 63 | "format-icons" = [ 64 | "󰃝" 65 | "󰃞" 66 | "󰃟" 67 | "󰃠" 68 | ]; 69 | }; 70 | "pulseaudio" = { 71 | "scroll-step" = 1; 72 | "format" = "{icon} {volume}%"; 73 | "format-muted" = "󰖁 Muted"; 74 | "format-icons" = { 75 | "default" = [ 76 | "" 77 | "" 78 | "" 79 | ]; 80 | }; 81 | # "on-click" = "pamixer -t"; 82 | "tooltip" = false; 83 | }; 84 | "battery" = { 85 | "interval" = 10; 86 | "states" = { 87 | "warning" = 20; 88 | "critical" = 10; 89 | }; 90 | "format" = "{icon} {capacity}%"; 91 | "format-icons" = [ 92 | "󰁺" 93 | "󰁻" 94 | "󰁼" 95 | "󰁽" 96 | "󰁾" 97 | "󰁿" 98 | "󰂀" 99 | "󰂁" 100 | "󰂂" 101 | "󰁹" 102 | ]; 103 | "format-full" = "{icon} {capacity}%"; 104 | "format-charging" = "󰂄 {capacity}%"; 105 | "tooltip" = false; 106 | }; 107 | "clock" = { 108 | "interval" = 1; 109 | "format" = "{:%I:%M %p %A %b %d}"; 110 | "tooltip" = true; 111 | "tooltip-format" = "{=%A; %d %B %Y}\n{calendar}"; 112 | }; 113 | "memory" = { 114 | "interval" = 1; 115 | "format" = "󰍛 {percentage}%"; 116 | "states" = { 117 | "warning" = 85; 118 | }; 119 | }; 120 | "cpu" = { 121 | "interval" = 1; 122 | "format" = "󰻠 {usage}%"; 123 | }; 124 | "mpd" = { 125 | "max-length" = 25; 126 | "format" = " {title}"; 127 | "format-paused" = " {title}"; 128 | "format-stopped" = ""; 129 | "format-disconnected" = ""; 130 | "on-click" = "mpc --quiet toggle"; 131 | "on-click-right" = "mpc update; mpc ls | mpc add"; 132 | "on-click-middle" = "kitty --class='ncmpcpp' ncmpcpp "; 133 | "on-scroll-up" = "mpc --quiet prev"; 134 | "on-scroll-down" = "mpc --quiet next"; 135 | "smooth-scrolling-threshold" = 5; 136 | "tooltip-format" = "{title} - {artist} ({elapsedTime:%M:%S}/{totalTime:%H:%M:%S})"; 137 | }; 138 | "network" = { 139 | "format-disconnected" = "󰯡 Disconnected"; 140 | "format-ethernet" = "󰀂 {ifname} ({ipaddr})"; 141 | "format-linked" = "󰖪 {essid} (No IP)"; 142 | "format-wifi" = "󰖩 {essid}"; 143 | "interval" = 1; 144 | "tooltip" = false; 145 | }; 146 | "temperature" = { 147 | # "hwmon-path"= "${env:HWMON_PATH}"; 148 | #"critical-threshold"= 80; 149 | "tooltip" = false; 150 | "format" = " {temperatureC}°C"; 151 | }; 152 | # "custom/powermenu" = { 153 | # "format" = ""; 154 | # "on-click" = "pkill rofi || ~/.config/rofi/powermenu.sh"; 155 | # "tooltip" = false; 156 | # }; 157 | "tray" = { 158 | "icon-size" = 15; 159 | "spacing" = 5; 160 | }; 161 | } 162 | ]; 163 | }; 164 | } 165 | -------------------------------------------------------------------------------- /user/desktop/hyprland/waybar/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: "JetBrainsMono Nerd Font"; 3 | font-size: 12pt; 4 | font-weight: bold; 5 | border-radius: 0px; 6 | transition-property: background-color; 7 | transition-duration: 0.5s; 8 | } 9 | 10 | @keyframes blink_red { 11 | to { 12 | background-color: rgba(242, 143, 173, 0.95); 13 | color: rgb(26, 24, 38); 14 | } 15 | } 16 | 17 | .warning, 18 | .critical, 19 | .urgent { 20 | animation-name: blink_red; 21 | animation-duration: 1s; 22 | animation-timing-function: linear; 23 | animation-iteration-count: infinite; 24 | animation-direction: alternate; 25 | } 26 | 27 | window#waybar { 28 | background-color: transparent; 29 | } 30 | 31 | window>box { 32 | background-color: rgba(30, 30, 46, 0.95); 33 | } 34 | 35 | #workspaces { 36 | padding-left: 0px; 37 | padding-right: 4px; 38 | } 39 | 40 | #workspaces button { 41 | padding-top: 5px; 42 | padding-bottom: 5px; 43 | padding-left: 6px; 44 | padding-right: 6px; 45 | } 46 | 47 | #workspaces button.active { 48 | background-color: rgba(181, 232, 224, 0.95); 49 | color: rgb(26, 24, 38); 50 | } 51 | 52 | #workspaces button.urgent { 53 | color: rgb(26, 24, 38); 54 | } 55 | 56 | #workspaces button:hover { 57 | background-color: rgba(248, 189, 150, 0.95); 58 | color: rgb(26, 24, 38); 59 | } 60 | 61 | tooltip { 62 | background: rgb(48, 45, 65); 63 | } 64 | 65 | tooltip label { 66 | color: rgb(217, 224, 238); 67 | } 68 | 69 | #custom-launcher { 70 | font-size: 20px; 71 | padding-left: 8px; 72 | padding-right: 6px; 73 | color: #7ebae4; 74 | } 75 | 76 | #mode, 77 | #clock, 78 | #memory, 79 | #temperature, 80 | #cpu, 81 | #mpd, 82 | #custom-wall, 83 | #temperature, 84 | #backlight, 85 | #pulseaudio, 86 | #network, 87 | #battery, 88 | #custom-powermenu, 89 | #custom-cava-internal { 90 | padding-left: 10px; 91 | padding-right: 10px; 92 | } 93 | 94 | /* #mode { 95 | margin-left: 10px; 96 | background-color: rgb(248, 189, 150); 97 | color: rgb(26, 24, 38); 98 | } */ 99 | 100 | #memory { 101 | color: rgb(181, 232, 224); 102 | } 103 | 104 | #cpu { 105 | color: rgb(245, 194, 231); 106 | } 107 | 108 | #clock { 109 | color: rgb(217, 224, 238); 110 | } 111 | 112 | /* #idle_inhibitor { 113 | color: rgb(221, 182, 242); 114 | } */ 115 | 116 | #custom-wall { 117 | color: rgb(221, 182, 242); 118 | } 119 | 120 | #temperature { 121 | color: rgb(150, 205, 251); 122 | } 123 | 124 | #backlight { 125 | color: rgb(248, 189, 150); 126 | } 127 | 128 | #pulseaudio { 129 | color: rgb(245, 224, 220); 130 | } 131 | 132 | #network { 133 | color: #ABE9B3; 134 | } 135 | 136 | #network.disconnected { 137 | color: rgb(255, 255, 255); 138 | } 139 | 140 | #battery.charging, 141 | #battery.full, 142 | #battery.discharging { 143 | color: rgb(250, 227, 176); 144 | } 145 | 146 | #battery.critical:not(.charging) { 147 | color: rgb(242, 143, 173); 148 | } 149 | 150 | #custom-powermenu { 151 | color: rgb(242, 143, 173); 152 | } 153 | 154 | #tray { 155 | padding-right: 8px; 156 | padding-left: 10px; 157 | } 158 | 159 | #mpd.paused { 160 | color: #414868; 161 | font-style: italic; 162 | } 163 | 164 | #mpd.stopped { 165 | background: transparent; 166 | } 167 | 168 | #mpd { 169 | color: #c0caf5; 170 | } 171 | 172 | /* #custom-cava-internal { 173 | font-family: "Hack Nerd Font"; 174 | } */ -------------------------------------------------------------------------------- /user/home.nix: -------------------------------------------------------------------------------- 1 | _: 2 | { 3 | programs.home-manager.enable = true; 4 | 5 | 6 | imports = [ 7 | ./desktop 8 | ./settings/flatpak.nix 9 | ./settings/gtk.nix 10 | ./settings/dconf/blackbox.nix 11 | ./packages/apps.nix 12 | ./packages/utils.nix 13 | ./programs/firefox.nix 14 | ./programs/shell.nix 15 | ./programs/vscode.nix 16 | ./programs/jetbrains.nix 17 | ./programs/obs-studio.nix 18 | ./programs/spicetify.nix 19 | ./programs/kitty.nix 20 | ./programs/git.nix 21 | ./programs/lazygit.nix 22 | ./programs/mangohud.nix 23 | ./programs/java.nix 24 | ./programs/dotnet.nix 25 | ./programs/gpg.nix 26 | ./services/syncthing.nix 27 | ./services/mpd.nix 28 | ./services/lorri.nix 29 | ]; 30 | 31 | home.stateVersion = "24.05"; 32 | } 33 | -------------------------------------------------------------------------------- /user/packages/apps.nix: -------------------------------------------------------------------------------- 1 | { pkgs, inputs, ... }: 2 | let 3 | inherit (pkgs.stdenv.hostPlatform) system; 4 | umu-launcher = inputs.umu.packages.${system}.default; 5 | in 6 | { 7 | home.packages = with pkgs; [ 8 | # Terminal 9 | (blackbox-terminal.override { sixelSupport = true; }) 10 | ptyxis 11 | # Web Browser 12 | chromium 13 | google-chrome 14 | brave 15 | # Social Apps 16 | tdesktop 17 | signal-desktop 18 | element-desktop 19 | cinny-desktop 20 | fractal 21 | qq 22 | wechat-uos 23 | discord 24 | dissent 25 | polari 26 | # Email 27 | thunderbird 28 | # Password Manager 29 | bitwarden 30 | bitwarden-cli 31 | # Music 32 | g4music 33 | ncmpcpp 34 | ncspot 35 | go-musicfox 36 | # RSS 37 | newsflash 38 | # Media 39 | komikku 40 | shortwave 41 | vlc 42 | (mpv-unwrapped.wrapper { mpv = mpv-unwrapped.override { cddaSupport = true; }; }) 43 | # CD/DVD 44 | brasero 45 | # Games 46 | osu-lazer-bin 47 | lunar-client 48 | (lutris.override { 49 | extraPkgs = pkgs: [ 50 | # List package dependencies here 51 | wineWowPackages.stable 52 | wineWowPackages.waylandFull 53 | pixman 54 | libjpeg 55 | zenity 56 | winetricks 57 | umu-launcher 58 | ]; 59 | }) 60 | umu-launcher 61 | bottles 62 | # IDE 63 | lapce 64 | zed-editor 65 | github-desktop 66 | # Network 67 | wireshark-qt 68 | # Todo 69 | kuro 70 | # Writing Tools 71 | logseq 72 | obsidian 73 | marktext 74 | rnote 75 | papers 76 | # Office Toolkits 77 | wpsoffice-cn 78 | libreoffice 79 | # File Searching 80 | fsearch 81 | # Bittorrent 82 | fragments 83 | # Kdenlive 84 | kdePackages.kdenlive 85 | frei0r 86 | mediainfo 87 | # File Sharing 88 | localsend 89 | nur.repos.rewine.landrop 90 | # Remote Desktop 91 | rustdesk 92 | parsec-bin 93 | remmina 94 | moonlight-qt 95 | # Virt Manager 96 | virt-manager 97 | looking-glass-client 98 | # Radio 99 | inputs.nixpkgs-stable.legacyPackages.${pkgs.stdenv.hostPlatform.system}.gqrx 100 | # Screenshot 101 | flameshot 102 | # Screenkey 103 | showmethekey 104 | # Uxplay 105 | uxplay 106 | # Backup 107 | pika-backup 108 | # Gnome Cicle Apps 109 | metadata-cleaner 110 | gnome-decoder 111 | video-trimmer 112 | raider 113 | dialect 114 | eyedropper 115 | collision 116 | # Dconf 117 | dconf-editor 118 | ]; 119 | } 120 | -------------------------------------------------------------------------------- /user/packages/utils.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | home.packages = with pkgs; [ 4 | # System information tool 5 | neofetch 6 | hyfetch 7 | fastfetch 8 | screenfetch 9 | cpufetch 10 | powertop 11 | bottom 12 | btop 13 | nvtopPackages.full 14 | # Terminal utils 15 | lolcat 16 | cmatrix 17 | # Alternative to ls/cat 18 | bat 19 | lsd 20 | # JSON filter 21 | jnv 22 | # Diff 23 | difftastic 24 | # Grep 25 | ripgrep 26 | # Find 27 | fd 28 | # TLDR 29 | tldr 30 | # File manager 31 | yazi 32 | # Screenshot 33 | grim 34 | slurp 35 | wl-clipboard 36 | # Network utils 37 | nali 38 | tcping-go 39 | gping 40 | # Wireless utils 41 | iw 42 | # Web video downloader 43 | you-get 44 | yt-dlp 45 | # Viedo tool 46 | ffmpeg 47 | # Unzip 48 | p7zip 49 | # Desktop tools 50 | handlr 51 | xdotool 52 | # Netowrk tools 53 | iperf3 54 | nmap 55 | tcpdump 56 | pwru 57 | wgcf 58 | # Proxy 59 | v2ray 60 | xray 61 | sing-box 62 | tor 63 | # IMPI 64 | ipmitool 65 | # Disk analayzer 66 | gdu 67 | duf 68 | # Develop Tools 69 | gh 70 | hugo 71 | devbox 72 | charm-freeze 73 | # Kubernetes 74 | kubectl 75 | kubectx 76 | kubernetes-helm 77 | helmfile 78 | k9s 79 | cilium-cli 80 | hubble 81 | argocd 82 | # Language Server 83 | nil 84 | # Nix Utils 85 | nix-output-monitor 86 | sops 87 | nurl 88 | nix-update 89 | # Wine 90 | wine 91 | winetricks 92 | # Binary Analayzer 93 | binwalk 94 | hexyl 95 | # Other utils 96 | openssl 97 | sshx 98 | ]; 99 | } 100 | -------------------------------------------------------------------------------- /user/programs/dotnet.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | let 3 | dotnet-sdks = with pkgs.dotnetCorePackages; combinePackages [ sdk_8_0 sdk_9_0 ]; 4 | in 5 | { 6 | # https://nixos.wiki/wiki/DotNET 7 | home.sessionVariables.DOTNET_ROOT = "${dotnet-sdks}/share/dotnet"; 8 | home.packages = [ dotnet-sdks ]; 9 | } 10 | -------------------------------------------------------------------------------- /user/programs/firefox.nix: -------------------------------------------------------------------------------- 1 | { inputs, ... }: 2 | let 3 | profile = "default"; 4 | in 5 | { 6 | home.file.".mozilla/firefox/${profile}/chrome/firefox-gnome-theme".source = 7 | inputs.firefox-gnome-theme; 8 | 9 | programs.firefox = { 10 | enable = true; 11 | profiles.${profile} = { 12 | extraConfig = '' 13 | ${builtins.readFile "${inputs.firefox-gnome-theme}/configuration/user.js"} 14 | ''; 15 | 16 | userChrome = '' 17 | @import "firefox-gnome-theme/userChrome.css"; 18 | 19 | #TabsToolbar { 20 | display: none; 21 | } 22 | 23 | #sidebar-header { 24 | display: none; 25 | } 26 | ''; 27 | 28 | userContent = '' 29 | @import "firefox-gnome-theme/userContent.css; 30 | ''; 31 | }; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /user/programs/git.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | programs.git = { 3 | enable = true; 4 | difftastic.enable = true; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /user/programs/gpg.nix: -------------------------------------------------------------------------------- 1 | { osConfig, ... }: 2 | { 3 | programs.gpg.enable = true; 4 | 5 | # https://wiki.archlinux.org/title/GnuPG 6 | services.gpg-agent = { 7 | enable = true; 8 | enableSshSupport = true; 9 | pinentryPackage = osConfig.programs.gnupg.agent.pinentryPackage; 10 | }; 11 | 12 | # Disable gnome-keyring-ssh 13 | xdg.configFile."autostart/gnome-keyring-ssh.desktop".text = '' 14 | [Desktop Entry] 15 | Type=Application 16 | Hidden=true 17 | ''; 18 | } 19 | -------------------------------------------------------------------------------- /user/programs/java.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | programs.java.enable = true; 3 | 4 | # Deprecated 5 | # home.packages = with pkgs; [ 6 | # adoptopenjdk-icedtea-web 7 | # ]; 8 | } 9 | -------------------------------------------------------------------------------- /user/programs/jetbrains.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | let 3 | jetbra = pkgs.fetchFromGitHub { 4 | owner = "LostAttractor"; 5 | repo = "jetbra"; 6 | rev = "94585581c360862eab1843bf7edd8082fdf22542"; 7 | sha256 = "sha256-9jeiF9QS4MCogIowu43l7Bqf7dhs40+7KKZML/k1oWo="; 8 | }; 9 | 10 | vmoptions = '' 11 | --add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED 12 | --add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED 13 | 14 | -javaagent:${jetbra}/ja-netfilter.jar=jetbrains 15 | ''; 16 | in 17 | { 18 | home.packages = with pkgs; [ 19 | jetbrains.idea-ultimate 20 | jetbrains.clion 21 | jetbrains.pycharm-professional 22 | ]; 23 | 24 | xdg.configFile."JetBrains/IntelliJIdea${pkgs.jetbrains.idea-ultimate.version}/idea64.vmoptions".text = 25 | vmoptions; 26 | xdg.configFile."JetBrains/PyCharm${pkgs.jetbrains.pycharm-professional.version}/pycharm64.vmoptions".text = 27 | vmoptions; 28 | xdg.configFile."JetBrains/CLion${pkgs.jetbrains.clion.version}/clion64.vmoptions".text = vmoptions; 29 | 30 | # https://jetbra.in/5d84466e31722979266057664941a71893322460 31 | } 32 | -------------------------------------------------------------------------------- /user/programs/kitty.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | programs.kitty = { 3 | enable = true; 4 | themeFile = "adwaita_dark"; 5 | settings.background_opacity = "0.95"; 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /user/programs/lazygit.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | programs.lazygit = { 3 | enable = true; 4 | settings.git.paging.externalDiffCommand = "difft"; 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /user/programs/mangohud.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | programs.mangohud.enable = true; 3 | 4 | # MANGOHUD=1 gamemoderun DXVK_ASYNC=1 %command% -novid -high +fps_max 144 5 | # gamemoderun DXVK_ASYNC=1 %command% 6 | 7 | # Force vulkan loader: 8 | # environment.variables.VK_ICD_FILENAMES = 9 | # "/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json"; 10 | # export VK_ICD_FILENAMES="/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json" 11 | # https://nixos.org/manual/nixos/unstable/index.html#sec-gpu-accel-vulkan 12 | } 13 | -------------------------------------------------------------------------------- /user/programs/obs-studio.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | programs.obs-studio = { 4 | enable = true; 5 | plugins = with pkgs.obs-studio-plugins; [ 6 | obs-pipewire-audio-capture 7 | obs-ndi 8 | obs-text-pthread 9 | obs-vkcapture 10 | waveform 11 | # Plugins that no longer in use 12 | # obs-multi-rtmp 13 | ]; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /user/programs/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: { 2 | programs.fish.enable = true; 3 | programs.fish.interactiveShellInit = '' 4 | ${pkgs.any-nix-shell}/bin/any-nix-shell fish --info-right | source 5 | ''; 6 | 7 | programs.nushell.enable = true; 8 | 9 | programs.fzf.enable = true; 10 | programs.zoxide.enable = true; 11 | 12 | programs.atuin = { 13 | enable = true; 14 | flags = [ "--disable-up-arrow" ]; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /user/programs/spicetify.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs, 3 | inputs, 4 | config, 5 | ... 6 | }: 7 | let 8 | spicePkgs = inputs.spicetify-nix.legacyPackages.${pkgs.system}; 9 | in 10 | { 11 | # import the flake's module for your system 12 | imports = [ inputs.spicetify-nix.homeManagerModules.default ]; 13 | 14 | # configure spicetify :) 15 | programs.spicetify = { 16 | enable = true; 17 | dontInstall = true; 18 | windowManagerPatch = true; 19 | 20 | enabledExtensions = with spicePkgs.extensions; [ 21 | adblock 22 | hidePodcasts 23 | shuffle # shuffle+ (special characters are sanitized out of extension names) 24 | ]; 25 | 26 | theme = spicePkgs.themes.sleek; 27 | colorScheme = "cherry"; 28 | }; 29 | 30 | home.packages = [ 31 | (config.programs.spicetify.spicedSpotify.overrideAttrs (oldAttrs: { 32 | postInstall = 33 | oldAttrs.postInstall or "" 34 | + '' 35 | wrapProgram $out/bin/${oldAttrs.meta.mainProgram} \ 36 | --add-flags "--enable-wayland-ime" 37 | ''; 38 | })) 39 | ] ++ config.programs.spicetify.theme.extraPkgs; 40 | } 41 | -------------------------------------------------------------------------------- /user/programs/vscode.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | programs.vscode = { 4 | enable = true; 5 | profiles.default.extensions = (with pkgs.vscode-marketplace; [ 6 | jnoortheen.nix-ide 7 | ms-vscode.makefile-tools 8 | ms-vscode.cpptools-extension-pack 9 | ms-vscode.cmake-tools 10 | twxs.cmake 11 | golang.go 12 | ms-vscode.hexeditor 13 | dakara.transformer 14 | eamodio.gitlens 15 | github.vscode-pull-request-github 16 | github.vscode-github-actions 17 | ms-azuretools.vscode-docker 18 | ms-kubernetes-tools.vscode-kubernetes-tools 19 | ms-vscode-remote.remote-ssh-edit 20 | ms-vscode.remote-explorer 21 | github.copilot 22 | # Theme 23 | pkief.material-icon-theme 24 | zhuangtongfa.material-theme 25 | # Lang 26 | ms-ceintl.vscode-language-pack-zh-hans 27 | ]) ++ (with pkgs.vscode-extensions; [ 28 | ms-python.python 29 | ms-vscode.cpptools 30 | rust-lang.rust-analyzer 31 | ms-vscode-remote.remote-ssh 32 | ms-vsliveshare.vsliveshare 33 | ]); 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /user/services/lorri.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | services.lorri.enable = true; 3 | programs.direnv.enable = true; 4 | programs.direnv.nix-direnv.enable = true; 5 | } 6 | -------------------------------------------------------------------------------- /user/services/mpd.nix: -------------------------------------------------------------------------------- 1 | { config, ... }: 2 | { 3 | services.mpd = { 4 | enable = true; 5 | musicDirectory = config.xdg.userDirs.music; 6 | extraConfig = '' 7 | audio_output { 8 | type "pipewire" 9 | name "PipeWire Output" 10 | } 11 | ''; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /user/services/syncthing.nix: -------------------------------------------------------------------------------- 1 | _: { services.syncthing.enable = true; } 2 | -------------------------------------------------------------------------------- /user/settings/dconf/blackbox.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | dconf.settings."com/raggesilver/BlackBox" = { 3 | font = "Monospace 11"; 4 | remember-window-size = true; 5 | use-sixel = true; 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /user/settings/flatpak.nix: -------------------------------------------------------------------------------- 1 | { config, ... }: 2 | { 3 | xdg.dataFile."flatpak/overrides/global".text = '' 4 | [Context] 5 | filesystems=/nix/store:ro;${config.xdg.dataHome}/fonts:ro;${config.home.homeDirectory}/.icons:ro;xdg-config/gtk-3.0;xdg-config/gtk-4.0 6 | ''; 7 | } 8 | -------------------------------------------------------------------------------- /user/settings/gtk.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | { 3 | home.packages = with pkgs; [ 4 | adw-gtk3 5 | ]; 6 | 7 | dconf.settings = { 8 | "org/gnome/desktop/interface" = { 9 | gtk-theme = "adw-gtk3-dark"; 10 | }; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /user/settings/i18n.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | # xdg.configFile."ibus/rime" = { 3 | # recursive = true; 4 | # source = inputs.rime-ice; 5 | # }; 6 | } -------------------------------------------------------------------------------- /wayland-text-input-v1-Implement-basic-text-input-v1-.patch: -------------------------------------------------------------------------------- 1 | From 18ea1ee68ad43b6f48c6a01576c6ca7feb520e3f Mon Sep 17 00:00:00 2001 2 | From: Alynx Zhou 3 | Date: Wed, 15 May 2024 00:07:41 +0800 4 | Subject: [PATCH] wayland/text-input-v1: Implement basic text-input-v1 support 5 | 6 | This commit makes input methods work in text-input-v1 only clients 7 | (mostly Chromium/Electron based apps with Ozone Wayland), which is 8 | needed by users who needs IME to input their languages, like Chinese, 9 | Japanese or Korean. 10 | 11 | Closes . 12 | --- 13 | clutter/clutter/clutter-enums.h | 3 + 14 | src/core/events.c | 11 +- 15 | src/meson.build | 3 + 16 | src/wayland/meta-wayland-seat.c | 12 +- 17 | src/wayland/meta-wayland-seat.h | 2 + 18 | src/wayland/meta-wayland-text-input-v1.c | 859 +++++++++++++++++++++++ 19 | src/wayland/meta-wayland-text-input-v1.h | 38 + 20 | src/wayland/meta-wayland-versions.h | 1 + 21 | src/wayland/meta-wayland.c | 7 + 22 | src/wayland/meta-wayland.h | 2 + 23 | 10 files changed, 933 insertions(+), 5 deletions(-) 24 | create mode 100644 src/wayland/meta-wayland-text-input-v1.c 25 | create mode 100644 src/wayland/meta-wayland-text-input-v1.h 26 | 27 | diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h 28 | index 45956bf57..8198e7351 100644 29 | --- a/clutter/clutter/clutter-enums.h 30 | +++ b/clutter/clutter/clutter-enums.h 31 | @@ -1183,6 +1183,9 @@ typedef enum 32 | CLUTTER_INPUT_CONTENT_HINT_SENSITIVE_DATA = 1 << 7, 33 | CLUTTER_INPUT_CONTENT_HINT_LATIN = 1 << 8, 34 | CLUTTER_INPUT_CONTENT_HINT_MULTILINE = 1 << 9, 35 | + CLUTTER_INPUT_CONTENT_HINT_DEFAULT = 1 << 10, 36 | + CLUTTER_INPUT_CONTENT_HINT_PASSWORD = 1 << 11, 37 | + CLUTTER_INPUT_CONTENT_HINT_AUTO_CORRECTION = 1 << 12, 38 | } ClutterInputContentHintFlags; 39 | 40 | typedef enum 41 | diff --git a/src/core/events.c b/src/core/events.c 42 | index 1f36d2feb..a1874d673 100644 43 | --- a/src/core/events.c 44 | +++ b/src/core/events.c 45 | @@ -238,6 +238,7 @@ meta_display_handle_event (MetaDisplay *display, 46 | #ifdef HAVE_WAYLAND 47 | MetaWaylandCompositor *wayland_compositor; 48 | MetaWaylandTextInput *wayland_text_input = NULL; 49 | + MetaWaylandTextInputV1 *wayland_text_input_v1 = NULL; 50 | #endif 51 | 52 | #ifdef HAVE_WAYLAND 53 | @@ -246,6 +247,8 @@ meta_display_handle_event (MetaDisplay *display, 54 | { 55 | wayland_text_input = 56 | meta_wayland_compositor_get_text_input (wayland_compositor); 57 | + wayland_text_input_v1 = 58 | + meta_wayland_compositor_get_text_input_v1 (wayland_compositor); 59 | } 60 | #endif 61 | 62 | @@ -287,9 +290,11 @@ meta_display_handle_event (MetaDisplay *display, 63 | } 64 | 65 | #ifdef HAVE_WAYLAND 66 | - if (wayland_text_input && 67 | - !meta_compositor_get_current_window_drag (compositor) && 68 | - meta_wayland_text_input_update (wayland_text_input, event)) 69 | + if (!meta_compositor_get_current_window_drag (compositor) && 70 | + ((wayland_text_input && 71 | + meta_wayland_text_input_update (wayland_text_input, event)) || 72 | + (wayland_text_input_v1 && 73 | + meta_wayland_text_input_v1_update (wayland_text_input_v1, event)))) 74 | return CLUTTER_EVENT_STOP; 75 | 76 | if (wayland_compositor) 77 | diff --git a/src/meson.build b/src/meson.build 78 | index 05df3bfd2..fad08706a 100644 79 | --- a/src/meson.build 80 | +++ b/src/meson.build 81 | @@ -688,6 +688,8 @@ if have_wayland 82 | 'wayland/meta-wayland-tablet-tool.h', 83 | 'wayland/meta-wayland-text-input.c', 84 | 'wayland/meta-wayland-text-input.h', 85 | + 'wayland/meta-wayland-text-input-v1.c', 86 | + 'wayland/meta-wayland-text-input-v1.h', 87 | 'wayland/meta-wayland-touch.c', 88 | 'wayland/meta-wayland-touch.h', 89 | 'wayland/meta-wayland-transaction.c', 90 | @@ -1076,6 +1078,7 @@ if have_wayland 91 | ['single-pixel-buffer', 'staging', 'v1', ], 92 | ['tablet', 'unstable', 'v2', ], 93 | ['text-input', 'unstable', 'v3', ], 94 | + ['text-input', 'unstable', 'v1', ], 95 | ['viewporter', 'stable', ], 96 | ['xdg-activation', 'staging', 'v1', ], 97 | ['xdg-foreign', 'unstable', 'v1', ], 98 | diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c 99 | index 2301e0068..d0f888084 100644 100 | --- a/src/wayland/meta-wayland-seat.c 101 | +++ b/src/wayland/meta-wayland-seat.c 102 | @@ -229,6 +229,7 @@ default_focus (MetaWaylandEventHandler *handler, 103 | surface); 104 | meta_wayland_tablet_seat_set_pad_focus (seat->tablet_seat, surface); 105 | meta_wayland_text_input_set_focus (seat->text_input, surface); 106 | + /* text-input-v1 will set focused surface on activate. */ 107 | } 108 | 109 | if (caps & CLUTTER_INPUT_CAPABILITY_TABLET_TOOL) 110 | @@ -290,6 +291,8 @@ meta_wayland_seat_new (MetaWaylandCompositor *compositor, 111 | NULL); 112 | 113 | seat->text_input = meta_wayland_text_input_new (seat); 114 | + /* Chromium/Electron-based apps only support text-input-v1. */ 115 | + seat->text_input_v1 = meta_wayland_text_input_v1_new (seat); 116 | 117 | meta_wayland_data_device_init (&seat->data_device, seat); 118 | meta_wayland_data_device_primary_init (&seat->primary_data_device, seat); 119 | @@ -338,6 +341,7 @@ meta_wayland_seat_free (MetaWaylandSeat *seat) 120 | g_object_unref (seat->touch); 121 | 122 | meta_wayland_text_input_destroy (seat->text_input); 123 | + meta_wayland_text_input_v1_destroy (seat->text_input_v1); 124 | 125 | g_free (seat); 126 | } 127 | @@ -478,7 +482,10 @@ meta_wayland_seat_handle_event_internal (MetaWaylandSeat *seat, 128 | if (event_type == CLUTTER_BUTTON_PRESS || 129 | event_type == CLUTTER_TOUCH_BEGIN) 130 | { 131 | - meta_wayland_text_input_handle_event (seat->text_input, event); 132 | + gboolean handled = FALSE; 133 | + handled = meta_wayland_text_input_handle_event (seat->text_input, event); 134 | + if (!handled) 135 | + handled = meta_wayland_text_input_v1_handle_event (seat->text_input_v1, event); 136 | } 137 | 138 | switch (event_type) 139 | @@ -510,7 +517,8 @@ meta_wayland_seat_handle_event_internal (MetaWaylandSeat *seat, 140 | case CLUTTER_IM_COMMIT: 141 | case CLUTTER_IM_DELETE: 142 | case CLUTTER_IM_PREEDIT: 143 | - if (meta_wayland_text_input_handle_event (seat->text_input, event)) 144 | + if (meta_wayland_text_input_handle_event (seat->text_input, event) || 145 | + meta_wayland_text_input_v1_handle_event (seat->text_input_v1, event)) 146 | return TRUE; 147 | 148 | break; 149 | diff --git a/src/wayland/meta-wayland-seat.h b/src/wayland/meta-wayland-seat.h 150 | index 83fd7de1e..37704cf5a 100644 151 | --- a/src/wayland/meta-wayland-seat.h 152 | +++ b/src/wayland/meta-wayland-seat.h 153 | @@ -30,6 +30,7 @@ 154 | #include "wayland/meta-wayland-pointer.h" 155 | #include "wayland/meta-wayland-tablet-tool.h" 156 | #include "wayland/meta-wayland-text-input.h" 157 | +#include "wayland/meta-wayland-text-input-v1.h" 158 | #include "wayland/meta-wayland-touch.h" 159 | #include "wayland/meta-wayland-types.h" 160 | 161 | @@ -49,6 +50,7 @@ struct _MetaWaylandSeat 162 | MetaWaylandDataDevicePrimary primary_data_device; 163 | 164 | MetaWaylandTextInput *text_input; 165 | + MetaWaylandTextInputV1 *text_input_v1; 166 | 167 | MetaWaylandInput *input_handler; 168 | MetaWaylandEventHandler *default_handler; 169 | diff --git a/src/wayland/meta-wayland-text-input-v1.c b/src/wayland/meta-wayland-text-input-v1.c 170 | new file mode 100644 171 | index 000000000..1826a4ff4 172 | --- /dev/null 173 | +++ b/src/wayland/meta-wayland-text-input-v1.c 174 | @@ -0,0 +1,859 @@ 175 | +/* 176 | + * Copyright (C) 2024 SUSE LLC 177 | + * 178 | + * This program is free software; you can redistribute it and/or 179 | + * modify it under the terms of the GNU General Public License as 180 | + * published by the Free Software Foundation; either version 2 of the 181 | + * License, or (at your option) any later version. 182 | + * 183 | + * This program is distributed in the hope that it will be useful, but 184 | + * WITHOUT ANY WARRANTY; without even the implied warranty of 185 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 186 | + * General Public License for more details. 187 | + * 188 | + * You should have received a copy of the GNU General Public License 189 | + * along with this program; if not, see . 190 | + * 191 | + * Author: Alynx Zhou 192 | + */ 193 | + 194 | +#include "config.h" 195 | +#include "wayland/meta-wayland-text-input-v1.h" 196 | + 197 | +#include 198 | + 199 | +#include "compositor/meta-surface-actor-wayland.h" 200 | +#include "wayland/meta-wayland-private.h" 201 | +#include "wayland/meta-wayland-seat.h" 202 | +#include "wayland/meta-wayland-versions.h" 203 | + 204 | +#include "text-input-unstable-v1-server-protocol.h" 205 | + 206 | +/* 207 | + * Main difference between text-input-v1 and text-input-v3: 208 | + * text-input-v1 is not required to be double-buffered, we are expected to send 209 | + * response immediately after we receive requests, while text-input-v3 requires 210 | + * us to hold pending state and apply on commit, and all responses are applied 211 | + * after we send done. 212 | + * 213 | + * This implementation is incomplete, but it do make IME work. 214 | + * 215 | + * Things won't be implemented (Reminders for myself): 216 | + * - set_preferred_language (We don't have equivalence in ClutterInputMethod.) 217 | + * - invoke_action (No description about what button and index are.) 218 | + * - input_panel_state (We don't set this from ClutterInputFocus to text_input, 219 | + * we only set this from text_input to ClutterInputFocus.) 220 | + * - cursor_position (We don't have equivalence in ClutterInputMethod.) 221 | + * - language (We don't have equivalence in ClutterInputMethod.) 222 | + * - text_direction (We don't have equivalence in ClutterInputMethod.) 223 | + * - keysym (This matches keysym request in input-method-v1, but we only have 224 | + * forward_key in ClutterInputMethod, which is more like key request in 225 | + * input-method-v1 and will finally become a keyboard key event, we don't have 226 | + * equivalence for this in ClutterInputMethod.) 227 | + * - modifiers_map (This is used by keysym and we don't support keysym.) 228 | + */ 229 | + 230 | +struct _MetaWaylandTextInputV1 231 | +{ 232 | + MetaWaylandSeat *seat; 233 | + ClutterInputFocus *input_focus; 234 | + 235 | + struct wl_list resource_list; 236 | + struct wl_list focus_resource_list; 237 | + MetaWaylandSurface *surface; 238 | + struct wl_listener surface_listener; 239 | + 240 | + GHashTable *resource_serials; 241 | + 242 | + struct 243 | + { 244 | + char *text; 245 | + uint32_t cursor; 246 | + uint32_t anchor; 247 | + } surrounding; 248 | +}; 249 | + 250 | +#define META_TYPE_WAYLAND_TEXT_INPUT_V1_FOCUS (meta_wayland_text_input_v1_focus_get_type ()) 251 | +G_DECLARE_FINAL_TYPE (MetaWaylandTextInputV1Focus, meta_wayland_text_input_v1_focus, 252 | + META, WAYLAND_TEXT_INPUT_V1_FOCUS, ClutterInputFocus) 253 | + 254 | +struct _MetaWaylandTextInputV1Focus 255 | +{ 256 | + ClutterInputFocus parent_instance; 257 | + MetaWaylandTextInputV1 *text_input; 258 | +}; 259 | +G_DEFINE_TYPE (MetaWaylandTextInputV1Focus, meta_wayland_text_input_v1_focus, 260 | + CLUTTER_TYPE_INPUT_FOCUS) 261 | + 262 | +static MetaBackend * 263 | +backend_from_text_input_v1 (MetaWaylandTextInputV1 *text_input) 264 | +{ 265 | + MetaWaylandSeat *seat = text_input->seat; 266 | + MetaWaylandCompositor *compositor = meta_wayland_seat_get_compositor (seat); 267 | + MetaContext *context = meta_wayland_compositor_get_context (compositor); 268 | + 269 | + return meta_context_get_backend (context); 270 | +} 271 | + 272 | +static uint32_t 273 | +get_serial (MetaWaylandTextInputV1 *text_input, 274 | + struct wl_resource *resource) 275 | +{ 276 | + return GPOINTER_TO_UINT (g_hash_table_lookup (text_input->resource_serials, 277 | + resource)); 278 | +} 279 | + 280 | +static void 281 | +set_serial (MetaWaylandTextInputV1 *text_input, 282 | + struct wl_resource *resource, 283 | + uint32_t serial) 284 | +{ 285 | + g_hash_table_insert (text_input->resource_serials, resource, 286 | + GUINT_TO_POINTER (serial)); 287 | +} 288 | + 289 | +static void 290 | +text_input_v1_send_preedit_string (struct wl_resource *resource, 291 | + uint32_t serial, 292 | + const char *text, 293 | + unsigned int cursor) 294 | +{ 295 | + gsize pos = 0; 296 | + 297 | + /* Chromium does not accept NULL as preedit/commit string... */ 298 | + text = text ? text : ""; 299 | + pos = g_utf8_offset_to_pointer (text, cursor) - text; 300 | + 301 | + /* We really don't need so much styles... */ 302 | + zwp_text_input_v1_send_preedit_styling (resource, 0, strlen (text), 303 | + ZWP_TEXT_INPUT_V1_PREEDIT_STYLE_UNDERLINE); 304 | + zwp_text_input_v1_send_preedit_cursor (resource, pos); 305 | + zwp_text_input_v1_send_preedit_string (resource, serial, text, text); 306 | +} 307 | + 308 | +static void 309 | +meta_wayland_text_input_v1_focus_set_preedit_text (ClutterInputFocus *focus, 310 | + const gchar *text, 311 | + unsigned int cursor, 312 | + unsigned int anchor) 313 | +{ 314 | + MetaWaylandTextInputV1 *text_input; 315 | + struct wl_resource *resource; 316 | + 317 | + text_input = META_WAYLAND_TEXT_INPUT_V1_FOCUS (focus)->text_input; 318 | + 319 | + wl_resource_for_each (resource, &text_input->focus_resource_list) 320 | + { 321 | + text_input_v1_send_preedit_string (resource, 322 | + get_serial (text_input, resource), 323 | + text, 324 | + cursor); 325 | + } 326 | +} 327 | + 328 | +static void 329 | +meta_wayland_text_input_v1_focus_request_surrounding (ClutterInputFocus *focus) 330 | +{ 331 | + MetaWaylandTextInputV1 *text_input; 332 | + long cursor, anchor; 333 | + 334 | + /* Clutter uses char offsets but text-input-v1 uses byte offsets. */ 335 | + text_input = META_WAYLAND_TEXT_INPUT_V1_FOCUS (focus)->text_input; 336 | + cursor = g_utf8_strlen (text_input->surrounding.text, 337 | + text_input->surrounding.cursor); 338 | + anchor = g_utf8_strlen (text_input->surrounding.text, 339 | + text_input->surrounding.anchor); 340 | + clutter_input_focus_set_surrounding (focus, 341 | + text_input->surrounding.text, 342 | + cursor, 343 | + anchor); 344 | +} 345 | + 346 | +static void 347 | +text_input_v1_send_commit_string (struct wl_resource *resource, 348 | + uint32_t serial, 349 | + const char *text) 350 | +{ 351 | + /* Chromium does not accept NULL as preedit/commit string... */ 352 | + text = text ? text : ""; 353 | + 354 | + zwp_text_input_v1_send_commit_string (resource, serial, text); 355 | +} 356 | + 357 | +static void 358 | +meta_wayland_text_input_v1_focus_delete_surrounding (ClutterInputFocus *focus, 359 | + int offset, 360 | + guint len) 361 | +{ 362 | + MetaWaylandTextInputV1 *text_input; 363 | + struct wl_resource *resource; 364 | + const char *start, *end; 365 | + const char *before, *after; 366 | + const char *cursor; 367 | + 368 | + /* 369 | + * offset and len are counted by UTF-8 chars, but text-input-v1's lengths are 370 | + * counted by bytes, so we convert UTF-8 char offsets to pointers here, this 371 | + * needs the surrounding text 372 | + */ 373 | + text_input = META_WAYLAND_TEXT_INPUT_V1_FOCUS (focus)->text_input; 374 | + offset = MIN (offset, 0); 375 | + 376 | + start = text_input->surrounding.text; 377 | + end = start + strlen (text_input->surrounding.text); 378 | + cursor = start + text_input->surrounding.cursor; 379 | + 380 | + before = g_utf8_offset_to_pointer (cursor, offset); 381 | + g_assert (before >= start); 382 | + 383 | + after = g_utf8_offset_to_pointer (cursor, offset + len); 384 | + g_assert (after <= end); 385 | + 386 | + wl_resource_for_each (resource, &text_input->focus_resource_list) 387 | + { 388 | + zwp_text_input_v1_send_delete_surrounding_text (resource, 389 | + before - cursor, 390 | + after - before); 391 | + /* 392 | + * text-input-v1 says delete_surrounding belongs to next commit, so an 393 | + * empty commit is required. 394 | + */ 395 | + text_input_v1_send_commit_string (resource, 396 | + get_serial (text_input, resource), 397 | + NULL); 398 | + } 399 | +} 400 | + 401 | +static void 402 | +meta_wayland_text_input_v1_focus_commit_text (ClutterInputFocus *focus, 403 | + const gchar *text) 404 | +{ 405 | + MetaWaylandTextInputV1 *text_input; 406 | + struct wl_resource *resource; 407 | + 408 | + text_input = META_WAYLAND_TEXT_INPUT_V1_FOCUS (focus)->text_input; 409 | + 410 | + wl_resource_for_each (resource, &text_input->focus_resource_list) 411 | + { 412 | + /* 413 | + * You have to clear preedit string after committing string, otherwise 414 | + * some apps (I reproduced with Code OSS) will send you empty surrounding 415 | + * text and breaks delete_surrounding_text. 416 | + */ 417 | + text_input_v1_send_commit_string (resource, 418 | + get_serial (text_input, resource), 419 | + text); 420 | + /* Clear preedit string because we already committed. */ 421 | + text_input_v1_send_preedit_string (resource, 422 | + get_serial (text_input, resource), 423 | + NULL, 424 | + 0); 425 | + } 426 | +} 427 | + 428 | +static void 429 | +meta_wayland_text_input_v1_focus_class_init (MetaWaylandTextInputV1FocusClass *klass) 430 | +{ 431 | + ClutterInputFocusClass *focus_class = CLUTTER_INPUT_FOCUS_CLASS (klass); 432 | + 433 | + focus_class->request_surrounding = meta_wayland_text_input_v1_focus_request_surrounding; 434 | + focus_class->delete_surrounding = meta_wayland_text_input_v1_focus_delete_surrounding; 435 | + focus_class->commit_text = meta_wayland_text_input_v1_focus_commit_text; 436 | + focus_class->set_preedit_text = meta_wayland_text_input_v1_focus_set_preedit_text; 437 | +} 438 | + 439 | +static void 440 | +meta_wayland_text_input_v1_focus_init (MetaWaylandTextInputV1Focus *focus) 441 | +{ 442 | +} 443 | + 444 | +static ClutterInputFocus * 445 | +meta_wayland_text_input_focus_new (MetaWaylandTextInputV1 *text_input) 446 | +{ 447 | + MetaWaylandTextInputV1Focus *focus; 448 | + 449 | + focus = g_object_new (META_TYPE_WAYLAND_TEXT_INPUT_V1_FOCUS, NULL); 450 | + focus->text_input = text_input; 451 | + 452 | + return CLUTTER_INPUT_FOCUS (focus); 453 | +} 454 | + 455 | +static void 456 | +move_resources (struct wl_list *destination, struct wl_list *source) 457 | +{ 458 | + wl_list_insert_list (destination, source); 459 | + wl_list_init (source); 460 | +} 461 | + 462 | +static void 463 | +move_resources_for_client (struct wl_list *destination, 464 | + struct wl_list *source, 465 | + struct wl_client *client) 466 | +{ 467 | + struct wl_resource *resource, *tmp; 468 | + wl_resource_for_each_safe (resource, tmp, source) 469 | + { 470 | + if (wl_resource_get_client (resource) == client) 471 | + { 472 | + wl_list_remove (wl_resource_get_link (resource)); 473 | + wl_list_insert (destination, wl_resource_get_link (resource)); 474 | + } 475 | + } 476 | +} 477 | + 478 | +static void 479 | +meta_wayland_text_input_v1_set_focus (MetaWaylandTextInputV1 *text_input, 480 | + MetaWaylandSurface *surface) 481 | +{ 482 | + if (text_input->surface == surface) 483 | + return; 484 | + 485 | + if (text_input->surface) 486 | + { 487 | + if (!wl_list_empty (&text_input->focus_resource_list)) 488 | + { 489 | + ClutterInputFocus *focus = text_input->input_focus; 490 | + ClutterInputMethod *input_method; 491 | + struct wl_resource *resource; 492 | + 493 | + if (clutter_input_focus_is_focused (focus)) 494 | + { 495 | + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); 496 | + clutter_input_focus_reset (focus); 497 | + clutter_input_method_focus_out (input_method); 498 | + } 499 | + 500 | + wl_resource_for_each (resource, &text_input->focus_resource_list) 501 | + { 502 | + zwp_text_input_v1_send_leave (resource); 503 | + } 504 | + 505 | + move_resources (&text_input->resource_list, 506 | + &text_input->focus_resource_list); 507 | + } 508 | + 509 | + wl_list_remove (&text_input->surface_listener.link); 510 | + text_input->surface = NULL; 511 | + } 512 | + 513 | + if (surface && surface->resource) 514 | + { 515 | + struct wl_resource *focus_surface_resource; 516 | + 517 | + text_input->surface = surface; 518 | + focus_surface_resource = text_input->surface->resource; 519 | + wl_resource_add_destroy_listener (focus_surface_resource, 520 | + &text_input->surface_listener); 521 | + 522 | + move_resources_for_client (&text_input->focus_resource_list, 523 | + &text_input->resource_list, 524 | + wl_resource_get_client (focus_surface_resource)); 525 | + 526 | + if (!wl_list_empty (&text_input->focus_resource_list)) 527 | + { 528 | + struct wl_resource *resource; 529 | + 530 | + wl_resource_for_each (resource, &text_input->focus_resource_list) 531 | + { 532 | + zwp_text_input_v1_send_enter (resource, surface->resource); 533 | + } 534 | + } 535 | + } 536 | +} 537 | + 538 | +static void 539 | +text_input_v1_handle_focus_surface_destroy (struct wl_listener *listener, 540 | + void *data) 541 | +{ 542 | + MetaWaylandTextInputV1 *text_input = wl_container_of (listener, text_input, surface_listener); 543 | + 544 | + meta_wayland_text_input_v1_set_focus (text_input, NULL); 545 | +} 546 | + 547 | +static void 548 | +text_input_v1_destructor (struct wl_resource *resource) 549 | +{ 550 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 551 | + 552 | + g_hash_table_remove (text_input->resource_serials, resource); 553 | + wl_list_remove (wl_resource_get_link (resource)); 554 | +} 555 | + 556 | +static gboolean 557 | +client_matches_focus (MetaWaylandTextInputV1 *text_input, 558 | + struct wl_client *client) 559 | +{ 560 | + if (!text_input->surface) 561 | + return FALSE; 562 | + 563 | + return client == wl_resource_get_client (text_input->surface->resource); 564 | +} 565 | + 566 | +static void 567 | +text_input_v1_activate (struct wl_client *client, 568 | + struct wl_resource *resource, 569 | + struct wl_resource *seat_resource, 570 | + struct wl_resource *surface_resource) 571 | +{ 572 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 573 | + MetaWaylandSurface *surface; 574 | + ClutterInputFocus *focus = text_input->input_focus; 575 | + ClutterInputMethod *input_method; 576 | + 577 | + /* 578 | + * Don't use client_matches_focus() here because we have no focused surface if 579 | + * not activated in text-input-v1. 580 | + */ 581 | + 582 | + surface = wl_resource_get_user_data (surface_resource); 583 | + meta_wayland_text_input_v1_set_focus (text_input, surface); 584 | + 585 | + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); 586 | + 587 | + if (input_method) 588 | + { 589 | + if (!clutter_input_focus_is_focused (focus)) 590 | + clutter_input_method_focus_in (input_method, focus); 591 | + 592 | + clutter_input_focus_set_can_show_preedit (focus, TRUE); 593 | + } 594 | +} 595 | + 596 | +static void 597 | +text_input_v1_deactivate (struct wl_client *client, 598 | + struct wl_resource *resource, 599 | + struct wl_resource *seat_resource) 600 | +{ 601 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 602 | + ClutterInputFocus *focus = text_input->input_focus; 603 | + ClutterInputMethod *input_method; 604 | + 605 | + if (!client_matches_focus (text_input, client)) 606 | + return; 607 | + 608 | + meta_wayland_text_input_v1_set_focus (text_input, NULL); 609 | + 610 | + input_method = clutter_backend_get_input_method (clutter_get_default_backend ()); 611 | + if (input_method && clutter_input_focus_is_focused (focus)) 612 | + { 613 | + clutter_input_focus_reset (focus); 614 | + clutter_input_method_focus_out (input_method); 615 | + } 616 | +} 617 | + 618 | +static void 619 | +text_input_v1_show_input_panel (struct wl_client *client, 620 | + struct wl_resource *resource) 621 | +{ 622 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 623 | + ClutterInputFocus *focus = text_input->input_focus; 624 | + 625 | + if (!client_matches_focus (text_input, client)) 626 | + return; 627 | + 628 | + clutter_input_focus_set_input_panel_state (focus, 629 | + CLUTTER_INPUT_PANEL_STATE_ON); 630 | +} 631 | + 632 | +static void 633 | +text_input_v1_hide_input_panel (struct wl_client *client, 634 | + struct wl_resource *resource) 635 | +{ 636 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 637 | + ClutterInputFocus *focus = text_input->input_focus; 638 | + 639 | + if (!client_matches_focus (text_input, client)) 640 | + return; 641 | + 642 | + clutter_input_focus_set_input_panel_state (focus, 643 | + CLUTTER_INPUT_PANEL_STATE_OFF); 644 | +} 645 | + 646 | +static void 647 | +text_input_v1_set_surrounding_text (struct wl_client *client, 648 | + struct wl_resource *resource, 649 | + const char *text, 650 | + uint32_t cursor, 651 | + uint32_t anchor) 652 | +{ 653 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 654 | + ClutterInputFocus *focus = text_input->input_focus; 655 | + long char_cursor, char_anchor; 656 | + 657 | + if (!client_matches_focus (text_input, client)) 658 | + return; 659 | + 660 | + /* Save the surrounding text for `delete_surrounding_text`. */ 661 | + g_free (text_input->surrounding.text); 662 | + text_input->surrounding.text = g_strdup (text); 663 | + text_input->surrounding.cursor = cursor; 664 | + text_input->surrounding.anchor = anchor; 665 | + 666 | + /* Pass the surrounding text to Clutter to handle it with input method. */ 667 | + /* Clutter uses char offsets but text-input-v1 uses byte offsets. */ 668 | + char_cursor = g_utf8_strlen (text_input->surrounding.text, 669 | + text_input->surrounding.cursor); 670 | + char_anchor = g_utf8_strlen (text_input->surrounding.text, 671 | + text_input->surrounding.anchor); 672 | + clutter_input_focus_set_surrounding (focus, 673 | + text_input->surrounding.text, 674 | + char_cursor, 675 | + char_anchor); 676 | +} 677 | + 678 | +static void 679 | +text_input_v1_reset (struct wl_client *client, 680 | + struct wl_resource *resource) 681 | +{ 682 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 683 | + ClutterInputFocus *focus = text_input->input_focus; 684 | + 685 | + if (!client_matches_focus (text_input, client)) 686 | + return; 687 | + 688 | + /* 689 | + * This means text was changed outside of normal input method flow, but we are 690 | + * still focusing the same text entry, so we only reset states, but don't 691 | + * reset focus, cursor position and panel visibility. 692 | + */ 693 | + g_clear_pointer (&text_input->surrounding.text, g_free); 694 | + clutter_input_focus_set_surrounding (focus, NULL, 0, 0); 695 | + clutter_input_focus_set_content_hints (focus, 0); 696 | + clutter_input_focus_set_content_purpose (focus, 697 | + CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL); 698 | +} 699 | + 700 | +static ClutterInputContentHintFlags 701 | +translate_hints (uint32_t hints) 702 | +{ 703 | + ClutterInputContentHintFlags clutter_hints = 0; 704 | + 705 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_DEFAULT) 706 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_DEFAULT; 707 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_PASSWORD) 708 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_PASSWORD; 709 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_COMPLETION) 710 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_COMPLETION; 711 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CORRECTION) 712 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_AUTO_CORRECTION; 713 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_AUTO_CAPITALIZATION) 714 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION; 715 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_LOWERCASE) 716 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_LOWERCASE; 717 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_UPPERCASE) 718 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_UPPERCASE; 719 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_TITLECASE) 720 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_TITLECASE; 721 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_HIDDEN_TEXT) 722 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_HIDDEN_TEXT; 723 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_SENSITIVE_DATA) 724 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_SENSITIVE_DATA; 725 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_LATIN) 726 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_LATIN; 727 | + if (hints & ZWP_TEXT_INPUT_V1_CONTENT_HINT_MULTILINE) 728 | + clutter_hints |= CLUTTER_INPUT_CONTENT_HINT_MULTILINE; 729 | + 730 | + return clutter_hints; 731 | +} 732 | + 733 | +static ClutterInputContentPurpose 734 | +translate_purpose (uint32_t purpose) 735 | +{ 736 | + switch (purpose) 737 | + { 738 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NORMAL: 739 | + return CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL; 740 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_ALPHA: 741 | + return CLUTTER_INPUT_CONTENT_PURPOSE_ALPHA; 742 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DIGITS: 743 | + return CLUTTER_INPUT_CONTENT_PURPOSE_DIGITS; 744 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NUMBER: 745 | + return CLUTTER_INPUT_CONTENT_PURPOSE_NUMBER; 746 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PHONE: 747 | + return CLUTTER_INPUT_CONTENT_PURPOSE_PHONE; 748 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_URL: 749 | + return CLUTTER_INPUT_CONTENT_PURPOSE_URL; 750 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_EMAIL: 751 | + return CLUTTER_INPUT_CONTENT_PURPOSE_EMAIL; 752 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_NAME: 753 | + return CLUTTER_INPUT_CONTENT_PURPOSE_NAME; 754 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_PASSWORD: 755 | + return CLUTTER_INPUT_CONTENT_PURPOSE_PASSWORD; 756 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATE: 757 | + return CLUTTER_INPUT_CONTENT_PURPOSE_DATE; 758 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_TIME: 759 | + return CLUTTER_INPUT_CONTENT_PURPOSE_TIME; 760 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_DATETIME: 761 | + return CLUTTER_INPUT_CONTENT_PURPOSE_DATETIME; 762 | + case ZWP_TEXT_INPUT_V1_CONTENT_PURPOSE_TERMINAL: 763 | + return CLUTTER_INPUT_CONTENT_PURPOSE_TERMINAL; 764 | + } 765 | + 766 | + g_warn_if_reached (); 767 | + return CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL; 768 | +} 769 | + 770 | +static void 771 | +text_input_v1_set_content_type (struct wl_client *client, 772 | + struct wl_resource *resource, 773 | + uint32_t hint, 774 | + uint32_t purpose) 775 | +{ 776 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 777 | + ClutterInputFocus *focus = text_input->input_focus; 778 | + 779 | + if (!client_matches_focus (text_input, client)) 780 | + return; 781 | + 782 | + clutter_input_focus_set_content_hints (focus, translate_hints (hint)); 783 | + clutter_input_focus_set_content_purpose (focus, translate_purpose (purpose)); 784 | +} 785 | + 786 | +static void 787 | +text_input_v1_set_cursor_rectangle (struct wl_client *client, 788 | + struct wl_resource *resource, 789 | + int32_t x, 790 | + int32_t y, 791 | + int32_t width, 792 | + int32_t height) 793 | +{ 794 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 795 | + ClutterInputFocus *focus = text_input->input_focus; 796 | + MtkRectangle rect = (MtkRectangle) { x, y, width, height }; 797 | + graphene_rect_t cursor_rect; 798 | + float x1, y1, x2, y2; 799 | + 800 | + if (!client_matches_focus (text_input, client)) 801 | + return; 802 | + 803 | + meta_wayland_surface_get_absolute_coordinates (text_input->surface, 804 | + rect.x, rect.y, &x1, &y1); 805 | + meta_wayland_surface_get_absolute_coordinates (text_input->surface, 806 | + rect.x + rect.width, 807 | + rect.y + rect.height, 808 | + &x2, &y2); 809 | + 810 | + graphene_rect_init (&cursor_rect, x1, y1, x2 - x1, y2 - y1); 811 | + clutter_input_focus_set_cursor_location (focus, &cursor_rect); 812 | +} 813 | + 814 | +static void 815 | +text_input_v1_set_preferred_lanaguage (struct wl_client *client, 816 | + struct wl_resource *resource, 817 | + const char *language) 818 | +{ 819 | + /* ClutterInputMethod does not support this so this is useless. */ 820 | +} 821 | + 822 | +/* 823 | + * text-input-v1 is not required to be double-buffered!!!!!!!!!!!!!!!!!!!!!!!!!! 824 | + * commit_state just means "I am giving you a new serial and you should use 825 | + * this". It can work without commit_state, chromium does not send this. 826 | + */ 827 | +static void 828 | +text_input_v1_commit_state (struct wl_client *client, 829 | + struct wl_resource *resource, 830 | + uint32_t serial) 831 | +{ 832 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 833 | + 834 | + if (!client_matches_focus (text_input, client)) 835 | + return; 836 | + 837 | + set_serial (text_input, resource, serial); 838 | +} 839 | + 840 | +static void 841 | +text_input_v1_invoke_action (struct wl_client *client, 842 | + struct wl_resource *resource, 843 | + uint32_t button, 844 | + uint32_t index) 845 | +{ 846 | + /* There is no doc about what button and index are, I am not an invoker. */ 847 | +} 848 | + 849 | +static struct zwp_text_input_v1_interface meta_text_input_v1_interface = { 850 | + text_input_v1_activate, 851 | + text_input_v1_deactivate, 852 | + text_input_v1_show_input_panel, 853 | + text_input_v1_hide_input_panel, 854 | + text_input_v1_reset, 855 | + text_input_v1_set_surrounding_text, 856 | + text_input_v1_set_content_type, 857 | + text_input_v1_set_cursor_rectangle, 858 | + text_input_v1_set_preferred_lanaguage, 859 | + text_input_v1_commit_state, 860 | + text_input_v1_invoke_action 861 | +}; 862 | + 863 | +void 864 | +meta_wayland_text_input_v1_destroy (MetaWaylandTextInputV1 *text_input) 865 | +{ 866 | + meta_wayland_text_input_v1_set_focus (text_input, NULL); 867 | + g_object_unref (text_input->input_focus); 868 | + g_hash_table_destroy (text_input->resource_serials); 869 | + g_clear_pointer (&text_input->surrounding.text, g_free); 870 | + g_free (text_input); 871 | +} 872 | + 873 | +static void 874 | +meta_wayland_text_input_v1_create_new_resource (MetaWaylandTextInputV1 *text_input, 875 | + struct wl_client *client, 876 | + uint32_t id) 877 | +{ 878 | + struct wl_resource *text_input_resource; 879 | + 880 | + text_input_resource = wl_resource_create (client, 881 | + &zwp_text_input_v1_interface, 882 | + META_ZWP_TEXT_INPUT_V1_VERSION, 883 | + id); 884 | + 885 | + wl_resource_set_implementation (text_input_resource, 886 | + &meta_text_input_v1_interface, 887 | + text_input, text_input_v1_destructor); 888 | + 889 | + if (text_input->surface && 890 | + wl_resource_get_client (text_input->surface->resource) == client) 891 | + { 892 | + wl_list_insert (&text_input->focus_resource_list, 893 | + wl_resource_get_link (text_input_resource)); 894 | + 895 | + zwp_text_input_v1_send_enter (text_input_resource, 896 | + text_input->surface->resource); 897 | + } 898 | + else 899 | + { 900 | + wl_list_insert (&text_input->resource_list, 901 | + wl_resource_get_link (text_input_resource)); 902 | + } 903 | +} 904 | + 905 | +static void 906 | +text_input_manager_v1_get_text_input (struct wl_client *client, 907 | + struct wl_resource *resource, 908 | + uint32_t id) 909 | +{ 910 | + MetaWaylandTextInputV1 *text_input = wl_resource_get_user_data (resource); 911 | + 912 | + meta_wayland_text_input_v1_create_new_resource (text_input, client, id); 913 | +} 914 | + 915 | +static struct zwp_text_input_manager_v1_interface meta_text_input_manager_v1_interface = { 916 | + text_input_manager_v1_get_text_input 917 | +}; 918 | + 919 | +static void 920 | +bind_text_input_v1 (struct wl_client *client, 921 | + void *data, 922 | + uint32_t version, 923 | + uint32_t id) 924 | +{ 925 | + MetaWaylandTextInputV1 *text_input = data; 926 | + struct wl_resource *resource; 927 | + 928 | + resource = wl_resource_create (client, 929 | + &zwp_text_input_manager_v1_interface, 930 | + META_ZWP_TEXT_INPUT_V1_VERSION, 931 | + id); 932 | + wl_resource_set_implementation (resource, 933 | + &meta_text_input_manager_v1_interface, 934 | + text_input, NULL); 935 | +} 936 | + 937 | +gboolean 938 | +meta_wayland_text_input_v1_init (MetaWaylandCompositor *compositor) 939 | +{ 940 | + return (wl_global_create (compositor->wayland_display, 941 | + &zwp_text_input_manager_v1_interface, 942 | + META_ZWP_TEXT_INPUT_V1_VERSION, 943 | + compositor->seat->text_input_v1, 944 | + bind_text_input_v1) != NULL); 945 | +} 946 | + 947 | +MetaWaylandTextInputV1 * 948 | +meta_wayland_text_input_v1_new (MetaWaylandSeat *seat) 949 | +{ 950 | + MetaWaylandTextInputV1 *text_input; 951 | + 952 | + text_input = g_new0 (MetaWaylandTextInputV1, 1); 953 | + text_input->input_focus = meta_wayland_text_input_focus_new (text_input); 954 | + text_input->seat = seat; 955 | + 956 | + wl_list_init (&text_input->resource_list); 957 | + wl_list_init (&text_input->focus_resource_list); 958 | + text_input->surface_listener.notify = text_input_v1_handle_focus_surface_destroy; 959 | + 960 | + text_input->resource_serials = g_hash_table_new (NULL, NULL); 961 | + 962 | + return text_input; 963 | +} 964 | + 965 | +/* This function eats key events and will send them to input method. */ 966 | +gboolean 967 | +meta_wayland_text_input_v1_update (MetaWaylandTextInputV1 *text_input, 968 | + const ClutterEvent *event) 969 | +{ 970 | + ClutterInputFocus *focus = text_input->input_focus; 971 | + ClutterEventType event_type; 972 | + 973 | + if (!text_input->surface || !clutter_input_focus_is_focused (focus)) 974 | + return FALSE; 975 | + 976 | + event_type = clutter_event_type (event); 977 | + 978 | + if (event_type == CLUTTER_KEY_PRESS || 979 | + event_type == CLUTTER_KEY_RELEASE) 980 | + { 981 | + gboolean filtered = FALSE; 982 | + 983 | + filtered = clutter_input_focus_filter_event (focus, event); 984 | + 985 | + return filtered; 986 | + } 987 | + 988 | + return FALSE; 989 | +} 990 | + 991 | +gboolean 992 | +meta_wayland_text_input_v1_handle_event (MetaWaylandTextInputV1 *text_input, 993 | + const ClutterEvent *event) 994 | +{ 995 | + ClutterInputFocus *focus = text_input->input_focus; 996 | + ClutterEventType event_type; 997 | + gboolean retval; 998 | + 999 | + if (!text_input->surface || !clutter_input_focus_is_focused (focus)) 1000 | + return FALSE; 1001 | + 1002 | + event_type = clutter_event_type (event); 1003 | + 1004 | + retval = clutter_input_focus_process_event (focus, event); 1005 | + 1006 | + if (event_type == CLUTTER_BUTTON_PRESS || event_type == CLUTTER_TOUCH_BEGIN) 1007 | + { 1008 | + MetaWaylandSurface *surface = NULL; 1009 | + MetaBackend *backend; 1010 | + ClutterStage *stage; 1011 | + ClutterActor *actor; 1012 | + 1013 | + backend = backend_from_text_input_v1 (text_input); 1014 | + stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); 1015 | + 1016 | + actor = clutter_stage_get_device_actor (stage, 1017 | + clutter_event_get_device (event), 1018 | + clutter_event_get_event_sequence (event)); 1019 | + 1020 | + if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) 1021 | + { 1022 | + MetaSurfaceActorWayland *actor_wayland = 1023 | + META_SURFACE_ACTOR_WAYLAND (actor); 1024 | + 1025 | + surface = meta_surface_actor_wayland_get_surface (actor_wayland); 1026 | + 1027 | + if (surface == text_input->surface) 1028 | + clutter_input_focus_reset (focus); 1029 | + } 1030 | + } 1031 | + 1032 | + return retval; 1033 | +} 1034 | diff --git a/src/wayland/meta-wayland-text-input-v1.h b/src/wayland/meta-wayland-text-input-v1.h 1035 | new file mode 100644 1036 | index 000000000..79b1c0a54 1037 | --- /dev/null 1038 | +++ b/src/wayland/meta-wayland-text-input-v1.h 1039 | @@ -0,0 +1,38 @@ 1040 | +/* 1041 | + * Copyright (C) 2024 SUSE LLC 1042 | + * 1043 | + * This program is free software; you can redistribute it and/or 1044 | + * modify it under the terms of the GNU General Public License as 1045 | + * published by the Free Software Foundation; either version 2 of the 1046 | + * License, or (at your option) any later version. 1047 | + * 1048 | + * This program is distributed in the hope that it will be useful, but 1049 | + * WITHOUT ANY WARRANTY; without even the implied warranty of 1050 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1051 | + * General Public License for more details. 1052 | + * 1053 | + * You should have received a copy of the GNU General Public License 1054 | + * along with this program; if not, see . 1055 | + * 1056 | + * Author: Alynx Zhou 1057 | + */ 1058 | + 1059 | +#pragma once 1060 | + 1061 | +#include 1062 | + 1063 | +#include "meta/window.h" 1064 | +#include "wayland/meta-wayland-types.h" 1065 | + 1066 | +typedef struct _MetaWaylandTextInputV1 MetaWaylandTextInputV1; 1067 | + 1068 | +MetaWaylandTextInputV1 * meta_wayland_text_input_v1_new (MetaWaylandSeat *seat); 1069 | +void meta_wayland_text_input_v1_destroy (MetaWaylandTextInputV1 *text_input); 1070 | + 1071 | +gboolean meta_wayland_text_input_v1_init (MetaWaylandCompositor *compositor); 1072 | + 1073 | +gboolean meta_wayland_text_input_v1_update (MetaWaylandTextInputV1 *text_input, 1074 | + const ClutterEvent *event); 1075 | + 1076 | +gboolean meta_wayland_text_input_v1_handle_event (MetaWaylandTextInputV1 *text_input, 1077 | + const ClutterEvent *event); 1078 | diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h 1079 | index 900f30d78..a77b81461 100644 1080 | --- a/src/wayland/meta-wayland-versions.h 1081 | +++ b/src/wayland/meta-wayland-versions.h 1082 | @@ -49,6 +49,7 @@ 1083 | #define META_ZXDG_OUTPUT_V1_VERSION 3 1084 | #define META_ZWP_XWAYLAND_KEYBOARD_GRAB_V1_VERSION 1 1085 | #define META_ZWP_TEXT_INPUT_V3_VERSION 1 1086 | +#define META_ZWP_TEXT_INPUT_V1_VERSION 1 1087 | #define META_WP_VIEWPORTER_VERSION 1 1088 | #define META_ZWP_PRIMARY_SELECTION_V1_VERSION 1 1089 | #define META_WP_PRESENTATION_VERSION 1 1090 | diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c 1091 | index 501b69a91..0114823c1 100644 1092 | --- a/src/wayland/meta-wayland.c 1093 | +++ b/src/wayland/meta-wayland.c 1094 | @@ -865,6 +865,7 @@ meta_wayland_compositor_new (MetaContext *context) 1095 | meta_wayland_keyboard_shortcuts_inhibit_init (compositor); 1096 | meta_wayland_surface_inhibit_shortcuts_dialog_init (); 1097 | meta_wayland_text_input_init (compositor); 1098 | + meta_wayland_text_input_v1_init (compositor); 1099 | meta_wayland_init_presentation_time (compositor); 1100 | meta_wayland_activation_init (compositor); 1101 | meta_wayland_transaction_init (compositor); 1102 | @@ -1124,6 +1125,12 @@ meta_wayland_compositor_get_text_input (MetaWaylandCompositor *compositor) 1103 | return compositor->seat->text_input; 1104 | } 1105 | 1106 | +MetaWaylandTextInputV1 * 1107 | +meta_wayland_compositor_get_text_input_v1 (MetaWaylandCompositor *compositor) 1108 | +{ 1109 | + return compositor->seat->text_input_v1; 1110 | +} 1111 | + 1112 | static void 1113 | meta_wayland_compositor_update_focus (MetaWaylandCompositor *compositor, 1114 | MetaWindow *window) 1115 | diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h 1116 | index 0a0476eba..c23e82cdc 100644 1117 | --- a/src/wayland/meta-wayland.h 1118 | +++ b/src/wayland/meta-wayland.h 1119 | @@ -26,6 +26,7 @@ 1120 | #include "meta/types.h" 1121 | #include "meta/meta-wayland-compositor.h" 1122 | #include "wayland/meta-wayland-text-input.h" 1123 | +#include "wayland/meta-wayland-text-input-v1.h" 1124 | #include "wayland/meta-wayland-types.h" 1125 | 1126 | META_EXPORT_TEST 1127 | @@ -88,6 +89,7 @@ void meta_wayland_compositor_schedule_surface_association (Me 1128 | MetaWindow *window); 1129 | 1130 | MetaWaylandTextInput * meta_wayland_compositor_get_text_input (MetaWaylandCompositor *compositor); 1131 | +MetaWaylandTextInputV1 * meta_wayland_compositor_get_text_input_v1 (MetaWaylandCompositor *compositor); 1132 | 1133 | #ifdef HAVE_XWAYLAND 1134 | void meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor, 1135 | -- 1136 | 2.45.2 1137 | 1138 | --------------------------------------------------------------------------------