diff --git a/flake.lock b/flake.lock index 6477864..14b0e6f 100755 --- a/flake.lock +++ b/flake.lock @@ -41,11 +41,11 @@ ] }, "locked": { - "lastModified": 1767024902, - "narHash": "sha256-sMdk6QkMDhIOnvULXKUM8WW8iyi551SWw2i6KQHbrrU=", + "lastModified": 1769428758, + "narHash": "sha256-0G/GzF7lkWs/yl82bXuisSqPn6sf8YGTnbEdFOXvOfU=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "b8a0c5ba5a9fbd2c660be7dd98bdde0ff3798556", + "rev": "def5e74c97370f15949a67c62e61f1459fcb0e15", "type": "github" }, "original": { @@ -178,11 +178,11 @@ ] }, "locked": { - "lastModified": 1768655473, - "narHash": "sha256-iWnILPS2mP9ubbjRAhNv6Fqg1J/upxmD9OQTZQR4O2w=", + "lastModified": 1769740633, + "narHash": "sha256-W4gMgX8RsDeJioRPQHhUgXD/TxqAQxdZjkhjHRX70Pk=", "owner": "caelestia-dots", "repo": "cli", - "rev": "7de6c6063119a7cef27c6bd4c88f2c5ac4cbc064", + "rev": "90fc2a981e587d38edc5a899011eca7979ecf124", "type": "github" }, "original": { @@ -200,11 +200,11 @@ "quickshell": "quickshell" }, "locked": { - "lastModified": 1769073714, - "narHash": "sha256-vppHLOKWw3ygroSlQ2oZ/evNIeXrBDl7cOPOyXZAh90=", + "lastModified": 1770122420, + "narHash": "sha256-SWFov0EDEZIjFMMNKiwOpTIsbiKO4jE7LSO7L2Bv3zE=", "owner": "caelestia-dots", "repo": "shell", - "rev": "617f7a19f335be9e975dd001e262794636a6716f", + "rev": "4c72e3e06bd58a31e16cc1588d94543069fbd00a", "type": "github" }, "original": { @@ -250,11 +250,11 @@ ] }, "locked": { - "lastModified": 1768923567, - "narHash": "sha256-GVJ0jKsyXLuBzRMXCDY6D5J8wVdwP1DuQmmvYL/Vw/Q=", + "lastModified": 1769524058, + "narHash": "sha256-zygdD6X1PcVNR2PsyK4ptzrVEiAdbMqLos7utrMDEWE=", "owner": "nix-community", "repo": "disko", - "rev": "00395d188e3594a1507f214a2f15d4ce5c07cb28", + "rev": "71a3fc97d80881e91710fe721f1158d3b96ae14d", "type": "github" }, "original": { @@ -430,17 +430,14 @@ }, "flake-parts_2": { "inputs": { - "nixpkgs-lib": [ - "neovim-nightly-overlay", - "nixpkgs" - ] + "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1768135262, - "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", + "lastModified": 1749398372, + "narHash": "sha256-tYBdgS56eXYaWVW3fsnPQ/nFlgWi/Z2Ymhyu21zVM98=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", + "rev": "9305fe4e5c2a6fcf5ba6a3ff155720fbe4076569", "type": "github" }, "original": { @@ -451,7 +448,28 @@ }, "flake-parts_3": { "inputs": { - "nixpkgs-lib": "nixpkgs-lib" + "nixpkgs-lib": [ + "neovim-nightly-overlay", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_4": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" }, "locked": { "lastModified": 1733312601, @@ -467,7 +485,7 @@ "type": "github" } }, - "flake-parts_4": { + "flake-parts_5": { "inputs": { "nixpkgs-lib": [ "nvf", @@ -488,7 +506,7 @@ "type": "github" } }, - "flake-parts_5": { + "flake-parts_6": { "inputs": { "nixpkgs-lib": [ "stylix", @@ -600,24 +618,6 @@ } }, "flake-utils_5": { - "inputs": { - "systems": "systems_6" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_6": { "inputs": { "systems": "systems_7" }, @@ -635,7 +635,7 @@ "type": "github" } }, - "flake-utils_7": { + "flake-utils_6": { "inputs": { "systems": "systems_11" }, @@ -679,11 +679,11 @@ "zon2nix": "zon2nix" }, "locked": { - "lastModified": 1769140056, - "narHash": "sha256-EaC2VOH6BzzzeOFXor9BbesOGgJsCCHw5Nx+BG0IZY4=", + "lastModified": 1770091344, + "narHash": "sha256-tKS5jzMfcWJjzq1Rm2QVUohzHEG/1VOM57aH6RQ5ALk=", "owner": "ghostty-org", "repo": "ghostty", - "rev": "4acd33954aaeafd414f483ae9c44ba1ae7effe98", + "rev": "51897c0cd51fee61fff824d616fb2901ac41e817", "type": "github" }, "original": { @@ -699,11 +699,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1769069492, - "narHash": "sha256-Efs3VUPelRduf3PpfPP2ovEB4CXT7vHf8W+xc49RL/U=", + "lastModified": 1769939035, + "narHash": "sha256-Fok2AmefgVA0+eprw2NDwqKkPGEI5wvR+twiZagBvrg=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "a1ef738813b15cf8ec759bdff5761b027e3e1d23", + "rev": "a8ca480175326551d6c4121498316261cbb5b260", "type": "github" }, "original": { @@ -824,11 +824,11 @@ ] }, "locked": { - "lastModified": 1769132734, - "narHash": "sha256-gmU9cRplrQWqoback9PgQX7Dlsdx8JlhlVZwf0q1F7E=", + "lastModified": 1770164260, + "narHash": "sha256-mQgOAYWlVJyuyXjZN6yxqXWyODvQI5P/UZUCU7IOuYo=", "owner": "nix-community", "repo": "home-manager", - "rev": "d055b309a6277343cb1033a11d7500f0a0f669fc", + "rev": "4fda26500b4539e0a1e3afba9f0e1616bdad4f85", "type": "github" }, "original": { @@ -882,11 +882,11 @@ ] }, "locked": { - "lastModified": 1766946335, - "narHash": "sha256-MRD+Jr2bY11MzNDfenENhiK6pvN+nHygxdHoHbZ1HtE=", + "lastModified": 1769284023, + "narHash": "sha256-xG34vwYJ79rA2wVC8KFuM8r36urJTG6/csXx7LiiSYU=", "owner": "hyprwm", "repo": "hyprgraphics", - "rev": "4af02a3925b454deb1c36603843da528b67ded6c", + "rev": "13c536659d46893596412d180449353a900a1d31", "type": "github" }, "original": { @@ -912,11 +912,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1769114016, - "narHash": "sha256-eYY8QyE+RY7sa69DZmdbfN2DFfyx3Jk9k/gALAKXi38=", + "lastModified": 1770164868, + "narHash": "sha256-sPyea7oYf5h420tdvkrwn0Z1uxfZdqhpuGrEVcdC7q8=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "64db62d7e2685d62cbab51a1a7cb7f2cf38a1b32", + "rev": "1bc857b12c434b7255119de009a50237856a90b2", "type": "github" }, "original": { @@ -988,11 +988,11 @@ ] }, "locked": { - "lastModified": 1767723101, - "narHash": "sha256-jObY8O7OI+91hoE137APsDxm0235/Yx+HhFIip187zM=", + "lastModified": 1769285097, + "narHash": "sha256-eVD4U3Oqzz0VU9ylJ5wo76xDcYKv2CpiiRXq4Is4QdA=", "owner": "hyprwm", "repo": "hyprland-plugins", - "rev": "fef398ed5e4faf59bc43b915e46a75cfe8b16697", + "rev": "06c0749a0dac978d89b1a76ae6adc76a3c15dbfa", "type": "github" }, "original": { @@ -1042,11 +1042,11 @@ ] }, "locked": { - "lastModified": 1764612430, - "narHash": "sha256-54ltTSbI6W+qYGMchAgCR6QnC1kOdKXN6X6pJhOWxFg=", + "lastModified": 1767983607, + "narHash": "sha256-8C2co8NYfR4oMOUEsPROOJ9JHrv9/ktbJJ6X1WsTbXc=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "0d00dc118981531aa731150b6ea551ef037acddd", + "rev": "d4037379e6057246b408bbcf796cf3e9838af5b2", "type": "github" }, "original": { @@ -1173,11 +1173,11 @@ ] }, "locked": { - "lastModified": 1767473322, - "narHash": "sha256-RGOeG+wQHeJ6BKcsSB8r0ZU77g9mDvoQzoTKj2dFHwA=", + "lastModified": 1769202094, + "narHash": "sha256-gdJr/vWWLRW85ucatSjoBULPB2dqBJd/53CZmQ9t91Q=", "owner": "hyprwm", "repo": "hyprwire", - "rev": "d5e7d6b49fe780353c1cf9a1cf39fa8970bd9d11", + "rev": "a45ca05050d22629b3c7969a926d37870d7dd75c", "type": "github" }, "original": { @@ -1251,6 +1251,28 @@ "type": "github" } }, + "mango": { + "inputs": { + "flake-parts": "flake-parts_2", + "nixpkgs": [ + "nixpkgs" + ], + "scenefx": "scenefx" + }, + "locked": { + "lastModified": 1770169526, + "narHash": "sha256-GYe2+1AT3lGAXPjcd0BDZ+AclFK+Z6NiGJ2F4rM2rLc=", + "owner": "DreamMaoMao", + "repo": "mango", + "rev": "8ba259fbb7737e4cef29ca20c731ed0a93e4017d", + "type": "github" + }, + "original": { + "owner": "DreamMaoMao", + "repo": "mango", + "type": "github" + } + }, "marks-nvim": { "flake": false, "locked": { @@ -1275,11 +1297,11 @@ "spectrum": "spectrum" }, "locked": { - "lastModified": 1768682386, - "narHash": "sha256-mKrMf7eG9TM2AM3pTuhIiCGmZ/JwDegCQH3ThVqcTuc=", + "lastModified": 1770074118, + "narHash": "sha256-3JFYOqJGLgn5QsEnBwOm6K+vFX3uckiiyVt3b9VT5h0=", "owner": "microvm-nix", "repo": "microvm.nix", - "rev": "f469c1dfede623bbbf1ac605f6359316fd4002ef", + "rev": "4f7e75d2be8a4c99778275ad3b3e4421029dcde0", "type": "github" }, "original": { @@ -1290,11 +1312,11 @@ }, "mnw": { "locked": { - "lastModified": 1768701608, - "narHash": "sha256-kSvWF3Xt2HW9hmV5V7i8PqeWJIBUKmuKoHhOgj3Znzs=", + "lastModified": 1769981889, + "narHash": "sha256-ndI7AxL/6auelkLHngdUGVImBiHkG8w2N2fOTKZKn4k=", "owner": "Gerg-L", "repo": "mnw", - "rev": "20d63a8a1ae400557c770052a46a9840e768926b", + "rev": "332fed8f43b77149c582f1782683d6aeee1f07cf", "type": "github" }, "original": { @@ -1327,16 +1349,16 @@ }, "neovim-nightly-overlay": { "inputs": { - "flake-parts": "flake-parts_2", + "flake-parts": "flake-parts_3", "neovim-src": "neovim-src", "nixpkgs": "nixpkgs_5" }, "locked": { - "lastModified": 1769126721, - "narHash": "sha256-vMWf9C4LK2fshCKgUYGR0fn4/3qg2/sWyFILv4YYTB8=", + "lastModified": 1770163968, + "narHash": "sha256-Ggh7hAS0tAOcPF66rrho9WAFZQZE0+SZYs+dnLgidpw=", "owner": "nix-community", "repo": "neovim-nightly-overlay", - "rev": "7c77dcce004c0845da25e0fe9a6c8b11bd46e614", + "rev": "4ae5c0c99f5e7fe02f0df0220a7d09b1945df646", "type": "github" }, "original": { @@ -1348,11 +1370,11 @@ "neovim-src": { "flake": false, "locked": { - "lastModified": 1769125444, - "narHash": "sha256-KOVSBncEUsn5ZqbkaDo5GhXWCoKqdZGij/KnLH5CoVI=", + "lastModified": 1770163048, + "narHash": "sha256-MEaHWrzF6PqjyQH8+m84dhVr8R4lDYc3V+XW194O4no=", "owner": "neovim", "repo": "neovim", - "rev": "c39d18ee939cba5f905416fcc97661b1836f4de4", + "rev": "ddd1bf757fab3615301053acab5cc85508340844", "type": "github" }, "original": { @@ -1373,11 +1395,11 @@ "xwayland-satellite-unstable": "xwayland-satellite-unstable" }, "locked": { - "lastModified": 1769095293, - "narHash": "sha256-GPlRdJ7LVLyabpJ2tDA9Bj5em9wi3mKXeedIDl7+LWs=", + "lastModified": 1770169657, + "narHash": "sha256-wiWbmO2xUoqh5DuSBYVLGOICo9AOcYq9mNPsvCtL7SM=", "owner": "sodiboo", "repo": "niri-flake", - "rev": "180bdbbc91c89f540a52d2b31c8c08116c53b91f", + "rev": "4c962a3fd37ef268337ed113cbffabfd1fe3ca5c", "type": "github" }, "original": { @@ -1429,11 +1451,11 @@ "niri-unstable": { "flake": false, "locked": { - "lastModified": 1768678265, - "narHash": "sha256-Ub8eed4DsfIDWyg30xEe+8bSxL/z5Af/gCjmvJ0V/Hs=", + "lastModified": 1770092965, + "narHash": "sha256-++K1ftjwPqMJzIO8t2GsdkYQzC2LLA5A1w21Uo+SLz4=", "owner": "YaLTeR", "repo": "niri", - "rev": "d7184a04b904e07113f4623610775ae78d32394c", + "rev": "189917c93329c86ac2ddd89f459c26a028d590ba", "type": "github" }, "original": { @@ -1486,17 +1508,17 @@ "nix-minecraft": { "inputs": { "flake-compat": "flake-compat_7", - "flake-utils": "flake-utils_5", "nixpkgs": [ "nixpkgs" - ] + ], + "systems": "systems_6" }, "locked": { - "lastModified": 1768962252, - "narHash": "sha256-HyWOOHcySV8rl36gs4+n0sxPinxpwWOgwXibfFPYeZ0=", + "lastModified": 1770172907, + "narHash": "sha256-rqYl9B+4shcM5b6OYjT+qdsdQNJ7SY64/xcPIb96NzU=", "owner": "Infinidoge", "repo": "nix-minecraft", - "rev": "433cf697394104123e1fd02fa689534ac1733bfa", + "rev": "8958a5a4259e1aebf4916823bf463faaf2538566", "type": "github" }, "original": { @@ -1507,15 +1529,15 @@ }, "nix-search-tv": { "inputs": { - "flake-utils": "flake-utils_6", + "flake-utils": "flake-utils_5", "nixpkgs": "nixpkgs_6" }, "locked": { - "lastModified": 1767922902, - "narHash": "sha256-ygA9AF4PrM+4G+Le70UI12OQPIjLmELg3Xpkmc7nMz0=", + "lastModified": 1770174568, + "narHash": "sha256-CuNnGNo2ON3LsBc4CAcE0znKKKRosGjdCetDsycmJRI=", "owner": "3timeslazy", "repo": "nix-search-tv", - "rev": "b21e232cb81320ee6225fea857ebcf33ebd19079", + "rev": "e1f74da24e3aded600d69d44ed39bbcf9ab83cd3", "type": "github" }, "original": { @@ -1546,7 +1568,7 @@ }, "nixd": { "inputs": { - "flake-parts": "flake-parts_3", + "flake-parts": "flake-parts_4", "flake-root": "flake-root", "nixpkgs": [ "nixpkgs" @@ -1554,11 +1576,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1768402933, - "narHash": "sha256-iNjr5pE5SvawTT3byEIU65FzWTMMjVfRhPXa2m818jM=", + "lastModified": 1769607914, + "narHash": "sha256-3eYf0yyS8yyXuzrIfbqDwpXZ+3z3TwHGFgbl1+/35DU=", "owner": "nix-community", "repo": "nixd", - "rev": "13a89b59d0711390f0c765e693509f8282a1ff7e", + "rev": "12e3e96245e81fbcaf1f0bad5079403b57c00e67", "type": "github" }, "original": { @@ -1584,6 +1606,21 @@ } }, "nixpkgs-lib": { + "locked": { + "lastModified": 1748740939, + "narHash": "sha256-rQaysilft1aVMwF14xIdGS3sj1yHlI6oKQNBRTF40cc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "656a64127e9d791a334452c6b6606d17539476e2", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_2": { "locked": { "lastModified": 1733096140, "narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=", @@ -1613,11 +1650,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1768940263, - "narHash": "sha256-sJERJIYTKPFXkoz/gBaBtRKke82h4DkX3BBSsKbfbvI=", + "lastModified": 1770136044, + "narHash": "sha256-tlFqNG/uzz2++aAmn4v8J0vAkV3z7XngeIIB3rM3650=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3ceaaa8bc963ced4d830e06ea2d0863b6490ff03", + "rev": "e576e3c9cf9bad747afcddd9e34f51d18c855b4e", "type": "github" }, "original": { @@ -1658,11 +1695,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1767379071, - "narHash": "sha256-EgE0pxsrW9jp9YFMkHL9JMXxcqi/OoumPJYwf+Okucw=", + "lastModified": 1769461804, + "narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "fb7944c166a3b630f177938e478f0378e64ce108", + "rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d", "type": "github" }, "original": { @@ -1674,11 +1711,11 @@ }, "nixpkgs_5": { "locked": { - "lastModified": 1768875095, - "narHash": "sha256-dYP3DjiL7oIiiq3H65tGIXXIT1Waiadmv93JS0sS+8A=", + "lastModified": 1770141374, + "narHash": "sha256-yD4K/vRHPwXbJf5CK3JkptBA6nFWUKNX/jlFp2eKEQc=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ed142ab1b3a092c4d149245d0c4126a5d7ea00b0", + "rev": "41965737c1797c1d83cfb0b644ed0840a6220bd1", "type": "github" }, "original": { @@ -1706,11 +1743,11 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1768875095, - "narHash": "sha256-dYP3DjiL7oIiiq3H65tGIXXIT1Waiadmv93JS0sS+8A=", + "lastModified": 1770141374, + "narHash": "sha256-yD4K/vRHPwXbJf5CK3JkptBA6nFWUKNX/jlFp2eKEQc=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ed142ab1b3a092c4d149245d0c4126a5d7ea00b0", + "rev": "41965737c1797c1d83cfb0b644ed0840a6220bd1", "type": "github" }, "original": { @@ -1722,11 +1759,11 @@ }, "nixpkgs_8": { "locked": { - "lastModified": 1768569498, - "narHash": "sha256-bB6Nt99Cj8Nu5nIUq0GLmpiErIT5KFshMQJGMZwgqUo=", + "lastModified": 1769740369, + "narHash": "sha256-xKPyJoMoXfXpDM5DFDZDsi9PHArf2k5BJjvReYXoFpM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "be5afa0fcb31f0a96bf9ecba05a516c66fcd8114", + "rev": "6308c3b21396534d8aaeac46179c14c439a89b8a", "type": "github" }, "original": { @@ -1759,11 +1796,11 @@ ] }, "locked": { - "lastModified": 1769145612, - "narHash": "sha256-uHtKorr5FamlD/WXSs7gJYYcsO9EGlVJhY/V4n4HmW4=", + "lastModified": 1770175191, + "narHash": "sha256-ge90SW/drqKfAFgnIedXJ0tn+5adDWL3ddDyGlnjH5E=", "owner": "noctalia-dev", "repo": "noctalia-shell", - "rev": "e4729d9b92346f86eeaccc6063506684575ea9ea", + "rev": "787aab1f0a6bf282fbba92816e06bdf62226a179", "type": "github" }, "original": { @@ -1800,7 +1837,7 @@ "nvf": { "inputs": { "flake-compat": "flake-compat_8", - "flake-parts": "flake-parts_4", + "flake-parts": "flake-parts_5", "mnw": "mnw", "ndg": "ndg", "nixpkgs": [ @@ -1809,11 +1846,11 @@ "systems": "systems_8" }, "locked": { - "lastModified": 1769111313, - "narHash": "sha256-2IU9TOe7BBG145mftfQW2aYxXxQd2YHfv8V1qTMFkmY=", + "lastModified": 1770130359, + "narHash": "sha256-IfoT9oaeIE6XjXprMORG2qZFzGGZ0v6wJcOlQRdlpvY=", "owner": "notashelf", "repo": "nvf", - "rev": "bebdddb5719ec2c3f86b0168a785d1a2aee1d857", + "rev": "92854bd0eaaa06914afba345741c372439b8e335", "type": "github" }, "original": { @@ -1855,11 +1892,11 @@ ] }, "locked": { - "lastModified": 1767281941, - "narHash": "sha256-6MkqajPICgugsuZ92OMoQcgSHnD6sJHwk8AxvMcIgTE=", + "lastModified": 1769069492, + "narHash": "sha256-Efs3VUPelRduf3PpfPP2ovEB4CXT7vHf8W+xc49RL/U=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "f0927703b7b1c8d97511c4116eb9b4ec6645a0fa", + "rev": "a1ef738813b15cf8ec759bdff5761b027e3e1d23", "type": "github" }, "original": { @@ -1876,11 +1913,11 @@ ] }, "locked": { - "lastModified": 1768689040, - "narHash": "sha256-Tlnr5BulJcMers/cb+YvmBQW4nKHjdKo9loInJkyO2k=", + "lastModified": 1769593411, + "narHash": "sha256-WW00FaBiUmQyxvSbefvgxIjwf/WmRrEGBbwMHvW/7uQ=", "ref": "refs/heads/master", - "rev": "7a427ce1979ce7447e885c4f30129b40f3d466f5", - "revCount": 729, + "rev": "1e4d804e7f3fa7465811030e8da2bf10d544426a", + "revCount": 732, "type": "git", "url": "https://git.outfoxxed.me/outfoxxed/quickshell" }, @@ -1904,6 +1941,7 @@ "lanzaboote": "lanzaboote", "mail-ntfy-server": "mail-ntfy-server", "mail-server": "mail-server", + "mango": "mango", "marks-nvim": "marks-nvim", "microvm": "microvm", "neovim-nightly-overlay": "neovim-nightly-overlay", @@ -1974,11 +2012,11 @@ ] }, "locked": { - "lastModified": 1769136478, - "narHash": "sha256-8UNd5lmGf8phCr/aKxagJ4kNsF0pCHLish2G4ZKCFFY=", + "lastModified": 1770174315, + "narHash": "sha256-GUaMxDmJB1UULsIYpHtfblskVC6zymAaQ/Zqfo+13jc=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "470ee44393bb19887056b557ea2c03fc5230bd5a", + "rev": "095c394bb91342882f27f6c73f64064fb9de9f2a", "type": "github" }, "original": { @@ -2008,16 +2046,37 @@ "type": "github" } }, + "scenefx": { + "inputs": { + "nixpkgs": [ + "mango", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1750785057, + "narHash": "sha256-tGX6j4W91rcb+glXJo43sjPI9zQvPotonknG1BdihR4=", + "owner": "wlrfx", + "repo": "scenefx", + "rev": "3a6cfb12e4ba97b43326357d14f7b3e40897adfc", + "type": "github" + }, + "original": { + "owner": "wlrfx", + "repo": "scenefx", + "type": "github" + } + }, "sops-nix": { "inputs": { "nixpkgs": "nixpkgs_8" }, "locked": { - "lastModified": 1768863606, - "narHash": "sha256-1IHAeS8WtBiEo5XiyJBHOXMzECD6aaIOJmpQKzRRl64=", + "lastModified": 1770145881, + "narHash": "sha256-ktjWTq+D5MTXQcL9N6cDZXUf9kX8JBLLBLT0ZyOTSYY=", "owner": "Mic92", "repo": "sops-nix", - "rev": "c7067be8db2c09ab1884de67ef6c4f693973f4a2", + "rev": "17eea6f3816ba6568b8c81db8a4e6ca438b30b7c", "type": "github" }, "original": { @@ -2049,7 +2108,7 @@ "base16-helix": "base16-helix", "base16-vim": "base16-vim", "firefox-gnome-theme": "firefox-gnome-theme", - "flake-parts": "flake-parts_5", + "flake-parts": "flake-parts_6", "gnome-shell": "gnome-shell", "nixpkgs": [ "nixpkgs" @@ -2063,11 +2122,11 @@ "tinted-zed": "tinted-zed" }, "locked": { - "lastModified": 1768744881, - "narHash": "sha256-3+h7OxqfrPIB/tRsiZXWE9sCbTm7NQN5Ie428p+S6BA=", + "lastModified": 1769978605, + "narHash": "sha256-Vjniae6HHJCb9xZLeUOP15aRQXSZuKeeaZFM+gRDCgo=", "owner": "nix-community", "repo": "stylix", - "rev": "06684f00cfbee14da96fd4307b966884de272d3a", + "rev": "ce22070ec5ce6169a6841da31baea33ce930ed38", "type": "github" }, "original": { @@ -2403,11 +2462,11 @@ "xwayland-satellite-unstable": { "flake": false, "locked": { - "lastModified": 1768765571, - "narHash": "sha256-C1JbyJ3ftogmN3vmLNfyPtnJw2wY64TiUTIhFtk1Leg=", + "lastModified": 1770167989, + "narHash": "sha256-rE2WTxKHe3KMG/Zr5YUNeKHkZfWwSFl7yJXrOKnunHg=", "owner": "Supreeeme", "repo": "xwayland-satellite", - "rev": "ed1cef792b4def3321ff9ab5479df09609f17a69", + "rev": "0947c4685f6237d4f8045482ce0c62feab40b6c4", "type": "github" }, "original": { @@ -2418,16 +2477,16 @@ }, "yazi": { "inputs": { - "flake-utils": "flake-utils_7", + "flake-utils": "flake-utils_6", "nixpkgs": "nixpkgs_9", "rust-overlay": "rust-overlay_4" }, "locked": { - "lastModified": 1769095881, - "narHash": "sha256-BZktPXn+8vyFyHapvW+9nepFsWRW/XBtdBcnLKrCNCw=", + "lastModified": 1769971982, + "narHash": "sha256-dc8lG9CxtrIk+tOsQx8TJKULQBG27Hoio4O4M/6CxFM=", "owner": "sxyazi", "repo": "yazi", - "rev": "4e0acf8cbfcd66924af38a9418d3e12dc31a7316", + "rev": "6757fed5aa82bfdcd5ecd52e8f374dc286220cc0", "type": "github" }, "original": { @@ -2446,11 +2505,11 @@ ] }, "locked": { - "lastModified": 1769059766, - "narHash": "sha256-u95Qe60mF3eoEqrd0tIej4A8TDWoc/N4ZjZ60npplgw=", + "lastModified": 1770097899, + "narHash": "sha256-FKRpvwWR96VDW4bdsxIrZgIAXvdXqsCTaV1HghCJBoQ=", "owner": "0xc000022070", "repo": "zen-browser-flake", - "rev": "dc0483a6e3ff1ffb04ad77d26c1a4458f4cf82d6", + "rev": "615a27db86f3fddd0f096b5e9ea832795a4608d1", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 7b3d88e..2b7dd0c 100755 --- a/flake.nix +++ b/flake.nix @@ -146,6 +146,11 @@ url = "github:noctalia-dev/noctalia-shell"; inputs.nixpkgs.follows = "nixpkgs"; }; + + mango = { + url = "github:DreamMaoMao/mango"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = @@ -231,6 +236,7 @@ inputs.attic.nixosModules.atticd inputs.mail-server.nixosModules.default inputs.niri.nixosModules.niri + inputs.mango.nixosModules.mango inputs.lanzaboote.nixosModules.lanzaboote ./options diff --git a/home/options/default.nix b/home/options/default.nix index 5c8bad0..1019229 100755 --- a/home/options/default.nix +++ b/home/options/default.nix @@ -4,5 +4,6 @@ ./hyprlock.nix ./sunsetr.nix ./noctalia.nix + ./wm.nix ]; } diff --git a/home/options/wm.nix b/home/options/wm.nix new file mode 100644 index 0000000..b54d9c5 --- /dev/null +++ b/home/options/wm.nix @@ -0,0 +1,455 @@ +{ + lib, + config, + pkgs, + ... +}: +let + inherit (lib) + mkOption + types + concatStringsSep + getExe + dropEnd + last + mkEnableOption + mapAttrs' + nameValuePair + splitString + ; + + inherit (builtins) length; + + cfg = config.wm; + bindCfg = cfg.keybinds; + + sep = bindCfg.separator; + mod = bindCfg.mod; + + main-color = "#EBDBB2"; + secondary-color = "#24273A"; + + mkHyprBind = + keys: + let + len = length keys; + prefix = if len > 1 then [ ] else [ "None" ]; + finalKeys = prefix ++ keys; + in + (concatStringsSep "+" (dropEnd 1 finalKeys)) + ",${last finalKeys}"; + + mkBindOption = + keys: + let + hypr-key = mkHyprBind keys; + in + mkOption { + type = types.str; + default = if bindCfg.hypr-type then hypr-key else (concatStringsSep sep keys); + }; + + mkGradientColorOption = + { + from ? main-color, + to ? secondary-color, + angle ? 45, + }: + { + from = mkOption { + type = types.str; + default = from; + }; + to = mkOption { + type = types.str; + default = to; + }; + angle = mkOption { + type = types.int; + default = angle; + }; + }; + +in +{ + options.wm = { + exec-once = mkOption { + type = with types; nullOr lines; + default = null; + apply = v: if v != null then pkgs.writeShellScript "exec-once" v else null; + }; + app = { + browser = { + package = mkOption { + type = with types; nullOr package; + default = null; + }; + name = mkOption { + type = with types; nullOr package; + default = null; + }; + }; + terminal = { + package = mkOption { + type = with types; nullOr package; + default = null; + }; + name = mkOption { + type = with types; nullOr str; + default = null; + }; + run = mkOption { + type = with types; nullOr str; + default = "${getExe cfg.terminal.package} -e "; + }; + }; + file-browser = { + package = mkOption { + type = with types; nullOr package; + default = null; + }; + name = mkOption { + type = with types; nullOr str; + default = null; + }; + }; + }; + window = { + opacity = mkOption { + type = types.float; + default = 0.85; + }; + }; + input = { + keyboard = { + repeat-delay = mkOption { + type = types.int; + default = 250; + }; + repeat-rate = mkOption { + type = types.int; + default = 35; + }; + }; + }; + border = { + active = mkGradientColorOption { }; + inactive = mkGradientColorOption { + from = secondary-color; + to = secondary-color; + }; + radius = mkOption { + type = types.int; + default = 12; + }; + }; + keybinds = { + mod = mkOption { + type = types.str; + default = "Mod"; + }; + separator = mkOption { + type = types.str; + default = "+"; + }; + hypr-type = mkEnableOption "hyprland-like bind syntax" // { + default = false; + }; + + spawn = mkOption { + type = types.attrs; + default = { + "${mod}${sep}ENTER" = "${getExe cfg.app.terminal.package}"; + "${mod}${sep}F" = "${getExe cfg.app.browser.package}"; + }; + apply = + binds: + let + hypr-binds = mapAttrs' (n: v: nameValuePair (mkHyprBind (splitString sep n)) v) binds; + in + if bindCfg.hypr-type then hypr-binds else binds; + }; + + spawn-repeat = mkOption { + type = types.attrs; + default = { }; + apply = + binds: + let + hypr-binds = mapAttrs' (n: v: nameValuePair (mkHyprBind (splitString sep n)) v) binds; + in + if bindCfg.hypr-type then hypr-binds else binds; + }; + + # ==== Movement ==== # + switch-window-focus = mkBindOption [ + mod + "TAB" + ]; + move-window-focus = { + left = mkBindOption [ + mod + "H" + ]; + right = mkBindOption [ + mod + "L" + ]; + up = mkBindOption [ + mod + "K" + ]; + down = mkBindOption [ + mod + "J" + ]; + }; + move-monitor-focus = { + left = mkBindOption [ + mod + "CTRL" + "H" + ]; + right = mkBindOption [ + mod + "CTRL" + "L" + ]; + }; + move-workspace-focus = { + # Workspace Focus + next = mkBindOption [ + mod + "CTRL" + "J" + ]; + prev = mkBindOption [ + mod + "CTRL" + "k" + ]; + }; + move-window = { + left = mkBindOption [ + mod + "SHIFT" + "H" + ]; + right = mkBindOption [ + mod + "SHIFT" + "L" + ]; + up = mkBindOption [ + mod + "SHIFT" + "K" + ]; + down = mkBindOption [ + mod + "SHIFT" + "J" + ]; + }; + + consume-window = { + left = mkBindOption [ + mod + "CTRL" + "SHIFT" + "H" + ]; + right = mkBindOption [ + mod + "CTRL" + "SHIFT" + "L" + ]; + }; + + switch-layout = mkBindOption [ + mod + "CTRL" + "ALT" + "SPACE" + ]; + + # ==== Actions ==== # + center-window = mkBindOption [ + mod + "C" + ]; + toggle-overview = mkBindOption [ + mod + "O" + ]; + close-window = mkBindOption [ + mod + "Q" + ]; + toggle-fullscreen = mkBindOption [ + "F11" + ]; + + # ==== Scrolling ==== # + move-workspace = { + down = mkBindOption [ + mod + "CTRL" + "SHIFT" + "J" + ]; + up = mkBindOption [ + mod + "CTRL" + "SHIFT" + "K" + ]; + }; + + switch-preset-column-width = mkBindOption [ + mod + "W" + ]; + switch-preset-window-height = mkBindOption [ + mod + "S" + ]; + expand-column-to-available-width = mkBindOption [ + mod + "P" + ]; + maximize-column = mkBindOption [ + mod + "M" + ]; + reset-window-height = mkBindOption [ + mod + "CTRL" + "S" + ]; + + # ==== Float ==== # + toggle-float = mkBindOption [ + mod + "V" + ]; + switch-focus-between-floating-and-tiling = mkBindOption [ + mod + "CTRL" + "V" + ]; + + minimize = mkBindOption [ + mod + "I" + ]; + + restore-minimize = mkBindOption [ + mod + "SHIFT" + "I" + ]; + + toggle-scratchpad = mkBindOption [ + mod + "Z" + ]; + + # ==== Screenshot ==== # + screenshot = { + area = mkBindOption [ + mod + "SHIFT" + "S" + ]; + window = mkBindOption [ + "CTRL" + "SHIFT" + "S" + ]; + screen = mkBindOption [ + mod + "CTRL" + "SHIFT" + "S" + ]; + }; + + toggle-control-center = mkBindOption [ + mod + "SLASH" + ]; + + toggle-launcher = mkBindOption [ + "ALT" + "SPACE" + ]; + + lock-screen = mkBindOption [ + mod + "CTRL" + "M" + ]; + + clipboard-history = mkBindOption [ + mod + "COMMA" + ]; + + emoji = mkBindOption [ + mod + "PERIOD" + ]; + + screen-recorder = mkBindOption [ + mod + "F12" + ]; + + notification-center = mkBindOption [ + mod + "N" + ]; + + toggle-dont-disturb = mkBindOption [ + mod + "CTRL" + "N" + ]; + + wallpaper-selector = mkBindOption [ + mod + "CTRL" + "W" + ]; + + wallpaper-random = mkBindOption [ + mod + "CTRL" + "SLASH" + ]; + + calculator = mkBindOption [ + mod + "CTRL" + "C" + ]; + + media = { + prev = mkBindOption [ + mod + "CTRL" + "COMMA" + ]; + + next = mkBindOption [ + mod + "CTRL" + "PERIOD" + ]; + }; + + focus-workspace-prefix = mkBindOption [ mod ]; + }; + }; +} diff --git a/home/presets/basic.nix b/home/presets/basic.nix index 41ca8ed..a2af5ff 100755 --- a/home/presets/basic.nix +++ b/home/presets/basic.nix @@ -20,5 +20,6 @@ ../user/ghostty.nix ../user/podman.nix ../user/image-viewer.nix + ../user/wm.nix ]; } diff --git a/home/user/hyprland.nix b/home/user/hyprland.nix index d15b46b..9f2989f 100755 --- a/home/user/hyprland.nix +++ b/home/user/hyprland.nix @@ -1,118 +1,123 @@ { + osConfig, + config, + lib, pkgs, inputs, ... }: let + inherit (lib) mkIf; inherit (pkgs.stdenv.hostPlatform) system; - terminal = "ghostty"; - - execOnceScript = pkgs.writeShellScript "hyprlandExecOnce" '' - # Fix nemo open in terminal - dconf write /org/cinnamon/desktop/applications/terminal/exec "''\'${terminal}''\'" & - dconf write /org/cinnamon/desktop/applications/terminal/exec-arg "''\'''\'" & - - systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME & - dbus-update-activation-environment --systemd HYPRLAND_INSTANCE_SIGNATURE - - # Hint dark theme - gsettings set org.gnome.desktop.interface color-scheme "prefer-dark" - ''; - - mainMod = "SUPER"; + wmCfg = config.wm; + bindCfg = wmCfg.keybinds; + mainMod = bindCfg.mod; in { - home.packages = with pkgs; [ - hyprcursor - ]; - - imports = [ - (import ./hypr/bind.nix { inherit mainMod; }) - ./hypr/workspace.nix - ./hypr/window.nix - ./hypr/windowrule.nix - ./hypr/input.nix - ]; - - wayland.windowManager.hyprland = { - enable = true; - xwayland.enable = true; - systemd = { - enable = true; - variables = [ "--all" ]; - }; - package = null; - portalPackage = null; - - plugins = ( - with inputs.hyprland-plugins.packages.${system}; - [ - hyprwinwrap - ] - ); - - settings = { - "$mainMod" = mainMod; - - debug = { - disable_logs = true; + config = mkIf osConfig.programs.hyprland.enable { + wm = { + exec-once = /* bash */ '' + dbus-update-activation-environment --systemd HYPRLAND_INSTANCE_SIGNATURE + ''; + keybinds = { + mod = "SUPER"; + separator = ","; + hypr-type = true; }; + }; - ecosystem.no_update_news = true; + home.packages = with pkgs; [ + hyprcursor + ]; - bindm = [ - # Move/resize windows with mainMod + LMB/RMB and dragging - ''${mainMod}, mouse:272, movewindow'' - ''${mainMod}, mouse:273, resizewindow'' - ]; + imports = [ + (import ./hypr/bind.nix { inherit mainMod; }) + ./hypr/workspace.nix + ./hypr/window.nix + ./hypr/windowrule.nix + ./hypr/input.nix + ]; - binde = - let - resizeStep = builtins.toString 20; - brightnessStep = builtins.toString 10; - volumeStep = builtins.toString 4; - in + wayland.windowManager.hyprland = { + enable = true; + xwayland.enable = true; + systemd = { + enable = true; + variables = [ "--all" ]; + }; + package = null; + portalPackage = null; + + plugins = ( + with inputs.hyprland-plugins.packages.${system}; [ - '',XF86AudioRaiseVolume, exec, wpctl set-mute @DEFAULT_SINK@ 0 && wpctl set-volume @DEFAULT_SINK@ ${volumeStep}%+'' - '',XF86AudioLowerVolume, exec, wpctl set-mute @DEFAULT_SINK@ 0 && wpctl set-volume @DEFAULT_SINK@ ${volumeStep}%-'' - '',XF86MonBrightnessDown, exec, brightnessctl set ${brightnessStep}%-'' - '',XF86MonBrightnessUp, exec, brightnessctl set ${brightnessStep}%+'' - ''${mainMod} CTRL, l, resizeactive, ${resizeStep} 0'' - ''${mainMod} CTRL, h, resizeactive, -${resizeStep} 0'' - ''${mainMod} CTRL, k, resizeactive, 0 -${resizeStep}'' - ''${mainMod} CTRL, j, resizeactive, 0 ${resizeStep}'' + hyprwinwrap + ] + ); + + settings = { + "$mainMod" = mainMod; + + debug = { + disable_logs = true; + }; + + ecosystem.no_update_news = true; + + bindm = [ + # Move/resize windows with mainMod + LMB/RMB and dragging + "${mainMod}, mouse:272, movewindow" + "${mainMod}, mouse:273, resizewindow" ]; - plugin = { - hyprwinrap = { - class = "kitty-bg"; + binde = + let + resizeStep = toString 20; + brightnessStep = toString 10; + volumeStep = toString 4; + in + [ + ",XF86AudioRaiseVolume, exec, wpctl set-mute @DEFAULT_SINK@ 0 && wpctl set-volume @DEFAULT_SINK@ ${volumeStep}%+" + ",XF86AudioLowerVolume, exec, wpctl set-mute @DEFAULT_SINK@ 0 && wpctl set-volume @DEFAULT_SINK@ ${volumeStep}%-" + ",XF86MonBrightnessDown, exec, brightnessctl set ${brightnessStep}%-" + ",XF86MonBrightnessUp, exec, brightnessctl set ${brightnessStep}%+" + "${mainMod} CTRL, l, resizeactive, ${resizeStep} 0" + "${mainMod} CTRL, h, resizeactive, -${resizeStep} 0" + "${mainMod} CTRL, k, resizeactive, 0 -${resizeStep}" + "${mainMod} CTRL, j, resizeactive, 0 ${resizeStep}" + ]; + + plugin = { + hyprwinrap = { + class = "kitty-bg"; + }; + + touch_gestures = { + sensitivity = 4.0; + workspace_swipe_fingers = 3; + workspace_swipe_edge = "d"; + long_press_delay = 400; + resize_on_border_long_press = true; + edge_margin = 10; + emulate_touchpad_swipe = false; + }; }; - touch_gestures = { - sensitivity = 4.0; - workspace_swipe_fingers = 3; - workspace_swipe_edge = "d"; - long_press_delay = 400; - resize_on_border_long_press = true; - edge_margin = 10; - emulate_touchpad_swipe = false; + exec-once = [ "${wmCfg.exec-once}" ]; + + env = [ + "XDG_CURRENT_DESKTOP, Hyprland" + "XDG_SESSION_DESKTOP, Hyprland" + "GDK_PIXBUF_MODULE_FILE, ${pkgs.librsvg}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" + ]; + + misc = { + disable_hyprland_logo = true; + force_default_wallpaper = 0; + disable_splash_rendering = true; }; }; - - exec-once = [ "${execOnceScript}" ]; - - env = [ - ''XDG_CURRENT_DESKTOP, Hyprland'' - ''XDG_SESSION_DESKTOP, Hyprland'' - ''GDK_PIXBUF_MODULE_FILE, ${pkgs.librsvg}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache'' - ]; - - misc = { - disable_hyprland_logo = true; - force_default_wallpaper = 0; - disable_splash_rendering = true; - }; }; }; } diff --git a/home/user/wm.nix b/home/user/wm.nix new file mode 100644 index 0000000..f6895fd --- /dev/null +++ b/home/user/wm.nix @@ -0,0 +1,93 @@ +{ + pkgs, + lib, + config, + ... +}: +let + inherit (lib) getExe getExe'; + + # ==== binary ==== # + rofi = getExe pkgs.rofi; + playerctl = getExe pkgs.playerctl; + wpctl = getExe' pkgs.wireplumber "wpctl"; + brightnessctl = getExe pkgs.brightnessctl; + + brightnessStep = toString 10; + volumeStep = toString 4; + + rofiWall = import ../../home/scripts/rofiwall.nix { inherit config pkgs; }; + rbwSelector = import ../../home/scripts/rbwSelector.nix { inherit pkgs; }; + toggleWlogout = pkgs.writeShellScript "toggleWlogout" '' + if ${pkgs.busybox}/bin/pgrep wlogout > /dev/null; then + ${pkgs.busybox}/bin/pkill wlogout + else + ${getExe config.programs.wlogout.package} --protocol layer-shell + fi + ''; + + cfg = config.wm; + mod = cfg.keybinds.mod; + sep = cfg.keybinds.separator; +in +{ + wm = { + exec-once = /* bash */ '' + # Fix nemo open in terminal + dconf write /org/cinnamon/desktop/applications/terminal/exec "''\'${cfg.app.terminal.name}''\'" & + dconf write /org/cinnamon/desktop/applications/terminal/exec-arg "''\'''\'" & + + # Hint dark theme + dconf write /org/gnome/desktop/interface/color-scheme '"prefer-dark"' & + + systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME & + ''; + + app = { + terminal = { + package = config.programs.ghostty.package; + name = "ghostty"; + run = "ghostty -e"; + }; + browser = { + package = config.programs.zen-browser.package; + name = "zen-twilight"; + }; + file-browser = { + package = config.programs.yazi.pacakge; + name = "yazi"; + }; + }; + keybinds = { + spawn-repeat = { + # ==== Media ==== # + "XF86AudioPrev" = "${playerctl} previous"; + "XF86AudioNext" = "${playerctl} next"; + "${mod}${sep}CTRL${sep}COMMA" = "${playerctl} previous"; + "${mod}${sep}CTRL${sep}PERIOD" = "${playerctl} next"; + "XF86AudioPlay" = "${playerctl} play-pause"; + "XF86AudioStop" = "${playerctl} stop"; + "XF86AudioMute" = "${wpctl} set-mute @DEFAULT_SINK@ toggle"; + "XF86AudioRaiseVolume" = + "${wpctl} set-mute @DEFAULT_SINK@ 0 && ${wpctl} set-volume @DEFAULT_SINK@ ${volumeStep}%+"; + "XF86AudioLowerVolume" = + "${wpctl} set-mute @DEFAULT_SINK@ 0 && ${wpctl} set-volume @DEFAULT_SINK@ ${volumeStep}%-"; + "XF86MonBrightnessDown" = "${brightnessctl} set ${brightnessStep}%-"; + "XF86MonBrightnessUp" = "${brightnessctl} set ${brightnessStep}%+"; + }; + spawn = { + "${mod}${sep}Return" = "${getExe cfg.app.terminal.package}"; + "${mod}${sep}F" = "${getExe cfg.app.browser.package}"; + "${mod}${sep}E" = "${cfg.app.terminal.run} ${cfg.app.file-browser.name}"; + "${mod}${sep}CTRL${sep}P" = "${rbwSelector}"; + "${mod}${sep}CTRL${sep}M" = "${toggleWlogout}"; + + # Launcher + "${mod}${sep}CTRL${sep}W" = "${rofiWall}"; + "ALT${sep}SPACE" = "${rofi} -config config/rofi/apps.rasi -show drun"; + "${mod}${sep}PERIOD" = "${rofi} -modi emoji -show emoji"; + "${mod}${sep}CTRL${sep}C" = "${rofi} -modi calc -show calc -no-show-match -no-sort"; + }; + }; + }; +} diff --git a/home/user/zen-browser.nix b/home/user/zen-browser.nix index 957b5f0..efd591c 100755 --- a/home/user/zen-browser.nix +++ b/home/user/zen-browser.nix @@ -3,10 +3,12 @@ config, helper, pkgs, + lib, ... }: let inherit (osConfig.systemConf) username; + inherit (lib) mkForce; inherit (helper) capitalize; inherit (pkgs) runCommand; @@ -14,7 +16,7 @@ let owner = "JustAdumbPrsn"; repo = "zen-nebula"; rev = "main"; - sha256 = "sha256-wtntRAkOGm6fr396kqzqk+GyPk+ytifXTqqOp0YIvlw="; + sha256 = "sha256-Eg9HsN+yDA8OdVcE9clS+FyUhVBH3ooN/odkZIVR/p4="; }; patchedNebula = @@ -143,6 +145,8 @@ in recursive = true; }; + home.file.".zen/${profileName}/search.json.mozlz4".force = mkForce true; + xdg.mimeApps = let value = diff --git a/options/systemconf.nix b/options/systemconf.nix index 3094cd9..fa6922f 100755 --- a/options/systemconf.nix +++ b/options/systemconf.nix @@ -10,8 +10,10 @@ let inherit (pkgs.stdenv.hostPlatform) system; inherit (lib) + optional mkOption mkEnableOption + mkMerge types mkIf ; @@ -64,7 +66,7 @@ in domain = mkOption { type = types.str; default = "local"; - description = ''Domain for system''; + description = "Domain for system"; }; username = mkOption { @@ -85,16 +87,15 @@ in }; }; - hyprland = { - enable = (mkEnableOption "Enable hyprland") // { - default = false; - }; - }; - - niri = { - enable = (mkEnableOption "Enable niri") // { - default = false; - }; + windowManager = mkOption { + type = + with types; + nullOr (enum [ + "hyprland" + "niri" + "mango" + ]); + default = null; }; enableHomeManager = (mkEnableOption "Home manager") // { @@ -117,7 +118,9 @@ in system.stateVersion = stateVersion; - programs.hyprland.enable = if (cfg.hyprland.enable && (!cfg.niri.enable)) then true else false; + programs.hyprland.enable = cfg.windowManager == "hyprland"; + programs.niri.enable = cfg.windowManager == "niri"; + programs.mango.enable = cfg.windowManager == "mango"; # ==== Home Manager ==== # home-manager = mkIf cfg.enableHomeManager { @@ -134,6 +137,7 @@ in inherit (cfg) username hostname; }; sharedModules = [ + inputs.mango.hmModules.mango inputs.hyprland.homeManagerModules.default inputs.caelestia-shell.homeManagerModules.default inputs.sops-nix.homeManagerModules.default diff --git a/pkgs/overlays/default.nix b/pkgs/overlays/default.nix index f05a430..164f24e 100755 --- a/pkgs/overlays/default.nix +++ b/pkgs/overlays/default.nix @@ -2,5 +2,5 @@ (import ./vesktop.nix) (import ./proton-dw-bin.nix) # (import ./powerdns-admin.nix) - # (import ./stalwart-mail) + # (import ./stalwart) ] diff --git a/pkgs/overlays/proton-dw-bin.nix b/pkgs/overlays/proton-dw-bin.nix index 3b550d0..567e1de 100644 --- a/pkgs/overlays/proton-dw-bin.nix +++ b/pkgs/overlays/proton-dw-bin.nix @@ -5,11 +5,11 @@ final: prev: { in final.pkgs.stdenv.mkDerivation (finalAttrs: rec { pname = "dwproton"; - version = "10.0-14"; + version = "10.0-16"; src = final.pkgs.fetchzip { url = "https://dawn.wine/dawn-winery/dwproton/releases/download/${pname}-${finalAttrs.version}/${pname}-${finalAttrs.version}-x86_64.tar.xz"; - hash = "sha256-5fDo7YUPhp0OwjdAXHfovSuFCgSPwHW0cSZk9E+FY98="; + hash = "sha256-9wDhtrB5IjFVZxyorAJUaivRwE85pzQ6/eDgHXCSEh8="; }; dontUnpack = true; diff --git a/pkgs/overlays/stalwart-mail/default.nix b/pkgs/overlays/stalwart/default.nix similarity index 53% rename from pkgs/overlays/stalwart-mail/default.nix rename to pkgs/overlays/stalwart/default.nix index 2cfb650..e35e07e 100755 --- a/pkgs/overlays/stalwart-mail/default.nix +++ b/pkgs/overlays/stalwart/default.nix @@ -1,5 +1,5 @@ final: prev: { - stalwart-mail = prev.stalwart-mail.overrideAttrs (oldAttrs: { + stalwart = prev.stalwart.overrideAttrs (oldAttrs: { patches = [ ./enable_root_ca.patch ]; diff --git a/pkgs/overlays/stalwart-mail/enable_root_ca.patch b/pkgs/overlays/stalwart/enable_root_ca.patch similarity index 100% rename from pkgs/overlays/stalwart-mail/enable_root_ca.patch rename to pkgs/overlays/stalwart/enable_root_ca.patch diff --git a/system/dev/dn-pre7780/default.nix b/system/dev/dn-pre7780/default.nix index bc46ec3..2832653 100755 --- a/system/dev/dn-pre7780/default.nix +++ b/system/dev/dn-pre7780/default.nix @@ -12,9 +12,8 @@ in systemConf = { inherit hostname username; enableHomeManager = true; + windowManager = "niri"; nvidia.enable = true; - hyprland.enable = false; - niri.enable = true; sddm.package = ( pkgs.sddm-astronaut.override { embeddedTheme = "purple_leaves"; diff --git a/system/dev/dn-pre7780/services/default.nix b/system/dev/dn-pre7780/services/default.nix index fff90ce..974420b 100755 --- a/system/dev/dn-pre7780/services/default.nix +++ b/system/dev/dn-pre7780/services/default.nix @@ -1,7 +1,6 @@ { imports = [ ../../../modules/postgresql.nix - # ./mail.nix ./nginx.nix # ./pangolin.nix ]; diff --git a/system/dev/dn-pre7780/services/mail.nix b/system/dev/dn-pre7780/services/mail.nix deleted file mode 100755 index 27bcb9c..0000000 --- a/system/dev/dn-pre7780/services/mail.nix +++ /dev/null @@ -1,205 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - inherit (lib) mkIf; - inherit (config.networking) domain; - mkCondition = ( - condition: ithen: ielse: [ - { - "if" = condition; - "then" = ithen; - } - { "else" = ielse; } - ] - ); - - rspamdWebPort = 11333; - rspamdPort = 31009; - fqdn = "mx1.dnywe.com"; - - rspamdSecretFile = config.sops.secrets."rspamd".path; - rspamdSecretPath = "/run/rspamd/rspamd-controller-password.inc"; -in -{ - networking.firewall.allowedTCPPorts = [ 8080 ]; - - imports = [ - (import ../../../modules/stalwart.nix { - inherit domain; - - enableNginx = false; - adminPassFile = config.sops.secrets."stalwart/adminPassword".path; - certs."default" = { - default = true; - cert = "%{file:${config.security.acme.certs.${fqdn}.directory}/cert.pem}%"; - private-key = "%{file:${config.security.acme.certs.${fqdn}.directory}/key.pem}%"; - }; - ldapConf = { - type = "ldap"; - url = "ldaps://ldap.net.dn"; - tls.enable = true; - timeout = "30s"; - base-dn = "ou=people,dc=net,dc=dn"; - attributes = { - name = "uid"; - email = "mail"; - email-alias = "mailRoutingAddress"; - secret = "userPassword"; - description = [ - "cn" - "description" - ]; - class = "objectClass"; - groups = [ "memberOf" ]; - }; - filter = { - name = "(&(objectClass=inetOrgPerson)(|(uid=?)(mail=?)(mailRoutingAddress=?)))"; - email = "(&(objectClass=inetOrgPerson)(|(mailRoutingAddress=?)(mail=?)))"; - }; - bind = { - dn = "cn=admin,dc=net,dc=dn"; - secret = "%{file:${config.sops.secrets."stalwart/ldap".path}}%"; - auth = { - method = "default"; - }; - }; - }; - }) - ]; - - services.stalwart-mail.settings.spam-filter.enable = !config.services.rspamd.enable; - - services.stalwart-mail.settings.session.milter."rspamd" = mkIf config.services.rspamd.enable { - enable = mkCondition "listener = 'smtp'" true false; - hostname = "127.0.0.1"; - port = rspamdPort; - stages = [ - "connect" - "ehlo" - "mail" - "rcpt" - "data" - ]; - tls = false; - allow-invalid-certs = false; - options = { - tempfail-on-error = true; - max-response-size = 52428800; # 50mb - version = 6; - }; - }; - - services.rspamd = { - enable = true; - locals = { - "redis.conf".text = '' - servers = "${config.services.redis.servers.rspamd.unixSocket}"; - ''; - "classifier-bayes.conf".text = '' - backend = "redis"; - autolearn = true; - ''; - "dkim_signing.conf".text = '' - enabled = false; - ''; - "milter_headers.conf".text = '' - enabled = true; - extended_spam_headers = true; - skip_local = false; - use = ["x-spamd-bar", "x-spam-level", "x-spam-status", "authentication-results", "x-spamd-result"]; - authenticated_headers = ["authentication-results"]; - ''; - }; - localLuaRules = - pkgs.writeText "rspamd-local.lua" - # lua - '' - -- Temporary fix for double dot issue rspamd#5273 - local lua_util = require("lua_util") - - rspamd_config.UNQUALIFY_SENDER_HOSTNAME = { - callback = function(task) - local hn = task:get_hostname() - if not hn then return end - local san_hn = string.gsub(hn, "%.$", "") - if hn ~= san_hn then - task:set_hostname(san_hn) - end - end, - type = "prefilter", - priority = lua_util.symbols_priorities.top + 1, - } - ''; - workers = { - rspamd_proxy = { - type = "rspamd_proxy"; - includes = [ "$CONFDIR/worker-proxy.inc" ]; - bindSockets = [ - "*:${toString rspamdPort}" - ]; - extraConfig = '' - self_scan = yes; - ''; - }; - controller = { - type = "controller"; - includes = [ - "$CONFDIR/worker-controller.inc" - ]; - extraConfig = '' - .include(try=true; priority=1,duplicate=merge) "${rspamdSecretPath}" - ''; - bindSockets = [ "127.0.0.1:${toString rspamdWebPort}" ]; - }; - }; - overrides."whitelist.conf".text = '' - whiltelist_from { - ${domain} = true; - } - ''; - }; - - systemd.services.rspamd = mkIf config.services.rspamd.enable { - path = [ - pkgs.rspamd - pkgs.coreutils - ]; - serviceConfig = { - ExecStartPre = [ - "${pkgs.writeShellScript "generate-rspamd-passwordfile" '' - RSPAMD_PASSWORD_HASH=$(rspamadm pw --password $(cat ${rspamdSecretFile})) - echo "enable_password = \"$RSPAMD_PASSWORD_HASH\";" > ${rspamdSecretPath} - chmod 770 "${rspamdSecretPath}" - ''}" - ]; - }; - }; - - services.redis.servers.rspamd = { - enable = true; - port = 0; - user = config.services.rspamd.user; - }; - - security.acme = { - acceptTerms = true; - certs."${fqdn}" = { - inheritDefaults = false; - group = config.systemd.services.stalwart-mail.serviceConfig.Group; - dnsProvider = "cloudflare"; - dnsResolver = "1.1.1.1:53"; - server = "https://acme-v02.api.letsencrypt.org/directory"; - validMinDays = 30; - email = "dachxy@${domain}"; - extraDomainNames = [ domain ]; - environmentFile = config.sops.secrets."cloudflare/secret".path; - postRun = '' - systemctl reload stalwart-mail - ''; - }; - }; -} diff --git a/system/dev/dn-pre7780/sops/sops-conf.nix b/system/dev/dn-pre7780/sops/sops-conf.nix index a5a1df9..596965b 100755 --- a/system/dev/dn-pre7780/sops/sops-conf.nix +++ b/system/dev/dn-pre7780/sops/sops-conf.nix @@ -32,9 +32,9 @@ in mode = "0660"; }; } - // (optionalAttrs config.services.stalwart-mail.enable ( + // (optionalAttrs config.services.stalwart.enable ( let - inherit (config.users.users.stalwart-mail) name group; + inherit (config.users.users.stalwart) name group; owner = name; in { diff --git a/system/dev/dn-pre7780/utility/davinci-resolve.nix b/system/dev/dn-pre7780/utility/davinci-resolve.nix index bf8d6c2..6b95868 100755 --- a/system/dev/dn-pre7780/utility/davinci-resolve.nix +++ b/system/dev/dn-pre7780/utility/davinci-resolve.nix @@ -1,5 +1,5 @@ { imports = [ - # ../../../modules/davinci-resolve.nix + ../../../modules/davinci-resolve.nix ]; } diff --git a/system/dev/dn-pre7780/utility/default.nix b/system/dev/dn-pre7780/utility/default.nix index c58d03c..03f9365 100755 --- a/system/dev/dn-pre7780/utility/default.nix +++ b/system/dev/dn-pre7780/utility/default.nix @@ -1,8 +1,8 @@ { imports = [ ../../../modules/localsend.nix - ./airplay.nix - ./davinci-resolve.nix + # ./airplay.nix + # ./davinci-resolve.nix # ./blender.nix ]; } diff --git a/system/dev/dn-server/services/default.nix b/system/dev/dn-server/services/default.nix index fb46780..7b910b2 100755 --- a/system/dev/dn-server/services/default.nix +++ b/system/dev/dn-server/services/default.nix @@ -1,4 +1,3 @@ -{ config, ... }: { imports = [ ./actual-budget.nix @@ -15,5 +14,6 @@ ./dns.nix ./acme.nix ./ntfy.nix + ./homepage.nix ]; } diff --git a/system/dev/dn-server/services/dns.nix b/system/dev/dn-server/services/dns.nix index 2b499c6..d9c848d 100644 --- a/system/dev/dn-server/services/dns.nix +++ b/system/dev/dn-server/services/dns.nix @@ -102,7 +102,7 @@ in "192.168.100.0/24" ]; dns.port = 5300; - yaml-settings = { + settings = { webservice.webserver = true; recordcache.max_negative_ttl = 60; }; diff --git a/system/dev/dn-server/services/homepage.nix b/system/dev/dn-server/services/homepage.nix new file mode 100644 index 0000000..f986316 --- /dev/null +++ b/system/dev/dn-server/services/homepage.nix @@ -0,0 +1,194 @@ +{ config, ... }: +let + inherit (config.networking) domain; + cfg = config.services.homepage-dashboard; +in +{ + sops.secrets = { + "homepage" = { + }; + }; + + services.homepage-dashboard = { + enable = true; + openFirewall = true; + listenPort = 8044; + environmentFile = config.sops.secrets."homepage".path; + allowedHosts = "www.${domain},${domain},localhost:${toString cfg.listenPort}"; + docker = { + docker = { + socket = "/var/run/docker.sock"; + }; + }; + widgets = [ + { + search = { + provider = "duckduckgo"; + target = "_blank"; + }; + } + { + datetime = { + text_size = "x1"; + format = { + dateStyle = "short"; + timeStyle = "short"; + hour12 = true; + }; + }; + } + ]; + services = [ + { + "Files & Documents" = [ + { + "Nextcloud" = { + icon = "nextcloud.svg"; + description = "☁️ Cloud drive"; + href = "https://${config.services.nextcloud.hostName}"; + widgets = [ + { + type = "nextcloud"; + url = "https://${config.services.nextcloud.hostName}"; + key = "{{HOMEPAGE_VAR_NEXTCLOUD_NC_TOKEN}}"; + } + ]; + }; + } + { + "Paperless" = { + icon = "paperless.svg"; + description = "PDF editing, tagging, and viewing"; + href = config.services.paperless.settings.PAPERLESS_URL; + }; + } + ]; + } + { + "VPN & IDP" = [ + { + "Netbird" = { + icon = "netbird.svg"; + description = "VPN Service: access internal services"; + href = "https://${config.services.netbird.server.domain}"; + }; + } + { + "Keycloak" = { + icon = "keycloak.svg"; + description = "Identity provider"; + href = "https://${config.services.keycloak.settings.hostname}"; + }; + } + ]; + } + { + "Monitor" = [ + { + "Grafana" = { + icon = "grafana.svg"; + description = "Show metrics!"; + href = config.services.grafana.settings.server.root_url; + }; + } + { + "Prometheus" = { + icon = "prometheus.svg"; + description = "The web is not that useful 🥀"; + href = config.services.prometheus.webExternalUrl; + }; + } + { + "Uptime Kuma" = { + icon = "uptime-kuma.svg"; + description = "Service health check"; + href = "https://uptime.${domain}"; + }; + } + ]; + } + { + "Utility" = [ + { + "Vaultwarden" = { + icon = "vaultwarden-light.svg"; + description = "Password manager"; + href = config.services.vaultwarden.config.DOMAIN; + }; + } + { + "PowerDNS" = { + icon = "powerdns.svg"; + description = "DNS record management"; + href = "https://powerdns.${domain}"; + }; + } + { + "Actual Budget" = { + icon = "actual-budget.svg"; + description = "Financial budget management"; + href = "https://actual.${domain}"; + }; + } + { + "Ntfy" = { + icon = "ntfy.svg"; + description = "Notification service"; + href = config.services.ntfy-sh.settings.base-url; + }; + } + ]; + } + { + "Games" = [ + { + "Minecraft" = { + icon = "minecraft.svg"; + description = "Minecraft servers"; + widgets = [ + { + type = "minecraft"; + fields = [ + "players" + "version" + "status" + ]; + url = "udp://mc.${domain}:${toString config.services.velocity.port}"; + } + ]; + }; + } + ]; + } + + ]; + settings = { + base = "https://www.${domain}"; + headerStyle = "boxed"; + title = "DN Home"; + description = "Welcome! maybe?"; + disableUpdateCheck = true; + providers = { + + }; + quicklaunch = { + searchDescriptions = true; + hideInternetSearch = true; + showSearchSuggestions = true; + hideVisitURL = true; + provider = "google"; + }; + }; + }; + + services.nginx.virtualHosts."${domain}" = { + useACMEHost = domain; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString cfg.listenPort}"; + }; + serverAliases = [ + "www.${domain}" + ]; + }; +} diff --git a/system/dev/dn-server/sops/secret.yaml b/system/dev/dn-server/sops/secret.yaml index 62082f0..113f423 100755 --- a/system/dev/dn-server/sops/secret.yaml +++ b/system/dev/dn-server/sops/secret.yaml @@ -65,6 +65,7 @@ forgejo: password: ENC[AES256_GCM,data:dcIotYpgtdFLcunAB3ttlczzQ68=,iv:vH3rckAfntFAEtH3dolF7NCAdj142cAzre56x7oBdDA=,tag:TaxRn8g/TVloM60D6Ud0Jg==,type:str] velocity: ENC[AES256_GCM,data:PYGSXfivm7OyKhBMKPOVDs+efpcb0hhwCAxlT05pM+kg9t0lH4TEMuxBXFRs80LUiQx+CYXyw8UvBkkKwPEc,iv:PppenjXIQ+eirCor3PxT16r2S7wO8bww5v/RyjQh9MI=,tag:Dc3BzmyQcTwYsvWShQ/JqQ==,type:str] fabricProxy: ENC[AES256_GCM,data:srGYmqHgfkxAKKSjy9uGX1mQpE3N0rXb06MYiycbYESj/sZu/vjsPspvUdzTHHb9zkF5SWLWkmP6llIpimkss/dm7A1pGlagin3+,iv:yoWQdWeP9UjoRO5rJ9FQGbBu3iypIdXGrSDqBfFhw6w=,tag:+d/Tp/m3vENZAXJyHOMJEA==,type:str] +homepage: ENC[AES256_GCM,data:SqRtz4xrwCTQulgFsRAgTcQNQZRyRes+K4UzlhQZW3GuAmQaRBIHJyFttgIQYDKlc21QAiM2zxa9IBOtGNpQAdkplUptaRTq0fZH/OYcNw==,iv:NLEiWjfPvsw2Tq+pqrIPy8pKlWFD8wVXt9TMH8Y8+jA=,tag:N91DrYQoYeyJ3AH3ujTI+g==,type:str] sops: age: - recipient: age17rjcght2y5p4ryr76ysnxpy2wff62sml7pyc5udcts48985j05vqpwdfq2 @@ -94,7 +95,7 @@ sops: OFloWEFuTC9GTXJsMG5NNktmdmIrY1kK0yN0ae0xNaydujV5lt2FiwXdyursG0DK 9i/B3TTAm9csDMMSTSFbiAUJDzG7kIqn++JU/cxvsGScSnhMqjEK/g== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-01-20T06:31:45Z" - mac: ENC[AES256_GCM,data:ad8EP8zk6mxlmMZaEijW0NWF72y2EikJPct7qxiCp6/sWGKKrGv8mRnC1zahgpRqpGR0jZKQ8Ot204EdGrJF9WI03+ZB9GgKi9ipQvXlGOCJq6m/Mp6WygI2hFAzRKCeoPqAPjVQxQ3Ctt/WEYXzvEp7CIKUq7WD6gTEFk6FDg0=,iv:20rJb79QnUW0DFbXTr0XXjiXjm7bK0CVs4oVan5SAKw=,tag:+mnMTBYQ1fhwe/abwGYNOA==,type:str] + lastmodified: "2026-01-30T04:08:29Z" + mac: ENC[AES256_GCM,data:egK9zlAccBV2IeJ+DYTP3AKQUUMFPmts8eZMilQlyh+EE/oXhNnKeKkmNg9h1RwoZ6zh0LRDsyjubCc06PI/wVx2lJ0JfPs4bt6PckC1hZglRSHHjmocyx1eF5bMVfBLmluDzQ3Zms1Ryvuh+M+EjtdhttBljAIb0JIRx8Wzwks=,iv:wWrRiOvzZDboZSMgTzmbVVWzpSIhLdlgxgUIFXCFet0=,tag:YLBtLivKLBvByyfm4PbVXQ==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0 diff --git a/system/dev/public/dn/common.nix b/system/dev/public/dn/common.nix index 17d9f0d..50271c2 100755 --- a/system/dev/public/dn/common.nix +++ b/system/dev/public/dn/common.nix @@ -27,6 +27,16 @@ in }; workspaces."game" = { }; window-rules = [ + # Wine systray + { + matches = [ + { + title = "^$"; + app-id = "^steam_app_(.*)$"; + } + ]; + open-fullscreen = false; + } # Steam Game Fullscreen { matches = [ @@ -68,5 +78,8 @@ in } ]; }; + wayland.windowManager.mango.settings = '' + xkb_rules_options = caps:escape + ''; }; } diff --git a/system/dev/skydrive-lap/default.nix b/system/dev/skydrive-lap/default.nix index ab73d81..5dcc56f 100755 --- a/system/dev/skydrive-lap/default.nix +++ b/system/dev/skydrive-lap/default.nix @@ -11,8 +11,7 @@ in inherit hostname username; domain = "net.dn"; enableHomeManager = true; - hyprland.enable = false; - niri.enable = true; + windowManager = "niri"; face = pkgs.fetchurl { url = "https://git.dnywe.com/dachxy/skydrive-avatar/raw/branch/main/skydrive.jpg"; hash = "sha256-aMjl6VL1Zy+r3ElfFyhFOlJKWn42JOnAFfBXF+GPB/Q="; diff --git a/system/modules/hyprland.nix b/system/modules/hyprland.nix index b69cb31..519f87b 100755 --- a/system/modules/hyprland.nix +++ b/system/modules/hyprland.nix @@ -7,44 +7,43 @@ }: let inherit (lib) mkIf; + inherit (pkgs.stdenv.hostPlatform) system; inherit (config.systemConf) username; - - hyprlandEnabled = config.programs.hyprland.enable; in { - programs.hyprland = { - enable = config.systemConf.hyprland.enable; - withUWSM = false; - package = inputs.hyprland.packages."${pkgs.system}".hyprland; - portalPackage = inputs.hyprland.packages.${pkgs.system}.xdg-desktop-portal-hyprland; - }; + config = mkIf config.programs.hyprland.enable { + programs.hyprland = { + withUWSM = false; + package = inputs.hyprland.packages."${system}".hyprland; + portalPackage = inputs.hyprland.packages.${system}.xdg-desktop-portal-hyprland; + }; - environment.sessionVariables = mkIf hyprlandEnabled { - NIXOS_OZONE_WL = "1"; - WLR_NO_HARDWARE_CURSORS = "1"; - }; + environment.sessionVariables = { + NIXOS_OZONE_WL = "1"; + WLR_NO_HARDWARE_CURSORS = "1"; + }; - environment.systemPackages = mkIf hyprlandEnabled ( - with pkgs; - [ - pyprland - hyprsunset - hyprpicker - hyprshot - kitty - ] - ); + environment.systemPackages = ( + with pkgs; + [ + pyprland + hyprsunset + hyprpicker + hyprshot + ] + ); - nix = mkIf hyprlandEnabled { - settings = { - substituters = [ "https://hyprland.cachix.org" ]; - trusted-public-keys = [ - "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" - ]; + nix = { + settings = { + substituters = [ "https://hyprland.cachix.org" ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + ]; + }; + }; + + home-manager.users."${username}" = { + imports = [ ../../home/user/hyprland.nix ]; }; }; - - home-manager.users."${username}" = mkIf hyprlandEnabled { - imports = [ ../../home/user/hyprland.nix ]; - }; } diff --git a/system/modules/mango.nix b/system/modules/mango.nix new file mode 100644 index 0000000..87a27ee --- /dev/null +++ b/system/modules/mango.nix @@ -0,0 +1,297 @@ +{ + config, + lib, + ... +}: +let + inherit (lib) + mkIf + removePrefix + concatStringsSep + mapAttrsToList + ; +in +{ + config = mkIf config.programs.mango.enable { + home-manager.sharedModules = [ + ( + { config, ... }: + let + wmCfg = config.wm; + bindCfg = wmCfg.keybinds; + in + { + wm.keybinds = { + mod = "SUPER"; + separator = ","; + hypr-type = true; + }; + + wayland.windowManager.mango = { + enable = true; + settings = + let + keybinds = concatStringsSep "\n" ( + mapAttrsToList (n: v: "bind=${n},spawn,${v}") (bindCfg.spawn-repeat // bindCfg.spawn) + ); + in + '' + # Window effect + blur=0 + blur_layer=0 + blur_optimized=1 + blur_params_num_passes = 2 + blur_params_radius = 5 + blur_params_noise = 0.02 + blur_params_brightness = 0.9 + blur_params_contrast = 0.9 + blur_params_saturation = 1.2 + + shadows = 0 + layer_shadows = 0 + shadow_only_floating = 1 + shadows_size = 10 + shadows_blur = 15 + shadows_position_x = 0 + shadows_position_y = 0 + shadowscolor= 0x000000ff + + border_radius=${toString wmCfg.border.radius} + no_radius_when_single=0 + focused_opacity=${toString wmCfg.window.opacity} + unfocused_opacity=${toString wmCfg.window.opacity} + + # Animation Configuration(support type:zoom,slide) + # tag_animation_direction: 1-horizontal,0-vertical + animations=1 + layer_animations=1 + animation_type_open=slide + animation_type_close=slide + animation_fade_in=1 + animation_fade_out=1 + tag_animation_direction=1 + zoom_initial_ratio=0.3 + zoom_end_ratio=0.8 + fadein_begin_opacity=0.5 + fadeout_begin_opacity=0.8 + animation_duration_move=500 + animation_duration_open=400 + animation_duration_tag=350 + animation_duration_close=800 + animation_duration_focus=0 + animation_curve_open=0.46,1.0,0.29,1 + animation_curve_move=0.46,1.0,0.29,1 + animation_curve_tag=0.46,1.0,0.29,1 + animation_curve_close=0.08,0.92,0,1 + animation_curve_focus=0.46,1.0,0.29,1 + animation_curve_opafadeout=0.5,0.5,0.5,0.5 + animation_curve_opafadein=0.46,1.0,0.29,1 + + # Scroller Layout Setting + scroller_structs=20 + scroller_default_proportion=0.8 + scroller_focus_center=0 + scroller_prefer_center=0 + edge_scroller_pointer_focus=1 + scroller_default_proportion_single=1.0 + scroller_proportion_preset=0.5,0.8,1.0 + + # Master-Stack Layout Setting + new_is_master=1 + default_mfact=0.55 + default_nmaster=1 + smartgaps=0 + + # Overview Setting + hotarea_size=10 + enable_hotarea=1 + ov_tab_mode=0 + overviewgappi=5 + overviewgappo=30 + + # Misc + no_border_when_single=0 + axis_bind_apply_timeout=100 + focus_on_activate=1 + idleinhibit_ignore_visible=0 + sloppyfocus=1 + warpcursor=1 + focus_cross_monitor=0 + focus_cross_tag=0 + enable_floating_snap=0 + snap_distance=30 + cursor_size=24 + drag_tile_to_tile=1 + + # keyboard + repeat_rate=${toString wmCfg.input.keyboard.repeat-rate} + repeat_delay=${toString wmCfg.input.keyboard.repeat-delay} + numlockon=0 + xkb_rules_layout=us + + # Trackpad + # need relogin to make it apply + disable_trackpad=0 + tap_to_click=1 + tap_and_drag=1 + drag_lock=1 + trackpad_natural_scrolling=0 + disable_while_typing=1 + left_handed=0 + middle_button_emulation=0 + swipe_min_threshold=1 + + # mouse + # need relogin to make it apply + mouse_natural_scrolling=0 + + # Appearance + gappih=5 + gappiv=5 + gappoh=10 + gappov=10 + scratchpad_width_ratio=0.8 + scratchpad_height_ratio=0.9 + borderpx=4 + rootcolor=0x${removePrefix "#" wmCfg.border.active.to}ff + bordercolor=0x${removePrefix "#" wmCfg.border.active.from}ff + focuscolor=0x${removePrefix "#" wmCfg.border.active.to}ff + maximizescreencolor=0x89aa61ff + urgentcolor=0xad401fff + scratchpadcolor=0x516c93ff + globalcolor=0xb153a7ff + overlaycolor=0x14a57cff + + # layout support: + # tile,scroller,grid,deck,monocle,center_tile,vertical_tile,vertical_scroller + tagrule=id:1,layout_name:tile + tagrule=id:2,layout_name:tile + tagrule=id:3,layout_name:tile + tagrule=id:4,layout_name:tile + tagrule=id:5,layout_name:tile + tagrule=id:6,layout_name:tile + tagrule=id:7,layout_name:tile + tagrule=id:8,layout_name:tile + tagrule=id:9,layout_name:tile + + # Key Bindings + # key name refer to `xev` or `wev` command output, + # mod keys name: super,ctrl,alt,shift,none + + ${keybinds} + + # exit + bind=${bindCfg.close-window},killclient + + # switch window focus + bind=${bindCfg.switch-window-focus},focusstack,next + bind=${bindCfg.move-window-focus.left},focusdir,left + bind=${bindCfg.move-window-focus.right},focusdir,right + bind=${bindCfg.move-window-focus.up},focusdir,up + bind=${bindCfg.move-window-focus.down},focusdir,down + + # swap window + bind=${bindCfg.move-window.up},exchange_client,up + bind=${bindCfg.move-window.down},exchange_client,down + bind=${bindCfg.move-window.left},exchange_client,left + bind=${bindCfg.move-window.right},exchange_client,right + + # switch window status + bind=SUPER,g,toggleglobal, + bind=${bindCfg.toggle-overview},toggleoverview, + bind=${bindCfg.toggle-float},togglefloating, + bind=${bindCfg.maximize-column},togglemaximizescreen, + # bind=${bindCfg.toggle-fullscreen},togglefullscreen, + bind=${bindCfg.toggle-fullscreen},togglefakefullscreen, + bind=${bindCfg.minimize},minimized, + # bind=SUPER,o,toggleoverlay, + bind=${bindCfg.restore-minimize},restore_minimized + bind=${bindCfg.toggle-scratchpad},toggle_scratchpad + + # scroller layout + bind=${bindCfg.expand-column-to-available-width},set_proportion,1.0 + bind=${bindCfg.switch-preset-column-width},switch_proportion_preset, + + # switch layout + bind=${bindCfg.switch-layout},switch_layout + + # tag switch + bind=SUPER,Left,viewtoleft,0 + bind=CTRL,Left,viewtoleft_have_client,0 + bind=SUPER,Right,viewtoright,0 + bind=CTRL,Right,viewtoright_have_client,0 + bind=CTRL+SUPER,Left,tagtoleft,0 + bind=CTRL+SUPER,Right,tagtoright,0 + + bind=${bindCfg.focus-workspace-prefix},1,view,1,0 + bind=${bindCfg.focus-workspace-prefix},2,view,2,0 + bind=${bindCfg.focus-workspace-prefix},3,view,3,0 + bind=${bindCfg.focus-workspace-prefix},4,view,4,0 + bind=${bindCfg.focus-workspace-prefix},5,view,5,0 + bind=${bindCfg.focus-workspace-prefix},6,view,6,0 + bind=${bindCfg.focus-workspace-prefix},7,view,7,0 + bind=${bindCfg.focus-workspace-prefix},8,view,8,0 + bind=${bindCfg.focus-workspace-prefix},9,view,9,0 + + # tag: move client to the tag and focus it + # tagsilent: move client to the tag and not focus it + # bind=Alt,1,tagsilent,1 + bind=Alt,1,tag,1,0 + bind=Alt,2,tag,2,0 + bind=Alt,3,tag,3,0 + bind=Alt,4,tag,4,0 + bind=Alt,5,tag,5,0 + bind=Alt,6,tag,6,0 + bind=Alt,7,tag,7,0 + bind=Alt,8,tag,8,0 + bind=Alt,9,tag,9,0 + + # monitor switch + bind=${bindCfg.move-monitor-focus.left},focusmon,left + bind=${bindCfg.move-monitor-focus.right},Right,focusmon,right + bind=SUPER+Alt,Left,tagmon,left + bind=SUPER+Alt,Right,tagmon,right + + # gaps + # bind=ALT+SHIFT,X,incgaps,1 + # bind=ALT+SHIFT,Z,incgaps,-1 + # bind=ALT+SHIFT,R,togglegaps + + # movewin + bind=CTRL+SHIFT,Up,movewin,+0,-50 + bind=CTRL+SHIFT,Down,movewin,+0,+50 + bind=CTRL+SHIFT,Left,movewin,-50,+0 + bind=CTRL+SHIFT,Right,movewin,+50,+0 + + # resizewin + bind=CTRL+ALT,Up,resizewin,+0,-50 + bind=CTRL+ALT,Down,resizewin,+0,+50 + bind=CTRL+ALT,Left,resizewin,-50,+0 + bind=CTRL+ALT,Right,resizewin,+50,+0 + + # Mouse Button Bindings + # NONE mode key only work in ov mode + mousebind=SUPER,btn_left,moveresize,curmove + mousebind=NONE,btn_middle,togglemaximizescreen,0 + mousebind=SUPER,btn_right,moveresize,curresize + mousebind=NONE,btn_left,toggleoverview,1 + mousebind=NONE,btn_right,killclient,0 + + # Axis Bindings + axisbind=SUPER,UP,viewtoleft_have_client + axisbind=SUPER,DOWN,viewtoright_have_client + + + # layer rule + layerrule=animation_type_open:zoom,layer_name:rofi + layerrule=animation_type_close:zoom,layer_name:rofi + ''; + autostart_sh = '' + ${wmCfg.exec-once} + ''; + }; + } + ) + ]; + }; +} diff --git a/system/modules/niri.nix b/system/modules/niri.nix index f243c28..63d0152 100755 --- a/system/modules/niri.nix +++ b/system/modules/niri.nix @@ -7,308 +7,264 @@ let inherit (lib) getExe + mkIf pipe + mapAttrs ; inherit (builtins) fetchurl genList listToAttrs; inherit (config.systemConf) username; - # nvidia-offload-enabled = config.hardware.nvidia.prime.offload.enableOffloadCmd; - prefix = "nvidia-offload"; - terminal = "ghostty"; - browser = "zen-twilight"; - - brightnessStep = toString 10; - volumeStep = toString 4; - - execOnceScript = pkgs.writeShellScript "startupExec" '' - # Fix nemo open in terminal - dconf write /org/cinnamon/desktop/applications/terminal/exec "''\'${terminal}''\'" & - dconf write /org/cinnamon/desktop/applications/terminal/exec-arg "''\'''\'" & - - # Hint dark theme - dconf write /org/gnome/desktop/interface/color-scheme '"prefer-dark"' & - - systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP QT_QPA_PLATFORMTHEME & - ''; - niri_peekaboo = fetchurl { url = "https://raw.githubusercontent.com/heyoeyo/niri_tweaks/refs/heads/main/niri_peekaboo.py"; sha256 = "sha256:0l1x0bsa9vr089jhzgcz3xbh1hg15sw6njb91q0j9pdbrp2ym3dc"; }; in { - programs.niri = { - enable = true; - package = pkgs.niri-unstable; - }; - - home-manager.users."${username}" = - { - osConfig, - config, - ... - }: - let - rofiWall = import ../../home/scripts/rofiwall.nix { inherit config pkgs; }; - rbwSelector = import ../../home/scripts/rbwSelector.nix { inherit pkgs; }; - rNiri = pkgs.writeShellScriptBin "rNiri" '' - NIRI_SOCKET="/run/user/1000/$(ls /run/user/1000 | grep niri | head -n 1)" niri $@ - ''; - toggleWlogout = pkgs.writeShellScript "toggleWlogout" '' - if ${pkgs.busybox}/bin/pgrep wlogout > /dev/null; then - ${pkgs.busybox}/bin/pkill wlogout - else - ${config.programs.wlogout.package}/bin/wlogout --protocol layer-shell - fi - ''; - in - with config.lib.niri.actions; - { - home.packages = with pkgs; [ - nautilus # xdg-desktop-portal-gnome file picker - rNiri - ]; - - xdg.portal = { - extraPortals = with pkgs; [ xdg-desktop-portal-gtk ]; - }; - - services.nfsm.enable = true; - - programs.niri.package = osConfig.programs.niri.package; - programs.niri.settings = { - spawn-at-startup = [ - { argv = [ "${execOnceScript}" ]; } - ]; - screenshot-path = "~/Pictures/Screenshots/%Y-%m-%d_%H-%M-%S.png"; - - prefer-no-csd = true; - - xwayland-satellite = { - enable = true; - path = getExe pkgs.xwayland-satellite-unstable; - }; - - animations = { - workspace-switch.kind.spring = { - damping-ratio = 1.0; - stiffness = 1000; - epsilon = 0.0001; - }; - - window-open.kind.easing = { - duration-ms = 150; - curve = "ease-out-expo"; - }; - - window-close.kind.easing = { - duration-ms = 150; - curve = "ease-out-quad"; - }; - - window-resize.kind.spring = { - damping-ratio = 1.0; - stiffness = 800; - epsilon = 0.0001; - }; - }; - - layout.border = { - enable = true; - width = 4; - active.gradient = { - from = "#24273A"; - to = "#EBDBB2"; - angle = 45; - in' = "oklab"; - relative-to = "window"; - }; - inactive.gradient = { - from = "#24273A"; - to = "#24273A"; - angle = 45; - in' = "oklab"; - relative-to = "window"; - }; - }; - - window-rules = [ - # Global - { - geometry-corner-radius = - let - round = 12.0; - in - { - bottom-left = round; - bottom-right = round; - top-left = round; - top-right = round; - }; - clip-to-geometry = true; - opacity = 1.0; - draw-border-with-background = false; - } - # Float - { - matches = [ - { app-id = "^xdg-desktop-portal-gtk$"; } - { app-id = "^(org.gnome.Nautilus)$"; } - { app-id = "^(org.gnome.Loupe)$"; } - ]; - open-floating = true; - } - ]; - - input = { - focus-follows-mouse = { - max-scroll-amount = "90%"; - enable = true; - }; - mouse.accel-speed = -0.1; - keyboard = { - repeat-delay = 250; - repeat-rate = 35; - }; - }; - - binds = - let - sh = spawn "sh" "-c"; - in - { - # ==== Launch ==== # - "Mod+Return".action = sh "${prefix} ${terminal}"; - "Mod+F".action = sh "${browser}"; - "Mod+E".action = sh "${prefix} ${terminal} -e yazi"; - "Mod+Ctrl+P".action = spawn "${rbwSelector}"; - "Mod+Ctrl+M".action = spawn "${toggleWlogout}"; - - # Rofi - "Mod+Ctrl+W".action = spawn "${rofiWall}"; - "Alt+Space".action = spawn "rofi" "-config" "~/.config/rofi/apps.rasi" "-show" "drun"; - "Mod+Period".action = spawn "rofi" "-modi" "emoji" "-show" "emoji"; - "Mod+Ctrl+C".action = spawn "rofi" "-modi" "calc" "-show" "calc" "-no-show-match" "-no-sort"; - - # ==== Media ==== # - "XF86AudioPrev".action = spawn "playerctl" "previous"; - "XF86AudioNext".action = spawn "playerctl" "next"; - "Mod+Ctrl+Comma".action = spawn "playerctl" "previous"; - "Mod+Ctrl+Period".action = spawn "playerctl" "next"; - "XF86AudioPlay".action = spawn "playerctl" "play-pause"; - "XF86AudioStop".action = spawn "playerctl" "stop"; - "XF86AudioMute".action = spawn "wpctl" "set-mute" "@DEFAULT_SINK@" "toggle"; - "XF86AudioRaiseVolume".action = - sh "wpctl set-mute @DEFAULT_SINK@ 0 && wpctl set-volume @DEFAULT_SINK@ ${volumeStep}%+"; - "XF86AudioLowerVolume".action = - sh "wpctl set-mute @DEFAULT_SINK@ 0 && wpctl set-volume @DEFAULT_SINK@ ${volumeStep}%-"; - "XF86MonBrightnessDown".action = spawn "brightnessctl set ${brightnessStep}%-"; - "XF86MonBrightnessUp".action = spawn "brightnessctl set ${brightnessStep}%+"; - - # ==== Movement ==== # - # Mouse Scroll - "Mod+WheelScrollDown" = { - cooldown-ms = 150; - action = focus-workspace-down; - }; - "Mod+WheelScrollUp" = { - cooldown-ms = 150; - action = focus-workspace-up; - }; - "Mod+Shift+WheelScrollDown" = { - cooldown-ms = 150; - action = focus-column-or-monitor-right; - }; - "Mod+Shift+WheelScrollUp" = { - cooldown-ms = 150; - action = focus-column-or-monitor-left; - }; - "Mod+WheelScrollRight".action = focus-column-right; - "Mod+WheelScrollLeft".action = focus-column-left; - - # Touchpad - "Mod+TouchpadScrollDown" = { - cooldown-ms = 150; - action = focus-window-or-workspace-down; - }; - "Mod+TouchpadScrollUp" = { - cooldown-ms = 150; - action = focus-window-or-workspace-up; - }; - - # Monitor Focus - "Mod+Ctrl+H".action = focus-monitor-left; - "Mod+Ctrl+L".action = focus-monitor-right; - - # Workspace Focus - "Mod+Ctrl+J".action = focus-workspace-down; - "Mod+Ctrl+K".action = focus-workspace-up; - - # General Focus - "Mod+J".action = focus-window-or-workspace-down; - "Mod+K".action = focus-window-or-workspace-up; - "Mod+H".action = focus-column-or-monitor-left; - "Mod+L".action = focus-column-or-monitor-right; - - # Workspace Move - "Mod+Ctrl+Shift+J".action = move-workspace-down; - "Mod+Ctrl+Shift+K".action = move-workspace-up; - - # Window & Column Move - "Mod+Shift+J".action = move-window-down-or-to-workspace-down; - "Mod+Shift+K".action = move-window-up-or-to-workspace-up; - "Mod+Shift+L".action = move-column-right-or-to-monitor-right; - "Mod+Shift+H".action = move-column-left-or-to-monitor-left; - - # Window Comsume - "Mod+Ctrl+Shift+L".action = consume-or-expel-window-right; - "Mod+Ctrl+Shift+H".action = consume-or-expel-window-left; - - # ==== Action ==== # - # General - "Mod+C".action = center-window; - "Mod+O".action = toggle-overview; - "Mod+Q".action = close-window; - "F11".action = if config.services.nfsm.enable then (spawn "nfsm-cli") else fullscreen-window; - "Mod+Shift+slash".action = show-hotkey-overlay; - "Mod+Ctrl+Shift+P".action = spawn "${getExe pkgs.python312}" "${niri_peekaboo}"; - - # Column Scale - "Mod+W".action = switch-preset-column-width; - "Mod+S".action = switch-preset-window-height; - "Mod+P".action = expand-column-to-available-width; - "Mod+M".action = maximize-column; - "Mod+Ctrl+S".action = reset-window-height; - - # Float - "Mod+V".action = toggle-window-floating; - "Mod+Ctrl+V".action = switch-focus-between-floating-and-tiling; - - # Screenshot - "Mod+Shift+S".action.screenshot = [ { show-pointer = false; } ]; - "Ctrl+Shift+S".action.screenshot-window = [ - { - write-to-disk = false; - } - ]; - "Mod+Ctrl+Shift+S".action.screenshot-screen = [ - { - write-to-disk = false; - } - ]; - } - # Map Mod+{1 ~ 9} to workspace{1 ~ 9} - // (pipe 9 [ - (x: genList (i: i + 1) x) - ( - x: - map (i: { - name = "Mod+${toString i}"; - value.action = focus-workspace i; - }) x - ) - (x: listToAttrs x) - ]); - }; + config = mkIf config.programs.niri.enable { + programs.niri = { + package = pkgs.niri-unstable; }; + + home-manager.users."${username}" = + { + osConfig, + config, + ... + }: + let + rNiri = pkgs.writeShellScriptBin "rNiri" '' + NIRI_SOCKET="/run/user/1000/$(ls /run/user/1000 | grep niri | head -n 1)" niri $@ + ''; + wmCfg = config.wm; + bindCfg = wmCfg.keybinds; + in + with config.lib.niri.actions; + { + home.packages = with pkgs; [ + nautilus # xdg-desktop-portal-gnome file picker + rNiri + ]; + + xdg.portal = { + extraPortals = with pkgs; [ xdg-desktop-portal-gtk ]; + }; + + services.nfsm.enable = true; + + programs.niri.package = osConfig.programs.niri.package; + programs.niri.settings = { + spawn-at-startup = [ + { argv = [ "${wmCfg.exec-once}" ]; } + ]; + screenshot-path = "~/Pictures/Screenshots/%Y-%m-%d_%H-%M-%S.png"; + + prefer-no-csd = true; + + xwayland-satellite = { + enable = true; + path = getExe pkgs.xwayland-satellite-unstable; + }; + + animations = { + workspace-switch.kind.spring = { + damping-ratio = 1.0; + stiffness = 1000; + epsilon = 0.0001; + }; + + window-open.kind.easing = { + duration-ms = 150; + curve = "ease-out-expo"; + }; + + window-close.kind.easing = { + duration-ms = 150; + curve = "ease-out-quad"; + }; + + window-resize.kind.spring = { + damping-ratio = 1.0; + stiffness = 800; + epsilon = 0.0001; + }; + }; + + layout.border = { + enable = true; + width = 4; + active.gradient = { + from = wmCfg.border.active.from; + to = wmCfg.border.active.to; + angle = wmCfg.border.active.angle; + in' = "oklab"; + relative-to = "window"; + }; + inactive.gradient = { + from = wmCfg.border.inactive.from; + to = wmCfg.border.inactive.to; + angle = wmCfg.border.inactive.angle; + in' = "oklab"; + relative-to = "window"; + }; + }; + + window-rules = [ + # Global + { + geometry-corner-radius = + let + round = wmCfg.border.radius + 0.0; + in + { + bottom-left = round; + bottom-right = round; + top-left = round; + top-right = round; + }; + clip-to-geometry = true; + opacity = 1.0; + draw-border-with-background = false; + } + # Float + { + matches = [ + { app-id = "^xdg-desktop-portal-gtk$"; } + { app-id = "^(org.gnome.Nautilus)$"; } + { app-id = "^(org.gnome.Loupe)$"; } + ]; + open-floating = true; + } + ]; + + input = { + focus-follows-mouse = { + max-scroll-amount = "90%"; + enable = true; + }; + mouse.accel-speed = -0.1; + keyboard = { + repeat-delay = wmCfg.input.keyboard.repeat-delay; + repeat-rate = wmCfg.input.keyboard.repeat-rate; + }; + }; + + binds = + let + sh = spawn "sh" "-c"; + spawnKeybinds = mapAttrs (name: value: { + action = sh value; + }) (wmCfg.keybinds.spawn-repeat // wmCfg.keybinds.spawn); + in + spawnKeybinds + // { + # ==== Movement ==== # + # Mouse Scroll + "Mod+WheelScrollDown" = { + cooldown-ms = 150; + action = focus-workspace-down; + }; + "Mod+WheelScrollUp" = { + cooldown-ms = 150; + action = focus-workspace-up; + }; + "Mod+Shift+WheelScrollDown" = { + cooldown-ms = 150; + action = focus-column-or-monitor-right; + }; + "Mod+Shift+WheelScrollUp" = { + cooldown-ms = 150; + action = focus-column-or-monitor-left; + }; + "Mod+WheelScrollRight".action = focus-column-right; + "Mod+WheelScrollLeft".action = focus-column-left; + + # Touchpad + "Mod+TouchpadScrollDown" = { + cooldown-ms = 150; + action = focus-window-or-workspace-down; + }; + "Mod+TouchpadScrollUp" = { + cooldown-ms = 150; + action = focus-window-or-workspace-up; + }; + + # Monitor Focus + "${bindCfg.move-monitor-focus.left}".action = focus-monitor-left; + "${bindCfg.move-monitor-focus.right}".action = focus-monitor-right; + + # Workspace Focus + "${bindCfg.move-workspace-focus.next}".action = focus-workspace-down; + "${bindCfg.move-workspace-focus.prev}".action = focus-workspace-up; + + # General Focus + "${bindCfg.move-window-focus.down}".action = focus-window-or-workspace-down; + "${bindCfg.move-window-focus.up}".action = focus-window-or-workspace-up; + "${bindCfg.move-window-focus.left}".action = focus-column-or-monitor-left; + "${bindCfg.move-window-focus.right}".action = focus-column-or-monitor-right; + + # Workspace Move + "${bindCfg.move-workspace.down}".action = move-workspace-down; + "${bindCfg.move-workspace.up}".action = move-workspace-up; + + # Window & Column Move + "${bindCfg.move-window.down}".action = move-window-down-or-to-workspace-down; + "${bindCfg.move-window.up}".action = move-window-up-or-to-workspace-up; + "${bindCfg.move-window.right}".action = move-column-right-or-to-monitor-right; + "${bindCfg.move-window.left}".action = move-column-left-or-to-monitor-left; + + # Window Comsume + "${bindCfg.consume-window.right}".action = consume-or-expel-window-right; + "${bindCfg.consume-window.left}".action = consume-or-expel-window-left; + + # ==== Action ==== # + # General + "${bindCfg.center-window}".action = center-window; + "${bindCfg.toggle-overview}".action = toggle-overview; + "${bindCfg.close-window}".action = close-window; + "${bindCfg.toggle-fullscreen}".action = + if config.services.nfsm.enable then (spawn "nfsm-cli") else fullscreen-window; + "Mod+Shift+slash".action = show-hotkey-overlay; + "Mod+Ctrl+Shift+P".action = spawn "${getExe pkgs.python312}" "${niri_peekaboo}"; + + # Column Scale + "${bindCfg.switch-preset-column-width}".action = switch-preset-column-width; + "${bindCfg.switch-preset-window-height}".action = switch-preset-window-height; + "${bindCfg.expand-column-to-available-width}".action = expand-column-to-available-width; + "${bindCfg.maximize-column}".action = maximize-column; + "${bindCfg.reset-window-height}".action = reset-window-height; + + # Float + "${bindCfg.toggle-float}".action = toggle-window-floating; + "${bindCfg.switch-focus-between-floating-and-tiling}".action = + switch-focus-between-floating-and-tiling; + + # Screenshot + "${bindCfg.screenshot.area}".action.screenshot = [ { show-pointer = false; } ]; + "${bindCfg.screenshot.window}".action.screenshot-window = [ + { + write-to-disk = false; + } + ]; + "${bindCfg.screenshot.screen}".action.screenshot-screen = [ + { + write-to-disk = false; + } + ]; + } + # Map Mod+{1 ~ 9} to workspace{1 ~ 9} + // (pipe 9 [ + (x: genList (i: i + 1) x) + ( + x: + map (i: { + name = "${bindCfg.focus-workspace-prefix}+${toString i}"; + value.action = focus-workspace i; + }) x + ) + (x: listToAttrs x) + ]); + }; + }; + + }; } diff --git a/system/modules/presets/basic.nix b/system/modules/presets/basic.nix index e62cb63..b0fed11 100755 --- a/system/modules/presets/basic.nix +++ b/system/modules/presets/basic.nix @@ -11,6 +11,7 @@ ../polkit.nix ../hyprland.nix ../niri.nix + ../mango.nix ]; programs.gdk-pixbuf.modulePackages = [ pkgs.librsvg ]; diff --git a/system/modules/shells/noctalia/default.nix b/system/modules/shells/noctalia/default.nix index 91c24dd..fdf42fc 100755 --- a/system/modules/shells/noctalia/default.nix +++ b/system/modules/shells/noctalia/default.nix @@ -3,7 +3,13 @@ let inherit (config.systemConf) username; inherit (builtins) mapAttrs; - inherit (lib) mkForce; + inherit (lib) + mkForce + removePrefix + concatStringsSep + mapAttrsToList + mkIf + ; in { @@ -15,7 +21,13 @@ in # ================================= # home-manager.users.${username} = - { config, ... }: + { osConfig, config, ... }: + let + wmCfg = config.wm; + bindCfg = wmCfg.keybinds; + mod = wmCfg.keybinds.mod; + sep = wmCfg.keybinds.separator; + in { # ==== Disabled Services ==== # services.swww.enable = mkForce false; # Wallpaper @@ -29,6 +41,21 @@ in "QT_QPA_PLATFORMTHEME=gtk3" ]; + wm.keybinds.spawn-repeat = { + # ==== Media ==== # + "XF86AudioPrev" = ''noctalia "media" "previous"''; + "XF86AudioNext" = ''noctalia "media" "next"''; + "${mod}${sep}CTRL${sep}COMMA" = ''noctalia "media" "previous"''; + "${mod}${sep}CTRL${sep}PERIOD" = ''noctalia "media" "next"''; + "XF86AudioPlay" = ''noctalia "media" "playPause"''; + "XF86AudioStop" = ''noctalia "media" "pause"''; + "XF86AudioMute" = ''noctalia "volume" "muteOutput"''; + "XF86AudioRaiseVolume" = ''noctalia "volume" "increase"''; + "XF86AudioLowerVolume" = ''noctalia "volume" "decrease"''; + "XF86MonBrightnessDown" = ''noctalia "brightness" "decrease"''; + "XF86MonBrightnessUp" = ''noctalia "brightness" "increase"''; + }; + programs.noctalia-shell = { enable = true; systemd.enable = true; @@ -43,7 +70,7 @@ in ]; position = "top_center"; sortByMostUsed = true; - terminalCommand = "ghostty -e"; + terminalCommand = "${wmCfg.app.terminal.run}"; useApp2Unit = false; viewMode = "list"; }; @@ -244,7 +271,7 @@ in }; }; - programs.niri.settings = + programs.niri.settings = mkIf osConfig.programs.niri.enable ( with config.lib.niri.actions; let noctalia = spawn "noctalia-shell" "ipc" "call"; @@ -252,33 +279,310 @@ in { binds = mapAttrs (name: value: mkForce value) { # Core - "Mod+Slash".action = noctalia "controlCenter" "toggle"; - "Alt+Space".action = noctalia "launcher" "toggle"; - "Mod+Ctrl+M".action = noctalia "lockScreen" "lock"; + "${bindCfg.toggle-control-center}".action = noctalia "controlCenter" "toggle"; + "${bindCfg.toggle-launcher}".action = noctalia "launcher" "toggle"; + "${bindCfg.lock-screen}".action = noctalia "lockScreen" "lock"; # Utilities - "Mod+Comma".action = noctalia "launcher" "clipboard"; - "Mod+Period".action = noctalia "launcher" "emoji"; - "Mod+F12".action = noctalia "screenRecorder" "toggle"; - "Mod+N".action = noctalia "notifications" "toggleHistory"; - "Mod+Ctrl+N".action = noctalia "notifications" "toggleDND"; - "Mod+Ctrl+W".action = noctalia "wallpaper" "toggle"; - "Mod+Ctrl+C".action = noctalia "launcher" "calculator"; - "Mod+Ctrl+Slash".action = noctalia "wallpaper" "random"; + "${bindCfg.clipboard-history}".action = noctalia "launcher" "clipboard"; + "${bindCfg.emoji}".action = noctalia "launcher" "emoji"; + "${bindCfg.screen-recorder}".action = noctalia "screenRecorder" "toggle"; + "${bindCfg.notification-center}".action = noctalia "notifications" "toggleHistory"; + "${bindCfg.toggle-dont-disturb}".action = noctalia "notifications" "toggleDND"; + "${bindCfg.wallpaper-selector}".action = noctalia "wallpaper" "toggle"; + "${bindCfg.calculator}".action = noctalia "launcher" "calculator"; + "${bindCfg.wallpaper-random}".action = noctalia "wallpaper" "random"; # Media "XF86AudioPlay".action = noctalia "media" "playPause"; "XF86AudioStop".action = noctalia "media" "pause"; "XF86AudioPrev".action = noctalia "media" "previous"; "XF86AudioNext".action = noctalia "media" "next"; - "Mod+Ctrl+Comma".action = noctalia "media" "previous"; - "Mod+Ctrl+Period".action = noctalia "media" "next"; + "${bindCfg.media.prev}".action = noctalia "media" "previous"; + "${bindCfg.media.next}".action = noctalia "media" "next"; "XF86AudioMute".action = noctalia "volume" "muteOutput"; "XF86AudioRaiseVolume".action = noctalia "volume" "increase"; "XF86AudioLowerVolume".action = noctalia "volume" "decrease"; "XF86MonBrightnessDown".action = noctalia "brightness" "decrease"; "XF86MonBrightnessUp".action = noctalia "brightness" "increase"; }; - }; + } + ); + + wayland.windowManager.mango.settings = mkIf osConfig.programs.mango.enable ( + mkForce ( + let + keybinds = concatStringsSep "\n" ( + mapAttrsToList (n: v: "bind=${n},spawn,${v}") (bindCfg.spawn-repeat // bindCfg.spawn) + ); + in + '' + # Window effect + blur=0 + blur_layer=0 + blur_optimized=1 + blur_params_num_passes = 2 + blur_params_radius = 5 + blur_params_noise = 0.02 + blur_params_brightness = 0.9 + blur_params_contrast = 0.9 + blur_params_saturation = 1.2 + + shadows = 0 + layer_shadows = 0 + shadow_only_floating = 1 + shadows_size = 10 + shadows_blur = 15 + shadows_position_x = 0 + shadows_position_y = 0 + shadowscolor= 0x000000ff + + border_radius=${toString wmCfg.border.radius} + no_radius_when_single=0 + focused_opacity=${toString wmCfg.window.opacity} + unfocused_opacity=${toString wmCfg.window.opacity} + + # Animation Configuration(support type:zoom,slide) + # tag_animation_direction: 1-horizontal,0-vertical + animations=1 + layer_animations=1 + animation_type_open=slide + animation_type_close=slide + animation_fade_in=1 + animation_fade_out=1 + tag_animation_direction=1 + zoom_initial_ratio=0.3 + zoom_end_ratio=0.8 + fadein_begin_opacity=0.5 + fadeout_begin_opacity=0.8 + animation_duration_move=500 + animation_duration_open=400 + animation_duration_tag=350 + animation_duration_close=800 + animation_duration_focus=0 + animation_curve_open=0.46,1.0,0.29,1 + animation_curve_move=0.46,1.0,0.29,1 + animation_curve_tag=0.46,1.0,0.29,1 + animation_curve_close=0.08,0.92,0,1 + animation_curve_focus=0.46,1.0,0.29,1 + animation_curve_opafadeout=0.5,0.5,0.5,0.5 + animation_curve_opafadein=0.46,1.0,0.29,1 + + # Scroller Layout Setting + scroller_structs=20 + scroller_default_proportion=0.8 + scroller_focus_center=0 + scroller_prefer_center=0 + edge_scroller_pointer_focus=1 + scroller_default_proportion_single=1.0 + scroller_proportion_preset=0.5,0.8,1.0 + + # Master-Stack Layout Setting + new_is_master=1 + default_mfact=0.55 + default_nmaster=1 + smartgaps=0 + + # Overview Setting + hotarea_size=10 + enable_hotarea=1 + ov_tab_mode=0 + overviewgappi=5 + overviewgappo=30 + + # Misc + no_border_when_single=0 + axis_bind_apply_timeout=100 + focus_on_activate=1 + idleinhibit_ignore_visible=0 + sloppyfocus=1 + warpcursor=1 + focus_cross_monitor=0 + focus_cross_tag=0 + enable_floating_snap=0 + snap_distance=30 + cursor_size=24 + drag_tile_to_tile=1 + + # keyboard + repeat_rate=${toString wmCfg.input.keyboard.repeat-rate} + repeat_delay=${toString wmCfg.input.keyboard.repeat-delay} + numlockon=0 + xkb_rules_layout=us + + # Trackpad + # need relogin to make it apply + disable_trackpad=0 + tap_to_click=1 + tap_and_drag=1 + drag_lock=1 + trackpad_natural_scrolling=0 + disable_while_typing=1 + left_handed=0 + middle_button_emulation=0 + swipe_min_threshold=1 + + # mouse + # need relogin to make it apply + mouse_natural_scrolling=0 + + # Appearance + gappih=5 + gappiv=5 + gappoh=10 + gappov=10 + scratchpad_width_ratio=0.8 + scratchpad_height_ratio=0.9 + borderpx=4 + rootcolor=0x${removePrefix "#" wmCfg.border.active.to}ff + bordercolor=0x${removePrefix "#" wmCfg.border.active.from}ff + focuscolor=0x${removePrefix "#" wmCfg.border.active.to}ff + maximizescreencolor=0x89aa61ff + urgentcolor=0xad401fff + scratchpadcolor=0x516c93ff + globalcolor=0xb153a7ff + overlaycolor=0x14a57cff + + # layout support: + # tile,scroller,grid,deck,monocle,center_tile,vertical_tile,vertical_scroller + tagrule=id:1,layout_name:tile + tagrule=id:2,layout_name:tile + tagrule=id:3,layout_name:tile + tagrule=id:4,layout_name:tile + tagrule=id:5,layout_name:tile + tagrule=id:6,layout_name:tile + tagrule=id:7,layout_name:tile + tagrule=id:8,layout_name:tile + tagrule=id:9,layout_name:tile + + # Key Bindings + # key name refer to `xev` or `wev` command output, + # mod keys name: super,ctrl,alt,shift,none + + ${keybinds} + + # exit + bind=${bindCfg.close-window},killclient + + # switch window focus + bind=${bindCfg.switch-window-focus},focusstack,next + bind=${bindCfg.move-window-focus.left},focusdir,left + bind=${bindCfg.move-window-focus.right},focusdir,right + bind=${bindCfg.move-window-focus.up},focusdir,up + bind=${bindCfg.move-window-focus.down},focusdir,down + + # swap window + bind=${bindCfg.move-window.up},exchange_client,up + bind=${bindCfg.move-window.down},exchange_client,down + bind=${bindCfg.move-window.left},exchange_client,left + bind=${bindCfg.move-window.right},exchange_client,right + + # switch window status + bind=SUPER,g,toggleglobal, + bind=${bindCfg.toggle-overview},toggleoverview, + bind=${bindCfg.toggle-float},togglefloating, + bind=${bindCfg.maximize-column},togglemaximizescreen, + # bind=${bindCfg.toggle-fullscreen},togglefullscreen, + bind=${bindCfg.toggle-fullscreen},togglefakefullscreen, + bind=${bindCfg.minimize},minimized, + # bind=SUPER,o,toggleoverlay, + bind=${bindCfg.restore-minimize},restore_minimized + bind=${bindCfg.toggle-scratchpad},toggle_scratchpad + + # scroller layout + bind=${bindCfg.expand-column-to-available-width},set_proportion,1.0 + bind=${bindCfg.switch-preset-column-width},switch_proportion_preset, + + # switch layout + bind=${bindCfg.switch-layout},switch_layout + + # tag switch + bind=SUPER,Left,viewtoleft,0 + bind=CTRL,Left,viewtoleft_have_client,0 + bind=SUPER,Right,viewtoright,0 + bind=CTRL,Right,viewtoright_have_client,0 + bind=CTRL+SUPER,Left,tagtoleft,0 + bind=CTRL+SUPER,Right,tagtoright,0 + + bind=${bindCfg.focus-workspace-prefix},1,view,1,0 + bind=${bindCfg.focus-workspace-prefix},2,view,2,0 + bind=${bindCfg.focus-workspace-prefix},3,view,3,0 + bind=${bindCfg.focus-workspace-prefix},4,view,4,0 + bind=${bindCfg.focus-workspace-prefix},5,view,5,0 + bind=${bindCfg.focus-workspace-prefix},6,view,6,0 + bind=${bindCfg.focus-workspace-prefix},7,view,7,0 + bind=${bindCfg.focus-workspace-prefix},8,view,8,0 + bind=${bindCfg.focus-workspace-prefix},9,view,9,0 + + # tag: move client to the tag and focus it + # tagsilent: move client to the tag and not focus it + # bind=Alt,1,tagsilent,1 + bind=Alt,1,tag,1,0 + bind=Alt,2,tag,2,0 + bind=Alt,3,tag,3,0 + bind=Alt,4,tag,4,0 + bind=Alt,5,tag,5,0 + bind=Alt,6,tag,6,0 + bind=Alt,7,tag,7,0 + bind=Alt,8,tag,8,0 + bind=Alt,9,tag,9,0 + + # monitor switch + bind=${bindCfg.move-monitor-focus.left},focusmon,left + bind=${bindCfg.move-monitor-focus.right},Right,focusmon,right + bind=SUPER+Alt,Left,tagmon,left + bind=SUPER+Alt,Right,tagmon,right + + # gaps + # bind=ALT+SHIFT,X,incgaps,1 + # bind=ALT+SHIFT,Z,incgaps,-1 + # bind=ALT+SHIFT,R,togglegaps + + # movewin + bind=CTRL+SHIFT,Up,movewin,+0,-50 + bind=CTRL+SHIFT,Down,movewin,+0,+50 + bind=CTRL+SHIFT,Left,movewin,-50,+0 + bind=CTRL+SHIFT,Right,movewin,+50,+0 + + # resizewin + bind=CTRL+ALT,Up,resizewin,+0,-50 + bind=CTRL+ALT,Down,resizewin,+0,+50 + bind=CTRL+ALT,Left,resizewin,-50,+0 + bind=CTRL+ALT,Right,resizewin,+50,+0 + + # Mouse Button Bindings + # NONE mode key only work in ov mode + mousebind=SUPER,btn_left,moveresize,curmove + mousebind=NONE,btn_middle,togglemaximizescreen,0 + mousebind=SUPER,btn_right,moveresize,curresize + mousebind=NONE,btn_left,toggleoverview,1 + mousebind=NONE,btn_right,killclient,0 + + # Axis Bindings + axisbind=SUPER,UP,viewtoleft_have_client + axisbind=SUPER,DOWN,viewtoright_have_client + + + # layer rule + layerrule=animation_type_open:zoom,layer_name:rofi + layerrule=animation_type_close:zoom,layer_name:rofi + + # Core + ${bindCfg.toggle-control-center},spawn,noctalia "controlCenter" "toggle"; + ${bindCfg.toggle-launcher},spawn,noctalia "launcher" "toggle"; + ${bindCfg.lock-screen},spawn,noctalia "lockScreen" "lock"; + + # Utilities + ${bindCfg.clipboard-history},spawn,noctalia "launcher" "clipboard"; + ${bindCfg.emoji},spawn,noctalia "launcher" "emoji"; + ${bindCfg.screen-recorder},spawn,noctalia "screenRecorder" "toggle"; + ${bindCfg.notification-center},spawn,noctalia "notifications" "toggleHistory"; + ${bindCfg.toggle-dont-disturb},spawn,noctalia "notifications" "toggleDND"; + ${bindCfg.wallpaper-selector},spawn,noctalia "wallpaper" "toggle"; + ${bindCfg.calculator},spawn,noctalia "launcher" "calculator"; + ${bindCfg.wallpaper-random},spawn,noctalia "wallpaper" "random"; + '' + ) + ); }; } diff --git a/system/modules/stalwart.nix b/system/modules/stalwart.nix index 5e9b9a8..e006154 100755 --- a/system/modules/stalwart.nix +++ b/system/modules/stalwart.nix @@ -14,7 +14,7 @@ let inherit (lib) mkIf; - logFilePath = "${config.services.stalwart-mail.dataDir}/logs"; + logFilePath = "${config.services.stalwart.dataDir}/logs"; in { services.postgresql = { @@ -32,13 +32,13 @@ in systemd.tmpfiles.rules = let - inherit (config.users.users.stalwart-mail) name group; + inherit (config.users.users.stalwart) name group; in [ "d ${logFilePath} 0750 ${name} ${group} - " ]; - services.stalwart-mail = { + services.stalwart = { enable = true; openFirewall = true; settings = {