Compare commits
39
Commits
7b0131f0c8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d830eab1e | ||
|
|
9f371b6ab1 | ||
|
|
2666a84516 | ||
|
|
6d699a2cfa | ||
|
|
66714d0675 | ||
|
|
33956f2edf | ||
|
|
03160f1c60 | ||
|
|
c2599707b6 | ||
|
|
e2d2ce6c6c | ||
|
|
b3913c9c9b | ||
|
|
9d9c429033 | ||
|
|
e1672d7cbe | ||
|
|
9e44cb4c99 | ||
|
|
d7a7627163 | ||
|
|
dd37b43078 | ||
|
|
ecebf8d98c | ||
|
|
8f09e5bf88 | ||
|
|
12e2113e15 | ||
|
|
eeb122ffd6 | ||
|
|
6e91fb16f2 | ||
|
|
7f232893f2 | ||
|
|
502f748f0d | ||
|
|
ae4454b5fa | ||
|
|
b4d9c12ada | ||
|
|
d805596763 | ||
|
|
460fbd4d7f | ||
|
|
605bd8e6e8 | ||
|
|
1cbab3e494 | ||
|
|
aeac1ff44b | ||
|
|
fe0d9e5198 | ||
|
|
b5920c6211 | ||
|
|
54e04477eb | ||
|
|
aa5da23957 | ||
|
|
7cefe60b84 | ||
|
|
76f6e74305 | ||
|
|
ad474292fd | ||
|
|
5b031f8a54 | ||
|
|
bbcf7c1f44 | ||
|
|
4e1aebf265 |
No files matched your search
+11
@@ -0,0 +1,11 @@
|
||||
keys:
|
||||
- &key age1tx6jdr6535xxeygpwkkgvdwc24tulr420cm7gk56xzfp0slzeqks2nwpyg
|
||||
creation_rules:
|
||||
- path_regex: host/[^/]+/secrets/.+$
|
||||
key_groups:
|
||||
- age:
|
||||
- *key
|
||||
- path_regex: user/[^/]+/secrets\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *key
|
||||
Generated
+172
-148
@@ -40,11 +40,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772460678,
|
||||
"narHash": "sha256-NYaWs8fYJ38IgFld0hGSdT2LEVhrgO8SiRReBjIH7YY=",
|
||||
"lastModified": 1784368054,
|
||||
"narHash": "sha256-zF1iJkBQSDWmRO4/LEeHR1SpKY0lqZaxkoQJpPS9K9U=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "aquamarine",
|
||||
"rev": "5d2cb726b16ee349df443f84b64cff53221b6983",
|
||||
"rev": "9b5f14d9483445e766294eb8fbe0b8f370269ed0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -80,11 +80,11 @@
|
||||
"tg_owt": "tg_owt"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783221862,
|
||||
"narHash": "sha256-Qr/TMEYbTsrQMacKkOdUtyBy6MbY2o/ywt57s0eKIl8=",
|
||||
"lastModified": 1792306878,
|
||||
"narHash": "sha256-x9gB1qSAWKDKiX3uW0Z5asE2XzxkCfdVk5B/Og+fDlo=",
|
||||
"owner": "ayugram-port",
|
||||
"repo": "ayugram-desktop",
|
||||
"rev": "8f88025a43b140cdfacca55169f7429e2b30d643",
|
||||
"rev": "5aafef7f62261f9dacb4e95aed950a4cc379273e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -165,11 +165,11 @@
|
||||
"firefox-gnome-theme": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1779670703,
|
||||
"narHash": "sha256-UdfMivNMwCCqQsYDg5pSz8X2IOaOrIZLIIy+Bg3CO2o=",
|
||||
"lastModified": 1783570805,
|
||||
"narHash": "sha256-ptl5aRlCv9/uRSv2u8Hq8UFVFeZ6Q/bT049bpqNgc3w=",
|
||||
"owner": "rafaelmardojai",
|
||||
"repo": "firefox-gnome-theme",
|
||||
"rev": "942159e73e40bf785816f7f1f5feed9ef3d7c8f9",
|
||||
"rev": "5602ed62d638142c1ab31dccd01dfbfb28841225",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -202,11 +202,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1778716662,
|
||||
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
|
||||
"lastModified": 1782949081,
|
||||
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
|
||||
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -249,42 +249,44 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gnome-shell": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767737596,
|
||||
"narHash": "sha256-eFujfIUQDgWnSJBablOuG+32hCai192yRdrNHTv0a+s=",
|
||||
"host": "gitlab.gnome.org",
|
||||
"lastModified": 1776175984,
|
||||
"narHash": "sha256-RJFlFW8GiMei6oqUGrMkGEvVqOH8U7Q8abc1yK4VKD8=",
|
||||
"owner": "GNOME",
|
||||
"repo": "gnome-shell",
|
||||
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
|
||||
"rev": "e0fdc4c13250e9a9b8ea9594c83925274f4a5dca",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"host": "gitlab.gnome.org",
|
||||
"owner": "GNOME",
|
||||
"ref": "50.1",
|
||||
"repo": "gnome-shell",
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"helix-steel": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1792336814,
|
||||
"narHash": "sha256-FU4WIMHhIyvEMxHeN8+Qgb3VHsU6DP74ylsyZACLzM8=",
|
||||
"owner": "mattwparas",
|
||||
"repo": "helix",
|
||||
"rev": "16a26934f39152b5cd81bf2f6944e18e680314d0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "GNOME",
|
||||
"repo": "gnome-shell",
|
||||
"rev": "ef02db02bf0ff342734d525b5767814770d85b49",
|
||||
"owner": "mattwparas",
|
||||
"ref": "steel-event-system",
|
||||
"repo": "helix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
@@ -295,11 +297,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783358420,
|
||||
"narHash": "sha256-UEyBpf+XmQe8laXfDzIlo11Er7E0rKrLS8jeMnMj0Ds=",
|
||||
"lastModified": 1792495086,
|
||||
"narHash": "sha256-TyoYH983Nsc++1scw0SoOEKshPSJWJDxK7tTmuZ974M=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "0d33882bd46c1f9ef62276700f5e5f2bd6ff6604",
|
||||
"rev": "ec80131710bffcdf3b8498cf41f3a0579833b023",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -324,11 +326,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772461003,
|
||||
"narHash": "sha256-pVICsV7FtcEeVwg5y/LFh3XFUkVJninm/P1j/JHzEbM=",
|
||||
"lastModified": 1776511930,
|
||||
"narHash": "sha256-fCpwFiTW0rT7oKJqr3cqHMnkwypSwQKpbtUEtxdkgrM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprcursor",
|
||||
"rev": "b62396457b9cfe2ebf24fe05404b09d2a40f8ed7",
|
||||
"rev": "39435900785d0c560c6ae8777d29f28617d031ef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -353,11 +355,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772461523,
|
||||
"narHash": "sha256-mI6A51do+hEUzeJKk9YSWfVHdI/SEEIBi2tp5Whq5mI=",
|
||||
"lastModified": 1782566056,
|
||||
"narHash": "sha256-haEZcHzYrePnjFOYSWTbxm/Nrla0aPslJfmvdCvqtVc=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprgraphics",
|
||||
"rev": "7d63c04b4a2dd5e59ef943b4b143f46e713df804",
|
||||
"rev": "c6e7b9f673f4360bc813d3dc75028f75ee88d3f8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -383,16 +385,16 @@
|
||||
"xdph": "xdph"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1773149218,
|
||||
"narHash": "sha256-m5Ewi+rgn18qPP54Um4O2zwZ02oiomlZssHvXYEUv3U=",
|
||||
"lastModified": 1785170029,
|
||||
"narHash": "sha256-8CKDx282HhxlD1pwXPnC4uK29Abn1Jsnh7LgPzeIXxI=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "Hyprland",
|
||||
"rev": "59f9f2688ac508a0584d1462151195a6c4992f99",
|
||||
"rev": "5c9377c15f85c50648f35ca5a213754f95b93ca0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"ref": "v0.54.2-b",
|
||||
"ref": "v0.56.1",
|
||||
"repo": "Hyprland",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -430,11 +432,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772467975,
|
||||
"narHash": "sha256-kipyuDBxrZq+beYpZqWzGvFWm4QbayW9agAvi94vDXY=",
|
||||
"lastModified": 1784196523,
|
||||
"narHash": "sha256-ahtKMGXFJdlQNhatQm1+BBU/pGfGYnAqQt3vWvq4p8s=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-guiutils",
|
||||
"rev": "5e1c6b9025aaf4d578f3eff7c0eb1f0c197a9507",
|
||||
"rev": "a6ccb6cb112ed5a244c0191fb972347ecfa893e0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -460,11 +462,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782769258,
|
||||
"narHash": "sha256-HAhqQOoz4S0gzIOMnClL49B+rMT7zdp3UDWeqxtMs/k=",
|
||||
"lastModified": 1792508453,
|
||||
"narHash": "sha256-y+V5RFJcjnV1+ZzImkfiSJ97iDIflanjP2OR9lemvTs=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprland-plugins",
|
||||
"rev": "71b8953d7d92dbebe87a6ff9895bdd30e7495873",
|
||||
"rev": "d2427d4d15b36df40468f5a58bbd67cdba19835d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -514,11 +516,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772459629,
|
||||
"narHash": "sha256-/iwvNUYShmmnwmz/czEUh6+0eF5vCMv0xtDW0STPIuM=",
|
||||
"lastModified": 1777320127,
|
||||
"narHash": "sha256-Qu+Wf2Bp5qUjyn2YpZNq8a7JyzTGowhT1knrwE38a9U=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprlang",
|
||||
"rev": "7615ee388de18239a4ab1400946f3d0e498a8186",
|
||||
"rev": "090117506ddc3d7f26e650ff344d378c2ec329cc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -566,11 +568,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772462885,
|
||||
"narHash": "sha256-5pHXrQK9zasMnIo6yME6EOXmWGFMSnCITcfKshhKJ9I=",
|
||||
"lastModified": 1782554491,
|
||||
"narHash": "sha256-+p3MlyN/nqRefcf2IckPlGRUn9+hielqpS9XClbLleM=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprtoolkit",
|
||||
"rev": "9af245a69fa6b286b88ddfc340afd288e00a6998",
|
||||
"rev": "bdba25ced39ea39ab004a8f31593ba0b0ff1ca35",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -591,11 +593,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772459870,
|
||||
"narHash": "sha256-xxkK2Cvqxpf/4UGcJ/TyCwrvmiNWsKsJfFzHMp2bxis=",
|
||||
"lastModified": 1784323413,
|
||||
"narHash": "sha256-XnAVV+H4f8Xdv0yZcSwJ5kCjLyE8fHxPeLX6a3HSrAU=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprutils",
|
||||
"rev": "e63f3a79334dec49f8eb1691f66f18115df04085",
|
||||
"rev": "5f03477ab3a005ff27c527486f551883535aea2f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -616,11 +618,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772459835,
|
||||
"narHash": "sha256-978jRz/y/9TKmZb/qD4lEYHCQGHpEXGqy+8X2lFZsak=",
|
||||
"lastModified": 1777159683,
|
||||
"narHash": "sha256-Jxixw6wZphUp+nHYxOKUYSckL17QMBx2d5Zp0rJHr1g=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwayland-scanner",
|
||||
"rev": "0a692d4a645165eebd65f109146b8861e3a925e7",
|
||||
"rev": "b8632713a6beaf28b56f2a7b0ab2fb7088dbb404",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -645,11 +647,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772463520,
|
||||
"narHash": "sha256-GIjASzYnV4fK19HnyJKmHyqyxHxIpjusK9foEA4Yo+4=",
|
||||
"lastModified": 1778410714,
|
||||
"narHash": "sha256-o6RzFj4nJXaPRY7EM01siuCQeT41RfwwmcmFQqwFJJg=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwire",
|
||||
"rev": "4e1933ae5602b350c5b6633f5c932549c9b8aca2",
|
||||
"rev": "85148a8e612808cf5ddb25d0b3c5840f3498a7dc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -692,11 +694,11 @@
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1783148766,
|
||||
"narHash": "sha256-uslt2pqShTIXDdAHRHv2QkYLsVdY8Oqwz0EA48/RSM8=",
|
||||
"lastModified": 1792503283,
|
||||
"narHash": "sha256-vhe2jyvRCgufWPqDuDq1S3t3ypE+ka46IFutV02xKso=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a50de1b7d8a586adc18d2395c19de7d6058e6030",
|
||||
"rev": "cd4ea8d57de16f4810bc5f14207bac45fbf19f67",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -708,11 +710,11 @@
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1782959384,
|
||||
"narHash": "sha256-xnJJk+ct+D2+wdRxj1wk36w5zV9RVESwRqcklPdt3fM=",
|
||||
"lastModified": 1792094642,
|
||||
"narHash": "sha256-zp8ToDMnqZcu4o4IH9pdwXFXGp7yLm/M0dEnNWnyd7I=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "65179426c83bb3f6bc14898b42ea1c6f01d374b0",
|
||||
"rev": "fe13242281a67641c0102cdb1087f0ebe586c7df",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -724,11 +726,11 @@
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1772542754,
|
||||
"narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=",
|
||||
"lastModified": 1784356753,
|
||||
"narHash": "sha256-12KrbMiWLcf8m7pCvAtZh1ZrgF85ZXDXvfR/fWTKy84=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8c809a146a140c5c8806f13399592dbcb1bb5dc4",
|
||||
"rev": "61b7c44c4073f0b827768aff0049561b5110ea5a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -740,11 +742,11 @@
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1783224372,
|
||||
"narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=",
|
||||
"lastModified": 1792502884,
|
||||
"narHash": "sha256-IoNisKcGbUjdd45qCqywGMCYmZ5EnkxezvLII0FWwNA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d407951447dcd00442e97087bf374aad70c04cea",
|
||||
"rev": "02c087f3fe673c9e317f206a627cb6b910336dbe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -756,11 +758,11 @@
|
||||
},
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1782175435,
|
||||
"narHash": "sha256-EMzXKmnOtBQ2MnvpiNOm7E+kOMvdPrIKaeg52Tip2Uk=",
|
||||
"lastModified": 1791487292,
|
||||
"narHash": "sha256-tqM7xDEsaeK1p6VvRygeZ9LkQRpUUkbRT02BHv6hnTM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "89570f24e97e614aa34aa9ab1c927b6578a43775",
|
||||
"rev": "8edc0c72e3a38faf5434e40d1f19431125fe4b30",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -772,11 +774,11 @@
|
||||
},
|
||||
"nixpkgs_6": {
|
||||
"locked": {
|
||||
"lastModified": 1780243769,
|
||||
"narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=",
|
||||
"lastModified": 1785454630,
|
||||
"narHash": "sha256-LQy14TZp77TwbQf40gg1V3jo8FwJG0jGDkAH+zRHqg8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "331800de5053fcebacf6813adb5db9c9dca22a0c",
|
||||
"rev": "1559d3daa3ecc813a650b79375ea61b6741b8746",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -788,11 +790,11 @@
|
||||
},
|
||||
"nixpkgs_7": {
|
||||
"locked": {
|
||||
"lastModified": 1779877693,
|
||||
"narHash": "sha256-NOF9NAREhxr50bbBfVcVOq+ArCMSoe8dP79Pk2uyARk=",
|
||||
"lastModified": 1790769526,
|
||||
"narHash": "sha256-5AIVFLRcx8YAwbFTVPTs7YhwJH7JyHfAQsvXmpovcXI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4100e830e085863741bc69b156ec4ccd53ab5be0",
|
||||
"rev": "c9fe7d12cd78d1adcd12dd15e24432dde5b155a0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -804,11 +806,11 @@
|
||||
},
|
||||
"nixpkgs_8": {
|
||||
"locked": {
|
||||
"lastModified": 1783224372,
|
||||
"narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=",
|
||||
"lastModified": 1792502884,
|
||||
"narHash": "sha256-IoNisKcGbUjdd45qCqywGMCYmZ5EnkxezvLII0FWwNA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d407951447dcd00442e97087bf374aad70c04cea",
|
||||
"rev": "02c087f3fe673c9e317f206a627cb6b910336dbe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -830,11 +832,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1780281641,
|
||||
"narHash": "sha256-M/+hUKoKbHXpV0xGVfELbN1Ds1aoe3pL5p5/t46YhVo=",
|
||||
"lastModified": 1785549842,
|
||||
"narHash": "sha256-DCwBZmGsySF7oKGTRgEv2HvpxVXkHT+38VhTM76k0B4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "30f9ae2f04174de63ba8bcf3580ca90843b28a01",
|
||||
"rev": "a9f987b57594e845e3e5cdd423b9a70846d70308",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -846,18 +848,17 @@
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"hyprland",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772024342,
|
||||
"narHash": "sha256-+eXlIc4/7dE6EcPs9a2DaSY3fTA9AE526hGqkNID3Wg=",
|
||||
"lastModified": 1784288435,
|
||||
"narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "6e34e97ed9788b17796ee43ccdbaf871a5c2b476",
|
||||
"rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -870,6 +871,7 @@
|
||||
"inputs": {
|
||||
"ags": "ags",
|
||||
"ayugram-desktop": "ayugram-desktop",
|
||||
"helix-steel": "helix-steel",
|
||||
"home-manager": "home-manager",
|
||||
"hyprland": "hyprland",
|
||||
"hyprland-plugins": "hyprland-plugins",
|
||||
@@ -887,11 +889,11 @@
|
||||
"russia-blocked-geoip": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1783376348,
|
||||
"narHash": "sha256-iKqGDS4FNXiqU+savy3QfMhldYiIZKSuSu/ywrmOgUU=",
|
||||
"lastModified": 1792592746,
|
||||
"narHash": "sha256-hDb67lqlxWt3iBsRvxWdE7G4Eg+JEyNRQo7OTqzaDRI=",
|
||||
"owner": "runetfreedom",
|
||||
"repo": "russia-blocked-geoip",
|
||||
"rev": "d0203cdf5f939e6ee936d3e0b521a63eb2514543",
|
||||
"rev": "8898c3b0d779b8aa05b933b97022d7458af2df8d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -902,6 +904,27 @@
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"helix-steel",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775358767,
|
||||
"narHash": "sha256-f2eC+WIfhjevCPQILuV08i/kmKZzYZpUvkom/33VxCA=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "20fd44bc663daa53a2575e01293e24e681d62244",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rust-overlay_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"yazi",
|
||||
@@ -909,11 +932,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1779851998,
|
||||
"narHash": "sha256-UkkMh3bX9QW4Luqkm98nUaOqKWrU6i65mUnph3WeSSw=",
|
||||
"lastModified": 1791013993,
|
||||
"narHash": "sha256-BiFPwFsbFnZH5GfWbQFKYuQNg+67aNQCoRSRNTeJFQc=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "6cddd512fa2bf7231f098d3a2f92f6e4cff71e0a",
|
||||
"rev": "7470661ba2b51156048af08464b82020223dc942",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -927,11 +950,11 @@
|
||||
"nixpkgs": "nixpkgs_5"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783174389,
|
||||
"narHash": "sha256-aCWC8ngycU7OdJrU2+Je3qf+1a2ykuBvpPhZT/9tXMc=",
|
||||
"lastModified": 1792056300,
|
||||
"narHash": "sha256-YU1LjDe1o2Ymg5zEiCHbmMXLkDCtxHQRiVqZ3nC5GGk=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "f1406619a3884cd5c47992a70b8b35c9c0fcb4c9",
|
||||
"rev": "44931708c62937c2b1bf7953902989fa5bb9ee1b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -958,11 +981,11 @@
|
||||
"tinted-zed": "tinted-zed"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783358511,
|
||||
"narHash": "sha256-/F85cBWvU8b2hpawuCog464065ZTJtdMgVPWwJ9yHjE=",
|
||||
"lastModified": 1791574276,
|
||||
"narHash": "sha256-UMnLnZ3JlA7UTBNNNx1rNsXYoPP/cirXLCKGiQ/yDx8=",
|
||||
"owner": "danth",
|
||||
"repo": "stylix",
|
||||
"rev": "14814ef555d8148ab82eba5054e654cd9eae3a1f",
|
||||
"rev": "2856c4c6a845b9bec98828ef197abe176e4806bb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -988,15 +1011,16 @@
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"lastModified": 1774449309,
|
||||
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"rev": "c29398b59d2048c4ab79345812849c9bd15e9150",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"ref": "future-26.11",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -1024,11 +1048,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1778847431,
|
||||
"narHash": "sha256-D7N+DQLcUFYANMo+N/odsVEwc263fFMlnMek+LaLBdg=",
|
||||
"lastModified": 1791698670,
|
||||
"narHash": "sha256-D4GTULEDsGmk4ue01cetWZ6E/emb3FrUys612rg7a5E=",
|
||||
"owner": "ndfined-crp",
|
||||
"repo": "tg_owt",
|
||||
"rev": "1cc099e066c910e9cb3180777ce03f3d72cbfa27",
|
||||
"rev": "29330d167ede474885e8aa87b037769cb1cabfc9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1056,11 +1080,11 @@
|
||||
"tinted-schemes": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1777806186,
|
||||
"narHash": "sha256-PDF0/wObw4nIsSBeXVYLsloXOiphXCgIdsrNcVXguKs=",
|
||||
"lastModified": 1785153830,
|
||||
"narHash": "sha256-fNdfCTeCXU3tZG3TMincd+u68qBHQgCr2Ljr/M1mWP0=",
|
||||
"owner": "tinted-theming",
|
||||
"repo": "schemes",
|
||||
"rev": "0c94645546f4f3ddac77a1a5fce54eb95bf50795",
|
||||
"rev": "9bd28ed313560db3c5b605c63bc4e309e78e3fc8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1072,11 +1096,11 @@
|
||||
"tinted-tmux": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1778379944,
|
||||
"narHash": "sha256-wPDFzMGSlARlw0Sfsn48Q2+jPSfk6N0Ng6BC/d+7Q24=",
|
||||
"lastModified": 1785031658,
|
||||
"narHash": "sha256-mZp9O2LjzdMzlqQF3l3fjqsuPBzXy+1qTfBEUGjTlpk=",
|
||||
"owner": "tinted-theming",
|
||||
"repo": "tinted-tmux",
|
||||
"rev": "fe0203a198690e71a5ff11e08812a4673de3678d",
|
||||
"rev": "5d2c67f61ea7af36f16865ab6d541cdba41dc257",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1088,11 +1112,11 @@
|
||||
"tinted-zed": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1778378178,
|
||||
"narHash": "sha256-OXPXRIQgGwV77HjYRryOHguh4ALX96jkg+tseLkGgHA=",
|
||||
"lastModified": 1785030526,
|
||||
"narHash": "sha256-klZf8UviewRkxuu74Bhbq6tqy7oxebQC7UVRWbbtQxU=",
|
||||
"owner": "tinted-theming",
|
||||
"repo": "base16-zed",
|
||||
"rev": "9cd816033ff969415b190722cddf134e78a5665f",
|
||||
"rev": "16f5a8adf4a6b1310d0a61ab172de963e8f76a02",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1129,11 +1153,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1772476586,
|
||||
"narHash": "sha256-N/ZwsRLULLpBP5ecvAUzNq8E/CgLRwPwSrHyY3xB5KM=",
|
||||
"lastModified": 1784371182,
|
||||
"narHash": "sha256-S8A1lezEalltWcCp3gAic5lssS0xTSISK6fKODefhOk=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "xdg-desktop-portal-hyprland",
|
||||
"rev": "eb6c02a2ead882f3474f3d7f2fbe966b64ed5110",
|
||||
"rev": "08d99f727944dd15e4740090305e31c5fb92a50a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1146,14 +1170,14 @@
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs_7",
|
||||
"rust-overlay": "rust-overlay"
|
||||
"rust-overlay": "rust-overlay_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783334588,
|
||||
"narHash": "sha256-8EZMWD8i8zji2uSHBjUBCUlLpXkt2rC+dSxaqvZi4SI=",
|
||||
"lastModified": 1792507858,
|
||||
"narHash": "sha256-EEfOrxveuFcXigE5frf6U5rzw1JdzRZ9IcSZzysnHGA=",
|
||||
"owner": "sxyazi",
|
||||
"repo": "yazi",
|
||||
"rev": "aa850f9a3bece5fa353b45adea9eee59fc7e6996",
|
||||
"rev": "7c45837d553b6cb8032bd7fec2106fdb628e4017",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1165,11 +1189,11 @@
|
||||
"yazi-plugins": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1783246245,
|
||||
"narHash": "sha256-f4y952sUF/lrHMX6enQts/obk2DeatqAcaVHfjTD65k=",
|
||||
"lastModified": 1792088615,
|
||||
"narHash": "sha256-3ddGRQSzxyurNcyYJA+9LTLXTCjBFGATTqdkuGKixzA=",
|
||||
"owner": "yazi-rs",
|
||||
"repo": "plugins",
|
||||
"rev": "8cd50c622898d3ace3ca821f540241965308289a",
|
||||
"rev": "9166202cc1694c98bac3a639874d6f4c0eaa2dab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1184,11 +1208,11 @@
|
||||
"zapret-flowseal": "zapret-flowseal"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783019330,
|
||||
"narHash": "sha256-iHxRHymhZD62FueROpiFjG6zmX7epR7rUNUDh/JW7sE=",
|
||||
"lastModified": 1792489877,
|
||||
"narHash": "sha256-4/g+qlw4G+2ACSww4vaRsJVLihREjf0eBwofDmeuTns=",
|
||||
"owner": "kartavkun",
|
||||
"repo": "zapret-discord-youtube",
|
||||
"rev": "c2786375ddc3e87e72ee297095b3d312cd846fda",
|
||||
"rev": "69b88b5e51242ddacd87109f31e028e1bef553f6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1200,11 +1224,11 @@
|
||||
"zapret-flowseal": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1783190817,
|
||||
"narHash": "sha256-8hNSwkVREf+16npV4mYnaNeyb9MGicxwSN9TZnZ9E1A=",
|
||||
"lastModified": 1792471264,
|
||||
"narHash": "sha256-5qKg2BvW4XcjY+Az9ocvwACcfsfBpG4I3Xh6SCPksIM=",
|
||||
"owner": "Flowseal",
|
||||
"repo": "zapret-discord-youtube",
|
||||
"rev": "d75903b44cb7c8e7eedb998c3dd9ff674d10880a",
|
||||
"rev": "176f56dc3f11ce5915c26abcdde903f93d835b64",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"https://yazi.cachix.org"
|
||||
];
|
||||
extra-trusted-public-keys = [
|
||||
"main:kpwMe+9BsGJ/IUb7i3iadaV38y5/Yuqoct0mf7wI9ds="
|
||||
"main:tR2gNhCBJHKAlVgohPNHBhGnWL55tB8SxXmMWJe5lo8="
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
"cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="
|
||||
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
|
||||
@@ -41,7 +41,7 @@
|
||||
flake = false;
|
||||
};
|
||||
|
||||
hyprland.url = "github:hyprwm/Hyprland/v0.54.2-b";
|
||||
hyprland.url = "github:hyprwm/Hyprland/v0.56.1";
|
||||
hyprland-plugins = {
|
||||
url = "github:hyprwm/hyprland-plugins";
|
||||
inputs.hyprland.follows = "hyprland";
|
||||
@@ -52,6 +52,11 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
helix-steel = {
|
||||
url = "github:mattwparas/helix/steel-event-system";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
russia-blocked-geoip = {
|
||||
url = "github:runetfreedom/russia-blocked-geoip/release";
|
||||
flake = false;
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
./modules/grab.nix
|
||||
./modules/swap.nix
|
||||
./modules/intel.nix
|
||||
./modules/nvidia.nix
|
||||
./modules/grab.nix
|
||||
./modules/thinkpad.nix
|
||||
./modules/fingerprint.nix
|
||||
./secrets/secrets.nix
|
||||
./modules/bottles.nix
|
||||
|
||||
(import ../modules/common.nix {
|
||||
inherit lib;
|
||||
@@ -29,7 +32,8 @@
|
||||
})
|
||||
];
|
||||
|
||||
programs.gamemode.enable = true;
|
||||
host.laptop = true;
|
||||
|
||||
hardware.bluetooth.enable = true;
|
||||
services.printing.enable = true;
|
||||
}
|
||||
@@ -8,18 +8,18 @@
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" "rtsx_pci_sdmmc" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" "thinkpad_acpi" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/e8f0717b-d1c8-4e17-ba2a-63b8cf8aa1f8";
|
||||
{ device = "/dev/disk/by-uuid/454d25a7-e24e-4104-946f-bfbde994923d";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/3400-C3B7";
|
||||
{ device = "/dev/disk/by-uuid/121E-43DF";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" "nofail" ];
|
||||
};
|
||||
@@ -31,8 +31,8 @@
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp4s0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp5s0.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{pkgs-stable, ...}: {
|
||||
environment.systemPackages = with pkgs-stable; [
|
||||
bottles
|
||||
];
|
||||
}
|
||||
@@ -1,20 +1,315 @@
|
||||
{ config, ... }: {
|
||||
services.fprintd.enable = true;
|
||||
{ lib, pkgs, ... }: let
|
||||
pythonValidityPatch = pkgs.writeText "python-validity-python-3.14.patch" ''
|
||||
diff --git a/validitysensor/flash.py b/validitysensor/flash.py
|
||||
index d37f15a..be3d4a1 100644
|
||||
--- a/validitysensor/flash.py
|
||||
+++ b/validitysensor/flash.py
|
||||
@@ -34,6 +34,10 @@ def get_flash_info():
|
||||
rsp = tls.cmd(unhex('3e'))
|
||||
assert_status(rsp)
|
||||
rsp = rsp[2:]
|
||||
+ if len(rsp) < 0xe:
|
||||
+ # An uninitialised 06cb:009a returns only the success status word.
|
||||
+ # Let init_flash() format it instead of failing in struct.unpack().
|
||||
+ return FlashInfo(None, 0, 0, 0, 0, [])
|
||||
hdr = rsp[:0xe]
|
||||
rsp = rsp[0xe:]
|
||||
jid0, jid1, blocks, unknown0, blocksize, unknown1, pcnt = unpack('<HHHHHHH', hdr)
|
||||
diff --git a/validitysensor/init.py b/validitysensor/init.py
|
||||
index 18890c5..710668c 100644
|
||||
--- a/validitysensor/init.py
|
||||
+++ b/validitysensor/init.py
|
||||
@@ -25,8 +25,8 @@ def close():
|
||||
|
||||
security.pam.services = {
|
||||
sudo.fprintAuth = true;
|
||||
login.fprintAuth = false;
|
||||
hyprlock.fprintAuth = false;
|
||||
};
|
||||
|
||||
security.polkit.extraConfig = ''
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "net.reactivated.fprint.device.enroll" &&
|
||||
subject.isInGroup("fprint")) {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
def open_common():
|
||||
init_data_dir()
|
||||
- init_flash()
|
||||
usb.send_init()
|
||||
+ init_flash()
|
||||
tls.parse_tls_flash(read_tls_flash())
|
||||
tls.open()
|
||||
upload_fwext()
|
||||
diff --git a/validitysensor/usb.py b/validitysensor/usb.py
|
||||
index 9db2b07..353b2c7 100644
|
||||
--- a/validitysensor/usb.py
|
||||
+++ b/validitysensor/usb.py
|
||||
@@ -1,6 +1,7 @@
|
||||
import errno
|
||||
import logging
|
||||
+import time
|
||||
import typing
|
||||
from binascii import hexlify, unhexlify
|
||||
from enum import Enum
|
||||
from struct import unpack
|
||||
@@ -68,22 +69,32 @@ class Usb:
|
||||
def close(self):
|
||||
if self.dev is not None:
|
||||
try:
|
||||
self.dev.reset()
|
||||
self.dev = None
|
||||
except:
|
||||
pass
|
||||
${" "}
|
||||
def usb_dev(self):
|
||||
return self.dev
|
||||
${" "}
|
||||
+ def cmd_retry_busy(self, command: bytes):
|
||||
+ # Metallica sensors can report 0x0104 for a few seconds after wake-up.
|
||||
+ for _ in range(20):
|
||||
+ rsp = self.cmd(command)
|
||||
+ status, = unpack('<H', rsp[:2])
|
||||
+ if status != 0x0104:
|
||||
+ return rsp
|
||||
+ time.sleep(0.5)
|
||||
+ return rsp
|
||||
+
|
||||
def send_init(self):
|
||||
# self.dev.set_configuration()
|
||||
${" "}
|
||||
# TODO analyse responses, detect hardware type
|
||||
- assert_status(self.cmd(unhexlify('01'))) # RomInfo.get()
|
||||
+ assert_status(self.cmd_retry_busy(unhexlify('01'))) # RomInfo.get()
|
||||
assert_status(self.cmd(unhexlify('19')))
|
||||
${" "}
|
||||
# 43 -- get partition header(?) (02 -- fwext partition)
|
||||
# c28c745a in response is a FwextBuildtime = 0x5A748CC2
|
||||
- rsp = self.cmd(unhexlify('4302')) # get_fw_info()
|
||||
+ rsp = self.cmd_retry_busy(unhexlify('4302')) # get_fw_info()
|
||||
${" "}
|
||||
'';
|
||||
|
||||
users.users.kirill.extraGroups = [ "fprint" ];
|
||||
python-validity = pkgs.python3Packages.buildPythonApplication rec {
|
||||
pname = "python-validity";
|
||||
version = "0.15-unstable-2020-12-14";
|
||||
pyproject = true;
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "uunicorn";
|
||||
repo = "python-validity";
|
||||
rev = "a6bbc21dce7b8b3c3cd92378a0b2579a2fb45920";
|
||||
hash = "sha256-RflX7e6nd11pSg8mh3mjZiVGNUSdox/SKXHR4W+PhMs=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
${lib.getExe pkgs.gitMinimal} apply ${pythonValidityPatch}
|
||||
'';
|
||||
|
||||
build-system = [ pkgs.python3Packages.setuptools ];
|
||||
|
||||
dependencies = with pkgs.python3Packages; [
|
||||
cryptography
|
||||
dbus-python
|
||||
pygobject3
|
||||
pyusb
|
||||
pyyaml
|
||||
];
|
||||
|
||||
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||
|
||||
postInstall = ''
|
||||
install -Dm755 dbus_service/dbus-service \
|
||||
"$out/lib/python-validity/dbus-service"
|
||||
install -Dm644 dbus_service/io.github.uunicorn.Fprint.conf \
|
||||
"$out/share/dbus-1/system.d/io.github.uunicorn.Fprint.conf"
|
||||
|
||||
install -Dm755 dbus_service/dbus-service \
|
||||
"$out/bin/python-validity-service"
|
||||
install -Dm755 scripts/factory-reset.py \
|
||||
"$out/bin/validity-factory-reset"
|
||||
|
||||
install -d "$out/share/python-validity/playground"
|
||||
install -m755 \
|
||||
scripts/dbus-cmd.py \
|
||||
scripts/lsdbus.py \
|
||||
scripts/factory-reset.py \
|
||||
scripts/prototype.py \
|
||||
"$out/share/python-validity/playground/"
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
wrapProgram "$out/bin/validity-sensors-firmware" \
|
||||
--prefix PATH : ${lib.makeBinPath [
|
||||
pkgs.findutils
|
||||
pkgs.innoextract
|
||||
]}
|
||||
'';
|
||||
|
||||
# Upstream does not have an automated test suite.
|
||||
doCheck = false;
|
||||
|
||||
meta = {
|
||||
description = "Userspace driver for Validity and Synaptics fingerprint sensors";
|
||||
homepage = "https://github.com/uunicorn/python-validity";
|
||||
license = lib.licenses.mit;
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
};
|
||||
|
||||
fprintd-clients = pkgs.runCommand "fprintd-clients" { } ''
|
||||
mkdir -p "$out/bin"
|
||||
for client in fprintd-delete fprintd-enroll fprintd-list fprintd-verify; do
|
||||
ln -s "${pkgs.fprintd}/bin/$client" "$out/bin/$client"
|
||||
done
|
||||
'';
|
||||
|
||||
systemctl = lib.getExe' pkgs.systemd "systemctl";
|
||||
busctl = lib.getExe' pkgs.systemd "busctl";
|
||||
timeout = lib.getExe' pkgs.coreutils "timeout";
|
||||
sleep = lib.getExe' pkgs.coreutils "sleep";
|
||||
fprintdList = lib.getExe' pkgs.fprintd "fprintd-list";
|
||||
|
||||
# python-validity initializes the sensor before it registers with
|
||||
# open-fprintd, so a successful ListEnrolledFingers call means the sensor is
|
||||
# usable. This is used as ExecStartPost and by greetd ordering.
|
||||
waitForFprint = pkgs.writeShellScript "wait-for-fprint" ''
|
||||
for ((i = 0; i < 120; i++)); do
|
||||
|
||||
devices="$(${timeout} 1 ${busctl} --system call \
|
||||
net.reactivated.Fprint \
|
||||
/net/reactivated/Fprint/Manager \
|
||||
net.reactivated.Fprint.Manager GetDevices 2>/dev/null || true)"
|
||||
|
||||
if [[ "$devices" =~ ^ao\ [1-9] ]]; then
|
||||
echo "wait-for-fprint: sensor initialized: $devices"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
${sleep} 0.5
|
||||
done
|
||||
|
||||
echo "wait-for-fprint: sensor initialization timeout" >&2
|
||||
exit 1
|
||||
'';
|
||||
|
||||
# The xHCI controller is reset during resume, which invalidates
|
||||
# python-validity's USB handle. Restart it from a systemd-sleep hook: the
|
||||
# hook runs before logind emits PrepareForSleep(false), so hyprlock's
|
||||
# built-in fingerprint auth sees a working sensor as soon as it resumes.
|
||||
fprintResumeHook = pkgs.writeShellScript "fprint-resume" ''
|
||||
if [ "$1" != "post" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Stop the old instance first so its stale D-Bus target cannot be selected
|
||||
# by the readiness checks below. Start without blocking because
|
||||
# python-validity's ExecStartPost waits for fprintd, but open-fprintd is
|
||||
# still suspended until Resume is called below.
|
||||
${timeout} 10 ${systemctl} stop python3-validity.service || true
|
||||
${systemctl} start --no-block python3-validity.service || true
|
||||
|
||||
# Clear open-fprintd's suspended flag. This also unblocks the new
|
||||
# python-validity instance's ExecStartPost.
|
||||
${timeout} 10 ${busctl} call net.reactivated.Fprint /net/reactivated/Fprint/Manager \
|
||||
net.reactivated.Fprint.Manager Resume || true
|
||||
|
||||
# Wait for the new backend to register.
|
||||
for ((i = 0; i < 30; i++)); do
|
||||
if ${timeout} 0.5 ${fprintdList} root >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
${sleep} 0.1
|
||||
done
|
||||
|
||||
# The target now exists, so Resume reinitializes the sensor. Wait for it
|
||||
# to become responsive before logind starts hyprlock's fingerprint auth.
|
||||
${timeout} 10 ${busctl} call net.reactivated.Fprint /net/reactivated/Fprint/Manager \
|
||||
net.reactivated.Fprint.Manager Resume || true
|
||||
|
||||
for ((i = 0; i < 30; i++)); do
|
||||
if ${timeout} 0.5 ${fprintdList} root >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
${sleep} 0.1
|
||||
done
|
||||
|
||||
echo "fprint-resume: fingerprint backend did not become ready" >&2
|
||||
'';
|
||||
|
||||
sleepTargets = [
|
||||
"suspend.target"
|
||||
"hibernate.target"
|
||||
"hybrid-sleep.target"
|
||||
"suspend-then-hibernate.target"
|
||||
];
|
||||
in {
|
||||
services = {
|
||||
# The 06cb:009a sensor is driven by python-validity through open-fprintd;
|
||||
# stock fprintd/libfprint cannot handle it.
|
||||
fprintd.enable = false;
|
||||
|
||||
dbus.packages = [
|
||||
pkgs.open-fprintd
|
||||
python-validity
|
||||
];
|
||||
};
|
||||
|
||||
security.pam.services = {
|
||||
greetd.fprintAuth = true;
|
||||
polkit-1.fprintAuth = true;
|
||||
sudo.fprintAuth = true;
|
||||
login.fprintAuth = true;
|
||||
|
||||
# hyprlock still needs a PAM service for password authentication, but it
|
||||
# must not run pam_fprintd: its own D-Bus fingerprint implementation is
|
||||
# used instead. Two implementations would fight over the device, and the
|
||||
# PAM one breaks when the sensor is reset across suspend.
|
||||
hyprlock = {};
|
||||
};
|
||||
|
||||
environment.etc."systemd/system-sleep/50-fprint-resume".source = fprintResumeHook;
|
||||
|
||||
systemd.services = {
|
||||
open-fprintd = {
|
||||
description = "Open FPrint daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "dbus";
|
||||
BusName = "net.reactivated.Fprint";
|
||||
ExecStart = "${pkgs.open-fprintd}/lib/open-fprintd/open-fprintd";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
||||
python3-validity = {
|
||||
description = "python-validity fingerprint sensor backend";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "open-fprintd.service" ];
|
||||
wants = [ "open-fprintd.service" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${python-validity}/bin/python-validity-service";
|
||||
ExecStartPost = "-${waitForFprint}";
|
||||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
RuntimeDirectory = "python-validity";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
RuntimeDirectoryPreserve = "yes";
|
||||
};
|
||||
};
|
||||
|
||||
open-fprintd-suspend = {
|
||||
description = "Suspend open-fprintd backends";
|
||||
wantedBy = sleepTargets;
|
||||
before = sleepTargets;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.open-fprintd}/lib/open-fprintd/suspend.py";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# The sleep hook above resumes open-fprintd before logind wakes the
|
||||
# graphical session. The stock open-fprintd-resume unit runs later and
|
||||
# resets the sensor while hyprlock is already verifying, so it must not be
|
||||
# enabled. Order greetd (and therefore Hyprland/hyprlock) after the
|
||||
# fingerprint backend so the first lock screen can use the sensor.
|
||||
systemd.services.greetd = {
|
||||
after = [ "python3-validity.service" ];
|
||||
wants = [ "python3-validity.service" ];
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
fprintd-clients
|
||||
python-validity
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
wayland.windowManager.hyprland.settings.monitor = [
|
||||
{
|
||||
output = "eDP-1";
|
||||
mode = "1920x1080@60";
|
||||
position = "0x0";
|
||||
scale = 1;
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -6,11 +6,22 @@
|
||||
|
||||
extraPackages = with pkgs; [
|
||||
intel-media-driver
|
||||
intel-compute-runtime
|
||||
libvdpau-va-gl
|
||||
];
|
||||
|
||||
extraPackages32 = with pkgs.pkgsi686Linux; [
|
||||
intel-media-driver
|
||||
];
|
||||
};
|
||||
|
||||
environment.sessionVariables = {
|
||||
LIBVA_DRIVER_NAME = "iHD";
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
intel-gpu-tools
|
||||
libva-utils
|
||||
clinfo
|
||||
];
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
services.xserver.videoDrivers = [ "nvidia" ];
|
||||
|
||||
hardware.nvidia = {
|
||||
modesetting.enable = true;
|
||||
|
||||
powerManagement = {
|
||||
enable = true;
|
||||
finegrained = false;
|
||||
};
|
||||
|
||||
package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
|
||||
|
||||
open = false;
|
||||
|
||||
prime = {
|
||||
offload.enable = true;
|
||||
|
||||
intelBusId = "PCI:0:2:0";
|
||||
nvidiaBusId = "PCI:1:0:0";
|
||||
};
|
||||
};
|
||||
|
||||
environment.shellAliases = {
|
||||
nvidia-offload = "__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{ config, lib, pkgs, ... }: {
|
||||
hardware = {
|
||||
enableRedistributableFirmware = true;
|
||||
|
||||
trackpoint = {
|
||||
enable = true;
|
||||
emulateWheel = true;
|
||||
};
|
||||
};
|
||||
|
||||
powerManagement.enable = true;
|
||||
|
||||
services = {
|
||||
fwupd.enable = true;
|
||||
thermald.enable = true;
|
||||
|
||||
logind.settings.Login = {
|
||||
HandleLidSwitch = "suspend-then-hibernate";
|
||||
HandleLidSwitchExternalPower = "suspend-then-hibernate";
|
||||
HandlePowerKey = "poweroff";
|
||||
};
|
||||
|
||||
tlp = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
START_CHARGE_THRESH_BAT0 = 70;
|
||||
STOP_CHARGE_THRESH_BAT0 = 95;
|
||||
START_CHARGE_THRESH_BAT1 = 70;
|
||||
STOP_CHARGE_THRESH_BAT1 = 85;
|
||||
RESTORE_THRESHOLDS_ON_BAT = 1;
|
||||
|
||||
AHCI_RUNTIME_PM_ON_AC = "on";
|
||||
AHCI_RUNTIME_PM_ON_BAT = "auto";
|
||||
SATA_LINKPWR_ON_AC = "med_power_with_dipm";
|
||||
SATA_LINKPWR_ON_BAT = "med_power_with_dipm";
|
||||
|
||||
USB_AUTOSUSPEND = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.networkmanager.wifi.powersave = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
acpi
|
||||
lm_sensors
|
||||
pciutils
|
||||
powertop
|
||||
smartmontools
|
||||
usbutils
|
||||
nvme-cli
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
sops = {
|
||||
age.keyFile = "/root/age.key";
|
||||
|
||||
secrets = { };
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
wayland.windowManager.hyprland.settings.monitor = [
|
||||
{
|
||||
output = "eDP-1";
|
||||
mode = "1920x1200@60";
|
||||
position = "0x0";
|
||||
scale = 1;
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -6,6 +6,26 @@
|
||||
./packages.nix
|
||||
];
|
||||
|
||||
options = {
|
||||
host = {
|
||||
laptop = lib.mkEnableOption "laptop mode";
|
||||
|
||||
nvidia.prime = {
|
||||
enable = lib.mkEnableOption "NVIDIA PRIME offload for hybrid graphics";
|
||||
intelBusId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "PCI:0:2:0";
|
||||
description = "Intel/iGPU Bus ID used by NVIDIA PRIME.";
|
||||
};
|
||||
nvidiaBusId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "PCI:1:0:0";
|
||||
description = "NVIDIA dGPU Bus ID used by NVIDIA PRIME.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
networking.hostName = hostname;
|
||||
time.timeZone = lib.mkDefault "Europe/Moscow";
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
{ config, pkgs, lib, ... }: let
|
||||
primeCfg = config.host.nvidia.prime;
|
||||
in {
|
||||
config = lib.mkIf primeCfg.enable {
|
||||
boot = {
|
||||
kernelParams = [ "nvidia-drm.modeset=1" ];
|
||||
initrd.kernelModules = [ "i915" ];
|
||||
};
|
||||
|
||||
services.xserver.videoDrivers = [ "modesetting" "nvidia" ];
|
||||
|
||||
hardware = {
|
||||
graphics = {
|
||||
enable = true;
|
||||
enable32Bit = true;
|
||||
};
|
||||
|
||||
nvidia = {
|
||||
modesetting.enable = true;
|
||||
|
||||
powerManagement = {
|
||||
enable = true;
|
||||
finegrained = false;
|
||||
};
|
||||
|
||||
open = false;
|
||||
nvidiaSettings = true;
|
||||
|
||||
package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
|
||||
|
||||
prime = {
|
||||
offload = {
|
||||
enable = true;
|
||||
enableOffloadCmd = true;
|
||||
};
|
||||
|
||||
intelBusId = primeCfg.intelBusId;
|
||||
nvidiaBusId = primeCfg.nvidiaBusId;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.sessionVariables = {
|
||||
__GL_VRR_ALLOWED = 1;
|
||||
ELECTRON_OZONE_PLATFORM_HINT = "auto";
|
||||
NIXOS_OZONE_WL = 1;
|
||||
};
|
||||
|
||||
environment.shellAliases = {
|
||||
nvidia-offload = "__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
helix
|
||||
bluetui
|
||||
fastfetch
|
||||
thunderbird
|
||||
];
|
||||
|
||||
fonts = {
|
||||
@@ -25,6 +26,8 @@
|
||||
noto-fonts-cjk-sans # Japanese
|
||||
powerline-symbols # Console decoration
|
||||
unifont # Other
|
||||
(pkgs.google-fonts.override { fonts = [ "Gabriela" ]; })
|
||||
];
|
||||
};
|
||||
fonts.fontconfig.enable = true;
|
||||
}
|
||||
+19
-1
@@ -1,3 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./host/bluetooth.nix
|
||||
@@ -13,7 +14,24 @@
|
||||
#./host/ai-agent.nix
|
||||
];
|
||||
|
||||
programs.hyprland.enable = true;
|
||||
programs = {
|
||||
dconf.enable = true;
|
||||
hyprland.enable = true;
|
||||
};
|
||||
|
||||
xdg.portal = {
|
||||
enable = true;
|
||||
xdgOpenUsePortal = true;
|
||||
extraPortals = with pkgs; [
|
||||
xdg-desktop-portal-hyprland
|
||||
xdg-desktop-portal-gtk
|
||||
xdg-desktop-portal-termfilechooser
|
||||
];
|
||||
config = {
|
||||
common.default = [ "hyprland" "gtk" ];
|
||||
hyprland.default = [ "hyprland" "gtk" ];
|
||||
};
|
||||
};
|
||||
services = {
|
||||
udisks2.enable = true;
|
||||
fstrim.enable = true;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
{ lib, ... }: {
|
||||
environment.variables = {
|
||||
EDITOR = "hx";
|
||||
RANGER_LOAD_DEFAULT_RC = "FALSE";
|
||||
QT_QPA_PLATFORMTHEME = "qt5ct";
|
||||
GSETTINGS_BACKEND = "keyfile";
|
||||
GTK_USE_PORTAL = "1";
|
||||
QT_QPA_PLATFORMTHEME = lib.mkForce "xdgdesktopportal";
|
||||
TDESKTOP_USE_GTK_FILE_DIALOG = "1";
|
||||
};
|
||||
}
|
||||
+4
-2
@@ -4,14 +4,16 @@
|
||||
./user/yazi.nix
|
||||
./user/sleepMode.nix
|
||||
./user/ghostty.nix
|
||||
./user/zed-idea.nix
|
||||
./user/qt.nix
|
||||
./user/helix.nix
|
||||
#./user/zed-idea.nix
|
||||
./user/walker.nix
|
||||
./user/btop.nix
|
||||
./user/zsh.nix
|
||||
./user/packages/utils.nix
|
||||
./user/packages/desktop.nix
|
||||
./user/packages/kdenlive.nix
|
||||
./user/quickshell.nix
|
||||
./user/wob.nix
|
||||
./user/secrets.nix
|
||||
];
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
{ config, inputs, pkgs, ... }: {
|
||||
{ config, inputs, pkgs, lib, ... }:
|
||||
let
|
||||
hyprLua = import ./hyprland/lua.nix { inherit lib; };
|
||||
in {
|
||||
imports = [ inputs.ags.homeManagerModules.default ];
|
||||
|
||||
programs.ags = {
|
||||
@@ -20,7 +23,7 @@
|
||||
pulsemixer
|
||||
];
|
||||
|
||||
wayland.windowManager.hyprland.settings.exec-once = [ "ags run" ];
|
||||
wayland.windowManager.hyprland.settings.on = [ (hyprLua.onStart [ "ags run" ]) ];
|
||||
|
||||
xdg.configFile."ags".source = (pkgs.callPackage ./ags/ags.nix { colors = config.lib.stylix.colors; });
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
{ inputs, pkgs, lib, config, ... }: let
|
||||
# glibc >= 2.44 defines bsearch() as a C23 const-generic macro, which clashes
|
||||
# with the copy vendored by some tree-sitter grammars (tree-sitter-perl).
|
||||
# Drop the vendored implementation, same as nixpkgs does for upstream helix.
|
||||
patchedStdenv = pkgs.stdenv // {
|
||||
mkDerivation = args: pkgs.stdenv.mkDerivation (args // {
|
||||
postPatch = (args.postPatch or "") + ''
|
||||
if [ -e src/bsearch.c ]; then
|
||||
rm src/bsearch.c
|
||||
substituteInPlace src/tsp_unicode.h \
|
||||
--replace-fail '#include "bsearch.c"' ""
|
||||
fi
|
||||
'';
|
||||
});
|
||||
};
|
||||
|
||||
helixGrammars = pkgs.callPackage "${inputs.helix-steel}/grammars.nix" {
|
||||
stdenv = patchedStdenv;
|
||||
};
|
||||
|
||||
helixSteel =
|
||||
(
|
||||
pkgs.callPackage "${inputs.helix-steel}/default.nix" {
|
||||
gitRev = inputs.helix-steel.rev;
|
||||
|
||||
# The upstream flake builds the grammars with its own callPackage,
|
||||
# swap in the patched ones.
|
||||
callPackage = path: args:
|
||||
if toString path == toString "${inputs.helix-steel}/grammars.nix" then helixGrammars
|
||||
else pkgs.callPackage path args;
|
||||
}
|
||||
)
|
||||
.overrideAttrs (old: {
|
||||
cargoBuildFlags = (old.cargoBuildFlags or []) ++ [
|
||||
"--features"
|
||||
"steel,git"
|
||||
];
|
||||
});
|
||||
|
||||
comment-headers = pkgs.fetchurl {
|
||||
url = "https://github.com/codingvivi/comment-dividers.hx/raw/refs/heads/main/comment_headers.scm";
|
||||
name = "comment_headers.scm";
|
||||
hash = "sha256-ohgn6DFJl0rdRJuri6Frs/uUlUsPxMvPHDuw4FS3qEE=";
|
||||
};
|
||||
|
||||
patched-comment-headers = pkgs.runCommand "comment_headers.scm" { } ''
|
||||
install -m 0644 ${comment-headers} "$out"
|
||||
|
||||
${pkgs.python3}/bin/python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import os
|
||||
import sys
|
||||
|
||||
p = Path(os.environ["out"])
|
||||
s = p.read_text()
|
||||
|
||||
start_marker = "(define (get-block-delims)"
|
||||
end_marker = "(define (delete_till_first_nonwhitespace!)"
|
||||
|
||||
try:
|
||||
start = s.index(start_marker)
|
||||
end = s.index(end_marker, start)
|
||||
except ValueError as e:
|
||||
sys.exit(f"failed to find function markers: {e}")
|
||||
|
||||
new_get_block_delims = """(define (get-block-delims)
|
||||
(helix.static.open_above)
|
||||
(helix.static.insert_string "test_string")
|
||||
(helix.static.normal_mode)
|
||||
(helix.static.extend_to_line_bounds)
|
||||
(helix.static.trim_selections)
|
||||
(helix.static.toggle_comments)
|
||||
(let* ([commented-test-string (helix.static.current-highlighted-text!)]
|
||||
[strings-without-whitespace (split-whitespace commented-test-string)])
|
||||
(delete-line-noyank!)
|
||||
(cond
|
||||
[(and (> (length strings-without-whitespace) 1)
|
||||
(equal? (last strings-without-whitespace) "test_string"))
|
||||
(list (first strings-without-whitespace) "")]
|
||||
[(> (length strings-without-whitespace) 2)
|
||||
(list (first strings-without-whitespace) (last strings-without-whitespace))]
|
||||
[else
|
||||
(list "" "")])))
|
||||
|
||||
"""
|
||||
|
||||
s = s[:start] + new_get_block_delims + s[end:]
|
||||
|
||||
old = "(make-line line-length fill-pattern #f padding-pattern)"
|
||||
new = "(make-line line-length \"\" fill-pattern padding-pattern)"
|
||||
|
||||
if old not in s:
|
||||
sys.exit("failed to find insert-divider make-line call")
|
||||
|
||||
s = s.replace(old, new)
|
||||
|
||||
p.write_text(s)
|
||||
PY
|
||||
'';
|
||||
in {
|
||||
home.packages = with pkgs; [
|
||||
steel
|
||||
wakatime-cli
|
||||
];
|
||||
|
||||
# Wakapi is WakaTime-compatible, so the same plugin/client works.
|
||||
sops.templates.".wakatime.cfg" = {
|
||||
path = "${config.home.homeDirectory}/.wakatime.cfg";
|
||||
mode = "0600";
|
||||
content = ''
|
||||
[settings]
|
||||
api_url = https://coding.srcoder.moe/api
|
||||
api_key = ${config.sops.placeholder."tokens/apis/wakapi"}
|
||||
'';
|
||||
};
|
||||
|
||||
home.activation.installWakatimeHx = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
export PATH="${pkgs.steel}/bin:$PATH"
|
||||
export STEEL_HOME="${config.xdg.dataHome}/steel"
|
||||
|
||||
if [ ! -f "$STEEL_HOME/cogs/wakatime/wakatime.scm" ]; then
|
||||
forge pkg install --git https://github.com/Xerxes-2/wakatime.hx.git
|
||||
fi
|
||||
'';
|
||||
|
||||
programs.helix = {
|
||||
enable = true;
|
||||
package = helixSteel;
|
||||
defaultEditor = true;
|
||||
|
||||
settings = {
|
||||
# theme = "catppuccin-mocha";
|
||||
editor = {
|
||||
insert-final-newline = false;
|
||||
indent-guides.render = true;
|
||||
|
||||
whitespace.render = {
|
||||
space = "all";
|
||||
tab = "all";
|
||||
nbsp = "none";
|
||||
nnbsp = "none";
|
||||
newline = "none";
|
||||
};
|
||||
|
||||
cursor-shape = {
|
||||
normal = "block";
|
||||
insert = "bar";
|
||||
select = "underline";
|
||||
};
|
||||
};
|
||||
|
||||
keys.normal = {
|
||||
space = {
|
||||
C-c = {
|
||||
h = ":comment-h1";
|
||||
j = ":comment-h2";
|
||||
k = ":comment-h3";
|
||||
d = ":comment-divider";
|
||||
};
|
||||
};
|
||||
|
||||
S-down = ["extend_to_line_bounds" "delete_selection" "paste_after"];
|
||||
S-up = ["extend_to_line_bounds" "delete_selection" "move_line_up" "paste_before"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
xdg.configFile = {
|
||||
"helix/cogs/comment_headers.scm".source = patched-comment-headers;
|
||||
"helix/helix.scm".text = ''
|
||||
(require (prefix-in div. "cogs/comment_headers.scm"))
|
||||
|
||||
(provide comment-h1 comment-h2 comment-h3 comment-divider)
|
||||
|
||||
(define (comment-h1)
|
||||
(div.insert-h1!))
|
||||
|
||||
(define (comment-h2)
|
||||
(div.insert-h2!))
|
||||
|
||||
(define (comment-h3)
|
||||
(div.insert-h3!))
|
||||
|
||||
(define (comment-divider)
|
||||
(div.insert-divider! 80 "~"))
|
||||
'';
|
||||
"helix/init.scm".text = ''
|
||||
;; Steel init file
|
||||
(require "wakatime/wakatime.scm")
|
||||
'';
|
||||
};
|
||||
}
|
||||
+98
-192
@@ -1,4 +1,16 @@
|
||||
{ pkgs, lib, config, swww_flags, inputs }: {
|
||||
{ pkgs, lib, config, inputs, host ? null }:
|
||||
let
|
||||
hyprLua = import ./hyprland/lua.nix { inherit lib; };
|
||||
direction = { left = "l"; right = "r"; up = "u"; down = "d"; };
|
||||
workspaceBinds = lib.concatMap (workspace:
|
||||
let key = if workspace == 10 then "0" else toString workspace; workspaceValue = toString workspace;
|
||||
in [
|
||||
(hyprLua.bind "SUPER + ${key}" "hl.dsp.focus({ workspace = ${workspaceValue} })")
|
||||
(hyprLua.bind "SUPER + SHIFT + ${key}" "hl.dsp.window.move({ workspace = ${workspaceValue}, follow = false })")
|
||||
]) (lib.range 1 10);
|
||||
in {
|
||||
imports = lib.optional (host != null && builtins.pathExists ../../host/${host.name}/modules/hyprland.nix) ../../host/${host.name}/modules/hyprland.nix;
|
||||
|
||||
home.packages = with pkgs; [
|
||||
ghostty
|
||||
pamixer
|
||||
@@ -8,211 +20,105 @@
|
||||
wl-clip-persist
|
||||
xclip
|
||||
];
|
||||
|
||||
wayland.windowManager.hyprland =
|
||||
let
|
||||
colors = config.lib.stylix.colors;
|
||||
|
||||
wallpaper_changer = pkgs.writers.writePython3Bin "wallpaper_changer" {
|
||||
libraries = [ pkgs.python3Packages.requests ];
|
||||
flakeIgnore = [ "E501" "E111" "E701" "E241" "E731" ];
|
||||
} /*py*/ ''
|
||||
from random import choice
|
||||
from os import system, listdir
|
||||
|
||||
folder = "${config.home.homeDirectory}/wallpapers"
|
||||
filename = choice(listdir(folder))
|
||||
system(f"${lib.getExe pkgs.awww} img {folder}/{filename} ${swww_flags}")
|
||||
'';
|
||||
in {
|
||||
wayland.windowManager.hyprland = {
|
||||
enable = true;
|
||||
configType = "hyprlang";
|
||||
configType = "lua";
|
||||
xwayland.enable = true;
|
||||
|
||||
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
|
||||
plugins = with inputs.hyprland-plugins.packages.${pkgs.stdenv.hostPlatform.system}; [
|
||||
# hyprbars # Version mismatch
|
||||
];
|
||||
|
||||
plugins = with inputs.hyprland-plugins.packages.${pkgs.stdenv.hostPlatform.system}; [ ];
|
||||
settings = {
|
||||
"$mainMod" = "SUPER";
|
||||
|
||||
ecosystem = {
|
||||
no_donation_nag = true;
|
||||
no_update_news = true;
|
||||
};
|
||||
|
||||
env = [
|
||||
"XDG_SESSION_TYPE,wayland"
|
||||
"QT_QPA_PLATFORM,wayland"
|
||||
|
||||
"XDG_CURRENT_DESKTOP,Hyprland"
|
||||
"XDG_SESSION_DESKTOP,Hyprland"
|
||||
|
||||
"XCURSOR_SIZE, ${toString config.stylix.cursor.size}"
|
||||
"XCURSOR_THEME, ${config.stylix.cursor.name}"
|
||||
|
||||
"XDG_SCREENSHOTS_DIR,~/screens"
|
||||
];
|
||||
|
||||
cursor.no_hardware_cursors = true;
|
||||
|
||||
debug = {
|
||||
disable_logs = false;
|
||||
enable_stdout_logs = true;
|
||||
};
|
||||
|
||||
misc = {
|
||||
focus_on_activate = true;
|
||||
};
|
||||
|
||||
input = {
|
||||
kb_layout = "us,ru";
|
||||
kb_options = "grp:caps_toggle";
|
||||
numlock_by_default = true;
|
||||
|
||||
follow_mouse = 1;
|
||||
|
||||
touchpad = {
|
||||
natural_scroll = false;
|
||||
config = {
|
||||
ecosystem = { no_donation_nag = true; no_update_news = true; };
|
||||
cursor.no_hardware_cursors = 1;
|
||||
debug = { disable_logs = false; enable_stdout_logs = true; };
|
||||
general."col.inactive_border" = lib.mkDefault "rgba(00000000)";
|
||||
decoration = { inactive_opacity = lib.mkDefault 0.95; border_part_of_window = false; };
|
||||
misc.focus_on_activate = true;
|
||||
input = {
|
||||
kb_layout = "us,ru"; kb_options = "grp:caps_toggle"; numlock_by_default = true;
|
||||
follow_mouse = 1; touchpad.natural_scroll = false; sensitivity = 0;
|
||||
};
|
||||
|
||||
sensitivity = 0;
|
||||
gestures = { workspace_swipe_invert = true; workspace_swipe_distance = 200; workspace_swipe_forever = true; };
|
||||
};
|
||||
|
||||
gestures = {
|
||||
workspace_swipe_invert = true;
|
||||
workspace_swipe_distance = 200;
|
||||
workspace_swipe_forever = true;
|
||||
};
|
||||
|
||||
gesture = [
|
||||
"3, horizontal, workspace"
|
||||
env = [
|
||||
{ _args = [ "XDG_SESSION_TYPE" "wayland" ]; }
|
||||
{ _args = [ "QT_QPA_PLATFORM" "wayland" ]; }
|
||||
{ _args = [ "QT_QPA_PLATFORMTHEME" "xdgdesktopportal" ]; }
|
||||
{ _args = [ "GTK_USE_PORTAL" "1" ]; }
|
||||
{ _args = [ "TDESKTOP_USE_GTK_FILE_DIALOG" "1" ]; }
|
||||
{ _args = [ "NIXOS_OZONE_WL" "1" ]; }
|
||||
{ _args = [ "ELECTRON_OZONE_PLATFORM_HINT" "auto" ]; }
|
||||
{ _args = [ "XDG_CURRENT_DESKTOP" "Hyprland" ]; }
|
||||
{ _args = [ "XDG_SESSION_DESKTOP" "Hyprland" ]; }
|
||||
{ _args = [ "XCURSOR_SIZE" (toString config.stylix.cursor.size) ]; }
|
||||
{ _args = [ "XCURSOR_THEME" config.stylix.cursor.name ]; }
|
||||
{ _args = [ "XDG_SCREENSHOTS_DIR" "~/screens" ]; }
|
||||
];
|
||||
|
||||
windowrule = [
|
||||
"match:class imv, float 1"
|
||||
"match:class feh, float 1"
|
||||
"match:class mpv, float 1"
|
||||
|
||||
"match:title Список друзей, float 1"
|
||||
"match:title nmtui, float 1"
|
||||
"match:title pulsemixer, float 1"
|
||||
|
||||
"match:title clipse, float 1"
|
||||
"match:title clipse, size 622 652"
|
||||
|
||||
"match:focus 1, rounding 0"
|
||||
"match:float 0, match:workspace w[t1], border_size 0"
|
||||
gesture = [ { fingers = 3; direction = "horizontal"; action = "workspace"; } ];
|
||||
workspace_rule = [ { workspace = "w[t1]"; gaps_out = 0; } ];
|
||||
window_rule = [
|
||||
{ match.class = "imv"; float = true; }
|
||||
{ match.class = "feh"; float = true; }
|
||||
{ match.class = "mpv"; float = true; }
|
||||
{ match.title = "Список друзей"; float = true; }
|
||||
{ match.title = "wifitui"; float = true; }
|
||||
{ match.title = "pulsemixer"; float = true; }
|
||||
{ match.title = "clipse"; float = true; }
|
||||
{ match.title = "clipse"; size = [ 622 652 ]; }
|
||||
{ match.focus = true; rounding = 0; }
|
||||
{ match = { float = false; workspace = "w[t1]"; }; border_size = 0; }
|
||||
];
|
||||
|
||||
exec-once = [
|
||||
on = [ (hyprLua.onStart [
|
||||
"systemctl --user start plasma-polkit-agent"
|
||||
"${lib.getExe' pkgs.dbus "dbus-update-activation-environment"} --systemd --all"
|
||||
"systemctl --user import-environment XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP XDG_SESSION_TYPE WAYLAND_DISPLAY DISPLAY GTK_USE_PORTAL QT_QPA_PLATFORMTHEME TDESKTOP_USE_GTK_FILE_DIALOG NIXOS_OZONE_WL ELECTRON_OZONE_PLATFORM_HINT"
|
||||
"${lib.getExe' pkgs.awww "awww-daemon"}"
|
||||
"${pkgs.bash}/bin/bash -c 'sleep 1 && ${lib.getExe wallpaper_changer}'"
|
||||
"wl-clip-persist --clipboard both"
|
||||
"clipse -listen"
|
||||
"${lib.getExe' pkgs.udiskie "udiskie"}"
|
||||
];
|
||||
|
||||
]) ];
|
||||
bind = [
|
||||
"$mainMod, V, exec, ghostty --title=clipse -e clipse"
|
||||
|
||||
"$mainMod, Return, exec, ghostty"
|
||||
"$mainMod, Q, killactive,"
|
||||
"$mainMod, M, exit,"
|
||||
"$mainMod, E, exec, ghostty -e sh -c yazi"
|
||||
"$mainMod, F, togglefloating,"
|
||||
"$mainMod, J, layoutmsg, togglesplit, # dwindle"
|
||||
|
||||
# Move focus with mainMod + arrow keys
|
||||
"$mainMod, left, movefocus, l"
|
||||
"$mainMod, right, movefocus, r"
|
||||
"$mainMod, up, movefocus, u"
|
||||
"$mainMod, down, movefocus, d"
|
||||
|
||||
# Moving windows
|
||||
"$mainMod SHIFT, left, swapwindow, l"
|
||||
"$mainMod SHIFT, right, swapwindow, r"
|
||||
"$mainMod SHIFT, up, swapwindow, u"
|
||||
"$mainMod SHIFT, down, swapwindow, d"
|
||||
|
||||
# Window resizing X Y
|
||||
"$mainMod CTRL, left, resizeactive, -60 0"
|
||||
"$mainMod CTRL, right, resizeactive, 60 0"
|
||||
"$mainMod CTRL, up, resizeactive, 0 -60"
|
||||
"$mainMod CTRL, down, resizeactive, 0 60"
|
||||
|
||||
# Switch workspaces with mainMod + [0-9]
|
||||
"$mainMod, 1, workspace, 1"
|
||||
"$mainMod, 2, workspace, 2"
|
||||
"$mainMod, 3, workspace, 3"
|
||||
"$mainMod, 4, workspace, 4"
|
||||
"$mainMod, 5, workspace, 5"
|
||||
"$mainMod, 6, workspace, 6"
|
||||
"$mainMod, 7, workspace, 7"
|
||||
"$mainMod, 8, workspace, 8"
|
||||
"$mainMod, 9, workspace, 9"
|
||||
"$mainMod, 0, workspace, 10"
|
||||
|
||||
# Move active window to a workspace with mainMod + SHIFT + [0-9]
|
||||
"$mainMod SHIFT, 1, movetoworkspacesilent, 1"
|
||||
"$mainMod SHIFT, 2, movetoworkspacesilent, 2"
|
||||
"$mainMod SHIFT, 3, movetoworkspacesilent, 3"
|
||||
"$mainMod SHIFT, 4, movetoworkspacesilent, 4"
|
||||
"$mainMod SHIFT, 5, movetoworkspacesilent, 5"
|
||||
"$mainMod SHIFT, 6, movetoworkspacesilent, 6"
|
||||
"$mainMod SHIFT, 7, movetoworkspacesilent, 7"
|
||||
"$mainMod SHIFT, 8, movetoworkspacesilent, 8"
|
||||
"$mainMod SHIFT, 9, movetoworkspacesilent, 9"
|
||||
"$mainMod SHIFT, 0, movetoworkspacesilent, 10"
|
||||
|
||||
"$mainMod SHIFT, F, fullscreen"
|
||||
|
||||
# Scroll through existing workspaces with mainMod + scroll
|
||||
"$mainMod, mouse_down, workspace, e+1"
|
||||
"$mainMod, mouse_up, workspace, e-1"
|
||||
|
||||
# Keyboard backlight
|
||||
"$mainMod, F3, exec, ${lib.getExe pkgs.brightnessctl} -d *::kbd_backlight set +33%"
|
||||
"$mainMod, F2, exec, ${lib.getExe pkgs.brightnessctl} -d *::kbd_backlight set 33%-"
|
||||
|
||||
# Volume and Media Control
|
||||
", XF86AudioMute, exec, pamixer -t"
|
||||
", XF86AudioMicMute, exec, pamixer --default-source -m"
|
||||
", XF86AudioPlay, exec, ${lib.getExe pkgs.playerctl} play-pause"
|
||||
", XF86AudioPrev, exec, ${lib.getExe pkgs.playerctl} position 5-"
|
||||
", XF86AudioNext, exec, ${lib.getExe pkgs.playerctl} position 5+"
|
||||
|
||||
", XF86Explorer, exec, ghostty -e sh -c yazi"
|
||||
", XF86Mail, exec, thunderbird"
|
||||
", XF86WWW, exec, google-chrome-stable" # TODO: Replace hard-code to some variable
|
||||
|
||||
# Brightness control
|
||||
", XF86MonBrightnessDown, exec, ${lib.getExe pkgs.brightnessctl} set 5%- "
|
||||
", XF86MonBrightnessUp, exec, ${lib.getExe pkgs.brightnessctl} set +5% "
|
||||
|
||||
# Waybar
|
||||
"$mainMod, B, exec, pkill -SIGUSR1 waybar"
|
||||
#"$mainMod, W, exec, pkill -SIGUSR2 waybar"
|
||||
|
||||
"$mainMod, W, exec, ${lib.getExe wallpaper_changer}"
|
||||
];
|
||||
|
||||
binde = [
|
||||
", XF86AudioRaiseVolume, exec, pamixer -i 5 "
|
||||
", XF86AudioLowerVolume, exec, pamixer -d 5 "
|
||||
];
|
||||
|
||||
bindo = [
|
||||
", XF86AudioPrev, exec, ${lib.getExe pkgs.playerctl} previous"
|
||||
", XF86AudioNext, exec, ${lib.getExe pkgs.playerctl} next"
|
||||
];
|
||||
|
||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||
bindm = [
|
||||
"$mainMod, mouse:272, movewindow"
|
||||
"$mainMod, mouse:273, resizewindow"
|
||||
(hyprLua.bind "SUPER + V" (hyprLua.exec "ghostty --title=clipse -e clipse"))
|
||||
(hyprLua.bind "SUPER + RETURN" (hyprLua.exec "ghostty"))
|
||||
(hyprLua.bind "SUPER + Q" "hl.dsp.window.close()")
|
||||
(hyprLua.bind "SUPER + M" "hl.dsp.exit()")
|
||||
(hyprLua.bind "SUPER + E" (hyprLua.exec "ghostty -e sh -c yazi"))
|
||||
(hyprLua.bind "SUPER + F" "hl.dsp.window.float({ action = \"toggle\" })")
|
||||
(hyprLua.bind "SUPER + J" "hl.dsp.layout(\"togglesplit\")")
|
||||
(hyprLua.bind "SUPER + LEFT" "hl.dsp.focus({ direction = \"${direction.left}\" })")
|
||||
(hyprLua.bind "SUPER + RIGHT" "hl.dsp.focus({ direction = \"${direction.right}\" })")
|
||||
(hyprLua.bind "SUPER + UP" "hl.dsp.focus({ direction = \"${direction.up}\" })")
|
||||
(hyprLua.bind "SUPER + DOWN" "hl.dsp.focus({ direction = \"${direction.down}\" })")
|
||||
(hyprLua.bind "SUPER + SHIFT + LEFT" "hl.dsp.window.swap({ direction = \"${direction.left}\" })")
|
||||
(hyprLua.bind "SUPER + SHIFT + RIGHT" "hl.dsp.window.swap({ direction = \"${direction.right}\" })")
|
||||
(hyprLua.bind "SUPER + SHIFT + UP" "hl.dsp.window.swap({ direction = \"${direction.up}\" })")
|
||||
(hyprLua.bind "SUPER + SHIFT + DOWN" "hl.dsp.window.swap({ direction = \"${direction.down}\" })")
|
||||
(hyprLua.bind "SUPER + CTRL + LEFT" "hl.dsp.window.resize({ x = -60, y = 0, relative = true })")
|
||||
(hyprLua.bind "SUPER + CTRL + RIGHT" "hl.dsp.window.resize({ x = 60, y = 0, relative = true })")
|
||||
(hyprLua.bind "SUPER + CTRL + UP" "hl.dsp.window.resize({ x = 0, y = -60, relative = true })")
|
||||
(hyprLua.bind "SUPER + CTRL + DOWN" "hl.dsp.window.resize({ x = 0, y = 60, relative = true })")
|
||||
] ++ workspaceBinds ++ [
|
||||
(hyprLua.bind "SUPER + SHIFT + F" "hl.dsp.window.fullscreen({ action = \"toggle\", mode = \"fullscreen\" })")
|
||||
(hyprLua.bind "SUPER + mouse_down" "hl.dsp.focus({ workspace = \"e+1\" })")
|
||||
(hyprLua.bind "SUPER + mouse_up" "hl.dsp.focus({ workspace = \"e-1\" })")
|
||||
(hyprLua.bind "SUPER + F3" (hyprLua.exec "${lib.getExe pkgs.brightnessctl} -d *::kbd_backlight set +33%"))
|
||||
(hyprLua.bind "SUPER + F2" (hyprLua.exec "${lib.getExe pkgs.brightnessctl} -d *::kbd_backlight set 33%-"))
|
||||
(hyprLua.bind "XF86AudioMute" (hyprLua.exec "pamixer -t"))
|
||||
(hyprLua.bind "XF86AudioMicMute" (hyprLua.exec "pamixer --default-source -m"))
|
||||
(hyprLua.bind "XF86AudioPlay" (hyprLua.exec "${lib.getExe pkgs.playerctl} play-pause"))
|
||||
(hyprLua.bind "XF86AudioPrev" (hyprLua.exec "${lib.getExe pkgs.playerctl} position 5-"))
|
||||
(hyprLua.bind "XF86AudioNext" (hyprLua.exec "${lib.getExe pkgs.playerctl} position 5+"))
|
||||
(hyprLua.bind "XF86Explorer" (hyprLua.exec "ghostty -e sh -c yazi"))
|
||||
(hyprLua.bind "XF86Mail" (hyprLua.exec "thunderbird"))
|
||||
(hyprLua.bind "XF86WWW" (hyprLua.exec "google-chrome-stable"))
|
||||
(hyprLua.bind "XF86MonBrightnessDown" (hyprLua.exec "${lib.getExe pkgs.brightnessctl} set 5%-"))
|
||||
(hyprLua.bind "XF86MonBrightnessUp" (hyprLua.exec "${lib.getExe pkgs.brightnessctl} set +5%"))
|
||||
(hyprLua.bindWithFlags "XF86AudioRaiseVolume" (hyprLua.exec "pamixer -i 5") { repeating = true; })
|
||||
(hyprLua.bindWithFlags "XF86AudioLowerVolume" (hyprLua.exec "pamixer -d 5") { repeating = true; })
|
||||
(hyprLua.bindWithFlags "XF86AudioPrev" (hyprLua.exec "${lib.getExe pkgs.playerctl} previous") { long_press = true; })
|
||||
(hyprLua.bindWithFlags "XF86AudioNext" (hyprLua.exec "${lib.getExe pkgs.playerctl} next") { long_press = true; })
|
||||
(hyprLua.bindWithFlags "SUPER + mouse:272" "hl.dsp.window.drag()" { mouse = true; })
|
||||
(hyprLua.bindWithFlags "SUPER + mouse:273" "hl.dsp.window.resize()" { mouse = true; })
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{ lib }:
|
||||
let
|
||||
inline = lib.generators.mkLuaInline;
|
||||
quote = builtins.toJSON;
|
||||
in rec {
|
||||
inherit inline;
|
||||
exec = command: "hl.dsp.exec_cmd(${quote command})";
|
||||
bind = keys: dispatcher: { _args = [ keys (inline dispatcher) ]; };
|
||||
bindWithFlags = keys: dispatcher: flags: { _args = [ keys (inline dispatcher) flags ]; };
|
||||
onStart = commands: {
|
||||
_args = [
|
||||
"hyprland.start"
|
||||
(inline ("function()\n" + lib.concatMapStringsSep "\n" (command: " hl.exec_cmd(${quote command})") commands + "\nend"))
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
{ pkgs, ... }: {
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
free-coding-models = import ./free-coding-models.nix {
|
||||
inherit pkgs;
|
||||
};
|
||||
in
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
#jetbrains.idea-oss
|
||||
android-studio
|
||||
@@ -6,6 +12,7 @@
|
||||
git
|
||||
tree
|
||||
opencode
|
||||
free-coding-models
|
||||
postgresql
|
||||
dbgate
|
||||
];
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
pnpm = pkgs.pnpm_10;
|
||||
in
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
pname = "free-coding-models";
|
||||
version = "0.5.97";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "vava-nessa";
|
||||
repo = "free-coding-models";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-1jjEBKoNUslrJEDNuqEQ7dHHiecJ3urOdH7MRrdhD1E=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkgs.nodejs
|
||||
pkgs.makeWrapper
|
||||
pkgs.pnpmConfigHook
|
||||
pnpm
|
||||
];
|
||||
|
||||
pnpmDeps = pkgs.fetchPnpmDeps {
|
||||
inherit pname version src pnpm;
|
||||
|
||||
fetcherVersion = 4;
|
||||
|
||||
hash = "sha256-TYOXu2XAdoLqbJPB8idemkWcxahs4+Z6UXAnh3+C47o=";
|
||||
};
|
||||
|
||||
dontNpmBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out/lib/node_modules/free-coding-models
|
||||
cp -r . $out/lib/node_modules/free-coding-models
|
||||
|
||||
mkdir -p $out/bin
|
||||
ln -s $out/lib/node_modules/free-coding-models/bin/free-coding-models.js \
|
||||
$out/bin/free-coding-models
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
wrapProgram $out/bin/free-coding-models \
|
||||
--prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.nodejs ]}
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Find, benchmark and install free coding LLM models";
|
||||
homepage = "https://github.com/vava-nessa/free-coding-models";
|
||||
license = pkgs.lib.licenses.mit;
|
||||
mainProgram = "free-coding-models";
|
||||
};
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{ pkgs, ... }: {
|
||||
home.packages = with pkgs; [
|
||||
heroic
|
||||
];
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{ pkgs, ... }: {
|
||||
home.packages = with pkgs; [
|
||||
kdePackages.kdenlive
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{ lib, ... }: {
|
||||
stylix.targets.qt.standardDialogs = "xdgdesktopportal";
|
||||
|
||||
home.sessionVariables = {
|
||||
QT_QPA_PLATFORMTHEME = lib.mkForce "xdgdesktopportal";
|
||||
TDESKTOP_USE_GTK_FILE_DIALOG = "1";
|
||||
};
|
||||
|
||||
qt = {
|
||||
enable = true;
|
||||
platformTheme.name = "qtct";
|
||||
style.name = "kvantum";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{ config, ... }: {
|
||||
sops = {
|
||||
defaultSopsFile = ../../user/${config.home.username}/secrets.yaml;
|
||||
age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
|
||||
|
||||
secrets."tokens/apis/wallhaven" = {};
|
||||
secrets."tokens/apis/wakapi" = {};
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,50 @@
|
||||
{ pkgs, lib, ... }: {
|
||||
wayland.windowManager.hyprland.settings.exec-once = [ "hyprlock" ];
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
hyprLua = import ./hyprland/lua.nix { inherit lib; };
|
||||
|
||||
hyprlock = lib.getExe pkgs.hyprlock;
|
||||
hyprctl = lib.getExe' config.wayland.windowManager.hyprland.package "hyprctl";
|
||||
loginctl = lib.getExe' pkgs.systemd "loginctl";
|
||||
pidof = lib.getExe' pkgs.procps "pidof";
|
||||
fprintdList = lib.getExe' pkgs.fprintd "fprintd-list";
|
||||
timeout = lib.getExe' pkgs.coreutils "timeout";
|
||||
sleepCmd = lib.getExe' pkgs.coreutils "sleep";
|
||||
sh = lib.getExe pkgs.bash;
|
||||
|
||||
hyprlockWait = pkgs.writeShellScript "hyprlock-wait-fprint" ''
|
||||
for i in $(seq 1 60); do
|
||||
if ${timeout} 1 ${fprintdList} kirill >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
${sleepCmd} 1
|
||||
done
|
||||
exec ${hyprlock}
|
||||
'';
|
||||
in {
|
||||
wayland.windowManager.hyprland.settings.on = [ (hyprLua.onStart [ "${hyprlockWait}" ]) ];
|
||||
|
||||
# Hypridle listens to logind's PrepareForSleep signal: it locks the session
|
||||
# before suspend and makes sure hyprlock is running (and the display is on)
|
||||
# after resume.
|
||||
services.hypridle = {
|
||||
enable = true;
|
||||
settings = {
|
||||
general = {
|
||||
lock_cmd = "${pidof} hyprlock >/dev/null || ${hyprlockWait}";
|
||||
before_sleep_cmd = "${loginctl} lock-session";
|
||||
after_sleep_cmd = "${pidof} hyprlock >/dev/null || ${hyprlockWait} & ${hyprctl} dispatch 'hl.dsp.dpms({action = \"on\"})'";
|
||||
};
|
||||
|
||||
# Hypridle requires at least one listener, so keep a no-op timer that
|
||||
# practically never fires. Screen locking is driven by sleep/resume only.
|
||||
listener = [
|
||||
{
|
||||
timeout = 604800; # 7 days
|
||||
on-timeout = "";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
programs.hyprlock = let
|
||||
image = pkgs.fetchurl {
|
||||
@@ -11,6 +56,17 @@
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
# Hyprlock's built-in fingerprint support watches logind's
|
||||
# PrepareForSleep signal and re-arms itself after resume. PAM-based
|
||||
# fingerprint auth (security.pam.services.hyprlock.fprintAuth) does not
|
||||
# survive the fingerprint device being reset during suspend.
|
||||
auth.fingerprint = {
|
||||
enabled = true;
|
||||
ready_message = "Scan fingerprint to unlock";
|
||||
present_message = "Scanning...";
|
||||
retry_delay = 250;
|
||||
};
|
||||
|
||||
background = {
|
||||
path = lib.mkForce "${image}";
|
||||
blur_passes = 0;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
{ lib, ... }:
|
||||
let
|
||||
hyprLua = import ./hyprland/lua.nix { inherit lib; };
|
||||
in {
|
||||
services = {
|
||||
walker = {
|
||||
enable = true;
|
||||
@@ -9,6 +12,7 @@
|
||||
};
|
||||
|
||||
wayland.windowManager.hyprland.settings.bind = [
|
||||
"$mainMod, D, exec, walker"
|
||||
(hyprLua.bind "SUPER + D" (hyprLua.exec "walker"))
|
||||
];
|
||||
|
||||
}
|
||||
+8
-12
@@ -1,4 +1,5 @@
|
||||
{ config, pkgs, lib, ... }: let
|
||||
hyprLua = import ./hyprland/lua.nix { inherit lib; };
|
||||
c = config.lib.stylix.colors;
|
||||
|
||||
wobSocket = ''"''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/wob.sock"'';
|
||||
@@ -53,16 +54,11 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
wayland.windowManager.hyprland.settings = {
|
||||
bindel = [
|
||||
", XF86AudioRaiseVolume, exec, ${lib.getExe volumeStep} up"
|
||||
", XF86AudioLowerVolume, exec, ${lib.getExe volumeStep} down"
|
||||
", XF86MonBrightnessUp, exec, ${lib.getExe brightnessStep} up"
|
||||
", XF86MonBrightnessDown, exec, ${lib.getExe brightnessStep} down"
|
||||
];
|
||||
|
||||
bind = [
|
||||
", XF86AudioMute, exec, ${lib.getExe volumeStep} mute"
|
||||
];
|
||||
};
|
||||
wayland.windowManager.hyprland.settings.bind = [
|
||||
(hyprLua.bindWithFlags "XF86AudioRaiseVolume" (hyprLua.exec "${lib.getExe volumeStep} up") { repeating = true; locked = true; })
|
||||
(hyprLua.bindWithFlags "XF86AudioLowerVolume" (hyprLua.exec "${lib.getExe volumeStep} down") { repeating = true; locked = true; })
|
||||
(hyprLua.bindWithFlags "XF86MonBrightnessUp" (hyprLua.exec "${lib.getExe brightnessStep} up") { repeating = true; locked = true; })
|
||||
(hyprLua.bindWithFlags "XF86MonBrightnessDown" (hyprLua.exec "${lib.getExe brightnessStep} down") { repeating = true; locked = true; })
|
||||
(hyprLua.bind "XF86AudioMute" (hyprLua.exec "${lib.getExe volumeStep} mute"))
|
||||
];
|
||||
}
|
||||
@@ -121,8 +121,14 @@ in {
|
||||
Exec=${lib.getExe fileManager1}
|
||||
'';
|
||||
|
||||
wayland.windowManager.hyprland.settings.windowrule = [
|
||||
"match:class dragon-drop, move cursor_x-window_w/2 cursor_y-window_h/2"
|
||||
wayland.windowManager.hyprland.settings.window_rule = [
|
||||
{
|
||||
match.class = "dragon-drop";
|
||||
move = [
|
||||
"(cursor_x-(window_w*0.5))"
|
||||
"(cursor_y-(window_h*0.5))"
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
programs.yazi = {
|
||||
|
||||
@@ -88,21 +88,21 @@
|
||||
openWayBar = "vim .config/f/home-manager/data/waybar.nix";
|
||||
rebuildFlake = "sudo nixos-rebuild switch --flake /home/kirill/.config/f --impure";
|
||||
openFlake = "vim /home/kirill/.config/f/flake.nix";
|
||||
swichWalls = "python3 /nix/store/6czqsnf0gbvvm472lipndyg34qhnfpis-wallpaper_changer/bin/wallpaper_changer";
|
||||
screenshot_f="grimblast save screen ~/screenshot_$(date +\%Y-\%m-\%d_\%H-\%M-\%S).png";
|
||||
screenshot="grimblast save area ~/screenshot_$(date +\%Y-\%m-\%d_\%H-\%M-\%S).png";
|
||||
screenshot_c = "grimblast copy area";
|
||||
loginPostgresql = "sudo -u postgres psql";
|
||||
startShell = "nix-shell . --run zsh";
|
||||
VPN = "sudo openvpn --config /home/kirill/VPN/184.22.37.202_udp_1727.ovpn";
|
||||
play2Go = "ssh -i ~/.ssh/id_rsa_play2go.pub root@93.123.84.45";
|
||||
swichWalls = "wallpaper_changer";
|
||||
shell = "nix-shell . --run zsh";
|
||||
testZapret = "sudo zapret-test-strategies";
|
||||
|
||||
charge = "sudo tlp setcharge 90 95 BAT0 && sudo tlp setcharge 90 95 BAT1 && echo 'Зарядка обеих батарей до 95% запущена (только на текущую сессию)'";
|
||||
};
|
||||
|
||||
initContent = ''
|
||||
eval "$(zoxide init zsh)"
|
||||
source "$(fzf-share)/key-bindings.zsh"
|
||||
source "$(fzf-share)/completion.zsh"
|
||||
|
||||
run() {
|
||||
nix run "nixpkgs#$1"
|
||||
}
|
||||
'';
|
||||
|
||||
envExtra = ''
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
# Секреты (sops-nix)
|
||||
|
||||
Кратко: как всё устроено, как добавить новый секрет и как поднять рабочий sops на новом устройстве.
|
||||
|
||||
## Как устроено
|
||||
|
||||
- `.sops.yaml` в корне репозитория — список age-реципиентов и правила выбора ключа по пути файла.
|
||||
- Секреты делятся на два уровня:
|
||||
- **host** (системные, читает root): зашифрованные файлы в `host/<Host>/secrets/<файл>`, метаданные в `host/<Host>/secrets/secrets.nix`, подключается из `host/<Host>/configuration.nix` через `imports`. При активации расшифровываются в `/run/secrets/<имя>`.
|
||||
- **user** (пользовательские, читает home-manager): один файл `user/<username>/secrets.yaml`, метаданные в `modules/user/secrets.nix`, подключается из `modules/user.nix` через `imports`. При активации расшифровываются в `~/.config/sops-nix/secrets/<имя>`.
|
||||
- Расшифровка идёт в runtime, в `/nix/store` секреты не попадают.
|
||||
- age-ключи выводятся из существующих SSH-ключей:
|
||||
- host — `/root/age.key` (читает root при активации),
|
||||
- user — `~/.config/sops/age/keys.txt` (читает пользователь при активации home-manager).
|
||||
|
||||
Текущие правила в `.sops.yaml`:
|
||||
|
||||
```yaml
|
||||
keys:
|
||||
- &key age1tx6jdr6535xxeygpwkkgvdwc24tulr420cm7gk56xzfp0slzeqks2nwpyg
|
||||
|
||||
creation_rules:
|
||||
- path_regex: host/[^/]+/secrets/.+$
|
||||
key_groups:
|
||||
- age:
|
||||
- *key
|
||||
- path_regex: user/[^/]+/secrets\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *key
|
||||
```
|
||||
|
||||
Правило выбирается по пути файла. Важно: `path_regex` проверяется против пути **входного** файла относительно корня репозитория, поэтому открытое значение нужно создавать по целевому пути (см. примеры ниже).
|
||||
|
||||
## Host-секрет (системный)
|
||||
|
||||
### Добавить новый
|
||||
|
||||
1. Придумай имя, дальше для примера — `mysecret`.
|
||||
|
||||
2. Положи открытое значение во временный файл **внутри** `host/<Host>/secrets/` (путь важен — см. `path_regex`):
|
||||
|
||||
```bash
|
||||
printf '%s' 'СЕКРЕТНОЕ_ЗНАЧЕНИЕ' > host/ThinkPad/secrets/mysecret.plain
|
||||
```
|
||||
|
||||
3. Зашифруй (приватный ключ не нужен — sops берёт публичного реципиента из `.sops.yaml`). Флаги указываются **до** позиционных аргументов:
|
||||
|
||||
```bash
|
||||
nix-shell -p sops --run \
|
||||
"sops --input-type binary --output-type binary \
|
||||
--encrypt --output host/ThinkPad/secrets/mysecret.enc \
|
||||
host/ThinkPad/secrets/mysecret.plain"
|
||||
rm host/ThinkPad/secrets/mysecret.plain
|
||||
```
|
||||
|
||||
`--input-type`/`--output-type` обязательны для бинарных данных, иначе sops пытается определить тип по расширению.
|
||||
|
||||
4. Опиши секрет в `host/<Host>/secrets/secrets.nix`:
|
||||
|
||||
```nix
|
||||
{
|
||||
sops = {
|
||||
age.keyFile = "/root/age.key";
|
||||
|
||||
secrets = {
|
||||
mysecret = {
|
||||
format = "binary"; # yaml | json | binary | dotenv | ini
|
||||
sopsFile = ./mysecret.enc;
|
||||
owner = "kirill"; # владелец расшифрованного файла
|
||||
mode = "0400";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
`format = "binary"` — для произвольных байтов (`.pem`, токены). Для структурированных данных используй `yaml`/`json`.
|
||||
`owner`/`mode` нужны, если секрет читает пользовательский процесс (а не root-сервис).
|
||||
|
||||
5. `git add` — **Nix видит только файлы, добавленные в git** — и ребилд:
|
||||
|
||||
```bash
|
||||
git add host/ThinkPad/secrets/
|
||||
sudo nixos-rebuild switch --flake .#ThinkPad
|
||||
```
|
||||
|
||||
6. Проверка:
|
||||
|
||||
```bash
|
||||
sudo ls -l /run/secrets/mysecret
|
||||
```
|
||||
|
||||
### Изменить или посмотреть существующий секрет
|
||||
|
||||
Используется приватный ключ (`/root/age.key`), поэтому нужен root:
|
||||
|
||||
```bash
|
||||
sudo SOPS_AGE_KEY_FILE=/root/age.key nix-shell -p sops --run \
|
||||
"sops --input-type binary --output-type binary host/ThinkPad/secrets/mysecret.enc"
|
||||
```
|
||||
|
||||
`sops` сам не ищет `/root/age.key`, путь передаётся через `SOPS_AGE_KEY_FILE`.
|
||||
Для бинарных файлов нужны `--input-type`/`--output-type`, иначе sops не сможет определить формат.
|
||||
|
||||
## User-секрет (home-manager)
|
||||
|
||||
Все пользовательские секреты лежат в одном файле `user/<username>/secrets.yaml`. Значения — вложенные ключи YAML, а имя секрета в nix-коде совпадает с путём этого ключа (`/` = вложенность). Например, секрет `tokens/apis/wallhaven` читается из:
|
||||
|
||||
```yaml
|
||||
tokens:
|
||||
apis:
|
||||
wallhaven: ЗНАЧЕНИЕ
|
||||
```
|
||||
|
||||
Путь расшифрованного файла: `~/.config/sops-nix/secrets/tokens/apis/wallhaven`.
|
||||
|
||||
### Добавить новый
|
||||
|
||||
1. Придумай имя, дальше для примера — `tokens/apis/wallhaven`.
|
||||
|
||||
2. Добавь значение в общий файл секретов (sops откроет расшифрованное содержимое в `$EDITOR` и зашифрует при сохранении; путь совпадает с `path_regex`, поэтому правило применится автоматически):
|
||||
|
||||
```bash
|
||||
nix-shell -p sops --run "sops user/kirill/secrets.yaml"
|
||||
```
|
||||
|
||||
Если файла ещё нет, создай его сразу по целевому пути и зашифруй на месте:
|
||||
|
||||
```bash
|
||||
printf 'tokens:\n apis:\n wallhaven: ЗНАЧЕНИЕ\n' > user/kirill/secrets.yaml
|
||||
nix-shell -p sops --run "sops --encrypt --in-place user/kirill/secrets.yaml"
|
||||
```
|
||||
|
||||
3. Опиши секрет в `modules/user/secrets.nix`:
|
||||
|
||||
```nix
|
||||
{ config, ... }: {
|
||||
sops = {
|
||||
defaultSopsFile = ../../user/${config.home.username}/secrets.yaml;
|
||||
age.keyFile = "${config.home.homeDirectory}/.config/sops/age/keys.txt";
|
||||
|
||||
secrets."tokens/apis/wallhaven" = {};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
4. Используй в home-manager конфиге через путь:
|
||||
|
||||
```nix
|
||||
config.sops.secrets."tokens/apis/wallhaven".path
|
||||
```
|
||||
|
||||
5. `git add` — **Nix видит только файлы, добавленные в git** — и ребилд:
|
||||
|
||||
```bash
|
||||
git add user/kirill/secrets.yaml modules/user/secrets.nix modules/user.nix
|
||||
sudo nixos-rebuild switch --flake .#ThinkPad
|
||||
```
|
||||
|
||||
6. Проверка:
|
||||
|
||||
```bash
|
||||
ls -l ~/.config/sops-nix/secrets/tokens/apis/wallhaven
|
||||
```
|
||||
|
||||
### Изменить или посмотреть существующий секрет
|
||||
|
||||
```bash
|
||||
nix-shell -p sops --run "sops user/kirill/secrets.yaml"
|
||||
```
|
||||
|
||||
sops подхватывает `~/.config/sops/age/keys.txt` автоматически. Если путь другой — задай `SOPS_AGE_KEY_FILE`.
|
||||
|
||||
## Новое устройство
|
||||
|
||||
1. Убедись, что на устройстве есть приватный SSH-ключ, из которого выводится age-ключ. Ключ должен быть **без пароля** — иначе расшифровка при активации будет требовать ввода. На текущей машине это `~/.ssh/id_ed25519_sops`.
|
||||
|
||||
2. Создай age-ключ хоста (root читает его при активации):
|
||||
|
||||
```bash
|
||||
sudo nix-shell -p ssh-to-age --run \
|
||||
"ssh-to-age -private-key -i /home/kirill/.ssh/id_ed25519_sops -o /root/age.key"
|
||||
sudo chmod 600 /root/age.key
|
||||
```
|
||||
|
||||
3. Создай age-ключ пользователя (home-manager читает его при активации):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/sops/age
|
||||
nix-shell -p ssh-to-age --run \
|
||||
"ssh-to-age -private-key -i ~/.ssh/id_ed25519_sops -o ~/.config/sops/age/keys.txt"
|
||||
chmod 700 ~/.config/sops/age
|
||||
chmod 600 ~/.config/sops/age/keys.txt
|
||||
```
|
||||
|
||||
4. Проверь, что публичный age-реципиент устройства совпадает с тем, что в `.sops.yaml`:
|
||||
|
||||
```bash
|
||||
nix-shell -p ssh-to-age --run \
|
||||
"ssh-to-age -i ~/.ssh/id_ed25519_sops.pub"
|
||||
```
|
||||
|
||||
Должно вывести:
|
||||
|
||||
```
|
||||
age1tx6jdr6535xxeygpwkkgvdwc24tulr420cm7gk56xzfp0slzeqks2nwpyg
|
||||
```
|
||||
|
||||
Если вывод другой — добавь новый реципиент (см. следующий раздел).
|
||||
|
||||
5. Создай структуру секретов хоста:
|
||||
|
||||
```
|
||||
host/<Host>/secrets/secrets.nix
|
||||
host/<Host>/secrets/<файлы секретов>
|
||||
```
|
||||
|
||||
Минимальный `secrets.nix`:
|
||||
|
||||
```nix
|
||||
{
|
||||
sops = {
|
||||
age.keyFile = "/root/age.key";
|
||||
secrets = { };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
И добавь `./secrets/secrets.nix` в `imports` в `host/<Host>/configuration.nix`.
|
||||
|
||||
6. Для пользовательских секретов создай `user/<username>/secrets.yaml` (см. раздел «User-секрет») и убедись, что `modules/user.nix` подключает `./user/secrets.nix`.
|
||||
|
||||
7. `git add` + ребилд:
|
||||
|
||||
```bash
|
||||
git add host/<Host>/secrets/ user/<username>/secrets.yaml modules/user/secrets.nix
|
||||
sudo nixos-rebuild switch --flake .#<Host>
|
||||
```
|
||||
|
||||
## Добавить устройство к существующим секретам
|
||||
|
||||
1. Получи age-реципиент устройства (шаг 4 выше).
|
||||
|
||||
2. Добавь его в `.sops.yaml` в оба правила:
|
||||
|
||||
```yaml
|
||||
keys:
|
||||
- &key age1tx6jdr6535xxeygpwkkgvdwc24tulr420cm7gk56xzfp0slzeqks2nwpyg
|
||||
- &newdevice age1...новый_реципиент... # замени на реальный
|
||||
|
||||
creation_rules:
|
||||
- path_regex: host/[^/]+/secrets/.+$
|
||||
key_groups:
|
||||
- age:
|
||||
- *key
|
||||
- *newdevice
|
||||
- path_regex: user/[^/]+/secrets\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *key
|
||||
- *newdevice
|
||||
```
|
||||
|
||||
3. Перешифруй существующие секреты под новый список реципиентов (нужен приватный ключ). Для host-секретов — root и `/root/age.key`:
|
||||
|
||||
```bash
|
||||
sudo SOPS_AGE_KEY_FILE=/root/age.key nix-shell -p sops --run \
|
||||
"sops updatekeys host/ThinkPad/secrets/mysecret.enc"
|
||||
```
|
||||
|
||||
Для user-секретов — пользовательский ключ:
|
||||
|
||||
```bash
|
||||
SOPS_AGE_KEY_FILE=~/.config/sops/age/keys.txt nix-shell -p sops --run \
|
||||
"sops updatekeys user/kirill/secrets.yaml"
|
||||
```
|
||||
|
||||
4. `git add` + ребилд на этом устройстве.
|
||||
@@ -1,79 +1,282 @@
|
||||
{ pkgs, lib, config, inputs, ... }: {
|
||||
{ pkgs, lib, config, inputs, host, ... }:
|
||||
let
|
||||
secretPath = config.sops.secrets."tokens/apis/wallhaven".path;
|
||||
|
||||
wallpaper_changer = pkgs.writers.writePython3Bin "wallpaper_changer" {
|
||||
libraries = [ pkgs.python3Packages.requests ];
|
||||
flakeIgnore = [ "E111" "E121" "E241" "E501" "E701" "E731" ];
|
||||
} /*py*/ ''
|
||||
import requests as requests
|
||||
from random import choice
|
||||
from os import environ, getuid, listdir, makedirs, remove, replace, system
|
||||
from os.path import exists, getmtime, isfile
|
||||
from subprocess import run
|
||||
|
||||
notify_id = None
|
||||
|
||||
|
||||
def notify(text, progress=None, expire_time=5000):
|
||||
global notify_id
|
||||
|
||||
command = [
|
||||
"${pkgs.libnotify}/bin/notify-send",
|
||||
"--app-name", "wallpaper_changer",
|
||||
"--print-id",
|
||||
"--expire-time", str(expire_time),
|
||||
]
|
||||
|
||||
if notify_id:
|
||||
command.extend(["--replace-id", str(notify_id)])
|
||||
|
||||
if progress is not None:
|
||||
command.extend(["--hint", f"int:value:{progress}"])
|
||||
|
||||
command.extend(["Wallpaper", text])
|
||||
|
||||
result = run(command, capture_output=True, text=True, check=False)
|
||||
output = result.stdout.strip()
|
||||
if output.isdigit():
|
||||
notify_id = output
|
||||
|
||||
|
||||
def download_with_progress(link, destination):
|
||||
temporary = f"{destination}.part"
|
||||
downloaded = 0
|
||||
last_progress = -1
|
||||
|
||||
response = None
|
||||
try:
|
||||
response = requests.get(link, stream=True, timeout=30)
|
||||
response.raise_for_status()
|
||||
total = int(response.headers.get("content-length", 0))
|
||||
|
||||
with open(temporary, "wb") as file:
|
||||
for chunk in response.iter_content(chunk_size=256 * 1024):
|
||||
if not chunk:
|
||||
continue
|
||||
|
||||
file.write(chunk)
|
||||
downloaded += len(chunk)
|
||||
|
||||
if total <= 0:
|
||||
continue
|
||||
|
||||
progress = min(100, downloaded * 100 // total)
|
||||
if progress == 100 or progress >= last_progress + 2:
|
||||
notify(f"Downloading... {progress}%", progress, 0)
|
||||
last_progress = progress
|
||||
|
||||
replace(temporary, destination)
|
||||
except Exception:
|
||||
if exists(temporary):
|
||||
remove(temporary)
|
||||
raise
|
||||
finally:
|
||||
if response is not None:
|
||||
response.close()
|
||||
|
||||
|
||||
def prune(folder, keep=20):
|
||||
files = [
|
||||
(name, getmtime(f"{folder}/{name}"))
|
||||
for name in listdir(folder)
|
||||
if isfile(f"{folder}/{name}") and not name.endswith(".part")
|
||||
]
|
||||
|
||||
if len(files) <= keep:
|
||||
return
|
||||
|
||||
for name, _ in sorted(files, key=lambda item: item[1])[:len(files) - keep]:
|
||||
remove(f"{folder}/{name}")
|
||||
|
||||
|
||||
def read_history(path):
|
||||
try:
|
||||
with open(path) as file:
|
||||
return [line.strip() for line in file if line.strip()]
|
||||
except OSError:
|
||||
return []
|
||||
|
||||
|
||||
def write_history(path, ids):
|
||||
try:
|
||||
with open(path, "w") as file:
|
||||
file.write("\n".join(dict.fromkeys(ids)) + "\n")
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
folder = "${config.home.homeDirectory}/wallpapers"
|
||||
url = "https://wallhaven.cc/api/v1/collections/BlackRaven21/2284568"
|
||||
runtime = environ.get("XDG_RUNTIME_DIR") or f"/run/user/{getuid()}"
|
||||
history = f"{runtime}/wallpaper_changer_history"
|
||||
|
||||
token = None
|
||||
try:
|
||||
with open("${secretPath}") as file:
|
||||
token = file.read().strip() or None
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
filename = None
|
||||
notify("Updating wallpaper...", 0)
|
||||
|
||||
try:
|
||||
params = {}
|
||||
if token:
|
||||
params["apikey"] = token
|
||||
|
||||
response = requests.get(url, params=params, timeout=10)
|
||||
response.raise_for_status()
|
||||
page_json = response.json()
|
||||
|
||||
walls = list(page_json['data'])
|
||||
for page in range(2, page_json['meta']['last_page'] + 1):
|
||||
params['page'] = page
|
||||
response = requests.get(url, params=params, timeout=10)
|
||||
response.raise_for_status()
|
||||
walls.extend(response.json()['data'])
|
||||
|
||||
seen = read_history(history)
|
||||
candidates = [wall for wall in walls if wall['id'] not in seen]
|
||||
|
||||
if not candidates:
|
||||
seen = []
|
||||
candidates = walls
|
||||
|
||||
wallpaper = choice(candidates)
|
||||
link = wallpaper['path']
|
||||
format = wallpaper['file_type']
|
||||
id = wallpaper['id']
|
||||
|
||||
if format == "image/jpeg": ext = "jpg"
|
||||
else: ext = "png"
|
||||
|
||||
filename = f"{id}.{ext}"
|
||||
destination = f"{folder}/{filename}"
|
||||
|
||||
if not exists(destination):
|
||||
makedirs(folder, exist_ok=True)
|
||||
notify("Downloading... 0%", 0, 0)
|
||||
download_with_progress(link, destination)
|
||||
notify("Downloaded", 100)
|
||||
prune(folder)
|
||||
else:
|
||||
notify("Using cached wallpaper", 100)
|
||||
|
||||
write_history(history, seen + [id])
|
||||
|
||||
except requests.exceptions.RequestException:
|
||||
notify("Offline mode")
|
||||
try:
|
||||
filename = choice(listdir(folder))
|
||||
except (FileNotFoundError, IndexError):
|
||||
notify("Offline mode and wallpaper cache is empty")
|
||||
|
||||
finally:
|
||||
if filename is not None:
|
||||
notify("Applying wallpaper", 100)
|
||||
system(f"${lib.getExe pkgs.awww} img {folder}/{filename} --transition-type center")
|
||||
'';
|
||||
in {
|
||||
imports = [(
|
||||
import ../../../modules/user/hyprland.nix {
|
||||
inherit lib;
|
||||
inherit pkgs;
|
||||
inherit config;
|
||||
inherit inputs;
|
||||
swww_flags = "--transition-type center";
|
||||
inherit host;
|
||||
}
|
||||
)];
|
||||
|
||||
home.packages = [ wallpaper_changer ];
|
||||
|
||||
wayland.windowManager.hyprland = let
|
||||
colors = config.lib.stylix.colors;
|
||||
hyprLua = import ../../../modules/user/hyprland/lua.nix { inherit lib; };
|
||||
in {
|
||||
settings = {
|
||||
monitor = [
|
||||
"eDP-1, preferred, auto, 1"
|
||||
config = {
|
||||
general = {
|
||||
gaps_in = 5;
|
||||
gaps_out = 5;
|
||||
border_size = 2;
|
||||
"col.active_border" = lib.mkForce {
|
||||
colors = [
|
||||
"rgba(${colors.base0C}ee)"
|
||||
"rgba(${colors.base0B}ee)"
|
||||
];
|
||||
angle = 45;
|
||||
};
|
||||
"col.inactive_border" = lib.mkForce "rgba(${colors.base05}aa)";
|
||||
layout = "dwindle";
|
||||
};
|
||||
|
||||
decoration = {
|
||||
border_part_of_window = false;
|
||||
rounding = 10;
|
||||
blur = {
|
||||
enabled = true;
|
||||
size = 16;
|
||||
passes = 2;
|
||||
new_optimizations = true;
|
||||
};
|
||||
shadow = {
|
||||
enabled = true;
|
||||
range = 4;
|
||||
render_power = 3;
|
||||
};
|
||||
};
|
||||
|
||||
animations.enabled = true;
|
||||
dwindle.smart_split = true;
|
||||
master.new_status = "master";
|
||||
|
||||
misc = {
|
||||
focus_on_activate = true;
|
||||
animate_manual_resizes = true;
|
||||
animate_mouse_windowdragging = true;
|
||||
enable_swallow = true;
|
||||
};
|
||||
};
|
||||
|
||||
animation = [
|
||||
{ leaf = "windows"; enabled = true; speed = 7; bezier = "myBezier"; }
|
||||
{ leaf = "windowsOut"; enabled = true; speed = 7; bezier = "default"; style = "popin 80%"; }
|
||||
{ leaf = "border"; enabled = true; speed = 10; bezier = "default"; }
|
||||
{ leaf = "borderangle"; enabled = true; speed = 8; bezier = "default"; }
|
||||
{ leaf = "fade"; enabled = true; speed = 7; bezier = "default"; }
|
||||
{ leaf = "workspaces"; enabled = true; speed = 6; bezier = "default"; }
|
||||
];
|
||||
|
||||
general = {
|
||||
gaps_in = 5;
|
||||
gaps_out = 10;
|
||||
border_size = 3;
|
||||
"col.active_border" = lib.mkForce "rgba(${colors.base0C}ee) rgba(${colors.base0B}ee) 45deg";
|
||||
"col.inactive_border" = lib.mkForce "rgba(${colors.base05}aa)";
|
||||
|
||||
layout = "dwindle";
|
||||
};
|
||||
|
||||
decoration = {
|
||||
rounding = 10;
|
||||
|
||||
blur = {
|
||||
enabled = true;
|
||||
size = 16;
|
||||
passes = 2;
|
||||
new_optimizations = true;
|
||||
};
|
||||
|
||||
shadow = {
|
||||
enabled = true;
|
||||
range = 4;
|
||||
render_power = 3;
|
||||
};
|
||||
};
|
||||
|
||||
animations = {
|
||||
enabled = true;
|
||||
|
||||
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
|
||||
|
||||
animation = [
|
||||
"windows, 1, 7, myBezier"
|
||||
"windowsOut, 1, 7, default, popin 80%"
|
||||
"border, 1, 10, default"
|
||||
"borderangle, 1, 8, default"
|
||||
"fade, 1, 7, default"
|
||||
"workspaces, 1, 6, default"
|
||||
curve = {
|
||||
_args = [
|
||||
"myBezier"
|
||||
{
|
||||
type = "bezier";
|
||||
points = [
|
||||
[ 0.05 0.9 ]
|
||||
[ 0.1 1.05 ]
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
dwindle = {
|
||||
smart_split = true;
|
||||
};
|
||||
workspace_rule = [
|
||||
{
|
||||
workspace = "2";
|
||||
layout = "scrolling";
|
||||
}
|
||||
];
|
||||
|
||||
master.new_status = "master";
|
||||
|
||||
misc = {
|
||||
animate_manual_resizes = true;
|
||||
animate_mouse_windowdragging = true;
|
||||
enable_swallow = true;
|
||||
};
|
||||
on = [
|
||||
(hyprLua.onStart [ "${lib.getExe wallpaper_changer}" ])
|
||||
];
|
||||
|
||||
bind = [
|
||||
"$mainMod Shift, S, exec, ${lib.getExe pkgs.grimblast} --notify --freeze copy area"
|
||||
", F11, exec, ghostty -e sh -c hyprlock"
|
||||
(hyprLua.bind "SUPER + W" (hyprLua.exec "${lib.getExe wallpaper_changer}"))
|
||||
(hyprLua.bind "SUPER + SHIFT + S" (hyprLua.exec "${lib.getExe pkgs.grimblast} --notify --freeze copy area"))
|
||||
(hyprLua.bind "F11" (hyprLua.exec "ghostty -e sh -c hyprlock"))
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
'';
|
||||
};
|
||||
in {
|
||||
gtk.gtk4.theme = lib.mkForce config.gtk.theme;
|
||||
|
||||
stylix = {
|
||||
enable = true;
|
||||
overlays.enable = false;
|
||||
@@ -79,5 +77,18 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/interface".color-scheme = "prefer-dark";
|
||||
};
|
||||
|
||||
gtk = {
|
||||
gtk4.extraConfig = {
|
||||
gtk-application-prefer-dark-theme = true;
|
||||
};
|
||||
gtk3.extraConfig = {
|
||||
gtk-application-prefer-dark-theme = true;
|
||||
};
|
||||
};
|
||||
|
||||
xdg.configFile."helix/config.toml".text = ''theme = "catppuccin_mocha"'';
|
||||
}
|
||||
@@ -1,4 +1,173 @@
|
||||
{ osConfig, config, pkgs, lib, ... }: {
|
||||
{ osConfig, config, pkgs, lib, ... }: let
|
||||
c = config.lib.stylix.colors.withHashtag;
|
||||
|
||||
# ---- Left edge power bar (separate waybar instance) ----
|
||||
leftWidth = 50;
|
||||
|
||||
networkSpeed = pkgs.writeShellApplication {
|
||||
name = "network-speed";
|
||||
runtimeInputs = [ pkgs.coreutils pkgs.gawk pkgs.iproute2 ];
|
||||
text = ''
|
||||
set -euo pipefail
|
||||
state=/tmp/waybar-network-speed
|
||||
|
||||
iface=$(ip route show default | awk '{print $5; exit}')
|
||||
if [ -z "$iface" ]; then
|
||||
iface=$(awk 'NR > 2 && $1 != "lo:" { sub(":", "", $1); print $1; exit }' /proc/net/dev)
|
||||
fi
|
||||
[ -z "$iface" ] && exit 0
|
||||
|
||||
read -r rx tx < <(awk -v i="$iface" '$1 ~ i":" { print $2, $10 }' /proc/net/dev)
|
||||
if [ -f "$state" ]; then
|
||||
read -r prx ptx ts < "$state"
|
||||
now=$(date +%s)
|
||||
dt=$((now - ts)); [ "$dt" -lt 1 ] && dt=1
|
||||
down=$(((rx - prx) / dt)); [ "$down" -lt 0 ] && down=0
|
||||
up=$(((tx - ptx) / dt)); [ "$up" -lt 0 ] && up=0
|
||||
echo " $(numfmt --to=iec --suffix=B/s "$down") $(numfmt --to=iec --suffix=B/s "$up")"
|
||||
fi
|
||||
printf '%s %s %s\n' "$rx" "$tx" "$(date +%s)" > "$state"
|
||||
'';
|
||||
};
|
||||
|
||||
pinnedApps = [
|
||||
{ id = "browser"; icon = ""; command = "vivaldi"; }
|
||||
{ id = "telegram"; icon = ""; command = "AyuGram"; }
|
||||
{ id = "vpn"; icon = ""; command = "clash-verge"; }
|
||||
];
|
||||
|
||||
pinnedModules = lib.listToAttrs (map (a: lib.nameValuePair "custom/pin-${a.id}" {
|
||||
format = a.icon;
|
||||
on-click = a.command;
|
||||
tooltip = false;
|
||||
}) pinnedApps);
|
||||
|
||||
pinnedCss = lib.concatMapStringsSep "," (a: "#custom-pin-${a.id}") pinnedApps;
|
||||
pinnedCssHover = lib.concatMapStringsSep "," (a: "#custom-pin-${a.id}:hover") pinnedApps;
|
||||
|
||||
leftbarJson = {
|
||||
collapsed = pkgs.writeText "leftbar-collapsed.json" (builtins.toJSON {
|
||||
layer = "top";
|
||||
exclusive = false;
|
||||
position = "left";
|
||||
width = 1;
|
||||
spacing = 0;
|
||||
modules-left = [ "custom/hidden" ];
|
||||
modules-center = [ ];
|
||||
modules-right = [ ];
|
||||
"custom/hidden" = {
|
||||
format = "";
|
||||
};
|
||||
});
|
||||
|
||||
expanded = pkgs.writeText "leftbar-expanded.json" (builtins.toJSON ({
|
||||
layer = "top";
|
||||
exclusive = false;
|
||||
position = "left";
|
||||
width = leftWidth;
|
||||
spacing = 0;
|
||||
modules-left = [ "custom/network-speed" ];
|
||||
modules-center = map (a: "custom/pin-${a.id}") pinnedApps;
|
||||
modules-right = [ "disk" ];
|
||||
"custom/network-speed" = {
|
||||
exec = "${lib.getExe networkSpeed}";
|
||||
interval = 2;
|
||||
rotate = 90;
|
||||
tooltip = false;
|
||||
};
|
||||
disk = {
|
||||
interval = 30;
|
||||
rotate = 90;
|
||||
format = "{used}/{free}";
|
||||
paths = [ "/" ];
|
||||
};
|
||||
} // pinnedModules));
|
||||
};
|
||||
|
||||
leftbarCss = {
|
||||
collapsed = pkgs.writeText "leftbar-collapsed.css" ''
|
||||
window#waybar {
|
||||
background: ${c.base0B};
|
||||
min-width: 1px;
|
||||
}
|
||||
'';
|
||||
|
||||
expanded = pkgs.writeText "leftbar-expanded.css" ''
|
||||
window#waybar {
|
||||
background: transparent;
|
||||
min-width: ${toString leftWidth}px;
|
||||
font-family: "Symbols Nerd Font Mono", "Monocraft", "Font Awesome 7 Free";
|
||||
font-weight: bold;
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
#custom-network-speed,
|
||||
#disk {
|
||||
background: ${c.base00};
|
||||
color: ${c.base05};
|
||||
border-radius: 6px;
|
||||
min-height: 34px;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
#custom-network-speed:hover,
|
||||
#disk:hover {
|
||||
background: ${c.base0B};
|
||||
color: ${c.base00};
|
||||
}
|
||||
|
||||
${pinnedCss} {
|
||||
background: ${c.base00};
|
||||
color: ${c.base04};
|
||||
border-radius: 6px;
|
||||
min-height: 34px;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
${pinnedCssHover} {
|
||||
background: ${c.base01};
|
||||
color: ${c.base0B};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
leftbarHover = pkgs.writeShellApplication {
|
||||
name = "leftbar-hover";
|
||||
runtimeInputs = [ pkgs.coreutils pkgs.systemd pkgs.findutils ];
|
||||
text = ''
|
||||
set -euo pipefail
|
||||
hyprctl="${(config.wayland.windowManager.hyprland.package or pkgs.hyprland)}/bin/hyprctl"
|
||||
rt="''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
|
||||
json="$rt/leftbar.json"
|
||||
css="$rt/leftbar.css"
|
||||
state=collapsed
|
||||
|
||||
cp -f "${leftbarJson.collapsed}" "$json"
|
||||
cp -f "${leftbarCss.collapsed}" "$css"
|
||||
|
||||
while true; do
|
||||
sig=$(basename "$(find "$rt/hypr" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | head -1)")
|
||||
[ -n "$sig" ] && export HYPRLAND_INSTANCE_SIGNATURE="$sig"
|
||||
pos="$(${pkgs.coreutils}/bin/timeout 1 "$hyprctl" cursorpos 2>/dev/null)" || pos=""
|
||||
x="''${pos%%,*}"
|
||||
if [ -n "$x" ]; then
|
||||
if [ "$state" != expanded ] && [ "$x" -ge 0 ] && [ "$x" -le 1 ]; then
|
||||
state=expanded
|
||||
cp -f "${leftbarJson.expanded}" "$json"
|
||||
cp -f "${leftbarCss.expanded}" "$css"
|
||||
systemctl --user restart waybar-left || true
|
||||
elif [ "$state" != collapsed ] && [ "$x" -gt ${toString leftWidth} ]; then
|
||||
state=collapsed
|
||||
cp -f "${leftbarJson.collapsed}" "$json"
|
||||
cp -f "${leftbarCss.collapsed}" "$css"
|
||||
systemctl --user restart waybar-left || true
|
||||
fi
|
||||
fi
|
||||
sleep 0.05
|
||||
done
|
||||
'';
|
||||
};
|
||||
in {
|
||||
home.packages = with pkgs; [
|
||||
#Fonts
|
||||
font-awesome
|
||||
@@ -323,4 +492,36 @@
|
||||
in builtins.readFile cssFile;
|
||||
};
|
||||
|
||||
# Left edge bar: own waybar instance with its own config/style,
|
||||
# toggled between 1px accent strip and 8px button bar by the hover daemon.
|
||||
xdg.configFile."waybar/leftbar-collapsed.json".source = leftbarJson.collapsed;
|
||||
xdg.configFile."waybar/leftbar-expanded.json".source = leftbarJson.expanded;
|
||||
xdg.configFile."waybar/leftbar-collapsed.css".source = leftbarCss.collapsed;
|
||||
xdg.configFile."waybar/leftbar-expanded.css".source = leftbarCss.expanded;
|
||||
|
||||
systemd.user.services.waybar-left = {
|
||||
Unit = {
|
||||
Description = "Waybar left edge bar";
|
||||
After = [ "waybar-left-hover.service" ];
|
||||
Wants = [ "waybar-left-hover.service" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${lib.getExe pkgs.waybar} -c %t/leftbar.json -s %t/leftbar.css";
|
||||
KillMode = "process";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 2;
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
systemd.user.services.waybar-left-hover = {
|
||||
Unit.Description = "Waybar left edge bar hover daemon";
|
||||
Service = {
|
||||
ExecStart = "${lib.getExe leftbarHover}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 2;
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
tokens:
|
||||
apis:
|
||||
wallhaven: ENC[AES256_GCM,data:yO+thw4xgpMBuNx2LyxguDxAzoKSeDCyAAOcgtTxx74=,iv:j3LGKXnmykTamSuuIFbACT0kRDFazOhNEgWtVoxiWK4=,tag:jLaJrcUmDuxVj1D65NZhyg==,type:str]
|
||||
wakapi: ENC[AES256_GCM,data:B4BOqy6TyZj4qPB9H7Ne+XaW701tX+ho8dMn0EGvqzdVOKq+,iv:/P6KZV9KgIBXslB3yZD5G3XER279iJ6/R2n+ZdTaBLs=,tag:r/SDXjofl8DdDlzP9Xo5mQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1MXcwbkFxZ2R4V0ppOGo3
|
||||
UmFsTTJGekQ0NGVtTFpCRm50ekxJcEZUUW1FCkF5aStVckVNaVJndmptdnhtNjgx
|
||||
Z056TVF5ZVRuMWJZKzk1WlRZTXN3bjAKLS0tIEhHd1JyTkhIdjJuZVZtSFlTRXIy
|
||||
cTRWRkZXUmcrcHRXU2pyTzh1OGhaSkkKiqYLrPm1zS0PfrIeUnZHXvvHcY15PxDS
|
||||
01jUzubGavkuOXb0hJmr6oBkEkSMBW+GLewduqj0SxGF2yxTSkM0kQ==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1tx6jdr6535xxeygpwkkgvdwc24tulr420cm7gk56xzfp0slzeqks2nwpyg
|
||||
lastmodified: "2026-10-21T17:46:52Z"
|
||||
mac: ENC[AES256_GCM,data:mLdD78pb0Qf30+l/igb+jXMHxNXTXJPNtsi3cGeEgYLKxnx02OVBuOnncMZvN351yh7h5if9pCqwCJeOISWU8uFZrQdJeDjdmIPlP1eqzBQ7fK4fhEeRzAcn4dTQ5tcmu3uXmWElKcBYhMFEPr3/etyfDcX5ZFwOra8wUqU8nq4=,iv:TydKNjO5stupovtCF/rHMtr1Da2IFafMZiLQxsln1uA=,tag:kXl5eELy9I5APJkAQ8tk3w==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.13.3
|
||||
Reference in new issue
Block a user