diff --git a/README.md b/README.md index fe7256a..23d3df5 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,7 @@ include_toc: true # NixOS system configurations -[toc] - -## Installation (WIP) + ## Hosts @@ -15,22 +13,33 @@ include_toc: true #### Programs -| Name | Type | -| :----------: | :-----------------: | -| KDE Plasma 6 | Desktop environment | -| Krohnkite | Auto-tiling plugin | -| Neovim | Text editor | -| Firefox | Web browser | -| Dolphin | File browser | -| qBittorrent | Torrent client | +# TODO: add a file manager -#### Games +| Name | Type | +| -----------------: | :------------------ | +| SwayFX | Wayland compositor | +| Aylur's GTK Shell | Bar and launcher | +| kitty | Terminal emulator | +| Neovim | Text editor | +| Firefox | Web browser | +| qBittorrent | Torrent client | +| LibreOffice | Office suite | +| GIMP | Photo editor | +| Inkscape | Vector image editor | +| EasyEffects | Audio equalizer | +| MusicBrainz Picard | Music tagging | +| Element | Matrix client | +| Vesktop | Discord client | -- Steam -- Minecraft (Prism Launcher) -- osu! (Lazer client) -- r2modman (Mod manager) -- ProtonUp-Qt +#### Games and game-related stuff + +| Name | Type | +| -------------: | :----------------------------------- | +| Steam | Game launcher | +| Prism Launcher | Minecraft launcher | +| osu!lazer | Rhythm game, open source version | +| r2modman | Mod manager | +| ProtonUp-Qt | Tool to update Proton-GE and similar | ### 🐳 Great Yamada | Home server @@ -38,17 +47,17 @@ include_toc: true **Still a WIP** -| Name | Type | Public-facing | -| :---------------: | :----------------------------: | :-----------: | -| Nginx | Web server and reverse proxy | x | -| PostgreSQL | Database engine | -| Forgejo | Git repository | x | -| Synapse | Matrix server | x | -| coturn | TURN server | x | -| Synapse (bridges) | Matrix server | | -| mautrix-whatsapp | WhatsApp bridge for Matrix | | -| PaperMC | Minecraft server | x | -| AdGuard Home | DNS server and content blocker | | -| Invidious | YouTube proxy | | -| SearXNG | Metasearch engine | | -| Radicale | CalDAV / CardDAV server | | +| Name | Type | Public-facing | +| ----------------: | :----------------------------- | :-----------: | +| Nginx | Web server and reverse proxy | x | +| PostgreSQL | Database engine | +| Forgejo | Git repository | x | +| Synapse | Matrix server | x | +| coturn | TURN server | x | +| Synapse (bridges) | Matrix server | | +| mautrix-whatsapp | WhatsApp bridge for Matrix | | +| PaperMC | Minecraft server | x | +| AdGuard Home | DNS server and content blocker | | +| Invidious | YouTube proxy | | +| SearXNG | Metasearch engine | | +| Radicale | CalDAV / CardDAV server | | diff --git a/common/nixos.nix b/common/nixos.nix index 2c8a76e..9676bb7 100644 --- a/common/nixos.nix +++ b/common/nixos.nix @@ -39,6 +39,7 @@ persist = true; }]; }; + polkit.enable = true; rtkit.enable = true; sudo.enable = false; }; diff --git a/flake.lock b/flake.lock index e46bc2b..60d4bf9 100644 --- a/flake.lock +++ b/flake.lock @@ -1,19 +1,39 @@ { "nodes": { + "ags": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1722047935, + "narHash": "sha256-ZgCY8wttXuGlpja4S5MzDJMM8jkaetAmUPplsAQL+NA=", + "owner": "ozwaldorf", + "repo": "ags", + "rev": "ee5f76545831c3d1e5305988dd9d8a8ef9c5cea1", + "type": "github" + }, + "original": { + "owner": "ozwaldorf", + "repo": "ags", + "type": "github" + } + }, "devshell": { "inputs": { - "flake-utils": "flake-utils", "nixpkgs": [ "nixvim", "nixpkgs" ] }, "locked": { - "lastModified": 1717408969, - "narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=", + "lastModified": 1722113426, + "narHash": "sha256-Yo/3loq572A8Su6aY5GP56knpuKYRvM2a1meP9oJZCw=", "owner": "numtide", "repo": "devshell", - "rev": "1ebbe68d57457c8cae98145410b164b5477761f4", + "rev": "67cce7359e4cd3c45296fb4aaf6a19e2a9c757ae", "type": "github" }, "original": { @@ -36,22 +56,6 @@ "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" } }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { "inputs": { "nixpkgs-lib": [ @@ -60,11 +64,11 @@ ] }, "locked": { - "lastModified": 1717285511, - "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=", + "lastModified": 1722555600, + "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8", + "rev": "8471fe90ad337a8074e957b69ca4d0089218391d", "type": "github" }, "original": { @@ -75,14 +79,14 @@ }, "flake-utils": { "inputs": { - "systems": "systems" + "systems": "systems_2" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -93,7 +97,10 @@ }, "git-hooks": { "inputs": { - "flake-compat": "flake-compat_2", + "flake-compat": [ + "nixvim", + "flake-compat" + ], "gitignore": "gitignore", "nixpkgs": [ "nixvim", @@ -105,11 +112,11 @@ ] }, "locked": { - "lastModified": 1719259945, - "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=", + "lastModified": 1724857454, + "narHash": "sha256-Qyl9Q4QMTLZnnBb/8OuQ9LSkzWjBU1T5l5zIzTxkkhk=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07", + "rev": "4509ca64f1084e73bc7a721b20c669a8d4c5ebe6", "type": "github" }, "original": { @@ -147,11 +154,11 @@ ] }, "locked": { - "lastModified": 1719677234, - "narHash": "sha256-qO9WZsj/0E6zcK4Ht1y/iJ8XfwbBzq7xdqhBh44OP/M=", + "lastModified": 1725180166, + "narHash": "sha256-fzssXuGR/mCeGbzM1ExaTqDz7QDGta3WA4jJsZyRruo=", "owner": "nix-community", "repo": "home-manager", - "rev": "36317d4d38887f7629876b0e43c8d9593c5cc48d", + "rev": "471e3eb0a114265bcd62d11d58ba8d3421ee68eb", "type": "github" }, "original": { @@ -168,11 +175,11 @@ ] }, "locked": { - "lastModified": 1719588253, - "narHash": "sha256-A03i8xiVgP14DCmV5P7VUv37eodCjY4e1iai0b2EuuM=", + "lastModified": 1724435763, + "narHash": "sha256-UNky3lJNGQtUEXT2OY8gMxejakSWPTfWKvpFkpFlAfM=", "owner": "nix-community", "repo": "home-manager", - "rev": "7e68e55d2e16d3a1e92a679430728c35a30fd24e", + "rev": "c2cd2a52e02f1dfa1c88f95abeb89298d46023be", "type": "github" }, "original": { @@ -210,11 +217,11 @@ ] }, "locked": { - "lastModified": 1719128254, - "narHash": "sha256-I7jMpq0CAOZA/i70+HDQO/ulLttyQu/K70cSESiMX7A=", + "lastModified": 1724561770, + "narHash": "sha256-zv8C9RNa86CIpyHwPIVO/k+5TfM8ZbjGwOOpTe1grls=", "owner": "lnl7", "repo": "nix-darwin", - "rev": "50581970f37f06a4719001735828519925ef8310", + "rev": "ac5694a0b855a981e81b4d9f14052e3ff46ca39e", "type": "github" }, "original": { @@ -225,11 +232,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1719506693, - "narHash": "sha256-C8e9S7RzshSdHB7L+v9I51af1gDM5unhJ2xO1ywxNH8=", + "lastModified": 1725432240, + "narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b2852eb9365c6de48ffb0dc2c9562591f652242a", + "rev": "ad416d066ca1222956472ab7d0555a6946746a80", "type": "github" }, "original": { @@ -241,16 +248,16 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1719099622, - "narHash": "sha256-YzJECAxFt+U5LPYf/pCwW/e1iUd2PF21WITHY9B/BAs=", + "lastModified": 1721524707, + "narHash": "sha256-5NctRsoE54N86nWd0psae70YSLfrOek3Kv1e8KoXe/0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5e8e3b89adbd0be63192f6e645e0a54080004924", + "rev": "556533a23879fc7e5f98dd2e0b31a6911a213171", "type": "github" }, "original": { "owner": "NixOS", - "ref": "release-23.11", + "ref": "release-24.05", "repo": "nixpkgs", "type": "github" } @@ -266,19 +273,43 @@ "nixpkgs": [ "nixpkgs" ], + "nuschtosSearch": "nuschtosSearch", "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1719666075, - "narHash": "sha256-65P3TcZi0s+dOc9uG6/+3bO3/IhG71RDjbkF44HjIfs=", + "lastModified": 1725545729, + "narHash": "sha256-FDremRVZu/qxpz9s0ESBC62U1IF2VuYvVFaY6MyqqFE=", "owner": "nix-community", "repo": "nixvim", - "rev": "049bbc168fe449cca37ddf3b0b56c4f93408052b", + "rev": "849c2da9d78eb6e6a258b3961df0f2ea1cb1e994", "type": "github" }, "original": { "owner": "nix-community", "repo": "nixvim", + "rev": "849c2da9d78eb6e6a258b3961df0f2ea1cb1e994", + "type": "github" + } + }, + "nuschtosSearch": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724584782, + "narHash": "sha256-7FfHv7b1jwMPSu9SPY9hdxStk8E6EeSwzqdvV69U4BM=", + "owner": "NuschtOS", + "repo": "search", + "rev": "5a08d691de30b6fc28d58ce71a5e420f2694e087", + "type": "github" + }, + "original": { + "owner": "NuschtOS", + "repo": "search", "type": "github" } }, @@ -290,11 +321,11 @@ ] }, "locked": { - "lastModified": 1719686795, - "narHash": "sha256-tc+gBY/vMUC9uqTN6DYv+uQ/8no9VOotHa5fCUxnAC0=", + "lastModified": 1725327224, + "narHash": "sha256-+cMfiE+zigDuChOFlhUH3yN7Yll9hr1LRBHsO09pqjY=", "owner": "pjones", "repo": "plasma-manager", - "rev": "1ffcff0d28f77862ab8ae6a578fc49260d47a808", + "rev": "3f1589c38428bd8121fd5deebd86ce4108b29d6e", "type": "github" }, "original": { @@ -305,6 +336,7 @@ }, "root": { "inputs": { + "ags": "ags", "home-manager": "home-manager", "nixpkgs": "nixpkgs", "nixvim": "nixvim", @@ -320,11 +352,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1719268571, - "narHash": "sha256-pcUk2Fg5vPXLUEnFI97qaB8hto/IToRfqskFqsjvjb8=", + "lastModified": 1725540166, + "narHash": "sha256-htc9rsTMSAY5ek+DB3tpntdD/es0eam2hJgO92bWSys=", "owner": "Mic92", "repo": "sops-nix", - "rev": "c2ea1186c0cbfa4d06d406ae50f3e4b085ddc9b3", + "rev": "d9d781523a1463965cd1e1333a306e70d9feff07", "type": "github" }, "original": { @@ -334,6 +366,21 @@ } }, "systems": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, + "systems_2": { "locked": { "lastModified": 1681028828, "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", @@ -356,11 +403,11 @@ ] }, "locked": { - "lastModified": 1719243788, - "narHash": "sha256-9T9mSY35EZSM1KAwb7K9zwQ78qTlLjosZgtUGnw4rn4=", + "lastModified": 1724833132, + "narHash": "sha256-F4djBvyNRAXGusJiNYInqR6zIMI3rvlp6WiKwsRISos=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "065a23edceff48f948816b795ea8cc6c0dee7cdf", + "rev": "3ffd842a5f50f435d3e603312eefa4790db46af5", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 8a80b3d..e5a5483 100644 --- a/flake.nix +++ b/flake.nix @@ -8,7 +8,8 @@ inputs.nixpkgs.follows = "nixpkgs"; }; nixvim = { - url = "github:nix-community/nixvim"; + url = + "github:nix-community/nixvim/849c2da9d78eb6e6a258b3961df0f2ea1cb1e994"; inputs.nixpkgs.follows = "nixpkgs"; }; sops-nix = { @@ -19,6 +20,11 @@ url = "github:pjones/plasma-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; + ags = { + # url = "github:Aylur/ags"; + url = "github:ozwaldorf/ags"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = { self, nixpkgs, ... }@inputs: { @@ -36,6 +42,7 @@ useUserPackages = true; users.avery = { imports = [ + inputs.ags.homeManagerModules.default inputs.nixvim.homeManagerModules.nixvim inputs.plasma-manager.homeManagerModules.plasma-manager ./common/home.nix diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/assets/microchip-symbolic.svg b/hosts/totsugeki/home-manager/desktop/ags/config/assets/microchip-symbolic.svg new file mode 100644 index 0000000..f140bde --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/assets/microchip-symbolic.svg @@ -0,0 +1,37 @@ + + + + + + + diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/assets/music-symbolic.svg b/hosts/totsugeki/home-manager/desktop/ags/config/assets/music-symbolic.svg new file mode 100644 index 0000000..f29a280 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/assets/music-symbolic.svg @@ -0,0 +1,37 @@ + + + + + + + diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/assets/nixos.svg b/hosts/totsugeki/home-manager/desktop/ags/config/assets/nixos.svg new file mode 100644 index 0000000..bed9e50 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/assets/nixos.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/assets/ram-custom-symbolic.svg b/hosts/totsugeki/home-manager/desktop/ags/config/assets/ram-custom-symbolic.svg new file mode 100644 index 0000000..4c186ff --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/assets/ram-custom-symbolic.svg @@ -0,0 +1,37 @@ + + + + + + + diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/config.js b/hosts/totsugeki/home-manager/desktop/ags/config/config.js new file mode 100644 index 0000000..2ce3452 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/config.js @@ -0,0 +1,270 @@ +import cpu from "./services/cpu.js"; +import ram from "./services/ram.js"; +import { launcher } from "./widgets/launcher/launcher.js"; +const { speaker } = await Service.import("audio"); +const mpris = await Service.import("mpris"); +const sway = await Service.import("sway"); +const players = mpris.bind("players"); +const date = Variable("", { + poll: [1000, 'date "+%H %M %S %b %e"'], +}); + +App.addIcons(`${App.configDir}/assets`); + +function Workspaces() { + return Widget.Box({ + children: Array.from({ length: 10 }, (_, i) => { + i += 1; + return Widget.Box({ + class_name: "workspace-button", + children: [Widget.Label({ hexpand: true, label: i.toString() })], + hpack: "center", + setup: (btn) => { + btn.hook( + sway, + (btn) => { + const ws = sway.getWorkspace(`${i}`); + btn.toggleClassName( + "occupied", + ws?.nodes.length + ws?.floating_nodes.length > 0, + ); + }, + "notify::workspaces", + ); + + btn.hook(sway.active.workspace, (btn) => { + btn.toggleClassName("active", sway.active.workspace.name == i); + }); + }, + }); + }), + spacing: 4, + vertical: true, + }); +} + +function ProcessorUsage() { + return Widget.Box({ + class_name: "system-stats", + css: cpu.bind("current-usage").as((usage) => { + let level = (usage * 100).toFixed(0); + return ` + background: linear-gradient( + 90deg, rgba(26, 27, 38, 0.6) ${level}%, rgba(26, 27, 38, 0.4) ${level}% + )`; + }), + children: [ + Widget.Icon({ + class_names: ["system-stats-icon"], + icon: "microchip-symbolic", + size: 16, + }), + Widget.Label({ + class_names: ["system-stats-text"], + hexpand: true, + label: cpu.bind("current-usage").as((usage) => { + return `${(usage * 100).toFixed(0)}%`; + }), + }), + ], + vertical: true, + }); +} + +function MemoryUsage() { + return Widget.Box({ + class_name: "system-stats", + css: ram.bind("current-usage-percentage").as((usage) => { + let level = (usage * 100).toFixed(0); + return ` + background: linear-gradient( + 90deg, rgba(26, 27, 38, 0.6) ${level}%, rgba(26, 27, 38, 0.4) ${level}% + )`; + }), + children: [ + Widget.Icon({ + class_names: ["system-stats-icon"], + icon: "ram-custom-symbolic", + size: 16, + }), + Widget.Label({ + class_names: ["system-stats-text"], + hexpand: true, + label: ram.bind("current-usage-percentage").as((usage) => { + return `${(usage * 100).toFixed(0)}%`; + }), + }), + ], + tooltip_text: ram.bind("current-usage").as((usage) => { + let usageGb = (usage / 1024 ** 2).toFixed(2); + let totalGb = (ram.total_available / 1024 ** 2).toFixed(2); + return `${usageGb}/${totalGb}GB (${(ram.current_usage_percentage * 100).toFixed(2)}%)`; + }), + vertical: true, + }); +} + +function CurrentSong(player) { + return Widget.Box({ + class_name: "music-indicator", + children: [ + Widget.Box({ + class_name: "album-art", + css: player.bind("cover_path").as((url) => { + if (url == undefined) { + return ` + background-color: rgba(0, 0, 0, 0.2); + background-image: url('${App.configDir}/assets/music-symbolic.svg'); + background-size: 50% 50%; + background-repeat: no-repeat; + background-position: center; + `; + } + return `background-image: url('${url}'); background-size: cover;`; + }), + }), + Widget.Icon({ + class_name: "playback-status", + icon: player.bind("play-back-status").as((status) => { + if (status == "Playing") { + return "media-playback-start"; + } else if (status == "Paused") { + return "media-playback-pause"; + } + return ""; + }), + }), + ], + // TODO: fill background based on track position + css: player.bind("position").as((position) => { + if (position == -1) { + return ""; + } + return ""; + }), + vertical: true, + }); +} + +function CTest() { + // TODO: only show active player + return Widget.Box({ + vertical: true, + visible: players.as((p) => p.length > 0), + children: players.as((p) => p.map(CurrentSong)), + }); +} + +function ProfilePicture() { + return Widget.Box({ + class_name: "profile-picture", + css: "background-image: url('/home/avery/.face.icon'); background-size: cover", + }); +} + +function VolumeWidget() { + return Widget.Box({ + class_name: "volume-widget", + children: [ + Widget.Icon({ + icon: speaker.bind("volume").as((l) => { + let level = l.toFixed(2) * 100; + if (level == 0) { + return "audio-volume-muted"; + } else if (level > 0 && level <= 30) { + return "audio-volume-low"; + } else if (level > 30 && level <= 70) { + return "audio-volume-medium"; + } else { + return "audio-volume-high"; + } + }), + size: 10, + }), + Widget.Box({ + class_name: "volume-box", + css: speaker.bind("volume").as((l) => { + let level = l.toFixed(2) * 100; + if (level >= 0 && level <= 100) { + return ` + background: linear-gradient( + 90deg, #7aa2f7 ${level}%, #24283b ${level}% + ); + `; + } else if (level > 100 && level <= 200) { + return ` + background: linear-gradient( + 90deg, #f7768e ${level - 100}%, #7aa2f7 ${level - 100}% + ); + `; + } else { + return "background: #f7768e"; + } + }), + hpack: "fill", + }), + ], + }); +} +function ClockWidget() { + return Widget.Box({ + children: [ + Widget.Label({ + class_name: "clock-hours", + label: date.bind().as((d) => { + return d.split(" ")[0]; + }), + }), + Widget.Label({ + class_name: "clock-minutes", + label: date.bind().as((d) => { + return d.split(" ")[1]; + }), + }), + Widget.Label({ + class_name: "clock-seconds", + label: date.bind().as((d) => { + return d.split(" ")[2]; + }), + }), + ], + class_name: "clock", + vertical: true, + }); +} + +const barContainer = Widget.Box({ + class_name: "bar", + vpack: "fill", + spacing: 6, + vertical: true, + children: [ + Workspaces(), + Widget.Box({ expand: true, vpack: "fill" }), // Separator + CTest(), + ProcessorUsage(), + MemoryUsage(), + ClockWidget(), + ], +}); + +const bar = Widget.Window({ + name: "bar", + anchor: ["left", "top", "bottom"], + exclusivity: "exclusive", + child: barContainer, +}); + +Utils.monitorFile( + `${App.configDir}/style.css`, + + function () { + App.resetCss; + App.applyCss(`${App.configDir}/style.css`); + }, +); + +App.config({ + style: "./style.css", + windows: [bar, launcher], +}); diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/services/cpu.js b/hosts/totsugeki/home-manager/desktop/ags/config/services/cpu.js new file mode 100644 index 0000000..70de005 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/services/cpu.js @@ -0,0 +1,40 @@ +class CPUService extends Service { + static { + Service.register(this, {}, { "current-usage": ["float", "r"] }); + } + + #previousIdle = 0.0; + #previousTotal = 0.0; + #currentUsage = 0.0; + + get current_usage() { + return this.#currentUsage; + } + + constructor() { + super(); + this.#update(); + const interval = setInterval(() => { + this.#update(); + }, 2000); + } + + #update() { + const currentValues = Utils.exec( + "sh -c 'cat /proc/stat | grep cpu | head -n 1 | tr -s \" \"'", + ) + .split(" ") + .slice(1, 10) + .map(Number); + let idle = currentValues[3]; + let total = currentValues.reduce((a, b) => a + b, 0); + this.#currentUsage = + 1.0 - (idle - this.#previousIdle) / (total - this.#previousTotal); + this.#previousIdle = idle; + this.#previousTotal = total; + this.changed("current-usage"); + } +} + +const cpu = new CPUService(); +export default cpu; diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/services/ram.js b/hosts/totsugeki/home-manager/desktop/ags/config/services/ram.js new file mode 100644 index 0000000..f71e70b --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/services/ram.js @@ -0,0 +1,56 @@ +class RAMService extends Service { + static { + Service.register( + this, + {}, + { + "current-usage": ["float", "r"], + "current-usage-percentage": ["float", "r"], + "total-available": ["float", "r"], + }, + ); + } + #currentUsage = 0; + #totalAvailable = 0; + + get current_usage() { + return this.#currentUsage; + } + + get current_usage_percentage() { + return this.#currentUsage / this.#totalAvailable; + } + + get total_available() { + return this.#totalAvailable; + } + + constructor() { + super(); + this.#totalAvailable = Number( + Utils.exec( + 'sh -c \'cat /proc/meminfo | grep MemTotal | tr -s " " | cut -d " " -f 2\'', + ), + ); + this.#update(); + const interval = setInterval(() => { + this.#update(); + }, 2000); + } + + #update() { + this.#currentUsage = + this.#totalAvailable - + Number( + Utils.exec( + 'sh -c \'cat /proc/meminfo | grep MemAvailable | tr -s " " | cut -d " " -f 2\'', + ), + ); + this.emit("changed"); + this.notify("current-usage"); + this.notify("current-usage-percentage"); + } +} + +const ram = new RAMService(); +export default ram; diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/style.css b/hosts/totsugeki/home-manager/desktop/ags/config/style.css new file mode 100644 index 0000000..4d27b99 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/style.css @@ -0,0 +1,185 @@ +@define-color bg rgba(26, 27, 38, 0.4); +@define-color normal rgba(26, 27, 38, 0.6); +@define-color hover rgba(76, 77, 88, 0.8); +@define-color press rgba(76, 77, 88, 0.2); +@define-color bg-noa rgb(26, 27, 38); + +window { + background-color: transparent; +} + +.bar { + background-color: @bg; + border-radius: 8px; + margin: 4px 0px 4px 4px; + padding: 4px 4px; + min-width: 32px; +} + +.volume-widget { + margin: 4px; +} + +.volume-box { + border-radius: 8px; + margin: 4px; + min-height: 4px; +} + +.clock { + border-radius: 8px; + background-color: @bg; + font-weight: bold; + font-family: "Iosevka Nerd Font"; + font-size: 1.2em; + padding: 4px 0; +} + +.clock-hours { + color: white; +} + +.clock-minutes { + color: #ddd; +} + +.clock-seconds { + color: #bbb; +} + +.music-indicator { + background-color: @bg; + border-radius: 8px; +} + +.profile-picture, +.album-art { + border-radius: 8px; + min-height: 32px; + min-width: 32px; +} + +.playback-status { + margin: 3px 0; +} + +.system-stats { + background-color: @bg; + border-radius: 8px; + color: white; + font-family: "Iosevka Nerd Font"; + font-weight: bold; + font-size: 0.95em; + padding: 4px 0; +} + +.workspace-button { + background-color: @bg; + border-radius: 8px; + color: #c0caf5; + font-family: "Iosevka Nerd Font"; + font-weight: bold; + font-size: 1em; + min-height: 20px; + min-width: 20px; + transition: + background-color 0.3s, + color 0.3s, + min-width 0.2s; +} + +.occupied { + border-radius: 8px; + min-width: 24px; +} + +.active { + color: @bg-noa; + border-radius: 8px; + min-width: 32px; +} + +.active:nth-child(1) { + background-color: #f7768e; +} + +.active:nth-child(2) { + background-color: #ff9e64; +} + +.active:nth-child(3) { + background-color: #e0af68; +} + +.active:nth-child(4) { + background-color: #9ece6a; +} + +.active:nth-child(5) { + background-color: #73daca; +} + +.active:nth-child(6) { + background-color: #7dcfff; +} + +.active:nth-child(7) { + background-color: #2ac3de; +} + +.active:nth-child(8) { + background-color: #7aa2f7; +} + +.active:nth-child(9) { + background-color: #bb9af7; +} + +.active:nth-child(10) { + background-color: #c0caf5; +} + +.launcher { + background-color: @bg; + border-radius: 8px; + padding: 8px; +} + +.launcher-search { + background-color: @normal; + border: 2px solid transparent; + border-radius: 8px; + box-shadow: none; + caret-color: white; + color: white; + font-weight: 500; + font-size: 1.1em; +} + +.launcher-search:focus { + border: 2px solid white; + + outline: none; +} + +.application { + all: unset; + background-color: @normal; + border-radius: 8px; + color: white; + padding: 8px; +} + +.application:hover, +.application:focus { + background-color: @hover; +} + +.application:active { + background-color: @press; +} + +.application_name { + font-size: 1.4em; + font-weight: 500; +} diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/widgets/launcher/application.js b/hosts/totsugeki/home-manager/desktop/ags/config/widgets/launcher/application.js new file mode 100644 index 0000000..c855ae4 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/widgets/launcher/application.js @@ -0,0 +1,25 @@ +export const Application = (application) => + Widget.Button({ + class_name: "application", + on_clicked: () => { + App.closeWindow("launcher"); + application.launch(); + }, + attribute: { application }, + child: Widget.Box({ + children: [ + Widget.Icon({ + icon: application.icon_name || "", + size: 32, + }), + Widget.Label({ + class_name: "application_name", + label: application.name, + xalign: 0, + vpack: "center", + truncate: "end", + }), + ], + spacing: 8, + }), + }); diff --git a/hosts/totsugeki/home-manager/desktop/ags/config/widgets/launcher/launcher.js b/hosts/totsugeki/home-manager/desktop/ags/config/widgets/launcher/launcher.js new file mode 100644 index 0000000..80052bc --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/config/widgets/launcher/launcher.js @@ -0,0 +1,87 @@ +import { Application } from "./application.js"; +const { query } = await Service.import("applications"); + +const Launcher = ({ width = 500, height = 600, spacing = 4 }) => { + let applications = query("").map(Application); + + const list = Widget.Box({ + css: "background-color: transparent", + vertical: true, + spacing, + children: applications, + }); + + function repopulate() { + applications = query("").map(Application); + list.children = applications; + } + + const searchBox = Widget.Entry({ + class_name: "launcher-search", + hexpand: true, + placeholder_text: "Buscar", + xalign: 0.5, + on_accept: () => { + const results = applications.filter((item) => item.visible); + if (results[0]) { + App.closeWindow("launcher"); + results[0].attribute.application.launch(); + } + }, + on_change: ({ text }) => { + text = text.toLowerCase(); + list.children = applications.sort((a, b) => { + var firstMatches = a.attribute.application.name + .toLowerCase() + .match(text ?? ""); + var secondMatches = b.attribute.application.name + .toLowerCase() + .match(text ?? ""); + if (firstMatches && secondMatches) { + return 0; + } else if (firstMatches) { + return -1; + } + return 1; + }); + + applications.forEach((item) => { + item.visible = item.attribute.application.match(text ?? ""); + }); + }, + }); + + return Widget.Box({ + class_name: "launcher", + vertical: true, + spacing, + children: [ + searchBox, + Widget.Scrollable({ + hscroll: "never", + css: `min-width: ${width}px; min-height: ${height}px;`, + child: list, + vexpand: true, + }), + ], + setup: (self) => + self.hook(App, (_, windowName, visible) => { + if (windowName == "launcher" && visible) { + repopulate(); + searchBox.text = ""; + searchBox.grab_focus(); + } + }), + }); +}; + +export const launcher = Widget.Window({ + name: "launcher", + setup: (self) => + self.keybind("Escape", () => { + App.closeWindow("launcher"); + }), + visible: false, + keymode: "exclusive", + child: Launcher({}), +}); diff --git a/hosts/totsugeki/home-manager/desktop/ags/default.nix b/hosts/totsugeki/home-manager/desktop/ags/default.nix new file mode 100644 index 0000000..71e5b1d --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/ags/default.nix @@ -0,0 +1,6 @@ +{ ... }: { + programs.ags = { + enable = true; + # configDir = ./widgets; + }; +} diff --git a/hosts/totsugeki/home-manager/desktop/cursor.nix b/hosts/totsugeki/home-manager/desktop/cursor.nix new file mode 100644 index 0000000..816819a --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/cursor.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: { + home.pointerCursor = { + gtk.enable = true; + package = pkgs.catppuccin-cursors.mochaMauve; + name = "catppuccin-mocha-mauve-cursors"; + size = 32; + }; +} diff --git a/hosts/totsugeki/home-manager/desktop/default.nix b/hosts/totsugeki/home-manager/desktop/default.nix index a1344cd..5f96595 100644 --- a/hosts/totsugeki/home-manager/desktop/default.nix +++ b/hosts/totsugeki/home-manager/desktop/default.nix @@ -1,22 +1,24 @@ -{ config, pkgs, ... }: { - imports = [ ./plasma ./firefox.nix ./gtk.nix ./kitty.nix ]; +{ pkgs, ... }: { + imports = [ + ./ags + ./cursor.nix + ./dunst.nix + ./firefox.nix + ./lf.nix + ./gtk.nix + ./kitty.nix + ./sway.nix + ]; home = { packages = with pkgs; [ gimp fastfetch inkscape + kdePackages.ark libreoffice-qt obs-studio picard protonup-qt - kdePackages.ark - kdePackages.dolphin - kdePackages.dolphin-plugins - kdePackages.kio - kdePackages.kio-extras - kdePackages.kimageformats - kdePackages.qtimageformats - kdePackages.sddm-kcm mpv noto-fonts-cjk-sans nsxiv @@ -26,8 +28,10 @@ qbittorrent r2modman wl-clipboard + wineWowPackages.stagingFull element-desktop vesktop + swww ]; }; nixpkgs.config.allowUnfree = true; diff --git a/hosts/totsugeki/home-manager/desktop/dunst.nix b/hosts/totsugeki/home-manager/desktop/dunst.nix new file mode 100644 index 0000000..eb4d001 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/dunst.nix @@ -0,0 +1,33 @@ +{ ... }: { + services.dunst = { + enable = true; + settings = { + global = { + timeout = 3; + corner_radius = 14; + frame_width = 2; + font = "Iosevka Nerd Font 10"; + format = '' + %s + %b''; + icon_position = "left"; + max_icon_size = 48; + icon_corner_radius = 4; + origin = "bottom-right"; + offset = "8x8"; + width = "(100, 400)"; + background = "#11111b"; + foreground = "#cdd6f4"; + frame_color = "#cba6f7"; + highlight = "#cba6f7"; + separator_color = "frame"; + progress_bar = true; + progress_bar_corner_radius = 4; + }; + volumectl = { + appname = "volumectl"; + alignment = "center"; + }; + }; + }; +} diff --git a/hosts/totsugeki/home-manager/desktop/firefox.nix b/hosts/totsugeki/home-manager/desktop/firefox.nix index 7711237..2c5b2ff 100644 --- a/hosts/totsugeki/home-manager/desktop/firefox.nix +++ b/hosts/totsugeki/home-manager/desktop/firefox.nix @@ -1,4 +1,4 @@ -{ pkgs, config, ... }: { +{ ... }: { programs.firefox = { enable = true; profiles.Avery = { @@ -21,6 +21,7 @@ Bing.metaData.hidden = true; DuckDuckGo.metaData.hidden = true; "Wikipedia (en)".metaData.hidden = true; + Qwant.metaData.hidden = true; }; force = true; order = [ "SearXNG" ]; @@ -89,7 +90,7 @@ "extensions.shield-recipe-client.api_url" = ""; "extensions.shield-recipe-client.enabled" = false; "extensions.webservice.discoverURL" = ""; - "font.name.serif.x-western" = "Inter"; + "font.name.serif.x-western" = "Ubuntu"; "media.autoplay.default" = 2; "media.eme.enabled" = false; "media.gmp-widevinecdm.enabled" = false; diff --git a/hosts/totsugeki/home-manager/desktop/gtk.nix b/hosts/totsugeki/home-manager/desktop/gtk.nix index 72f9ea3..c49636a 100644 --- a/hosts/totsugeki/home-manager/desktop/gtk.nix +++ b/hosts/totsugeki/home-manager/desktop/gtk.nix @@ -6,8 +6,8 @@ name = "kora"; }; font = { - package = pkgs.inter; - name = "Inter"; + package = pkgs.ubuntu-sans; + name = "Ubuntu Sans"; size = 10; }; theme = { diff --git a/hosts/totsugeki/home-manager/desktop/kitty.nix b/hosts/totsugeki/home-manager/desktop/kitty.nix index 8116ee4..f4bcfe6 100644 --- a/hosts/totsugeki/home-manager/desktop/kitty.nix +++ b/hosts/totsugeki/home-manager/desktop/kitty.nix @@ -3,7 +3,7 @@ enable = true; font = { name = "Iosevka Nerd Font"; - size = 12; + size = 14; }; keybindings = { "ctrl+alt+1" = "goto_tab 1"; @@ -17,7 +17,7 @@ "ctrl+alt+9" = "goto_tab 9"; }; settings = { - "background_opacity" = "0.90"; + "background_opacity" = "0.6"; "dynamic_background_opacity" = true; "force_ltr" = "yes"; "disable_ligatures" = "never"; @@ -31,8 +31,7 @@ "tab_powerline_style" = "round"; "tab_title_template" = "{title}{' :{}:'.format(num_windows) if num_windows > 1 else ''}"; - "background" = "#1E1E2F"; }; - theme = "Catppuccin-Mocha"; + theme = "Tokyo Night"; }; } diff --git a/hosts/totsugeki/home-manager/desktop/lf.nix b/hosts/totsugeki/home-manager/desktop/lf.nix new file mode 100644 index 0000000..725f88e --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/lf.nix @@ -0,0 +1,6 @@ +{ ... }: { + programs.lf = { + enable = true; + + }; +} diff --git a/hosts/totsugeki/home-manager/desktop/plasma/default.nix b/hosts/totsugeki/home-manager/desktop/plasma/default.nix deleted file mode 100644 index 3bd77c3..0000000 --- a/hosts/totsugeki/home-manager/desktop/plasma/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ ... }: { - imports = - [ ./input.nix ./hotkeys.nix ./krohnkite.nix ./nobaloo.nix ./theme.nix ]; - programs.plasma = { - enable = true; - overrideConfig = true; - workspace.clickItemTo = "open"; - kwin = { - virtualDesktops = { - rows = 1; - number = 10; - }; - effects.desktopSwitching.animation = "slide"; - }; - configFile = { "kded5rc" = { Module-gtkconfig.autoload = false; }; }; - }; -} diff --git a/hosts/totsugeki/home-manager/desktop/plasma/hotkeys.nix b/hosts/totsugeki/home-manager/desktop/plasma/hotkeys.nix deleted file mode 100644 index eea0984..0000000 --- a/hosts/totsugeki/home-manager/desktop/plasma/hotkeys.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ ... }: { - programs.plasma.shortcuts = { - kwin = { - "Switch to Desktop 1" = "Meta+1"; - "Window to Desktop 1" = "Meta+!"; - "Switch to Desktop 2" = "Meta+2"; - "Window to Desktop 2" = ''Meta+"''; - "Switch to Desktop 3" = "Meta+3"; - "Window to Desktop 3" = "Meta+·"; - "Switch to Desktop 4" = "Meta+4"; - "Window to Desktop 4" = "Meta+$"; - "Switch to Desktop 5" = "Meta+5"; - "Window to Desktop 5" = "Meta+%"; - "Switch to Desktop 6" = "Meta+6"; - "Window to Desktop 6" = "Meta+&"; - "Switch to Desktop 7" = "Meta+7"; - "Window to Desktop 7" = "Meta+/"; - "Switch to Desktop 8" = "Meta+8"; - "Window to Desktop 8" = "Meta+("; - "Switch to Desktop 9" = "Meta+9"; - "Window to Desktop 9" = "Meta+)"; - "Switch to Desktop 10" = "Meta+0"; - "Window to Desktop 10" = "Meta+="; - }; - "services/kitty.desktop"."_launch" = "Ctrl+Alt+T"; - "org.kde.krunner.desktop"."_launch" = "Meta+Space"; - }; -} diff --git a/hosts/totsugeki/home-manager/desktop/plasma/input.nix b/hosts/totsugeki/home-manager/desktop/plasma/input.nix deleted file mode 100644 index 5debf3c..0000000 --- a/hosts/totsugeki/home-manager/desktop/plasma/input.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ ... }: { - programs.plasma.configFile = { - kcminputrc."Libinput/9610/54/Glorious Model O" = { - PointerAcceleration = -0.4; - PointerAccelerationProfile = 1; - }; - kxkbrc.Layout = { - LayoutList = "es"; - Use = true; - VariantList = "dvorak"; - Options = "caps:menu"; - ResetOldOptions = true; - }; - }; -} diff --git a/hosts/totsugeki/home-manager/desktop/plasma/krohnkite.nix b/hosts/totsugeki/home-manager/desktop/plasma/krohnkite.nix deleted file mode 100644 index b6930be..0000000 --- a/hosts/totsugeki/home-manager/desktop/plasma/krohnkite.nix +++ /dev/null @@ -1,23 +0,0 @@ -# TODO: find a way to automatically install krohnkite -{ ... }: { - programs.plasma.configFile.kwinrc = { - Plugins.krohnkiteEnabled = true; - Script-krohnkite = { - enableMonocleLayout = false; - enableSpreadLayout = false; - enableStairLayout = false; - enableThreeColumnLayout = false; - enableTileLayout = false; - ignoreClass = "krunner,yakuake,spectacle,kded5,plasmashell"; - layoutPerActivity = false; - layoutPerDesktop = false; - limitTileWidthRatio = 0.6; - noTileBorder = true; - screenGapBottom = 20; - screenGapLeft = 8; - screenGapRight = 8; - screenGapTop = 8; - tileLayoutGap = 2; - }; - }; -} diff --git a/hosts/totsugeki/home-manager/desktop/plasma/nobaloo.nix b/hosts/totsugeki/home-manager/desktop/plasma/nobaloo.nix deleted file mode 100644 index e8e31e7..0000000 --- a/hosts/totsugeki/home-manager/desktop/plasma/nobaloo.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ ... }: { - programs.plasma.configFile.baloofilerc = { - "Basic Settings".Indexing-Enabled = false; - }; -} diff --git a/hosts/totsugeki/home-manager/desktop/plasma/theme.nix b/hosts/totsugeki/home-manager/desktop/plasma/theme.nix deleted file mode 100644 index 8262acd..0000000 --- a/hosts/totsugeki/home-manager/desktop/plasma/theme.nix +++ /dev/null @@ -1,59 +0,0 @@ -{ pkgs, ... }: -let cursorThemeName = "catppuccin-mocha-mauve-cursors"; -in { - home = { - packages = with pkgs; [ - (catppuccin-kde.override { - flavour = [ "mocha" ]; - accents = [ "mauve" ]; - }) - catppuccin-cursors.mochaMauve - ]; - pointerCursor = { - gtk.enable = true; - package = pkgs.catppuccin-cursors.mochaMauve; - name = cursorThemeName; - size = 32; - }; - }; - programs.plasma = { - fonts = { - general = { - family = "Inter Display"; - pointSize = 11; - weight = "medium"; - }; - fixedWidth = { - family = "Iosevka Nerd Font"; - pointSize = 12; - }; - small = { - family = "Inter Display"; - pointSize = 8; - }; - toolbar = { - family = "Inter Display"; - pointSize = 11; - weight = "medium"; - }; - menu = { - family = "Inter Display"; - pointSize = 11; - weight = "medium"; - }; - windowTitle = { - family = "Inter Display"; - pointSize = 11; - weight = "medium"; - }; - }; - workspace = { - colorScheme = "CatppuccinMochaMauve"; - lookAndFeel = "Catppuccin-Mocha-Mauve"; - cursor = { - theme = cursorThemeName; - size = 32; - }; - }; - }; -} diff --git a/hosts/totsugeki/home-manager/desktop/sway.nix b/hosts/totsugeki/home-manager/desktop/sway.nix new file mode 100644 index 0000000..a9cbc60 --- /dev/null +++ b/hosts/totsugeki/home-manager/desktop/sway.nix @@ -0,0 +1,125 @@ +{ config, pkgs, ... }: +let cfg = config.wayland.windowManager.sway.config; +in { + home.packages = with pkgs; [ autotiling ]; + wayland.windowManager.sway = { + enable = true; + package = pkgs.swayfx; + checkConfig = false; # checkConfig crashes with swayfx on activation + config = { + bars = [ ]; + input = { + "type:keyboard" = { + xkb_layout = "es"; + xkb_variant = "dvorak"; + xkb_options = "lv5:caps_switch"; + }; + "type:pointer" = { + "accel_profile" = "flat"; + "pointer_accel" = "-0.4"; + }; + }; + focus.followMouse = "always"; + floating.titlebar = false; + gaps = { + inner = 4; + smartBorders = "off"; + smartGaps = false; + }; + keybindings = let + Super = "Mod4"; + Hyper = "Mod3"; + in { + "Ctrl+Alt+T" = "exec ${cfg.terminal}"; + "${Super}+Space" = "exec ags -t launcher"; + # Workspace management + "${Super}+1" = "workspace number 1"; + "${Super}+2" = "workspace number 2"; + "${Super}+3" = "workspace number 3"; + "${Super}+4" = "workspace number 4"; + "${Super}+5" = "workspace number 5"; + "${Super}+6" = "workspace number 6"; + "${Super}+7" = "workspace number 7"; + "${Super}+8" = "workspace number 8"; + "${Super}+9" = "workspace number 9"; + "${Super}+0" = "workspace number 10"; + "${Super}+Shift+1" = "move container to workspace number 1"; + "${Super}+Shift+2" = "move container to workspace number 2"; + "${Super}+Shift+3" = "move container to workspace number 3"; + "${Super}+Shift+4" = "move container to workspace number 4"; + "${Super}+Shift+5" = "move container to workspace number 5"; + "${Super}+Shift+6" = "move container to workspace number 6"; + "${Super}+Shift+7" = "move container to workspace number 7"; + "${Super}+Shift+8" = "move container to workspace number 8"; + "${Super}+Shift+9" = "move container to workspace number 9"; + "${Super}+Shift+0" = "move container to workspace number 10"; + # Window management + "${Super}+W" = "kill"; + "${Super}+${cfg.left}" = "focus left"; + "${Super}+${cfg.right}" = "focus right"; + "${Super}+${cfg.up}" = "focus up"; + "${Super}+${cfg.down}" = "focus down"; + "${Super}+Shift+${cfg.left}" = "move left"; + "${Super}+Shift+${cfg.right}" = "move right"; + "${Super}+Shift+${cfg.up}" = "move up"; + "${Super}+Shift+${cfg.down}" = "move down"; + "${Super}+F11" = "fullscreen toggle"; + # Modes + "${Hyper}+W" = "mode wallpaper"; + "${Hyper}+M" = "mode music"; + "${Hyper}+R" = "mode resize"; + # Speaker volume + "XF86AudioRaiseVolume" = "exec volumectl output +5"; + "XF86AudioLowerVolume" = "exec volumectl output -5"; + # Microphone volume + "Shift+XF86AudioRaiseVolume" = "exec volumectl input +5"; + "Shift+XF86AudioLowerVolume" = "exec volumectl input -5"; + # Brightness + "Alt+XF86AudioRaiseVolume" = "exec ddc-brightness +5"; + "Alt+XF86AudioLowerVolume" = "exec ddc-brightness -5"; + # Screenshots + "${Super}+S" = "exec screenshot full"; + "${Super}+Shift+S" = "exec screenshot section"; + }; + modes = { + music = { + p = "exec playerctl play-pause"; + h = "exec playerctl previous"; + l = "exec playerctl next"; + Escape = "mode default"; + }; + resize = { + "${cfg.left}" = "resize shrink width 10px"; + "${cfg.right}" = "resize grow width 10px"; + "${cfg.up}" = "resize shrink height 10px"; + "${cfg.down}" = "resize grow height 10px"; + Escape = "mode default"; + }; + wallpaper = { + l = "exec change-wallpaper next"; + h = "exec change-wallpaper previous"; + Escape = "mode default"; + }; + }; + output.DP-1.resolution = "2560x1440@165Hz"; + seat."*".xcursor_theme = "catppuccin-mocha-mauve-cursors 32"; + startup = [ + { command = "swww-daemon"; } + { command = "autotiling"; } + { command = "ags"; } + ]; + terminal = "kitty"; + }; + extraConfig = '' + # SwayFX configuration + blur enable + blur_radius 4 + blur_passes 3 + corner_radius 8 + default_dim_inactive 0.4 + default_border none + layer_effects bar blur enable; blur_ignore_transparent enable + layer_effects launcher blur enable; corner_radius 8 + ''; + }; +} diff --git a/hosts/totsugeki/home-manager/development/nixvim/completion.nix b/hosts/totsugeki/home-manager/development/nixvim/completion.nix index 1d68b41..79b5266 100644 --- a/hosts/totsugeki/home-manager/development/nixvim/completion.nix +++ b/hosts/totsugeki/home-manager/development/nixvim/completion.nix @@ -1,4 +1,4 @@ -{ inputs, lib, ... }: { +{ lib, ... }: { programs.nixvim = { extraConfigLua = '' function has_words_before() diff --git a/hosts/totsugeki/home-manager/development/nixvim/default.nix b/hosts/totsugeki/home-manager/development/nixvim/default.nix index 7ffec28..bb08745 100644 --- a/hosts/totsugeki/home-manager/development/nixvim/default.nix +++ b/hosts/totsugeki/home-manager/development/nixvim/default.nix @@ -1,4 +1,4 @@ -{ inputs, pkgs, ... }: { +{ pkgs, ... }: { imports = [ ./completion.nix ./lsp.nix @@ -10,14 +10,14 @@ programs.nixvim = { enable = true; - colorschemes.catppuccin = { + colorschemes.tokyonight = { enable = true; settings = { - flavour = "mocha"; - no_italic = true; - integrations = { - cmp = true; - neotree = true; + style = "night"; + transparent = true; + styles = { + comments.italic = false; + keywords.italic = false; }; }; }; diff --git a/hosts/totsugeki/home-manager/development/nixvim/lsp.nix b/hosts/totsugeki/home-manager/development/nixvim/lsp.nix index 4993271..5038061 100644 --- a/hosts/totsugeki/home-manager/development/nixvim/lsp.nix +++ b/hosts/totsugeki/home-manager/development/nixvim/lsp.nix @@ -1,9 +1,9 @@ -{ inputs, ... }: { +{ ... }: { programs.nixvim.plugins = { lsp = { enable = true; - servers = { + nil-ls.enable = true; pyright.enable = true; rust-analyzer = { enable = true; diff --git a/hosts/totsugeki/home-manager/development/nixvim/none-ls.nix b/hosts/totsugeki/home-manager/development/nixvim/none-ls.nix index 1cf4af1..a71f72c 100644 --- a/hosts/totsugeki/home-manager/development/nixvim/none-ls.nix +++ b/hosts/totsugeki/home-manager/development/nixvim/none-ls.nix @@ -21,9 +21,7 @@ nixfmt.enable = true; prettier = { enable = true; - withArgs = '' - {extra_filetypes = {"svelte"}} - ''; + settings = { extra_filetypes = [ "svelte" ]; }; }; }; }; diff --git a/hosts/totsugeki/home-manager/development/nixvim/treesitter.nix b/hosts/totsugeki/home-manager/development/nixvim/treesitter.nix index d8c58ec..9ab63ae 100644 --- a/hosts/totsugeki/home-manager/development/nixvim/treesitter.nix +++ b/hosts/totsugeki/home-manager/development/nixvim/treesitter.nix @@ -1,7 +1,10 @@ { ... }: { - programs.nixvim.plugins.treesitter = { - enable = true; - indent = true; - nixvimInjections = true; + programs.nixvim.plugins.treesitter = { + enable = true; + settings = { + indent.enable = true; + highlight.enable = true; }; + nixvimInjections = true; + }; } diff --git a/hosts/totsugeki/home-manager/scripts/change-wallpaper.nix b/hosts/totsugeki/home-manager/scripts/change-wallpaper.nix new file mode 100644 index 0000000..2d3828d --- /dev/null +++ b/hosts/totsugeki/home-manager/scripts/change-wallpaper.nix @@ -0,0 +1,81 @@ +{ pkgs }: + +pkgs.writeShellApplication { + name = "change-wallpaper"; + runtimeInputs = with pkgs; [ dunst rofi swww ]; + text = '' + shopt -s nullglob + + WALLPAPER_PATH="$HOME/.local/share/wallpapers" + WALLPAPERS=("$WALLPAPER_PATH"/*) + + if [ ! -f "$WALLPAPER_PATH/.current_path" ]; then + # Current wallpaper file does not exist, create it + echo "''${WALLPAPERS[0]}" > "$WALLPAPER_PATH/.current_path" + fi + + CURRENT_WALLPAPER=$(cat "$WALLPAPER_PATH/.current_path") + CURRENT_WP_INDEX=-1 + # Get the current wallpaper's index + for index in "''${!WALLPAPERS[@]}"; do + if [ "''${WALLPAPERS[$index]}" = "$CURRENT_WALLPAPER" ]; then + CURRENT_WP_INDEX=$index + fi + done + + if [ "$CURRENT_WP_INDEX" -eq -1 ]; then + CURRENT_WP_INDEX=0 + fi + + if [ "$1" = "previous" ]; then + WALLPAPER="''${WALLPAPERS[$CURRENT_WP_INDEX - 1]}" + TRANSITION_ANGLE=300 + elif [ "$1" = "next" ]; then + NEXT_INDEX=$((CURRENT_WP_INDEX + 1)) + if [ "$NEXT_INDEX" = "''${#WALLPAPERS[@]}" ]; then + NEXT_INDEX=0 + fi + WALLPAPER=''${WALLPAPERS[$NEXT_INDEX]} + TRANSITION_ANGLE=120 + elif [ "$1" = "open-menu" ]; then + INPUT="" + for index in "''${!WALLPAPERS[@]}"; do + if [ "$index" = "$CURRENT_WP_INDEX" ]; then + continue + fi + _WALLPAPER=''${WALLPAPERS[$index]} + _WALLPAPER_NAME=$(basename "$_WALLPAPER") + INPUT+="$_WALLPAPER_NAME\0icon\x1f$_WALLPAPER" + if [ ! $((index + 1)) -eq ''${#WALLPAPERS[@]} ]; then + INPUT+=$'\n' + fi + done + if ! WALLPAPER=$(echo -en "$INPUT" | rofi -dmenu -mesg "Cambiar fondo de pantalla" -p "" -i -theme ~/.config/rofi/wallpaper_selector.rasi); then + exit 1 + fi + WALLPAPER="$WALLPAPER_PATH/$WALLPAPER" + TRANSITION_ANGLE=270 + else + echo "Unknown first argument: $1" + exit 1 + fi + + if [ -z "$WALLPAPER" ]; then + exit 1 + fi + + WALLPAPER_NAME=$(basename "$WALLPAPER") + echo "Setting wallpaper to $WALLPAPER" + echo "$WALLPAPER" > "$WALLPAPER_PATH/.current_path" + ln -sf "$WALLPAPER" "$WALLPAPER_PATH/.current_image" + dunstify -i "$WALLPAPER" -t 2800 "Cambiando fondo de pantalla" "Cambiando a $WALLPAPER_NAME" + swww img\ + --transition-type wipe\ + --transition-angle $TRANSITION_ANGLE\ + --transition-step 90\ + --transition-duration 1\ + --transition-fps 165\ + "$WALLPAPER" + + ''; +} diff --git a/hosts/totsugeki/home-manager/scripts/ddc-brightness.nix b/hosts/totsugeki/home-manager/scripts/ddc-brightness.nix new file mode 100644 index 0000000..e3f353f --- /dev/null +++ b/hosts/totsugeki/home-manager/scripts/ddc-brightness.nix @@ -0,0 +1,51 @@ +{ pkgs }: +pkgs.writeShellApplication { + # Only for GIGABYTE G32QC monitor + name = "ddc-brightness"; + runtimeInputs = with pkgs; [ ddcutil ]; + text = '' + usage() { + echo "Usage: ddc-brightness VALUE" + echo "Possible values are +X, -X or X" + exit 1 + } + BRIGHTNESS_REGEX="^(-|\+)*[0-9]+$" + test -n 1 || usage + CACHE_FILE="/run/user/$UID/current-brightness" + CURRENT_BRIGHTNESS=0 + if [ -f "$CACHE_FILE" ]; then + CURRENT_BRIGHTNESS=$(cat "$CACHE_FILE") + else + CURRENT_BRIGHTNESS=$(ddcutil getvcp 10 | tr -s " " | cut -d " " -f 9 | tr -d ",") + echo "$CURRENT_BRIGHTNESS" > "$CACHE_FILE" + fi + echo "Current brightness level is $CURRENT_BRIGHTNESS" + if [[ ! "$1" =~ $BRIGHTNESS_REGEX ]]; then + echo "Invalid value: '$1'" + exit 1 + fi + NEW_BRIGHTNESS_VALUE=0 + if [ "''${1:0:1}" == "+" ]; then + NEW_BRIGHTNESS_VALUE=$(("$CURRENT_BRIGHTNESS" + "''${1:1}")) + elif [ "''${1:0:1}" == "-" ]; then + NEW_BRIGHTNESS_VALUE=$(("$CURRENT_BRIGHTNESS" - "''${1:1}")) + else + NEW_BRIGHTNESS_VALUE="$1" + fi + if [ "$NEW_BRIGHTNESS_VALUE" -lt 0 ]; then + NEW_BRIGHTNESS_VALUE=0 + elif [ "$NEW_BRIGHTNESS_VALUE" -gt 100 ]; then + NEW_BRIGHTNESS_VALUE=100 + fi + echo "$NEW_BRIGHTNESS_VALUE" > "$CACHE_FILE" + echo "Setting brightness level to $NEW_BRIGHTNESS_VALUE" + ddcutil setvcp 10 "$NEW_BRIGHTNESS_VALUE" + dunstify \ + --appname "volumectl"\ + --replace 9002\ + --urgency low\ + --timeout 1250\ + --hints "int:value:$NEW_BRIGHTNESS_VALUE"\ + " $NEW_BRIGHTNESS_VALUE%" + ''; +} diff --git a/hosts/totsugeki/home-manager/scripts/default.nix b/hosts/totsugeki/home-manager/scripts/default.nix index 82e8246..91f240d 100644 --- a/hosts/totsugeki/home-manager/scripts/default.nix +++ b/hosts/totsugeki/home-manager/scripts/default.nix @@ -1,6 +1,10 @@ { pkgs, ... }: { - home.packages = with pkgs; [ + home.packages = [ + (import ./change-wallpaper.nix { inherit pkgs; }) + (import ./ddc-brightness.nix { inherit pkgs; }) (import ./play-on-soundboard.nix { inherit pkgs; }) + (import ./screenshot.nix { inherit pkgs; }) (import ./setup-soundboard.nix { inherit pkgs; }) + (import ./volumectl.nix { inherit pkgs; }) ]; } diff --git a/hosts/totsugeki/home-manager/scripts/screenshot.nix b/hosts/totsugeki/home-manager/scripts/screenshot.nix new file mode 100644 index 0000000..b859939 --- /dev/null +++ b/hosts/totsugeki/home-manager/scripts/screenshot.nix @@ -0,0 +1,36 @@ +{ pkgs }: + +pkgs.writeShellApplication { + name = "screenshot"; + runtimeInputs = with pkgs; [ + dunst + grim + libjxl + slurp + wl-clipboard + xdg-user-dirs + ]; + text = '' + usage() { + echo "Usage: screenshot { full | section }" + exit 1 + } + + test -n 1 || usage + + FILE_NAME=$(date +'Screenshot_%Y%m%d_%H%M%S') + TEMPORARY_PATH="/tmp/$FILE_NAME.png" + SCREENSHOT_PATH="$(xdg-user-dir PICTURES)/Capturas/$FILE_NAME.jxl" + if [ "$1" == "full" ]; then + grim "$TEMPORARY_PATH" + elif [ "$1" == "section" ]; then + grim -g "$(slurp -b '#000000aa' -w 0)" "$TEMPORARY_PATH" + else + usage + fi + wl-copy < "$TEMPORARY_PATH" + cjxl "$TEMPORARY_PATH" "$SCREENSHOT_PATH" + dunstify --raw_icon="$TEMPORARY_PATH" "Captura de pantalla realizada" "Guardada como $FILE_NAME.jxl" + rm "$TEMPORARY_PATH" + ''; +} diff --git a/hosts/totsugeki/home-manager/scripts/volumectl.nix b/hosts/totsugeki/home-manager/scripts/volumectl.nix new file mode 100644 index 0000000..6fc7977 --- /dev/null +++ b/hosts/totsugeki/home-manager/scripts/volumectl.nix @@ -0,0 +1,65 @@ +{ pkgs }: +pkgs.writeShellApplication { + name = "volumectl"; + runtimeInputs = with pkgs; [ dunst pamixer ]; + text = '' + VOLUME_REGEX="^(-*|\+*)[0-9]+$" + volume="" + + if [ "$1" == "output" ]; then + if [[ "$2" =~ $VOLUME_REGEX ]]; then + if [ "$(pamixer --get-mute)" == "true" ]; then + pamixer --unmute > /dev/null + fi + if [ "''${2:0:1}" == "-" ]; then + pamixer --allow-boost -d "''${2:1}" > /dev/null + elif [ "''${2:0:1}" == "+" ]; then + pamixer --allow-boost -i "''${2:1}" > /dev/null + fi + volume="$(pamixer --get-volume-human)" + message=" $volume" + elif [ "$2" == "toggle-mute" ]; then + if [ "$(pamixer --get-mute)" == "true" ]; then + pamixer --unmute > /dev/null + volume="$(pamixer --get-volume-human)" + message=" $volume" + else + pamixer --mute > /dev/null + message="󰖁 Silenciado" + fi + else + message="volumectl error: Unknown second argument" + fi + elif [ "$1" == "input" ]; then + if [[ "$2" =~ $VOLUME_REGEX ]]; then + if [ "$(pamixer --default-source --get-mute)" == "true" ]; then + pamixer --default-source --unmute > /dev/null + fi + if [ "''${2:0:1}" == "-" ];then + pamixer --default-source --allow-boost -d "''${2:1}" > /dev/null + elif [ "''${2:0:1}" == "+" ]; then + pamixer --default-source --allow-boost -i "''${2:1}" > /dev/null + fi + volume="$(pamixer --default-source --get-volume-human)" + message=" $volume" + elif [ "$2" == "toggle-mute" ]; then + if [ "$(pamixer --default-source --get-mute)" == "true" ]; then + pamixer --default-source --unmute > /dev/null + volume="$(pamixer --default-source --get-volume-human)" + message=" $volume" + else + pamixer --default-source --mute > /dev/null + message=" Silenciado" + fi + else + message="volumectl error: Unknown second argument" + fi + else + message="volumectl error: Unknown first argument" + fi + + volume="$(echo "$volume" | tr -d "%")" + + dunstify --appname "volumectl" --replace 9001 --urgency low --timeout 1250 --hints "int:value:$volume" "$message" + ''; +} diff --git a/hosts/totsugeki/nixos/default.nix b/hosts/totsugeki/nixos/default.nix index a916f91..56ee2d0 100644 --- a/hosts/totsugeki/nixos/default.nix +++ b/hosts/totsugeki/nixos/default.nix @@ -1,6 +1,6 @@ -{ config, lib, pkgs, ... }: { +{ lib, pkgs, ... }: { - imports = [ ./filesystems.nix ./plasma.nix ./steam.nix ]; + imports = [ ./filesystems.nix ./steam.nix ]; boot = { kernelModules = [ "kvm-amd" ]; @@ -21,6 +21,10 @@ }; }; + environment.systemPackages = with pkgs; [ amf-headers ffmpeg-full ]; + + hardware.i2c.enable = true; + networking = { firewall = { enable = true; @@ -61,12 +65,32 @@ enable = true; gpuOverclock.enable = true; }; + dconf.enable = true; nix-ld.enable = true; }; - xdg.portal.enable = true; + xdg.portal = { + config.common = { + default = "gtk"; + "org.freedesktop.impl.portal.ScreenCast" = "wlr"; + }; + enable = true; + extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; + wlr = { + enable = true; + settings = { + screencast = { + output_name = "DP-1"; + max_fps = 165; + chooser_type = "simple"; + chooser_cmd = "${pkgs.slurp}/bin/slurp -f %o -or"; + }; + }; + }; + }; services = { + gvfs.enable = true; jellyfin = { enable = true; openFirewall = true; @@ -83,13 +107,6 @@ udev.extraRules = '' SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", MODE="0666" ''; - displayManager = { - defaultSession = "plasma"; - sddm = { - enable = true; - wayland.enable = true; - }; - }; }; systemd = { services = { NetworkManager-wait-online.enable = false; }; }; diff --git a/hosts/totsugeki/nixos/plasma.nix b/hosts/totsugeki/nixos/plasma.nix deleted file mode 100644 index d4026df..0000000 --- a/hosts/totsugeki/nixos/plasma.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ pkgs, ... }: { - services.desktopManager.plasma6.enable = true; - environment.plasma6.excludePackages = with pkgs.kdePackages; [ - konsole - oxygen - elisa - kate - okular - ]; -}