From 8e7a88b4f1a923fc72935ce93ac5c4eb1586cd52 Mon Sep 17 00:00:00 2001 From: Adam0 Date: Sun, 9 Aug 2026 18:46:27 -0400 Subject: [PATCH] Migrate to noctalia v5 Add RAM and swap system monitor widgets Make Noctalia shell translucent Remove Noctalia defaults from configuration Add performance widget controls Reorganize Noctalia v5 configuration Fix Noctalia plugin derivation syntax --- flake.lock | 211 +------ flake.nix | 13 +- modules/desktop/hyprland/gestures.nix | 7 +- .../desktop/hyprland/keybinds/brightness.nix | 8 +- modules/desktop/hyprland/keybinds/media.nix | 10 +- .../keybinds/screenshots-and-color.nix | 7 +- modules/desktop/hyprland/keybinds/shell.nix | 20 +- modules/desktop/hyprland/keybinds/system.nix | 16 +- .../hyprland/keybinds/window-management.nix | 12 +- modules/desktop/hyprland/rules.nix | 26 +- modules/desktop/hyprland/screenshot.nix | 5 - modules/desktop/noctalia/audio.nix | 11 - modules/desktop/noctalia/bar.nix | 357 +++++++----- modules/desktop/noctalia/brightness.nix | 12 +- modules/desktop/noctalia/calendar.nix | 24 - modules/desktop/noctalia/control-center.nix | 40 ++ modules/desktop/noctalia/controlcenter.nix | 64 --- modules/desktop/noctalia/default.nix | 22 +- modules/desktop/noctalia/delobotomize.nix | 125 ----- modules/desktop/noctalia/dock.nix | 39 +- modules/desktop/noctalia/general.nix | 63 --- modules/desktop/noctalia/hooks.nix | 22 - modules/desktop/noctalia/idle.nix | 93 ++-- modules/desktop/noctalia/launcher.nix | 34 -- modules/desktop/noctalia/location.nix | 47 +- modules/desktop/noctalia/lockscreen.nix | 69 +++ modules/desktop/noctalia/network.nix | 15 - modules/desktop/noctalia/notifications.nix | 13 - .../patches/noctalia-launcher-ipc.patch | 26 - .../patches/noctalia-location-override.patch | 66 --- .../patches/noctalia-settings-fallback.patch | 55 -- modules/desktop/noctalia/plugins.nix | 165 ++---- .../noctalia/plugins/performance/plugin.toml | 40 ++ .../noctalia/plugins/performance/toggle.luau | 72 +++ .../plugins/performance/translations/en.json | 6 + modules/desktop/noctalia/sessionmenu.nix | 64 --- modules/desktop/noctalia/shell.nix | 142 +++++ modules/desktop/noctalia/system-monitor.nix | 13 + modules/desktop/noctalia/systemmonitor.nix | 38 -- modules/desktop/noctalia/theme.nix | 39 +- modules/desktop/noctalia/ui.nix | 14 - modules/desktop/noctalia/wallpaper.nix | 22 +- modules/desktop/xdg/polkit.nix | 9 - modules/hosts/desktop/home.nix | 17 +- modules/hosts/laptop/home.nix | 2 +- modules/pkgs/default.nix | 2 +- modules/pkgs/performance-mode.nix | 122 +++++ modules/pkgs/performant-mode.nix | 67 --- modules/profiles/personal.nix | 2 - modules/programs/gui/tangled.nix | 39 +- modules/programs/tui/pi/computer-use.nix | 36 ++ modules/programs/tui/pi/default.nix | 22 +- modules/programs/tui/pi/extensions/mcp.nix | 63 ++- .../tui/pi/extensions/tool-renderer.nix | 11 +- modules/programs/tui/pi/instructions.md | 7 + modules/programs/tui/pi/settings.nix | 1 - .../tui/pi/skills/nix-search/SKILL.md | 2 +- .../programs/tui/pi/skills/simplify/SKILL.md | 2 +- .../programs/tui/television/nix-search.nix | 2 +- noctalia-config.toml | 513 ++++++++++++++++++ vars.nix | 1 - 61 files changed, 1625 insertions(+), 1442 deletions(-) delete mode 100644 modules/desktop/hyprland/screenshot.nix delete mode 100644 modules/desktop/noctalia/audio.nix delete mode 100644 modules/desktop/noctalia/calendar.nix create mode 100644 modules/desktop/noctalia/control-center.nix delete mode 100644 modules/desktop/noctalia/controlcenter.nix delete mode 100644 modules/desktop/noctalia/delobotomize.nix delete mode 100644 modules/desktop/noctalia/general.nix delete mode 100644 modules/desktop/noctalia/hooks.nix delete mode 100644 modules/desktop/noctalia/launcher.nix create mode 100644 modules/desktop/noctalia/lockscreen.nix delete mode 100644 modules/desktop/noctalia/network.nix delete mode 100644 modules/desktop/noctalia/notifications.nix delete mode 100644 modules/desktop/noctalia/patches/noctalia-launcher-ipc.patch delete mode 100644 modules/desktop/noctalia/patches/noctalia-location-override.patch delete mode 100644 modules/desktop/noctalia/patches/noctalia-settings-fallback.patch create mode 100644 modules/desktop/noctalia/plugins/performance/plugin.toml create mode 100644 modules/desktop/noctalia/plugins/performance/toggle.luau create mode 100644 modules/desktop/noctalia/plugins/performance/translations/en.json delete mode 100644 modules/desktop/noctalia/sessionmenu.nix create mode 100644 modules/desktop/noctalia/shell.nix create mode 100644 modules/desktop/noctalia/system-monitor.nix delete mode 100644 modules/desktop/noctalia/systemmonitor.nix delete mode 100644 modules/desktop/noctalia/ui.nix delete mode 100644 modules/desktop/xdg/polkit.nix create mode 100644 modules/pkgs/performance-mode.nix delete mode 100644 modules/pkgs/performant-mode.nix create mode 100644 modules/programs/tui/pi/computer-use.nix create mode 100644 noctalia-config.toml diff --git a/flake.lock b/flake.lock index 26ef2e9..d463b8c 100644 --- a/flake.lock +++ b/flake.lock @@ -174,7 +174,7 @@ "pi-nix", "systems" ], - "treefmt-nix": "treefmt-nix_3" + "treefmt-nix": "treefmt-nix_2" }, "locked": { "lastModified": 1778446047, @@ -459,22 +459,6 @@ "url": "https://git.lix.systems/lix-project/flake-compat.git" } }, - "flake-compat_7": { - "flake": false, - "locked": { - "lastModified": 1767039857, - "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", - "owner": "NixOS", - "repo": "flake-compat", - "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "flake-compat", - "type": "github" - } - }, "flake-file": { "locked": { "lastModified": 1785282747, @@ -571,24 +555,6 @@ "type": "github" } }, - "flake-parts_5": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib_2" - }, - "locked": { - "lastModified": 1782949081, - "narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, "flake-utils": { "inputs": { "systems": [ @@ -648,28 +614,6 @@ "url": "https://flakehub.com/f/cachix/git-hooks.nix/0.1.941" } }, - "git-hooks-nix_2": { - "inputs": { - "flake-compat": "flake-compat_7", - "nixpkgs": [ - "tg", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1784288435, - "narHash": "sha256-ReRHaLgr/uVqdD8afFSn+myXIfpHeOhP0yYe0TJqAA8=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "43b3c1ab9d40fb1dbb008f451988a91e375825e9", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, "gitignore": { "inputs": { "nixpkgs": [ @@ -1412,21 +1356,6 @@ "type": "github" } }, - "nixpkgs-lib_2": { - "locked": { - "lastModified": 1782614948, - "narHash": "sha256-ePjCwr1sNm9NYUqywL7QfK3JnlS015msC+eBu2zKlp8=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "db3f255737b94216eb71cce308e2912cf6bc2d7c", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, "nixpkgs-nixcord": { "locked": { "lastModified": 1785386831, @@ -1552,48 +1481,22 @@ "inputs": { "nixpkgs": [ "nixpkgs" - ], - "noctalia-qs": [ - "noctalia-qs" ] }, "locked": { - "lastModified": 1783017890, - "narHash": "sha256-bAzrtN0GDMH0dOZkgeI3zSxfFs2rdD3pMuzOxvTF0bs=", + "lastModified": 1786292031, + "narHash": "sha256-NUSkPXfefx4Ji2aPJMe0oT36KQSeBKqJQ/wVjkCsCv8=", "owner": "noctalia-dev", "repo": "noctalia", - "rev": "a48885b9fec485c903c955749a7da6e30147cd38", + "rev": "cc1e476b083392487d4b97903c972ed5480f5b25", "type": "github" }, "original": { "owner": "noctalia-dev", - "ref": "legacy-v4", "repo": "noctalia", "type": "github" } }, - "noctalia-qs": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "systems": "systems_5", - "treefmt-nix": "treefmt-nix_2" - }, - "locked": { - "lastModified": 1783820560, - "narHash": "sha256-ZTpxiN6evzEEca3DeMba7GtUkMVC/FJBHyIYy4uTLVc=", - "owner": "noctalia-dev", - "repo": "noctalia-qs", - "rev": "606adedbfea92caba306730edd0f6adba4acf310", - "type": "github" - }, - "original": { - "owner": "noctalia-dev", - "repo": "noctalia-qs", - "type": "github" - } - }, "nur": { "inputs": { "flake-parts": [ @@ -1604,11 +1507,11 @@ ] }, "locked": { - "lastModified": 1786233186, - "narHash": "sha256-sqDu3uQvU1LimxIZ907iFGqwVEBBZIB5ZSgGlb7zKqY=", + "lastModified": 1786326302, + "narHash": "sha256-ttCPd59KOQTYtxSbDNdr7mgJeW7gBgrHQi0wngRkLp4=", "owner": "nix-community", "repo": "NUR", - "rev": "317f059fb7463680165802d82ddad2126fabf8d3", + "rev": "c31d0b9511aadb1f2366b37dc4796f2c45dca722", "type": "github" }, "original": { @@ -1652,7 +1555,7 @@ "nixpkgs" ], "quickshell": "quickshell", - "systems": "systems_6", + "systems": "systems_5", "treefmt-nix": [ "treefmt-nix" ] @@ -1675,7 +1578,7 @@ "nixpkgs": [ "nixpkgs" ], - "systems": "systems_7" + "systems": "systems_6" }, "locked": { "lastModified": 1786166024, @@ -1830,7 +1733,6 @@ "nixpkgs-crowdsec": "nixpkgs-crowdsec", "nixpkgs-crowdsec-blocklist-import": "nixpkgs-crowdsec-blocklist-import", "noctalia": "noctalia", - "noctalia-qs": "noctalia-qs", "nur": "nur", "nvf": "nvf", "overzicht": "overzicht", @@ -1838,8 +1740,7 @@ "sops-nix": "sops-nix", "spicetify-nix": "spicetify-nix", "stylix": "stylix", - "tg": "tg", - "treefmt-nix": "treefmt-nix_5", + "treefmt-nix": "treefmt-nix_3", "tuigreet": "tuigreet", "zen-browser": "zen-browser" } @@ -1890,7 +1791,7 @@ "nixpkgs": [ "nixpkgs" ], - "systems": "systems_8" + "systems": "systems_7" }, "locked": { "lastModified": 1785652745, @@ -1923,7 +1824,7 @@ "nur": [ "nur" ], - "systems": "systems_9", + "systems": "systems_8", "tinted-kitty": "tinted-kitty", "tinted-schemes": "tinted-schemes", "tinted-tmux": "tinted-tmux", @@ -2004,21 +1905,6 @@ } }, "systems_5": { - "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_6": { "locked": { "lastModified": 1681028828, "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", @@ -2033,7 +1919,7 @@ "type": "github" } }, - "systems_7": { + "systems_6": { "locked": { "lastModified": 1681028828, "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", @@ -2048,7 +1934,7 @@ "type": "github" } }, - "systems_8": { + "systems_7": { "locked": { "lastModified": 1681028828, "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", @@ -2063,7 +1949,7 @@ "type": "github" } }, - "systems_9": { + "systems_8": { "locked": { "lastModified": 1774449309, "narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=", @@ -2092,29 +1978,6 @@ "url": "https://tangled.org/csw.im/tangled-catppuccin/archive/main?format=tar.gz" } }, - "tg": { - "inputs": { - "flake-parts": "flake-parts_5", - "git-hooks-nix": "git-hooks-nix_2", - "nixpkgs": [ - "nixpkgs" - ], - "treefmt-nix": "treefmt-nix_4" - }, - "locked": { - "lastModified": 1785520023, - "narHash": "sha256-0R6k6X7/k2/LjAy/pwPke/ja/Lx9/MFrF/jYtAKIdqI=", - "ref": "refs/heads/master", - "rev": "c2391cb2f22526bcb0beb1b84c7764084436f9e7", - "revCount": 127, - "type": "git", - "url": "https://tangled.org/aly.codes/tg" - }, - "original": { - "type": "git", - "url": "https://tangled.org/aly.codes/tg" - } - }, "tinted-kitty": { "flake": false, "locked": { @@ -2201,27 +2064,6 @@ } }, "treefmt-nix_2": { - "inputs": { - "nixpkgs": [ - "noctalia-qs", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1780220602, - "narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "db947814a175b7ca6ded66e21383d938df01c227", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "treefmt-nix_3": { "inputs": { "nixpkgs": [ "pi-nix", @@ -2243,28 +2085,7 @@ "type": "github" } }, - "treefmt-nix_4": { - "inputs": { - "nixpkgs": [ - "tg", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1785360170, - "narHash": "sha256-XE1lKgQ3eIO3E7zWryqcRsax+mYXod/5RHBn4YaR9YE=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "d1187f8bc71fb8aab02395869ec3f5c1920f75c0", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "treefmt-nix_5": { + "treefmt-nix_3": { "inputs": { "nixpkgs": [ "nixpkgs" diff --git a/flake.nix b/flake.nix index 588d8f9..051c839 100644 --- a/flake.nix +++ b/flake.nix @@ -67,14 +67,7 @@ nixpkgs-crowdsec.url = "github:TornaxO7/nixpkgs/saltsprint"; nixpkgs-crowdsec-blocklist-import.url = "github:gaelj/nixpkgs/init-crowdsec-blocklist-import"; noctalia = { - url = "github:noctalia-dev/noctalia?ref=legacy-v4"; - inputs = { - nixpkgs.follows = "nixpkgs"; - noctalia-qs.follows = "noctalia-qs"; - }; - }; - noctalia-qs = { - url = "github:noctalia-dev/noctalia-qs"; + url = "github:noctalia-dev/noctalia"; inputs.nixpkgs.follows = "nixpkgs"; }; nur = { @@ -117,10 +110,6 @@ nur.follows = "nur"; }; }; - tg = { - url = "git+https://tangled.org/aly.codes/tg"; - inputs.nixpkgs.follows = "nixpkgs"; - }; treefmt-nix = { url = "github:numtide/treefmt-nix"; inputs.nixpkgs.follows = "nixpkgs"; diff --git a/modules/desktop/hyprland/gestures.nix b/modules/desktop/hyprland/gestures.nix index c6efd08..9f44d87 100644 --- a/modules/desktop/hyprland/gestures.nix +++ b/modules/desktop/hyprland/gestures.nix @@ -10,14 +10,13 @@ (lib) # keep-sorted start getExe - getExe' mkEnableOption mkIf # keep-sorted end ; # keep-sorted start - noctalia = "${getExe' config.programs.noctalia-shell.package "noctalia-shell"} ipc --path ${config.xdg.configHome}/quickshell/noctalia call"; + noctalia = "${getExe config.programs.noctalia.package} msg"; overzicht = getExe config.programs.overzicht.package; # keep-sorted end @@ -39,14 +38,14 @@ direction = "down"; fingers = 3; action = "exec"; - exec = "${noctalia} launcher close"; + exec = "${noctalia} panel-close launcher"; } { direction = "up"; fingers = 3; action = "exec"; - exec = "${noctalia} launcher open"; + exec = "${noctalia} panel-open launcher"; } # keep-sorted end diff --git a/modules/desktop/hyprland/keybinds/brightness.nix b/modules/desktop/hyprland/keybinds/brightness.nix index 1f55d60..4be6669 100644 --- a/modules/desktop/hyprland/keybinds/brightness.nix +++ b/modules/desktop/hyprland/keybinds/brightness.nix @@ -9,7 +9,7 @@ inherit (lib) # keep-sorted start - getExe' + getExe mkEnableOption optionals # keep-sorted end @@ -18,7 +18,7 @@ cfg = config.hyprland.brightness; - noctalia = "${getExe' config.programs.noctalia-shell.package "noctalia-shell"} ipc --path ${config.xdg.configHome}/quickshell/noctalia call"; + noctalia = "${getExe config.programs.noctalia.package} msg"; in { options.hyprland.brightness.enable = mkEnableOption "function-row brightness keybindings"; @@ -29,7 +29,7 @@ description = "Brightness down"; keys = ["XF86MonBrightnessDown"]; - exec = "${noctalia} brightness decrease"; + exec = "${noctalia} brightness-down"; options = { # keep-sorted start @@ -43,7 +43,7 @@ description = "Brightness up"; keys = ["XF86MonBrightnessUp"]; - exec = "${noctalia} brightness increase"; + exec = "${noctalia} brightness-up"; options = { # keep-sorted start diff --git a/modules/desktop/hyprland/keybinds/media.nix b/modules/desktop/hyprland/keybinds/media.nix index dcbe66c..5e445e8 100644 --- a/modules/desktop/hyprland/keybinds/media.nix +++ b/modules/desktop/hyprland/keybinds/media.nix @@ -6,10 +6,10 @@ # keep-sorted end ... }: let - inherit (lib) getExe'; + inherit (lib) getExe; inherit (lib.self) mkHylixBindGroup; - noctalia = "${getExe' config.programs.noctalia-shell.package "noctalia-shell"} ipc --path ${config.xdg.configHome}/quickshell/noctalia call"; + noctalia = "${getExe config.programs.noctalia.package} msg"; in { config.programs.hylix.bindGroups = [ (mkHylixBindGroup "Media" [ @@ -18,7 +18,7 @@ description = "Mute"; keys = ["XF86AudioMute"]; - exec = "${noctalia} volume muteOutput"; + exec = "${noctalia} volume-mute"; options.locked = true; } @@ -27,7 +27,7 @@ description = "Volume down"; keys = ["XF86AudioLowerVolume"]; - exec = "${noctalia} volume decrease"; + exec = "${noctalia} volume-down"; options = { # keep-sorted start @@ -41,7 +41,7 @@ description = "Volume up"; keys = ["XF86AudioRaiseVolume"]; - exec = "${noctalia} volume increase"; + exec = "${noctalia} volume-up"; options = { # keep-sorted start diff --git a/modules/desktop/hyprland/keybinds/screenshots-and-color.nix b/modules/desktop/hyprland/keybinds/screenshots-and-color.nix index 7e81b73..4909680 100644 --- a/modules/desktop/hyprland/keybinds/screenshots-and-color.nix +++ b/modules/desktop/hyprland/keybinds/screenshots-and-color.nix @@ -12,8 +12,7 @@ # keep-sorted start hyprpicker = getExe pkgs.hyprpicker; - hyprshot = getExe config.programs.hyprshot.package; - screenshotDir = "${config.xdg.userDirs.pictures}/screenshots"; + noctalia = getExe config.programs.noctalia.package; # keep-sorted end in { config.programs.hylix.bindGroups = [ @@ -30,14 +29,14 @@ description = "Screenshot output"; keys = ["SUPER" "Print"]; - exec = "${hyprshot} -m output -o ${screenshotDir}"; + exec = "${noctalia} msg screenshot-fullscreen"; } { description = "Screenshot region"; keys = ["SUPER" "SHIFT" "S"]; - exec = "${hyprshot} -m region -o ${screenshotDir}"; + exec = "${noctalia} msg screenshot-region"; } # keep-sorted end ]) diff --git a/modules/desktop/hyprland/keybinds/shell.nix b/modules/desktop/hyprland/keybinds/shell.nix index bd9a2cc..be08198 100644 --- a/modules/desktop/hyprland/keybinds/shell.nix +++ b/modules/desktop/hyprland/keybinds/shell.nix @@ -6,10 +6,10 @@ # keep-sorted end ... }: let - inherit (lib) getExe'; + inherit (lib) getExe; inherit (lib.self) mkHylixBindGroup; - noctalia = "${getExe' config.programs.noctalia-shell.package "noctalia-shell"} ipc --path ${config.xdg.configHome}/quickshell/noctalia call"; + noctalia = "${getExe config.programs.noctalia.package} msg"; in { config.programs.hylix.bindGroups = [ (mkHylixBindGroup "Shell" [ @@ -18,56 +18,56 @@ description = "Clipboard"; keys = ["SUPER" "SHIFT" "V"]; - exec = "${noctalia} launcher clipboard"; + exec = "${noctalia} panel-toggle clipboard"; } { description = "Control center"; keys = ["SUPER" "U"]; - exec = "${noctalia} controlCenter toggle"; + exec = "${noctalia} panel-toggle control-center"; } { description = "Emoji picker"; keys = ["SUPER" "G"]; - exec = "${noctalia} launcher emoji"; + exec = "${noctalia} panel-toggle launcher /emo"; } { description = "Idle inhibitor"; keys = ["SUPER" "Y"]; - exec = "${noctalia} idleInhibitor toggle"; + exec = "${noctalia} caffeine-toggle"; } { description = "Launcher"; keys = ["SUPER" "Tab"]; - exec = "${noctalia} launcher toggle"; + exec = "${noctalia} panel-toggle launcher"; } { description = "Notifications"; keys = ["SUPER" "O"]; - exec = "${noctalia} notifications toggleHistory"; + exec = "${noctalia} panel-toggle control-center notifications"; } { description = "Session menu"; keys = ["SUPER" "Escape"]; - exec = "${noctalia} sessionMenu toggle"; + exec = "${noctalia} panel-toggle session"; } { description = "Wallpaper picker"; keys = ["SUPER" "C"]; - exec = "${noctalia} wallpaper toggle"; + exec = "${noctalia} panel-toggle wallpaper"; } # keep-sorted end ]) diff --git a/modules/desktop/hyprland/keybinds/system.nix b/modules/desktop/hyprland/keybinds/system.nix index 72b0f24..14c824e 100644 --- a/modules/desktop/hyprland/keybinds/system.nix +++ b/modules/desktop/hyprland/keybinds/system.nix @@ -6,17 +6,11 @@ # keep-sorted end ... }: let - inherit - (lib) - # keep-sorted start - getExe - getExe' - # keep-sorted end - ; + inherit (lib) getExe; inherit (lib.self) mkHylixBindGroup; # keep-sorted start - noctalia = "${getExe' config.programs.noctalia-shell.package "noctalia-shell"} ipc --path ${config.xdg.configHome}/quickshell/noctalia call"; + noctalia = "${getExe config.programs.noctalia.package} msg"; overzicht = "${getExe config.programs.overzicht.package} ipc call"; # keep-sorted end in { @@ -27,7 +21,7 @@ description = "Keybind cheatsheet"; keys = ["SUPER" "Space"]; - exec = "${noctalia} plugin togglePanel keybind-cheatsheet"; + exec = "${noctalia} panel-toggle kenn/keybind-cheatsheet:cheatsheet"; } { @@ -38,10 +32,10 @@ } { - description = "Performance profile"; + description = "Performance mode"; keys = ["SUPER" "F1"]; - exec = "${noctalia} powerProfile toggleNoctaliaPerformance"; + exec = "${noctalia} plugin adam0/performance:toggle focused:main toggle"; } # keep-sorted end ]) diff --git a/modules/desktop/hyprland/keybinds/window-management.nix b/modules/desktop/hyprland/keybinds/window-management.nix index 184937c..e1cad10 100644 --- a/modules/desktop/hyprland/keybinds/window-management.nix +++ b/modules/desktop/hyprland/keybinds/window-management.nix @@ -44,9 +44,15 @@ description = "Toggle floating"; keys = ["SUPER" "V"]; - action = "window.float"; - - args.action = "toggle"; + lua = '' + function() + local window = hl.get_active_window() + if window == nil or window.class == "dev.noctalia.Noctalia" then + return + end + hl.dispatch(hl.dsp.window.float({action = "toggle", window = window})) + end + ''; } { diff --git a/modules/desktop/hyprland/rules.nix b/modules/desktop/hyprland/rules.nix index 892a238..512e0c3 100644 --- a/modules/desktop/hyprland/rules.nix +++ b/modules/desktop/hyprland/rules.nix @@ -2,7 +2,6 @@ flake.modules.homeManager.hyprland = { # keep-sorted start config, - inputs, lib, osConfig, pkgs, @@ -23,7 +22,7 @@ grim = getExe pkgs.grim; hyprctl = getExe' osConfig.programs.hyprland.package "hyprctl"; hyprpicker = getExe pkgs.hyprpicker; - noctalia-qs = getExe' inputs.noctalia-qs.packages.${pkgs.stdenv.hostPlatform.system}.quickshell ".quickshell-wrapped"; + noctalia = getExe' config.programs.noctalia.package ".noctalia-wrapped"; overzicht = getExe' config.programs.quickshell.package ".quickshell-wrapped"; xdg-desktop-portal-hyprland = getExe' osConfig.programs.hyprland.portalPackage ".xdg-desktop-portal-hyprland-wrapped"; # keep-sorted end @@ -58,7 +57,7 @@ } { - binary = escapeRegex noctalia-qs; + binary = escapeRegex noctalia; mode = "allow"; type = "screencopy"; } @@ -86,16 +85,6 @@ no_anim = true; } - { - match.namespace = "noctalia-background-.*$"; - - # keep-sorted start - blur = true; - blur_popups = true; - ignore_alpha = 0.94; - # keep-sorted end - } - { match.namespace = "noctalia.+"; @@ -260,6 +249,17 @@ opacity = "1 override 1 override"; } + { + match.class = "dev.noctalia.Noctalia"; + + # keep-sorted start + center = true; + float = true; + opacity = "0.95 override 0.95 override"; + size = [1200 850]; + # keep-sorted end + } + { match.class = "equibop"; diff --git a/modules/desktop/hyprland/screenshot.nix b/modules/desktop/hyprland/screenshot.nix deleted file mode 100644 index ea34c7a..0000000 --- a/modules/desktop/hyprland/screenshot.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ - flake.modules.homeManager.hyprland = { - programs.hyprshot.enable = true; - }; -} diff --git a/modules/desktop/noctalia/audio.nix b/modules/desktop/noctalia/audio.nix deleted file mode 100644 index eecf742..0000000 --- a/modules/desktop/noctalia/audio.nix +++ /dev/null @@ -1,11 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - programs.noctalia-shell.settings.audio = { - # keep-sorted start - cavaFrameRate = 60; - visualizerType = "mirrored"; - volumeOverdrive = true; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/bar.nix b/modules/desktop/noctalia/bar.nix index 91c5360..5fe3143 100644 --- a/modules/desktop/noctalia/bar.nix +++ b/modules/desktop/noctalia/bar.nix @@ -4,156 +4,257 @@ config, lib, osConfig, + pkgs, # keep-sorted end ... }: let - inherit (lib) optional; + inherit (lib) getExe optional; # keep-sorted start - cfgBattery = config.programs.noctalia-shell.battery.enable; + btop = getExe config.programs.btop.package; + cfgBattery = config.programs.noctalia.battery.enable; cfgBluetooth = osConfig.capabilities.bluetooth; - cfgGpu = config.programs.noctalia-shell.systemMonitor.enableGpu; + terminal = getExe config.xdg.terminal-exec.package; + wiremix = config.xdg.desktopEntries.wiremix.exec; # keep-sorted end - in { - programs.noctalia-shell.settings.bar = { + + mkStat = stat: { + inherit stat; + type = "sysmon"; + # keep-sorted start - backgroundOpacity = 1; - density = "compact"; - floating = false; - outerCorners = false; - position = "top"; - showCapsule = true; - useSeparateOpacity = true; + actions.middle = "exec ${terminal} --title=Btop ${btop}"; + color = "primary"; + show_glyph = true; + show_value = false; + visualization = "gauge"; # keep-sorted end + }; + in { + programs.noctalia.settings = { + bar = { + order = ["main"]; + + main = { + # Layout + # keep-sorted start + margin_ends = 0; + padding = 4; + position = "top"; + scale = 0.85; + thickness = 24; + widget_spacing = 4; + # keep-sorted end + + # Shape + # keep-sorted start + border_width = 1.0; + concave_edge_corners = false; + radius = 0; + # keep-sorted end + + # Capsule + # keep-sorted start + capsule = true; + capsule_border = "outline"; + capsule_padding = 4.0; + capsule_radius = 0.0; + # keep-sorted end + + # Content + # keep-sorted start + color = "on_surface_variant"; + font_weight = 600; + icon_color = "on_surface"; + # keep-sorted end + + start = [ + "group:system-monitor" + "privacy" + "lock_keys" + "active_window" + "media" + ]; - widgets = { - left = [ - { - id = "SystemMonitor"; - showCpuFreq = true; - showCpuTemp = true; - showCpuUsage = true; - showGpuTemp = cfgGpu; - showMemoryAsPercent = false; - showMemoryUsage = true; - showNetworkStats = false; - showSwapUsage = true; - } - - {id = "plugin:privacy-indicator";} - - { - id = "LockKeys"; - capsLockIcon = "circle-dashed-letter-c"; - numLockIcon = "circle-dashed-letter-n"; - scrollLockIcon = "circle-dashed-letter-s"; - showCapsLock = true; - showNumLock = false; - showScrollLock = false; - } - - { - id = "ActiveWindow"; - colorizeIcons = false; - hideMode = "hidden"; - maxWidth = 145; - scrollingMode = "hover"; - showIcon = true; - useFixedWidth = false; - } - - { - id = "MediaMini"; - hideMode = "hidden"; - hideWhenIdle = false; - maxWidth = 145; - scrollingMode = "hover"; - showAlbumArt = true; - showVisualizer = false; - useFixedWidth = false; - visualizerType = "linear"; - } - ]; - - center = [ - { - id = "Workspace"; - hideUnoccupied = true; - labelMode = "none"; - followFocusedScreen = true; - } - ]; - - right = let - wiremix = config.xdg.desktopEntries.wiremix.exec; - in - [ + center = ["workspaces"]; + + end = + [ + "tray" + "performance" + "volume" + "microphone" + ] + ++ optional cfgBluetooth "bluetooth" + ++ [ + "network" + "brightness" + ] + ++ optional cfgBattery "battery" + ++ [ + "caffeine" + "notifications" + "clock" + "control-center" + ]; + + dead_zone.actions.right = "none"; + + capsule_group = [ { - id = "Tray"; - colorizeIcons = false; - drawerEnabled = true; - pinned = [ - "Equibop" - "Beeper" - "spotify-client" - "steam" + accordion = false; + accordion_direction = "end"; + enabled = true; + fill = "surface_variant"; + id = "system-monitor"; + members = [ + "cpu-usage" + "cpu-temperature" + "gpu-usage" + "gpu-temperature" + "ram" + "swap" ]; + opacity = 1.0; + padding = 6.0; } + ]; + }; + }; - { - id = "VPN"; - displayMode = "onhover"; - } + widget = { + # keep-sorted start block=yes newline_separated=yes + "control-center" = { + # keep-sorted start + custom_image = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + custom_image_colorize = true; + icon_color = "tertiary"; + scale = 1.05; + # keep-sorted end + }; - {id = "NoctaliaPerformance";} + "cpu-temperature" = mkStat "cpu_temp"; - { - id = "Volume"; - displayMode = "onhover"; - middleClickCommand = wiremix; - } + "cpu-usage" = mkStat "cpu_usage"; - { - id = "Microphone"; - displayMode = "onhover"; - middleClickCommand = wiremix; - } - ] - ++ (optional cfgBluetooth {id = "Bluetooth";}) - ++ [ - {id = "Network";} + "gpu-temperature" = mkStat "gpu_temp"; - { - id = "Brightness"; - displayMode = "onhover"; - } - ] - ++ [{id = "KeepAwake";}] - ++ (optional cfgBattery {id = "plugin:battery-monitor-plus";}) - ++ [ - {id = "plugin:github-feed";} + "gpu-usage" = mkStat "gpu_usage"; - { - id = "NotificationHistory"; - showUnreadBadge = true; - } + active_window = { + # keep-sorted start + color = "on_surface_variant"; + display = "icon_and_text"; + inactive_opacity = 1.0; + max_length = 145.0; + min_length = 0.0; + show_empty_label = true; + title_scroll = "on_hover"; + # keep-sorted end + }; - { - id = "Clock"; - formatHorizontal = "yyyy-MM-dd HH:mm"; - formatVertical = "HH mm - dd MM"; - tooltipFormat = "ddd, MMM dd HH:mm"; - useCustomFont = false; - clockColor = "primary"; - } + battery = { + color = "on_surface_variant"; + display_mode = "glyph"; + icon_color = "on_surface"; + show_label = true; + }; - { - id = "ControlCenter"; - colorizeSystemIcon = "tertiary"; - enableColorization = true; - useDistroLogo = true; - } + brightness = { + color = "on_surface_variant"; + icon_color = "on_surface"; + show_label = true; + }; + + clock = { + # keep-sorted start + color = "primary"; + format = "{:%Y-%m-%d %H:%M}"; + tooltip_format = "{:%a, %b %d %H:%M}"; + vertical_format = "{:%H\n%M - %d\n%m}"; + # keep-sorted end + }; + + lock_keys = { + # keep-sorted start + display = "short"; + show_caps_lock = true; + show_num_lock = true; + show_scroll_lock = true; + # keep-sorted end + }; + + media = { + # keep-sorted start + color = "on_surface_variant"; + hide_album_art = false; + hide_when_no_media = false; + max_length = 145.0; + min_length = 0.0; + title_scroll = "on_hover"; + # keep-sorted end + }; + + microphone = { + # keep-sorted start + color = "on_surface_variant"; + device = "input"; + show_label = true; + type = "volume"; + # keep-sorted end + + actions.middle = "exec ${wiremix}"; + }; + + network = { + # keep-sorted start + color = "on_surface_variant"; + show_label = true; + show_vpn_label = false; + vpn_status = "both"; + # keep-sorted end + }; + + performance = { + color = "on_surface"; + type = "adam0/performance:toggle"; + }; + + ram = mkStat "ram_used"; + + swap = mkStat "swap_pct"; + + tray = { + # keep-sorted start + detached_panel = true; + drawer = true; + drawer_columns = 4; + # keep-sorted end + + pinned = [ + "Equibop" + "spotify-client" + "steam" + "Beeper" ]; + }; + + volume = { + color = "on_surface_variant"; + icon_color = "on_surface"; + show_label = true; + actions.middle = "exec ${wiremix}"; + }; + + workspaces = { + # keep-sorted start + focused_output_only = true; + occupied_color = "outline"; + pill_scale = 0.8; + show_labels = true; + # keep-sorted end + }; + # keep-sorted end }; }; }; diff --git a/modules/desktop/noctalia/brightness.nix b/modules/desktop/noctalia/brightness.nix index 21914ab..ea45a9e 100644 --- a/modules/desktop/noctalia/brightness.nix +++ b/modules/desktop/noctalia/brightness.nix @@ -1,10 +1,10 @@ { - flake.modules.homeManager.noctalia = { - programs.noctalia-shell.settings.brightness = { - # keep-sorted start - enableDdcSupport = true; - enforceMinimum = false; - # keep-sorted end + flake.modules.homeManager.noctalia = {pkgs, ...}: { + home.packages = [pkgs.ddcutil]; + + programs.noctalia.settings = { + audio.enable_overdrive = true; + brightness.enable_ddcutil = true; }; }; } diff --git a/modules/desktop/noctalia/calendar.nix b/modules/desktop/noctalia/calendar.nix deleted file mode 100644 index c4fada8..0000000 --- a/modules/desktop/noctalia/calendar.nix +++ /dev/null @@ -1,24 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - programs.noctalia-shell = { - packageOverrides.calendarSupport = true; - - settings.calendar.cards = [ - { - id = "calendar-header-card"; - enabled = true; - } - - { - id = "weather-card"; - enabled = false; - } - - { - id = "calendar-month-card"; - enabled = true; - } - ]; - }; - }; -} diff --git a/modules/desktop/noctalia/control-center.nix b/modules/desktop/noctalia/control-center.nix new file mode 100644 index 0000000..9052379 --- /dev/null +++ b/modules/desktop/noctalia/control-center.nix @@ -0,0 +1,40 @@ +{ + flake.modules.homeManager.noctalia = { + # keep-sorted start + lib, + osConfig, + # keep-sorted end + ... + }: let + inherit (lib) optional; + + cfgBluetooth = osConfig.capabilities.bluetooth; + in { + programs.noctalia.settings = { + calendar.enabled = true; + + control_center = { + # keep-sorted start + show_shortcut_labels = true; + sidebar = "compact"; + sidebar_section = "compact"; + width = 640; + # keep-sorted end + + calendar.show_week_numbers = true; + + shortcuts = + [{type = "wifi";}] + ++ optional cfgBluetooth {type = "bluetooth";} + ++ [ + {type = "noctalia/screen_recorder:toggle";} + {type = "wallpaper";} + {type = "notification";} + {type = "power_profile";} + {type = "nightlight";} + ] + ++ optional (!cfgBluetooth) {type = "caffeine";}; + }; + }; + }; +} diff --git a/modules/desktop/noctalia/controlcenter.nix b/modules/desktop/noctalia/controlcenter.nix deleted file mode 100644 index 8091d33..0000000 --- a/modules/desktop/noctalia/controlcenter.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - # keep-sorted start - lib, - osConfig, - # keep-sorted end - ... - }: let - inherit (lib) optional; - - cfgBluetooth = osConfig.capabilities.bluetooth; - cfgWifi = osConfig.capabilities.wifi; - in { - programs.noctalia-shell.settings.controlCenter = { - # keep-sorted start block=yes newline_separated=yes - cards = [ - { - id = "profile-card"; - enabled = true; - } - { - id = "shortcuts-card"; - enabled = true; - } - { - id = "audio-card"; - enabled = false; - } - { - id = "brightness-card"; - enabled = false; - } - { - id = "weather-card"; - enabled = true; - } - { - id = "media-sysmon-card"; - enabled = true; - } - ]; - - position = "close_to_bar_button"; - - shortcuts = { - left = - [{id = "Network";}] - ++ (optional cfgBluetooth {id = "Bluetooth";}) - ++ [ - {id = "plugin:screen-recorder";} - {id = "WallpaperSelector";} - ]; - right = - [ - {id = "Notifications";} - {id = "PowerProfile";} - {id = "KeepAwake";} - ] - ++ (optional cfgWifi {id = "AirplaneMode";}); - }; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/default.nix b/modules/desktop/noctalia/default.nix index 7144d33..2f3e5a4 100644 --- a/modules/desktop/noctalia/default.nix +++ b/modules/desktop/noctalia/default.nix @@ -7,17 +7,7 @@ }: { flake-file.inputs = { noctalia = { - url = "github:noctalia-dev/noctalia?ref=legacy-v4"; - inputs = { - # keep-sorted start - nixpkgs.follows = "nixpkgs"; - noctalia-qs.follows = "noctalia-qs"; - # keep-sorted end - }; - }; - - noctalia-qs = { - url = "github:noctalia-dev/noctalia-qs"; + url = "github:noctalia-dev/noctalia"; inputs.nixpkgs.follows = "nixpkgs"; }; }; @@ -39,17 +29,11 @@ in { imports = [inputs.noctalia.homeModules.default]; - options.programs.noctalia-shell.battery.enable = mkEnableOption "Enable the battery service & widgets."; + options.programs.noctalia.battery.enable = mkEnableOption "battery widgets"; - config.programs.noctalia-shell = { + config.programs.noctalia = { enable = true; systemd.enable = true; - - # keep-sorted start block=yes newline_separated=yes - packageOverrides.calendarSupport = true; - - settings.templates.enableUserTheming = false; - # keep-sorted end }; }; } diff --git a/modules/desktop/noctalia/delobotomize.nix b/modules/desktop/noctalia/delobotomize.nix deleted file mode 100644 index 1344d80..0000000 --- a/modules/desktop/noctalia/delobotomize.nix +++ /dev/null @@ -1,125 +0,0 @@ -{inputs, ...}: { - flake.modules.homeManager.noctalia = { - # keep-sorted start - config, - lib, - pkgs, - # keep-sorted end - ... - }: let - inherit - (lib) - # keep-sorted start - getExe - mkForce - mkOption - optionals - types - # keep-sorted end - ; - - inherit (pkgs.stdenv.hostPlatform) system; - - cfg = config.programs.noctalia-shell; - - basePackage = - if cfg.packageOverrides.package != null - then cfg.packageOverrides.package - else inputs.noctalia.packages.${system}.default; - - overrideArgs = removeAttrs cfg.packageOverrides ["package"]; - locationFileEnv = optionals (cfg.systemd.locationFile != null) ["NOCTALIA_LOCATION_FILE=${cfg.systemd.locationFile}"]; - stableConfigPath = "${config.xdg.configHome}/quickshell/noctalia"; - in { - options = { - programs.noctalia-shell = { - # keep-sorted start block=yes newline_separated=yes - # Keep a base package and overrides for local patches. - packageOverrides = mkOption { - description = "Override arguments applied to the base package."; - - type = types.submodule { - # keep-sorted start block=yes newline_separated=yes - freeformType = types.attrs; - - # Add runtime tools directly to the wrapped shell package path. - options.extraPackages = mkOption { - description = "Additional runtime packages prepended to the shell wrapper PATH."; - - type = types.listOf types.package; - default = []; - }; - - options.package = mkOption { - description = "Optional base package used before applying local patches."; - - type = types.nullOr types.package; - default = null; - }; - # keep-sorted end - }; - - default = {}; - }; - - # Keep gui settings writes outside the nix store. - systemd = { - # keep-sorted start block=yes newline_separated=yes - locationFile = mkOption { - description = '' - Optional file whose trimmed contents override `settings.location.name` before the shell starts. - Point this at a sops secret path to keep the location out of the nix store. - ''; - - type = types.nullOr types.path; - default = null; - }; - - mutableRuntimeSettings = mkOption { - description = "Whether noctalia-shell creates a gui-settings.json to store setting changes made within the GUI at runtime."; - - type = types.bool; - default = true; - }; - # keep-sorted end - }; - # keep-sorted end - }; - }; - - config = { - programs.noctalia-shell = { - # keep-sorted start block=yes newline_separated=yes - # Restore gui-settings fallback behavior and add a location file override. - package = mkForce ((basePackage.override overrideArgs).overrideAttrs (old: { - patches = - (old.patches or []) - ++ [ - # keep-sorted start - ./patches/noctalia-launcher-ipc.patch - ./patches/noctalia-location-override.patch - ./patches/noctalia-settings-fallback.patch - # keep-sorted end - ]; - })); - # keep-sorted end - }; - - # Keep the Quickshell instance path stable across package rebuilds. - xdg.configFile."quickshell/noctalia".source = "${cfg.package}/share/noctalia-shell"; - - # Pass through runtime settings paths and optional location override file. - systemd.user.services.noctalia-shell.Service = let - cfgEnv = config.programs.noctalia-shell.systemd; - in { - # Use dot decimals for plugin shell scripts. - Environment = - ["LC_NUMERIC=C"] - ++ optionals (cfgEnv.enable && cfgEnv.mutableRuntimeSettings) ["NOCTALIA_SETTINGS_FALLBACK=%h/.config/noctalia/gui-settings.json"] - ++ optionals cfgEnv.enable locationFileEnv; - - ExecStart = mkForce "${getExe cfg.package} --path ${stableConfigPath}"; - }; - }; - }; -} diff --git a/modules/desktop/noctalia/dock.nix b/modules/desktop/noctalia/dock.nix index c5302db..0c8f523 100644 --- a/modules/desktop/noctalia/dock.nix +++ b/modules/desktop/noctalia/dock.nix @@ -1,15 +1,34 @@ { flake.modules.homeManager.noctalia = { - programs.noctalia-shell.settings.dock = { - # keep-sorted start - backgroundOpacity = 0.95; - colorizeIcons = false; - displayMode = "auto_hide"; - enabled = false; - floatingRatio = 0.5; - onlySameOutput = true; - size = 0.3; - # keep-sorted end + programs.noctalia.settings = { + desktop_widgets.enabled = false; + dock = { + enabled = true; + + # Layout + # keep-sorted start + active_monitor_only = true; + cross_axis_padding = 4; + icon_size = 24; + main_axis_padding = 4; + margin_edge = 8; + reserve_space = false; + # keep-sorted end + + # Appearance + # keep-sorted start + background_opacity = 0.95; + border_width = 1.0; + radius = 0; + show_dots = true; + # keep-sorted end + + # Hiding and magnification + # keep-sorted start + auto_hide = true; + magnification_scale = 1.3; + # keep-sorted end + }; }; }; } diff --git a/modules/desktop/noctalia/general.nix b/modules/desktop/noctalia/general.nix deleted file mode 100644 index d6f0be7..0000000 --- a/modules/desktop/noctalia/general.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - flake.modules.homeManager.noctalia = {config, ...}: { - programs.noctalia-shell.settings.general = let - # Use sharp corners (no rounding) for consistent design. - radius = 0; - - cfgTouch = config.programs.hylix.touch.enable or false; - in { - # keep-sorted start - animationSpeed = 2; - dimmerOpacity = 0; - iRadiusRatio = radius; - lockOnSuspend = true; - radiusRatio = radius; - reverseScroll = cfgTouch; - scaleRatio = 0.8; - shadowDirection = "center"; - shadowOffsetX = 0; - shadowOffsetY = 0; - showChangelogOnStartup = false; - telemetryEnabled = false; - # keep-sorted end - - # keep-sorted start - clockStyle = "analog"; - lockScreenAnimations = true; - lockScreenBlur = 0.2; - # keep-sorted end - - keybinds = { - # keep-sorted start block=yes newline_separated=yes - keyDown = [ - # keep-sorted start - "Ctrl+J" - "Down" - # keep-sorted end - ]; - - keyLeft = [ - # keep-sorted start - "Ctrl+H" - "Left" - # keep-sorted end - ]; - - keyRight = [ - # keep-sorted start - "Ctrl+L" - "Right" - # keep-sorted end - ]; - - keyUp = [ - # keep-sorted start - "Ctrl+K" - "Up" - # keep-sorted end - ]; - # keep-sorted end - }; - }; - }; -} diff --git a/modules/desktop/noctalia/hooks.nix b/modules/desktop/noctalia/hooks.nix deleted file mode 100644 index 564bce9..0000000 --- a/modules/desktop/noctalia/hooks.nix +++ /dev/null @@ -1,22 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - # keep-sorted start - lib, - pkgs, - # keep-sorted end - ... - }: let - inherit (lib) getExe; - in { - programs.noctalia-shell.settings.hooks = let - performantMode = getExe pkgs.performant-mode; - in { - enabled = true; - - # keep-sorted start - performanceModeDisabled = performantMode; - performanceModeEnabled = performantMode; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/idle.nix b/modules/desktop/noctalia/idle.nix index 681530f..eb8a501 100644 --- a/modules/desktop/noctalia/idle.nix +++ b/modules/desktop/noctalia/idle.nix @@ -7,56 +7,67 @@ # keep-sorted end ... }: let - inherit (builtins) toJSON; - inherit - (lib) - # keep-sorted start - getExe - mkEnableOption - mkIf - optionalAttrs - # keep-sorted end - ; + inherit (lib) getExe mkEnableOption optional; - cfg = config.programs.noctalia-shell.idle; + cfg = config.programs.noctalia.idle; brightnessctl = getExe pkgs.brightnessctl; in { - options.programs.noctalia-shell.idle = { + options.programs.noctalia.idle = { # keep-sorted start - brightness.enable = mkEnableOption "Enable noctalia idle brightness dimming actions."; - suspend.enable = mkEnableOption "Enable noctalia idle suspend timeout."; + brightness.enable = mkEnableOption "Noctalia idle brightness dimming actions"; + suspend.enable = mkEnableOption "Noctalia idle suspend timeout"; # keep-sorted end }; - config.programs.noctalia-shell.settings.idle = - { - enabled = true; + config.programs.noctalia.settings.idle = { + behavior_order = + [ + "dim-screen" + "dim-keyboard" + "lock" + "screen-off" + ] + ++ optional cfg.suspend.enable "lock-and-suspend"; - # keep-sorted start - lockTimeout = 300; - screenOffTimeout = 330; - # keep-sorted end + pre_action_fade_seconds = 5.0; + + behavior = { + # keep-sorted start block=yes newline_separated=yes + "dim-keyboard" = { + action = "command"; + command = "${brightnessctl} -sd rgb:kbd:backlight set 0"; + enabled = cfg.brightness.enable; + resume_command = "${brightnessctl} -rd rgb:kbd:backlight"; + timeout = 150.0; + }; + + "dim-screen" = { + action = "command"; + command = "${brightnessctl} -s set 10"; + enabled = cfg.brightness.enable; + resume_command = "${brightnessctl} -r"; + timeout = 150.0; + }; - customCommands = mkIf cfg.brightness.enable (toJSON [ - # keep-sorted start block=yes newline_separated=yes - { - name = "Dim screen brightness"; - timeout = 150; - command = "${brightnessctl} -s set 10"; - resumeCommand = "${brightnessctl} -r"; - } - - { - name = "Turn off keyboard backlight brightness"; - timeout = 150; - command = "${brightnessctl} -sd rgb:kbd:backlight set 0"; - resumeCommand = "${brightnessctl} -rd rgb:kbd:backlight"; - } - # keep-sorted end - ]); - } - // optionalAttrs cfg.suspend.enable { - suspendTimeout = 480; + "lock-and-suspend" = { + action = "lock_and_suspend"; + enabled = cfg.suspend.enable; + timeout = 480.0; + }; + + "screen-off" = { + action = "screen_off"; + enabled = true; + timeout = 330.0; + }; + + lock = { + action = "lock"; + enabled = true; + timeout = 300.0; + }; + # keep-sorted end }; + }; }; } diff --git a/modules/desktop/noctalia/launcher.nix b/modules/desktop/noctalia/launcher.nix deleted file mode 100644 index 920eed6..0000000 --- a/modules/desktop/noctalia/launcher.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - # keep-sorted start - config, - lib, - pkgs, - # keep-sorted end - ... - }: let - inherit (lib) getExe; - in { - programs.noctalia-shell = { - # keep-sorted start block=yes newline_separated=yes - # Keep launcher runtime tools in the wrapped shell package path. - packageOverrides.extraPackages = [pkgs.wtype]; - - settings.appLauncher = { - # keep-sorted start - autoPasteClipboard = true; - customLaunchPrefix = getExe pkgs.runapp; - customLaunchPrefixEnabled = true; - density = "comfortable"; - enableClipboardHistory = true; - enableSettingsSearch = false; - overviewLayer = true; - position = "center"; - showIconBackground = true; - terminalCommand = getExe config.xdg.terminal-exec.package; - # keep-sorted end - }; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/location.nix b/modules/desktop/noctalia/location.nix index 06de7fb..5a696a2 100644 --- a/modules/desktop/noctalia/location.nix +++ b/modules/desktop/noctalia/location.nix @@ -4,7 +4,6 @@ config, lib, osConfig, - vars, # keep-sorted end ... }: let @@ -18,12 +17,11 @@ types # keep-sorted end ; - inherit (vars) noctaliaFirstDayOfWeek; + inherit (config.lib.file) mkOutOfStoreSymlink; - cfgLocation = config.programs.noctalia-shell.location.source; + cfgLocation = config.programs.noctalia.location.source; in { - # Control whether Noctalia reads weather data from autolocation or sops. - options.programs.noctalia-shell.location.source = mkOption { + options.programs.noctalia.location.source = mkOption { description = '' Configure the Noctalia location source. Set to "autolocate" to use automatic location detection, or to "sops" @@ -41,29 +39,38 @@ config = mkMerge [ { - programs.noctalia-shell.settings.location = { - # keep-sorted start - analogClockInCalendar = true; - autoLocate = true; - firstDayOfWeek = noctaliaFirstDayOfWeek; - showCalendarWeather = false; - showWeekNumberInCalendar = true; - # keep-sorted end + programs.noctalia.settings = { + location.auto_locate = true; + + weather = { + # keep-sorted start + effects = true; + enabled = true; + unit = "metric"; + # keep-sorted end + }; }; } - # Read the desktop weather location from sops at runtime. + # Loads the private location as a later merged config fragment. (let hostname = osConfig.networking.hostName; + secretName = "noctalia/location/${hostname}"; + templateName = "noctalia-location"; in mkIf (cfgLocation == "sops") { - sops.secrets."noctalia/location/${hostname}" = {}; - programs.noctalia-shell = { - # keep-sorted start - settings.location.autoLocate = mkForce false; - systemd.locationFile = config.sops.secrets."noctalia/location/${hostname}".path; - # keep-sorted end + programs.noctalia.settings.location.auto_locate = mkForce false; + + sops = { + secrets.${secretName} = {}; + templates.${templateName}.content = '' + [location] + address = "${config.sops.placeholder.${secretName}}" + auto_locate = false + ''; }; + + xdg.configFile."noctalia/location.toml".source = mkOutOfStoreSymlink config.sops.templates.${templateName}.path; }) ]; }; diff --git a/modules/desktop/noctalia/lockscreen.nix b/modules/desktop/noctalia/lockscreen.nix new file mode 100644 index 0000000..8c28b59 --- /dev/null +++ b/modules/desktop/noctalia/lockscreen.nix @@ -0,0 +1,69 @@ +{ + flake.modules.homeManager.noctalia = { + programs.noctalia.settings = { + lockscreen = { + # keep-sorted start + blur_intensity = 0.4; + blurred_desktop = true; + tint_intensity = 0.2; + # keep-sorted end + }; + + lockscreen_widgets = { + enabled = true; + schema_version = 2; + widget_order = [ + "lockscreen-login-box@eDP-1" + "lockscreen-widget-0000000000000002" + ]; + + grid = { + cell_size = 16; + major_interval = 4; + visible = true; + }; + + widget."lockscreen-login-box@eDP-1" = { + box_height = 196.0; + box_width = 810.0; + cx = 960.0; + cy = 898.0; + output = "eDP-1"; + rotation = 0.0; + type = "login_box"; + settings = { + background_color = "surface_variant"; + background_opacity = 0.88; + background_radius = 12.0; + center_password_text = false; + input_opacity = 1.0; + input_radius = 6.0; + layout = "regular"; + show_caps_lock = true; + show_keyboard_layout = true; + show_login_button = true; + show_media = true; + show_session_buttons = true; + show_unlock_hint = true; + show_weather = true; + }; + }; + + widget.lockscreen-widget-0000000000000002 = { + box_height = 48.0; + box_width = 816.0; + cx = 960.0; + cy = 724.0; + output = "eDP-1"; + rotation = 0.0; + type = "audio_visualizer"; + settings = { + background_opacity = 0.0; + bands = 32; + show_when_idle = true; + }; + }; + }; + }; + }; +} diff --git a/modules/desktop/noctalia/network.nix b/modules/desktop/noctalia/network.nix deleted file mode 100644 index 79907b1..0000000 --- a/modules/desktop/noctalia/network.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ - flake.modules.homeManager.noctalia = {osConfig, ...}: let - cfgWifi = osConfig.capabilities.wifi; - in { - # Propagate host wifi/bluetooth availability into noctalia menus. - programs.noctalia-shell.settings.network = { - # keep-sorted start - bluetoothAutoConnect = false; - bluetoothHideUnnamedDevices = true; - bluetoothRssiPollingEnabled = true; - wifiEnabled = cfgWifi; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/notifications.nix b/modules/desktop/noctalia/notifications.nix deleted file mode 100644 index b994dfd..0000000 --- a/modules/desktop/noctalia/notifications.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - programs.noctalia-shell.settings.notifications = { - # keep-sorted start - criticalUrgencyDuration = 8; - enableKeyboardLayoutToast = false; - lowUrgencyDuration = 2; - normalUrgencyDuration = 4; - respectExpireTimeout = false; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/patches/noctalia-launcher-ipc.patch b/modules/desktop/noctalia/patches/noctalia-launcher-ipc.patch deleted file mode 100644 index d28c6e9..0000000 --- a/modules/desktop/noctalia/patches/noctalia-launcher-ipc.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/Services/Control/IPCService.qml b/Services/Control/IPCService.qml ---- a/Services/Control/IPCService.qml -+++ b/Services/Control/IPCService.qml -@@ -332,6 +332,22 @@ - } - }, Settings.data.appLauncher.overviewLayer); - } -+ function open() { -+ root.screenDetector.withCurrentScreen(screen => { -+ if (!PanelService.isLauncherOpen(screen)) { -+ PanelService.openLauncherWithSearch(screen, ""); -+ } else { -+ PanelService.setLauncherSearchText(screen, ""); -+ } -+ }, Settings.data.appLauncher.overviewLayer); -+ } -+ function close() { -+ root.screenDetector.withCurrentScreen(screen => { -+ if (PanelService.isLauncherOpen(screen)) { -+ PanelService.closeLauncher(screen); -+ } -+ }, Settings.data.appLauncher.overviewLayer); -+ } - function clipboard() { - root.screenDetector.withCurrentScreen(screen => { - var searchText = PanelService.getLauncherSearchText(screen); diff --git a/modules/desktop/noctalia/patches/noctalia-location-override.patch b/modules/desktop/noctalia/patches/noctalia-location-override.patch deleted file mode 100644 index c634478..0000000 --- a/modules/desktop/noctalia/patches/noctalia-location-override.patch +++ /dev/null @@ -1,66 +0,0 @@ -diff --git a/Commons/Settings.qml b/Commons/Settings.qml ---- a/Commons/Settings.qml -+++ b/Commons/Settings.qml -@@ -32,9 +32,12 @@ - readonly property string cacheDir: ensureTrailingSlash(Quickshell.env("NOCTALIA_CACHE_DIR") || (Quickshell.env("XDG_CACHE_HOME") || Quickshell.env("HOME") + "/.cache") + "/" + shellName + "/") - - readonly property string settingsFile: Quickshell.env("NOCTALIA_SETTINGS_FILE") || (configDir + "settings.json") -+ readonly property string envLocation: (Quickshell.env("NOCTALIA_LOCATION") || "").trim() -+ readonly property string envLocationFile: Quickshell.env("NOCTALIA_LOCATION_FILE") || "" - readonly property string defaultAvatar: Quickshell.env("HOME") + "/.face" - readonly property string defaultVideosDirectory: Quickshell.env("HOME") + "/Videos" - readonly property string defaultWallpapersDirectory: Quickshell.env("HOME") + "/Pictures/Wallpapers" -+ property string fileLocationOverride: "" - - signal settingsLoaded - signal settingsSaved -@@ -92,6 +95,18 @@ - settingsFileView.adapter = adapter; - } - -+ function applyLocationOverride() { -+ const locationOverride = (fileLocationOverride || envLocation).trim(); -+ -+ if (locationOverride === "") { -+ return; -+ } -+ -+ if (adapter.location.name !== locationOverride) { -+ adapter.location.name = locationOverride; -+ } -+ } -+ - // Don't write settings to disk immediately - // This avoid excessive IO when a variable changes rapidly (ex: sliders) - Timer { -@@ -135,6 +150,8 @@ - // Finally, update our local settings version - adapter.settingsVersion = settingsVersion; - -+ applyLocationOverride(); -+ - // Emit the signal - root.isLoaded = true; - root.settingsLoaded(); -@@ -172,6 +189,21 @@ - onFileChanged: scheduleExternalReload() - } - -+ FileView { -+ id: locationOverrideFileView -+ path: envLocationFile !== "" ? envLocationFile : undefined -+ printErrors: false -+ watchChanges: true -+ onLoaded: { -+ root.fileLocationOverride = text().trim(); -+ root.applyLocationOverride(); -+ } -+ onLoadFailed: { -+ root.fileLocationOverride = ""; -+ root.applyLocationOverride(); -+ } -+ } -+ - // FileView to load default settings for comparison - FileView { - id: defaultSettingsFileView diff --git a/modules/desktop/noctalia/patches/noctalia-settings-fallback.patch b/modules/desktop/noctalia/patches/noctalia-settings-fallback.patch deleted file mode 100644 index 8d8e721..0000000 --- a/modules/desktop/noctalia/patches/noctalia-settings-fallback.patch +++ /dev/null @@ -1,55 +0,0 @@ -diff --git a/Commons/Settings.qml b/Commons/Settings.qml ---- a/Commons/Settings.qml -+++ b/Commons/Settings.qml -@@ -34,6 +34,7 @@ - readonly property string settingsFile: Quickshell.env("NOCTALIA_SETTINGS_FILE") || (configDir + "settings.json") - readonly property string envLocation: (Quickshell.env("NOCTALIA_LOCATION") || "").trim() - readonly property string envLocationFile: Quickshell.env("NOCTALIA_LOCATION_FILE") || "" -+ readonly property string settingsFallbackFile: Quickshell.env("NOCTALIA_SETTINGS_FALLBACK") || "" - readonly property string defaultAvatar: Quickshell.env("HOME") + "/.face" - readonly property string defaultVideosDirectory: Quickshell.env("HOME") + "/Videos" - readonly property string defaultWallpapersDirectory: Quickshell.env("HOME") + "/Pictures/Wallpapers" -@@ -170,7 +171,9 @@ - if (error.toString().includes("No such file") || error === 2) { - // File doesn't exist, create it with default values - root.isFreshInstall = true; -- writeAdapter(); -+ if (!writeSettingsFallbackAdapter()) { -+ writeAdapter(); -+ } - - // We started without settings, we should open the setupWizard - root.shouldOpenSetupWizard = true; -@@ -212,0 +216,8 @@ -+ -+ // Write-only fallback for mutable GUI settings when settings.json is declarative. -+ FileView { -+ id: settingsFallbackFileView -+ path: settingsFallbackFile !== "" ? settingsFallbackFile : undefined -+ printErrors: false -+ watchChanges: false -+ } -@@ -1111,9 +1122,22 @@ - data.bar.screenOverrides = overrides; - } - -+ function writeSettingsFallbackAdapter() { -+ if (settingsFallbackFile === "") { -+ return false; -+ } -+ -+ settingsFallbackFileView.adapter = adapter; -+ settingsFallbackFileView.writeAdapter(); -+ settingsFallbackFileView.adapter = null; -+ return true; -+ } -+ - // ----------------------------------------------------- - // Public function to trigger immediate settings saving - function saveImmediate() { -- settingsFileView.writeAdapter(); -+ if (!writeSettingsFallbackAdapter()) { -+ settingsFileView.writeAdapter(); -+ } - root.settingsSaved(); // Emit signal after saving - } diff --git a/modules/desktop/noctalia/plugins.nix b/modules/desktop/noctalia/plugins.nix index 2d8d7a5..a446c7b 100644 --- a/modules/desktop/noctalia/plugins.nix +++ b/modules/desktop/noctalia/plugins.nix @@ -4,148 +4,73 @@ config, lib, pkgs, - vars, # keep-sorted end ... }: let - inherit (builtins) toJSON; - inherit - (lib) - # keep-sorted start - genAttrs - optional - # keep-sorted end - ; - inherit (config.lib.file) mkOutOfStoreSymlink; - inherit (vars) gitUsername; + inherit (lib) getExe; - inherit (config.xdg) stateHome; - cfgBattery = config.programs.noctalia-shell.battery.enable; videosDir = config.xdg.userDirs.videos; - colors = config.lib.stylix.colors.withHashtag; + performancePlugin = pkgs.runCommandLocal "noctalia-performance-plugin" {} '' + mkdir -p "$out" + cp -r ${./plugins/performance} "$out/performance" + substituteInPlace "$out/performance/toggle.luau" \ + --replace-fail '@performanceMode@' '${getExe pkgs.performance-mode}' + ''; in { - # keep-sorted start block=yes newline_separated=yes - programs.noctalia-shell = { - plugins = let - noctaliaPluginsUrl = "https://github.com/noctalia-dev/noctalia-plugins"; - in { - version = 2; + home.packages = [pkgs.gpu-screen-recorder]; - sources = [ - { - enabled = true; - name = "Noctalia Plugins"; - url = noctaliaPluginsUrl; - } - ]; - - states = let - mkPlugin = _name: { - enabled = true; - sourceUrl = noctaliaPluginsUrl; - }; - in - genAttrs ([ - # keep-sorted start - "github-feed" - "kaomoji-provider" - "keybind-cheatsheet" - "nvim-session-provider" - "privacy-indicator" - "screen-recorder" - "unicode-picker" - "web-search" - # keep-sorted end - ] - ++ optional cfgBattery "battery-monitor-plus") - mkPlugin; - }; - - # keep-sorted start block=yes newline_separated=yes - # Provide runtime tools used by bundled plugins. - packageOverrides.extraPackages = [pkgs.gpu-screen-recorder]; - - pluginSettings = { - # keep-sorted start block=yes newline_separated=yes - battery-monitor-plus = { + programs.noctalia.settings = { + plugin_settings = { + "kenn/keybind-cheatsheet" = { # keep-sorted start - hideIfNotDetected = false; - showPowerInBar = false; - showPowerProfiles = true; - showTimeInBar = false; + columns = 4; + compositor = "hyprland"; + hyprland_parser = "lua"; # keep-sorted end }; - github-feed = mkOutOfStoreSymlink config.sops.templates."noctalia-github-config".path; - - keybind-cheatsheet = with colors; { + "noctalia/screen_recorder" = { # keep-sorted start - hyprlandParserMode = "lua"; - windowWidth = 1600; - # keep-sorted end - - # keep-sorted start - descriptionTextColor = base05; - keyColorAlt = base08; - keyColorMouse = base0E; - keyColorNumeric = base0D; - keyColorPrint = base0D; - keyColorXF86 = base0D; - keyTextAlt = base00; - keyTextCtrl = base00; - keyTextDefault = base00; - keyTextMouse = base00; - keyTextNumeric = base00; - keyTextPrint = base00; - keyTextShift = base00; - keyTextSuper = base00; - keyTextXF86 = base00; - # keep-sorted end - }; - - nvim-session-provider.sessionDir = "${stateHome}/nvf/sessions"; - - screen-recorder = { - # keep-sorted start - copyToClipboard = true; + copy_to_clipboard = true; directory = "${videosDir}/Recordings"; - videoCodec = "hevc"; + video_codec = "hevc"; # keep-sorted end }; + }; - web-search = { + plugins = { + auto_update = true; + enabled = [ # keep-sorted start - max_results = 5; - search_engine = "Brave Search"; - show_suggestions = false; + "adam0/performance" + "kenn/keybind-cheatsheet" + "noctalia/kaomoji" + "noctalia/screen_recorder" # keep-sorted end - }; - # keep-sorted end - }; + ]; - settings.plugins.autoUpdate = true; - # keep-sorted end - }; + # Keeps the local source after upstream plugin sources. + source = [ + { + kind = "git"; + location = "https://github.com/noctalia-dev/official-plugins"; + name = "official"; + } - # Render github-feed settings from sops. - sops = { - secrets."noctalia/github_token" = {}; + { + kind = "git"; + location = "https://github.com/noctalia-dev/community-plugins"; + name = "community"; + } - templates."noctalia-github-config".content = let - sopsVal = config.sops.placeholder; - in - toJSON { - # keep-sorted start - defaultTab = 1; - enableSystemNotifications = true; - maxEvents = 64; - refreshInterval = 2000; - token = sopsVal."noctalia/github_token"; - username = gitUsername; - # keep-sorted end - }; + { + kind = "path"; + location = "${performancePlugin}"; + name = "local"; + } + ]; + }; }; - # keep-sorted end }; } diff --git a/modules/desktop/noctalia/plugins/performance/plugin.toml b/modules/desktop/noctalia/plugins/performance/plugin.toml new file mode 100644 index 0000000..0bc606f --- /dev/null +++ b/modules/desktop/noctalia/plugins/performance/plugin.toml @@ -0,0 +1,40 @@ +id = "adam0/performance" +name = "Performance Mode" +version = "1.1.0" +plugin_api = 23 +author = "adam0" +license = "MIT" +icon = "rocket" +description = "Toggle reduced-resource settings for Noctalia and Hyprland." + +[[widget]] +id = "toggle" +entry = "toggle.luau" + +[widget.actions] +left = "plugin adam0/performance:toggle focused toggle" +right = "plugin adam0/performance:toggle focused refresh" + +[[widget.setting]] +key = "enabled_glyph" +type = "glyph" +label_key = "settings.enabled_glyph.label" +default = "rocket" + +[[widget.setting]] +key = "disabled_glyph" +type = "glyph" +label_key = "settings.disabled_glyph.label" +default = "rocket-off" + +[[widget.setting]] +key = "enabled_tooltip" +type = "string" +label_key = "settings.enabled_tooltip.label" +default = "Disable performance mode" + +[[widget.setting]] +key = "disabled_tooltip" +type = "string" +label_key = "settings.disabled_tooltip.label" +default = "Enable performance mode" diff --git a/modules/desktop/noctalia/plugins/performance/toggle.luau b/modules/desktop/noctalia/plugins/performance/toggle.luau new file mode 100644 index 0000000..e5a14b2 --- /dev/null +++ b/modules/desktop/noctalia/plugins/performance/toggle.luau @@ -0,0 +1,72 @@ +--!nonstrict + +local command = "@performanceMode@" +local enabled = false +local busy = false +local enabledGlyph = noctalia.getConfig("enabled_glyph") +local disabledGlyph = noctalia.getConfig("disabled_glyph") +local enabledTooltip = noctalia.getConfig("enabled_tooltip") +local disabledTooltip = noctalia.getConfig("disabled_tooltip") + +local function render() + barWidget.setGlyph(if enabled then enabledGlyph else disabledGlyph) + barWidget.setTooltip(if enabled then enabledTooltip else disabledTooltip) +end + +local function refresh(showNotification) + busy = true + local accepted = noctalia.runAsync(command .. " status", function(result) + enabled = result.exitCode == 0 + busy = false + render() + if showNotification then + noctalia.notify("Performance mode", if enabled then "Enabled" else "Disabled") + end + end) + + if not accepted then + busy = false + noctalia.notifyError("Performance mode", "Could not read performance mode status") + render() + end +end + +local function toggle() + if busy then return end + busy = true + + local accepted = noctalia.runAsync(command .. " toggle", function(result) + if result.exitCode ~= 0 then + busy = false + noctalia.notifyError("Performance mode", "Could not toggle performance mode") + render() + return + end + refresh(true) + end) + + if not accepted then + busy = false + noctalia.notifyError("Performance mode", "Could not start performance mode command") + render() + end +end + +function onClick() + toggle() +end + +function onRightClick() + refresh(true) +end + +function onIpc(event, _payload) + if event == "toggle" then + toggle() + elseif event == "refresh" then + refresh(true) + end +end + +render() +refresh(false) diff --git a/modules/desktop/noctalia/plugins/performance/translations/en.json b/modules/desktop/noctalia/plugins/performance/translations/en.json new file mode 100644 index 0000000..f142cf2 --- /dev/null +++ b/modules/desktop/noctalia/plugins/performance/translations/en.json @@ -0,0 +1,6 @@ +{ + "settings.enabled_glyph.label": "Enabled glyph", + "settings.disabled_glyph.label": "Disabled glyph", + "settings.enabled_tooltip.label": "Enabled tooltip", + "settings.disabled_tooltip.label": "Disabled tooltip" +} diff --git a/modules/desktop/noctalia/sessionmenu.nix b/modules/desktop/noctalia/sessionmenu.nix deleted file mode 100644 index ddff77c..0000000 --- a/modules/desktop/noctalia/sessionmenu.nix +++ /dev/null @@ -1,64 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - programs.noctalia-shell.settings.sessionMenu = { - # keep-sorted start - countdownDuration = 8000; - largeButtonsStyle = false; - # keep-sorted end - - powerOptions = [ - { - action = "lock"; - enabled = true; - countdownEnabled = false; - keybind = "1"; - } - - { - action = "suspend"; - enabled = true; - countdownEnabled = true; - command = "systemctl suspend"; - keybind = "2"; - } - - { - action = "reboot"; - enabled = true; - countdownEnabled = true; - command = "systemctl reboot"; - keybind = "3"; - } - - { - action = "logout"; - enabled = true; - countdownEnabled = true; - keybind = "4"; - } - - { - action = "shutdown"; - enabled = true; - countdownEnabled = true; - command = "systemctl poweroff"; - keybind = "5"; - } - - { - action = "hibernate"; - enabled = false; - countdownEnabled = true; - } - - { - action = "rebootToUefi"; - enabled = true; - countdownEnabled = true; - command = "systemctl reboot --firmware-setup"; - keybind = "6"; - } - ]; - }; - }; -} diff --git a/modules/desktop/noctalia/shell.nix b/modules/desktop/noctalia/shell.nix new file mode 100644 index 0000000..8bf9c6d --- /dev/null +++ b/modules/desktop/noctalia/shell.nix @@ -0,0 +1,142 @@ +{ + flake.modules.homeManager.noctalia = {config, ...}: { + programs.noctalia.settings = { + accessibility.ui_scale = 0.8; + + keybinds = { + # keep-sorted start block=yes newline_separated=yes + down = [ + "ctrl+j" + "down" + ]; + + left = [ + "ctrl+h" + "left" + ]; + + right = [ + "ctrl+l" + "right" + ]; + + up = [ + "ctrl+k" + "up" + ]; + # keep-sorted end + }; + + shell = { + # Appearance + # keep-sorted start + avatar_path = "${config.home.homeDirectory}/.face"; + corner_radius_scale = 0.0; + font_family = "JetBrainsMonoNL Nerd Font Propo"; + # keep-sorted end + + # Behavior + # keep-sorted start + launch_apps_as_systemd_services = true; + panel_anchor_bar = "main"; + polkit_agent = true; + screen_time_enabled = true; + setup_wizard_enabled = false; + # keep-sorted end + + # Clipboard + # keep-sorted start + clipboard_confirm_clear_history = false; + clipboard_history_max_entries = 64; + # keep-sorted end + + animation.speed = 2.0; + + launcher.providers.calculator.global = false; + + panel = { + # Appearance + # keep-sorted start + borders = true; + list_item_background = true; + shadow = true; + transparency_mode = "solid"; + # keep-sorted end + + # Placement + # keep-sorted start + control_center_placement = "floating"; + open_near_click_control_center = true; + session_placement = "floating"; + session_position = "center"; + wallpaper_placement = "floating"; + wallpaper_position = "center"; + # keep-sorted end + }; + + screenshot = { + # keep-sorted start + directory = "${config.xdg.userDirs.pictures}/screenshots"; + filename_pattern = "screenshot_%Y-%m-%dT%H:%M:%S"; + show_cursor = true; + # keep-sorted end + }; + + session = { + # keep-sorted start + grid = false; + show_shortcuts = true; + # keep-sorted end + + actions = [ + { + action = "lock"; + countdown_seconds = 0.0; + shortcut = "1"; + } + + { + action = "lock_and_suspend"; + countdown_seconds = 8.0; + shortcut = "2"; + } + + { + action = "reboot"; + countdown_seconds = 8.0; + shortcut = "3"; + } + + { + action = "logout"; + countdown_seconds = 8.0; + shortcut = "4"; + } + + { + action = "shutdown"; + countdown_seconds = 8.0; + shortcut = "5"; + variant = "destructive"; + } + + { + action = "reboot"; + command = "systemctl reboot --firmware-setup"; + countdown_seconds = 8.0; + glyph = "settings-automation"; + label = "UEFI"; + shortcut = "6"; + } + ]; + }; + + shadow.direction = "center"; + }; + }; + }; + + flake.modules.nixos.noctalia = { + security.polkit.enable = true; + }; +} diff --git a/modules/desktop/noctalia/system-monitor.nix b/modules/desktop/noctalia/system-monitor.nix new file mode 100644 index 0000000..15092e3 --- /dev/null +++ b/modules/desktop/noctalia/system-monitor.nix @@ -0,0 +1,13 @@ +{ + flake.modules.homeManager.noctalia = { + programs.noctalia.settings.system.monitor = { + # keep-sorted start + cpu_poll_seconds = 1.0; + disk_poll_seconds = 4.0; + gpu_poll_seconds = 1.0; + memory_poll_seconds = 4.0; + network_poll_seconds = 4.0; + # keep-sorted end + }; + }; +} diff --git a/modules/desktop/noctalia/systemmonitor.nix b/modules/desktop/noctalia/systemmonitor.nix deleted file mode 100644 index eb7aedb..0000000 --- a/modules/desktop/noctalia/systemmonitor.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - # keep-sorted start - config, - lib, - # keep-sorted end - ... - }: let - inherit (lib) mkEnableOption getExe; - - cfgGpu = config.programs.noctalia-shell.systemMonitor.enableGpu; - in { - # Expose a GPU toggle for Noctalia system monitor widgets. - options.programs.noctalia-shell.systemMonitor.enableGpu = mkEnableOption "Enable dGPU monitoring and GPU temperature widgets."; - - config.programs.noctalia-shell.settings.systemMonitor = let - # Reuse a shared 4s interval for slower sensors. - generalInterval = 4000; - in { - # keep-sorted start - cpuPollingInterval = 1000; - diskPollingInterval = generalInterval; - memPollingInterval = generalInterval; - networkPollingInterval = generalInterval; - # keep-sorted end - - # keep-sorted start block=yes - enableDgpuMonitoring = cfgGpu; - externalMonitor = let - # keep-sorted start - btop = getExe config.programs.btop.package; - terminalCommand = getExe config.xdg.terminal-exec.package; - # keep-sorted end - in "${terminalCommand} --title=Btop ${btop}"; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/theme.nix b/modules/desktop/noctalia/theme.nix index 5a39e4e..7a3ed91 100644 --- a/modules/desktop/noctalia/theme.nix +++ b/modules/desktop/noctalia/theme.nix @@ -9,7 +9,7 @@ inherit (lib) mkForce; colors = config.lib.stylix.colors.withHashtag; in { - stylix.targets.noctalia-shell.colors.override.withHashtag = with colors; { + stylix.targets.noctalia.colors.override.withHashtag = with colors; { # keep-sorted start base05 = base06; base0C = base0D; @@ -18,34 +18,31 @@ # keep-sorted end }; - programs.noctalia-shell = { - # keep-sorted start block=yes newline_separated=yes - settings = { - # keep-sorted start block=yes newline_separated=yes - bar = { - # keep-sorted start - backgroundOpacity = mkForce 1.0; - capsuleOpacity = mkForce 1.0; - # keep-sorted end - }; + programs.noctalia.settings = { + theme = { + custom_palette = "stylix"; - systemMonitor = with colors; { + templates = { # keep-sorted start - criticalColor = base08; - useCustomColors = true; - warningColor = base0A; + enable_builtin_templates = false; + enable_community_templates = false; # keep-sorted end }; - # keep-sorted end + }; + bar.main = { # keep-sorted start - dock.backgroundOpacity = mkForce 1.0; - notifications.backgroundOpacity = mkForce 1.0; - osd.backgroundOpacity = mkForce 1.0; - ui.panelBackgroundOpacity = mkForce 1.0; + background_opacity = mkForce 0.95; + capsule_opacity = mkForce 1.0; # keep-sorted end }; - # keep-sorted end + + notification = { + background_opacity = mkForce 0.95; + layer = "overlay"; + }; + + osd.background_opacity = mkForce 0.95; }; }; } diff --git a/modules/desktop/noctalia/ui.nix b/modules/desktop/noctalia/ui.nix deleted file mode 100644 index 91d0def..0000000 --- a/modules/desktop/noctalia/ui.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ - flake.modules.homeManager.noctalia = { - programs.noctalia-shell.settings.ui = { - # keep-sorted start - boxBorderEnabled = true; - fontDefaultScale = 0.8; - fontFixedScale = 0.8; - panelBackgroundOpacity = 0.95; - panelsAttachedToBar = false; - settingsPanelMode = "centered"; - # keep-sorted end - }; - }; -} diff --git a/modules/desktop/noctalia/wallpaper.nix b/modules/desktop/noctalia/wallpaper.nix index a1f68c2..0efec3e 100644 --- a/modules/desktop/noctalia/wallpaper.nix +++ b/modules/desktop/noctalia/wallpaper.nix @@ -2,19 +2,21 @@ flake.modules.homeManager.noctalia = {config, ...}: let picturesDir = config.xdg.userDirs.pictures; in { - programs.noctalia-shell.settings.wallpaper = { + programs.noctalia.settings.wallpaper = { # keep-sorted start block=yes - automationEnabled = true; directory = "${picturesDir}/wallpapers"; - hideWallpaperFilenames = true; - overviewEnabled = true; - panelPosition = "center"; - randomIntervalSec = 7200; - setWallpaperOnAllMonitors = true; - showHiddenFiles = true; - skipStartupTransition = true; - transitionType = ["honeycomb"]; + transition = ["honeycomb"]; + transition_on_startup = true; # keep-sorted end + + automation = { + # keep-sorted start + enabled = true; + interval_seconds = 7200; + order = "random"; + recursive = false; + # keep-sorted end + }; }; }; } diff --git a/modules/desktop/xdg/polkit.nix b/modules/desktop/xdg/polkit.nix deleted file mode 100644 index 79d3c12..0000000 --- a/modules/desktop/xdg/polkit.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ - flake.modules.homeManager.polkit = { - services.polkit-gnome.enable = true; - }; - - flake.modules.nixos.polkit = { - security.polkit.enable = true; - }; -} diff --git a/modules/hosts/desktop/home.nix b/modules/hosts/desktop/home.nix index ef3cc7f..e399cbf 100644 --- a/modules/hosts/desktop/home.nix +++ b/modules/hosts/desktop/home.nix @@ -1,14 +1,11 @@ { flake.modules.nixos.desktop = { # keep-sorted start - lib, self, vars, # keep-sorted end ... }: let - inherit (lib) mkForce; - inherit (vars) username; in { home-manager.users.${username} = { @@ -43,18 +40,8 @@ } ]; - noctalia-shell = { - # keep-sorted start newline_separated=yes - # Keep the desktop weather location in sops. - location.source = "sops"; - - # Avoid desktop suspend after idle blanking. - settings.idle.suspendTimeout = mkForce 0; - - # Enable gpu acceleration for noctalia. - systemMonitor.enableGpu = true; - # keep-sorted end - }; + # Keeps the desktop weather location in sops. + noctalia.location.source = "sops"; # Gpu monitoring support for multi-gpu desktop. nvtop.types = [ diff --git a/modules/hosts/laptop/home.nix b/modules/hosts/laptop/home.nix index 4cb3b69..f223503 100644 --- a/modules/hosts/laptop/home.nix +++ b/modules/hosts/laptop/home.nix @@ -47,7 +47,7 @@ nixcord.equibop.camera.enable = true; # Laptop battery and idle controls. - noctalia-shell = { + noctalia = { battery.enable = true; idle = { # keep-sorted start diff --git a/modules/pkgs/default.nix b/modules/pkgs/default.nix index a2283f3..7ab4282 100644 --- a/modules/pkgs/default.nix +++ b/modules/pkgs/default.nix @@ -16,7 +16,7 @@ jj-conflict-nvim man-preview os-age - performant-mode + performance-mode pptx2md-adapter proton-port-forward rclone-bisync-runner diff --git a/modules/pkgs/performance-mode.nix b/modules/pkgs/performance-mode.nix new file mode 100644 index 0000000..627243a --- /dev/null +++ b/modules/pkgs/performance-mode.nix @@ -0,0 +1,122 @@ +{ + perSystem = {pkgs, ...}: let + inherit (pkgs.lib) escapeShellArg; + inherit (pkgs) writeShellApplication; + + luaScript = '' + hl.config({ + animations = {enabled = false}, + + decoration = { + active_opacity = 1, + inactive_opacity = 1, + blur = {enabled = false}, + shadow = {enabled = false}, + }, + + general = { + border_size = 1, + gaps_in = 0, + gaps_out = 0, + }, + }) + + hl.window_rule({ + name = "performance-mode-opacity", + match = {class = ".*"}, + opacity = "1 override 1 override 1 override", + }) + ''; + in { + packages.performance-mode = writeShellApplication { + name = "performance-mode"; + runtimeInputs = with pkgs; [ + # keep-sorted start + coreutils + hyprland + # keep-sorted end + ]; + text = '' + config_home="''${XDG_CONFIG_HOME:-$HOME/.config}/noctalia" + performance_config="$config_home/zz-performance.toml" + + reload_noctalia() { + if command -v noctalia >/dev/null 2>&1; then + noctalia msg config-reload >/dev/null 2>&1 || true + fi + } + + enable_hyprland_mode() { + [ "$(hyprctl eval ${escapeShellArg luaScript} 2>/dev/null)" = ok ] + } + + enable_mode() { + mkdir -p "$config_home" + + tmp="$(mktemp "$config_home/.zz-performance.XXXXXX")" + trap 'rm -f "$tmp"' EXIT + cat > "$tmp" <<'EOF' + [lockscreen] + blur_intensity = 0.0 + + [shell] + popup_shadows = false + + [shell.animation] + enabled = false + + [shell.panel] + shadow = false + + [wallpaper] + enabled = false + + [wallpaper.automation] + enabled = false + EOF + mv "$tmp" "$performance_config" + + enable_hyprland_mode + reload_noctalia + printf 'enabled\n' + } + + disable_mode() { + rm -f "$performance_config" + + hyprctl reload + reload_noctalia + printf 'disabled\n' + } + + case "''${1:-toggle}" in + disable) + disable_mode + ;; + enable) + enable_mode + ;; + status) + if [ -e "$performance_config" ]; then + printf 'enabled\n' + exit 0 + fi + printf 'disabled\n' + exit 1 + ;; + toggle) + if [ -e "$performance_config" ]; then + disable_mode + else + enable_mode + fi + ;; + *) + printf 'usage: performance-mode [enable|disable|toggle|status]\n' >&2 + exit 2 + ;; + esac + ''; + }; + }; +} diff --git a/modules/pkgs/performant-mode.nix b/modules/pkgs/performant-mode.nix deleted file mode 100644 index f5002f0..0000000 --- a/modules/pkgs/performant-mode.nix +++ /dev/null @@ -1,67 +0,0 @@ -{ - perSystem = {pkgs, ...}: let - inherit (pkgs.lib) escapeShellArg; - inherit (pkgs) writeShellApplication; - - luaScript = '' - hl.config({ - animations = {enabled = false}, - - decoration = { - active_opacity = 1, - inactive_opacity = 1, - blur = {enabled = false}, - shadow = {enabled = false}, - }, - - general = { - border_size = 1, - gaps_in = 0, - gaps_out = 0, - }, - }) - - hl.window_rule({ - name = "performant-mode-opacity", - match = {class = ".*"}, - opacity = "1 override 1 override 1 override", - }) - ''; - in { - packages.performant-mode = writeShellApplication { - name = "performant-mode"; - runtimeInputs = with pkgs; [ - # keep-sorted start - gawk - hyprland - # keep-sorted end - ]; - excludeShellChecks = ["SC2276"]; - text = '' - get_option_value() { - hyprctl getoption "$1" 2>/dev/null \ - | gawk 'NR == 1 && ($1 == "int:" || $1 == "bool:") { print $2 }' \ - || true - } - - performant_mode_enabled() { - [ "$1" = 1 ] || [ "$1" = true ] - } - - enable_lua_performant_mode() { - [ "$(hyprctl eval ${escapeShellArg luaScript} 2>/dev/null)" = ok ] - } - - HYPRPERFORMANTMODE=$(get_option_value animations.enabled) - - if performant_mode_enabled "$HYPRPERFORMANTMODE"; then - enable_lua_performant_mode - exit - fi - - # Restore normal settings by reloading hyprland. - hyprctl reload - ''; - }; - }; -} diff --git a/modules/profiles/personal.nix b/modules/profiles/personal.nix index db8b1fd..febdf86 100644 --- a/modules/profiles/personal.nix +++ b/modules/profiles/personal.nix @@ -13,7 +13,6 @@ hyprland keyd noctalia - polkit tablet tuigreet uwsm @@ -71,7 +70,6 @@ hyprland noctalia overzicht - polkit stylixPersonal uwsm xdgApplications diff --git a/modules/programs/gui/tangled.nix b/modules/programs/gui/tangled.nix index 3362ede..7827b28 100644 --- a/modules/programs/gui/tangled.nix +++ b/modules/programs/gui/tangled.nix @@ -1,38 +1,5 @@ -{inputs, ...}: { - flake-file.inputs.tg = { - url = "git+https://tangled.org/aly.codes/tg"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - flake.modules.homeManager.tangled = {pkgs, ...}: let - inherit - (pkgs) - # keep-sorted start - installShellFiles - runCommand - # keep-sorted end - ; - - tg = inputs.tg.packages.${pkgs.stdenv.hostPlatform.system}.tg; - tg-completions = runCommand "tg-completions" {nativeBuildInputs = [installShellFiles tg];} '' - installShellCompletion --cmd tg \ - --bash <(tg completion bash) \ - --fish <(tg completion fish) \ - --zsh <(tg completion zsh) - ''; - in { - home.packages = [tg]; - - programs.bash.initExtra = '' - source ${tg-completions}/share/bash-completion/completions/tg - ''; - - programs.fish.interactiveShellInit = '' - source ${tg-completions}/share/fish/vendor_completions.d/tg.fish - ''; - - programs.zsh.initContent = '' - source ${tg-completions}/share/zsh/site-functions/_tg - ''; +_: { + flake.modules.homeManager.tangled = {pkgs, ...}: { + home.packages = [pkgs.nur.repos.adam0.tg]; }; } diff --git a/modules/programs/tui/pi/computer-use.nix b/modules/programs/tui/pi/computer-use.nix new file mode 100644 index 0000000..c43d145 --- /dev/null +++ b/modules/programs/tui/pi/computer-use.nix @@ -0,0 +1,36 @@ +{ + flake.modules.nixos.computerUseLinux = {vars, ...}: { + services.gnome.at-spi2-core.enable = true; + users.users.${vars.username}.extraGroups = ["input"]; + }; + + flake.modules.homeManager.pi = { + # keep-sorted start + lib, + pkgs, + # keep-sorted end + ... + }: let + inherit (lib) getExe'; + in { + dconf.settings."org/gnome/desktop/interface".toolkit-accessibility = true; + + home.packages = [pkgs.ydotool]; + + programs.pi.coding-agent.extensions = ["npm:@agent-sh/computer-use-linux@0.4.7"]; + + systemd.user.services.ydotoold = { + Unit = { + After = ["graphical-session.target"]; + PartOf = ["graphical-session.target"]; + }; + + Service = { + ExecStart = "${getExe' pkgs.ydotool "ydotoold"} --socket-path=%t/.ydotool_socket --socket-perm=0600"; + Restart = "on-failure"; + }; + + Install.WantedBy = ["graphical-session.target"]; + }; + }; +} diff --git a/modules/programs/tui/pi/default.nix b/modules/programs/tui/pi/default.nix index f9d342e..f1cc8ab 100644 --- a/modules/programs/tui/pi/default.nix +++ b/modules/programs/tui/pi/default.nix @@ -30,6 +30,24 @@ piPackage = inputs.pi-nix.packages.${pkgs.stdenv.hostPlatform.system}.coding-agent-bun; + bunRuntime = symlinkJoin { + name = "bun-runtime"; + meta.mainProgram = "bun"; + + paths = [ + (pkgs.writeShellScriptBin "bun" '' + if [[ "''${1-}" == install ]]; then + exec ${getExe pkgs.bun} "$@" --trust + fi + exec ${getExe pkgs.bun} "$@" + '') + ]; + + postBuild = '' + ln -s ${getExe pkgs.bun} $out/bin/node + ''; + }; + runtimePackages = (with pkgs; [ # keep-sorted start @@ -37,6 +55,7 @@ wl-clipboard # keep-sorted end ]) + ++ [bunRuntime] ++ attrValues config.programs.pi.mcpServers; in { imports = [inputs.pi-nix.homeModules.default]; @@ -47,14 +66,15 @@ # Provide runtime commands used by Pi and its extensions. package = symlinkJoin { name = "pi-coding-agent-wrapped"; + meta.mainProgram = "pi"; paths = [piPackage]; nativeBuildInputs = [makeWrapper]; postBuild = '' wrapProgram $out/bin/pi \ --prefix PATH : ${makeBinPath runtimePackages} ''; - meta.mainProgram = "pi"; }; + settings.npmCommand = [(getExe bunRuntime)]; rules = ./instructions.md; }; diff --git a/modules/programs/tui/pi/extensions/mcp.nix b/modules/programs/tui/pi/extensions/mcp.nix index b911862..6b87d93 100644 --- a/modules/programs/tui/pi/extensions/mcp.nix +++ b/modules/programs/tui/pi/extensions/mcp.nix @@ -21,6 +21,36 @@ jsonFormat = pkgs.formats.json {}; + mcpConfig = jsonFormat.generate "pi-mcp.json" { + settings = { + directTools = false; + idleTimeout = 1; + }; + + mcpServers = { + context7 = { + command = "context7-mcp-wrapper"; + directTools = false; + exposeResources = false; + lifecycle = "lazy"; + }; + + github = { + command = "github-mcp-server-wrapper"; + directTools = false; + exposeResources = false; + lifecycle = "lazy"; + }; + + tangled = { + command = "tangled-mcp-wrapper"; + directTools = false; + exposeResources = false; + lifecycle = "lazy"; + }; + }; + }; + # keep-sorted start block=yes newline_separated=yes context7McpWrapper = writeShellApplication { name = "context7-mcp-wrapper"; @@ -85,35 +115,10 @@ }; }; - home.file.".pi/agent/mcp.json".source = jsonFormat.generate "pi-mcp.json" { - settings = { - directTools = false; - idleTimeout = 1; - }; - - mcpServers = { - context7 = { - command = "context7-mcp-wrapper"; - directTools = false; - exposeResources = false; - lifecycle = "lazy"; - }; - - github = { - command = "github-mcp-server-wrapper"; - directTools = false; - exposeResources = false; - lifecycle = "lazy"; - }; - - tangled = { - command = "tangled-mcp-wrapper"; - directTools = false; - exposeResources = false; - lifecycle = "lazy"; - }; - }; - }; + # Keep the declarative baseline writable for extensions that register servers. + home.activation.writePiMcpConfig = lib.hm.dag.entryAfter ["writeBoundary"] '' + ${pkgs.coreutils}/bin/install -Dm600 ${mcpConfig} "$HOME/.pi/agent/mcp.json" + ''; }; }; } diff --git a/modules/programs/tui/pi/extensions/tool-renderer.nix b/modules/programs/tui/pi/extensions/tool-renderer.nix index 273ee95..fc44d57 100644 --- a/modules/programs/tui/pi/extensions/tool-renderer.nix +++ b/modules/programs/tui/pi/extensions/tool-renderer.nix @@ -26,9 +26,18 @@ $'\tif (settingBoolean("renderGrepFindTools", true, cwd)) {\n\t\tregisterReadOnly(pi, agent, cwd, "grep");\n\t\tregisterReadOnly(pi, agent, cwd, "find");\n\t}' substituteInPlace extensions/tool-renderer/generic.ts \ + --replace-fail \ + $'\ttextContent,\n\ttype TruncatedLines,' \ + $'\ttextContent,\n\trenderToolPathText,\n\ttype TruncatedLines,' \ --replace-fail \ $'\t"get_search_content",\n\t"code_search",' \ - $'\t"get_search_content",\n\t"lsp_definition",\n\t"lsp_diagnostics",\n\t"lsp_hover",\n\t"lsp_references",\n\t"lsp_symbols",\n\t"code_search",' + $'\t"get_search_content",\n\t"lsp_definition",\n\t"lsp_diagnostics",\n\t"lsp_hover",\n\t"lsp_references",\n\t"lsp_symbols",\n\t"code_search",' \ + --replace-fail \ + $'export function renderGenericToolCall(name: string, args: any, theme: any, context: any): TruncatedLines {\n\treturn makeTruncatedLines(`''${genericStatusPrefix(context, theme)}''${toolLabel(theme, `''${humanizeToolName(name)} `)}''${summarizeGenericCall(name, args, theme)}`);\n}' \ + $'export function renderGenericToolCall(name: string, args: any, theme: any, context: any): TruncatedLines {\n\tif (name === "lsp_diagnostics") {\n\t\treturn makeTruncatedLines(`''${genericStatusPrefix(context, theme)}''${toolLabel(theme, "LSP Diagnostics ")}''${renderToolPathText(args?.path, theme, context?.cwd)}`);\n\t}\n\treturn makeTruncatedLines(`''${genericStatusPrefix(context, theme)}''${toolLabel(theme, `''${humanizeToolName(name)} `)}''${summarizeGenericCall(name, args, theme)}`);\n}' \ + --replace-fail \ + $'export function renderGenericToolResult(name: string, result: any, { expanded, isPartial }: any, theme: any, context: any): TruncatedLines | ReturnType {\n\tif (isPartial) return renderPendingDetail(`''${humanizeToolName(name)}…`, theme);\n\tclearBlink(context);\n\tconst raw = textContent(result).trim();' \ + $'export function renderGenericToolResult(name: string, result: any, { expanded, isPartial }: any, theme: any, context: any): TruncatedLines | ReturnType {\n\tif (isPartial) return renderPendingDetail(`''${humanizeToolName(name)}…`, theme);\n\tclearBlink(context);\n\tconst raw = textContent(result).trim();\n\tif (name === "lsp_diagnostics") {\n\t\tconst lines = raw ? splitTerminalLines(raw) : [];\n\t\tif (context?.isError) {\n\t\t\treturn makeTruncatedLines(`''${treeConnector(theme, "└")}''${theme.fg("error", lines[0] || "LSP diagnostics failed")}`);\n\t\t}\n\t\tif (lines.length === 0) return makeTruncatedLines(`''${treeConnector(theme, "└")}''${theme.fg("muted", "no diagnostics")}`);\n\t\treturn makeTruncatedLines(lines.map((line, index) => {\n\t\t\tconst color = line.includes(" - error:") ? "error" : line.startsWith("⚠️") || line.includes(" - warning:") ? "warning" : line.startsWith("✅") ? "success" : "dim";\n\t\t\treturn `''${treeConnector(theme, index === lines.length - 1 ? "└" : "│")}''${theme.fg(color, clipLine(line, context?.cwd))}`;\n\t\t}).join("\\n"));\n\t}' ''; installPhase = '' diff --git a/modules/programs/tui/pi/instructions.md b/modules/programs/tui/pi/instructions.md index 558a911..39d4fd5 100644 --- a/modules/programs/tui/pi/instructions.md +++ b/modules/programs/tui/pi/instructions.md @@ -22,6 +22,13 @@ - Do not mirror the user's tone unless explicitly required. - Stay strictly aligned with the requested task. +## Repository configuration + +- Pi configuration lives in + `/home/adam0/Infra/modules/programs/tui/pi/`, regardless of the current + working directory. Update it there rather than writing directly to `~/.pi`. +- Treat this config as Nix-first. + ## NixOS command availability - Do not assume development tools are installed globally. diff --git a/modules/programs/tui/pi/settings.nix b/modules/programs/tui/pi/settings.nix index 281f4d3..830a889 100644 --- a/modules/programs/tui/pi/settings.nix +++ b/modules/programs/tui/pi/settings.nix @@ -3,7 +3,6 @@ programs.pi.coding-agent.settings = { clearOnStart = true; enableInstallTelemetry = false; - packages = []; quietStartup = true; }; }; diff --git a/modules/programs/tui/pi/skills/nix-search/SKILL.md b/modules/programs/tui/pi/skills/nix-search/SKILL.md index c4ad151..ab5f6a6 100644 --- a/modules/programs/tui/pi/skills/nix-search/SKILL.md +++ b/modules/programs/tui/pi/skills/nix-search/SKILL.md @@ -20,7 +20,7 @@ nix-search-tv preview --indexes nixos boot.loader.systemd-boot.enable nix-search-tv preview --indexes zen-browser enable nix-search-tv preview --indexes nixpkgs --json firefox nix-search-tv source --indexes authentik-nix services.authentik -nix-search-tv source --indexes noctalia programs.noctalia-shell.settings.bar +nix-search-tv source --indexes noctalia programs.noctalia.settings.bar nix-search-tv homepage --indexes nixpkgs firefox ``` diff --git a/modules/programs/tui/pi/skills/simplify/SKILL.md b/modules/programs/tui/pi/skills/simplify/SKILL.md index b26479e..cca095c 100644 --- a/modules/programs/tui/pi/skills/simplify/SKILL.md +++ b/modules/programs/tui/pi/skills/simplify/SKILL.md @@ -1,5 +1,5 @@ --- -name: ce-simplify-code +name: simplify description: "Simplify settled, recently changed code for clarity, reuse, quality, and efficiency while preserving behavior. Use after implementation and before review; use ce-debug for bugs." argument-hint: "[blank to simplify current branch changes, or describe what to simplify]" --- diff --git a/modules/programs/tui/television/nix-search.nix b/modules/programs/tui/television/nix-search.nix index ddfc88b..15a4e84 100644 --- a/modules/programs/tui/television/nix-search.nix +++ b/modules/programs/tui/television/nix-search.nix @@ -134,7 +134,7 @@ noctalia = { rawDoc = mkHomeManagerDoc inputs.noctalia.homeModules.default; - prefixes = ["programs.noctalia-shell"]; + prefixes = ["programs.noctalia"]; }; nvf = { diff --git a/noctalia-config.toml b/noctalia-config.toml new file mode 100644 index 0000000..f4e46dd --- /dev/null +++ b/noctalia-config.toml @@ -0,0 +1,513 @@ +[accessibility] +ui_scale = 0.80000000000000004 + +[audio] +enable_overdrive = true + +[bar] +order = [ "main" ] + + [bar.main] + background_opacity = 0.94999999999999996 + border_width = 1.0 + capsule = true + capsule_border = "outline" + capsule_opacity = 1.0 + capsule_padding = 4.0 + capsule_radius = 0.0 + center = [ "workspaces" ] + color = "on_surface_variant" + concave_edge_corners = false + end = [ + "tray", + "performance", + "volume", + "microphone", + "bluetooth", + "network", + "brightness", + "battery", + "caffeine", + "notifications", + "clock", + "control-center" + ] + font_weight = 600 + icon_color = "on_surface" + margin_ends = 0 + padding = 4 + position = "top" + radius = 0 + scale = 0.84999999999999998 + start = [ "group:system-monitor", "privacy", "lock_keys", "active_window", "media" ] + thickness = 24 + widget_spacing = 4 + + [bar.main.dead_zone.actions] + right = "none" + + [[bar.main.capsule_group]] + accordion = false + accordion_direction = "end" + enabled = true + fill = "surface_variant" + id = "system-monitor" + members = [ "cpu-usage", "cpu-temperature", "gpu-usage", "gpu-temperature", "ram", "swap" ] + opacity = 1.0 + padding = 6.0 + +[brightness] +enable_ddcutil = true + +[calendar] +enabled = true + +[control_center] +show_shortcut_labels = true +sidebar = "compact" +sidebar_section = "compact" +width = 640 + + [control_center.calendar] + show_week_numbers = true + + [[control_center.shortcuts]] + type = "wifi" + + [[control_center.shortcuts]] + type = "bluetooth" + + [[control_center.shortcuts]] + type = "noctalia/screen_recorder:toggle" + + [[control_center.shortcuts]] + type = "wallpaper" + + [[control_center.shortcuts]] + type = "notification" + + [[control_center.shortcuts]] + type = "power_profile" + + [[control_center.shortcuts]] + type = "nightlight" + +[desktop_widgets] +enabled = false + +[dock] +active_monitor_only = true +auto_hide = true +background_opacity = 0.94999999999999996 +border_width = 1.0 +cross_axis_padding = 4 +enabled = true +icon_size = 24 +magnification_scale = 1.3 +main_axis_padding = 4 +margin_edge = 8 +radius = 0 +reserve_space = false +show_dots = true + +[idle] +behavior_order = [ "dim-screen", "dim-keyboard", "lock", "screen-off", "lock-and-suspend" ] +pre_action_fade_seconds = 5.0 + + [idle.behavior.dim-keyboard] + action = "command" + command = "/nix/store/0rpfr3y6m574ywxhvkp8w7skw0zgnwp0-brightnessctl-0.5.1/bin/brightnessctl -sd rgb:kbd:backlight set 0" + enabled = true + resume_command = "/nix/store/0rpfr3y6m574ywxhvkp8w7skw0zgnwp0-brightnessctl-0.5.1/bin/brightnessctl -rd rgb:kbd:backlight" + timeout = 150.0 + + [idle.behavior.dim-screen] + action = "command" + command = "/nix/store/0rpfr3y6m574ywxhvkp8w7skw0zgnwp0-brightnessctl-0.5.1/bin/brightnessctl -s set 10" + enabled = true + resume_command = "/nix/store/0rpfr3y6m574ywxhvkp8w7skw0zgnwp0-brightnessctl-0.5.1/bin/brightnessctl -r" + timeout = 150.0 + + [idle.behavior.lock] + action = "lock" + enabled = true + timeout = 300.0 + + [idle.behavior.lock-and-suspend] + action = "lock_and_suspend" + enabled = true + timeout = 480.0 + + [idle.behavior.screen-off] + action = "screen_off" + enabled = true + timeout = 330.0 + +[keybinds] +down = [ "ctrl+j", "down" ] +left = [ "ctrl+h", "left" ] +right = [ "ctrl+l", "right" ] +up = [ "ctrl+k", "up" ] + +[location] +auto_locate = true + +[lockscreen] +blur_intensity = 0.40000000000000002 +blurred_desktop = true +tint_intensity = 0.20000000000000001 + +[lockscreen_widgets] +enabled = true +schema_version = 2 +widget_order = [ "lockscreen-login-box@eDP-1", "lockscreen-widget-0000000000000002" ] + + [lockscreen_widgets.grid] + cell_size = 16 + major_interval = 4 + visible = true + + [lockscreen_widgets.widget."lockscreen-login-box@eDP-1"] + box_height = 196.0 + box_width = 810.0 + cx = 960.0 + cy = 898.0 + output = "eDP-1" + rotation = 0.0 + type = "login_box" + + [lockscreen_widgets.widget."lockscreen-login-box@eDP-1".settings] + background_color = "surface_variant" + background_opacity = 0.88 + background_radius = 12.0 + center_password_text = false + input_opacity = 1.0 + input_radius = 6.0 + layout = "regular" + show_caps_lock = true + show_keyboard_layout = true + show_login_button = true + show_media = true + show_session_buttons = true + show_unlock_hint = true + show_weather = true + + [lockscreen_widgets.widget.lockscreen-widget-0000000000000002] + box_height = 48.0 + box_width = 816.0 + cx = 960.0 + cy = 724.0 + output = "eDP-1" + rotation = 0.0 + type = "audio_visualizer" + + [lockscreen_widgets.widget.lockscreen-widget-0000000000000002.settings] + background_opacity = 0.0 + bands = 32 + show_when_idle = true + +[notification] +background_opacity = 0.94999999999999996 +layer = "overlay" + +[osd] +background_opacity = 0.94999999999999996 + +[plugin_settings."kenn/keybind-cheatsheet"] +columns = 4 +compositor = "hyprland" +hyprland_parser = "lua" + +[plugin_settings."noctalia/screen_recorder"] +copy_to_clipboard = true +directory = "/home/adam0/Videos/Recordings" +video_codec = "hevc" + +[plugins] +auto_update = true +enabled = [ "adam0/performance", "kenn/keybind-cheatsheet", "noctalia/kaomoji", "noctalia/screen_recorder" ] + + [[plugins.source]] + kind = "git" + location = "https://github.com/noctalia-dev/official-plugins" + name = "official" + + [[plugins.source]] + kind = "git" + location = "https://github.com/noctalia-dev/community-plugins" + name = "community" + + [[plugins.source]] + kind = "path" + location = "/nix/store/d5ap85sr3f9wazmpfri27ya4vpcdq5h0-noctalia-performance-plugin" + name = "local" + +[shell] +avatar_path = "/home/adam0/.face" +clipboard_confirm_clear_history = false +clipboard_history_max_entries = 64 +corner_radius_scale = 0.0 +font_family = "JetBrainsMonoNL Nerd Font Propo" +launch_apps_as_systemd_services = true +panel_anchor_bar = "main" +polkit_agent = true +screen_time_enabled = true +setup_wizard_enabled = false + + [shell.animation] + speed = 2.0 + + [shell.launcher.providers.calculator] + global = false + + [shell.panel] + borders = true + control_center_placement = "floating" + list_item_background = true + open_near_click_control_center = true + session_placement = "floating" + session_position = "center" + shadow = true + transparency_mode = "solid" + wallpaper_placement = "floating" + wallpaper_position = "center" + + [shell.screenshot] + directory = "/home/adam0/Pictures/screenshots" + filename_pattern = "screenshot_%Y-%m-%dT%H:%M:%S" + show_cursor = true + + [shell.session] + grid = false + show_shortcuts = true + + [[shell.session.actions]] + action = "lock" + countdown_seconds = 0.0 + shortcut = "1" + + [[shell.session.actions]] + action = "lock_and_suspend" + countdown_seconds = 8.0 + shortcut = "2" + + [[shell.session.actions]] + action = "reboot" + countdown_seconds = 8.0 + shortcut = "3" + + [[shell.session.actions]] + action = "logout" + countdown_seconds = 8.0 + shortcut = "4" + + [[shell.session.actions]] + action = "shutdown" + countdown_seconds = 8.0 + shortcut = "5" + variant = "destructive" + + [[shell.session.actions]] + action = "reboot" + command = "systemctl reboot --firmware-setup" + countdown_seconds = 8.0 + glyph = "settings-automation" + label = "UEFI" + shortcut = "6" + + [shell.shadow] + direction = "center" + +[system.monitor] +cpu_poll_seconds = 1.0 +disk_poll_seconds = 4.0 +gpu_poll_seconds = 1.0 +memory_poll_seconds = 4.0 +network_poll_seconds = 4.0 + +[theme] +custom_palette = "stylix" +mode = "dark" +source = "custom" + + [theme.templates] + enable_builtin_templates = false + enable_community_templates = false + +[wallpaper] +directory = "/home/adam0/Pictures/wallpapers" +transition = [ "honeycomb" ] +transition_on_startup = true + + [wallpaper.automation] + enabled = true + interval_seconds = 7200 + order = "random" + recursive = false + + [wallpaper.default] + path = "/home/adam0/Pictures/wallpapers/98.png" + + [wallpaper.last] + path = "/home/adam0/Pictures/wallpapers/98.png" + + [wallpaper.monitors.eDP-1] + path = "/home/adam0/Pictures/wallpapers/98.png" + +[weather] +effects = true +enabled = true +unit = "metric" + +[widget.active_window] +color = "on_surface_variant" +display = "icon_and_text" +inactive_opacity = 1.0 +max_length = 145.0 +min_length = 0.0 +show_empty_label = true +title_scroll = "on_hover" + +[widget.battery] +color = "on_surface_variant" +display_mode = "glyph" +icon_color = "on_surface" +show_label = true + +[widget.brightness] +color = "on_surface_variant" +icon_color = "on_surface" +show_label = true + +[widget.clock] +color = "primary" +format = "{:%Y-%m-%d %H:%M}" +tooltip_format = "{:%a, %b %d %H:%M}" +vertical_format = """{:%H +%M - %d +%m}""" + +[widget.control-center] +custom_image = "/nix/store/ss4h6fag7x83mv94cbhjcgcm9nazb3ks-nixos-icons-0-unstable-2025-06-28/share/icons/hicolor/scalable/apps/nix-snowflake.svg" +custom_image_colorize = true +icon_color = "tertiary" +scale = 1.05 + +[widget.cpu-temperature] +color = "primary" +show_glyph = true +show_value = false +stat = "cpu_temp" +type = "sysmon" +visualization = "gauge" + + [widget.cpu-temperature.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Btop /nix/store/1r2dkryq028hnvaj6m505a818w184ycg-btop-1.4.7/bin/btop" + +[widget.cpu-usage] +color = "primary" +show_glyph = true +show_value = false +stat = "cpu_usage" +type = "sysmon" +visualization = "gauge" + + [widget.cpu-usage.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Btop /nix/store/1r2dkryq028hnvaj6m505a818w184ycg-btop-1.4.7/bin/btop" + +[widget.gpu-temperature] +color = "primary" +show_glyph = true +show_value = false +stat = "gpu_temp" +type = "sysmon" +visualization = "gauge" + + [widget.gpu-temperature.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Btop /nix/store/1r2dkryq028hnvaj6m505a818w184ycg-btop-1.4.7/bin/btop" + +[widget.gpu-usage] +color = "primary" +show_glyph = true +show_value = false +stat = "gpu_usage" +type = "sysmon" +visualization = "gauge" + + [widget.gpu-usage.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Btop /nix/store/1r2dkryq028hnvaj6m505a818w184ycg-btop-1.4.7/bin/btop" + +[widget.lock_keys] +display = "short" +show_caps_lock = true +show_num_lock = true +show_scroll_lock = true + +[widget.media] +color = "on_surface_variant" +hide_album_art = false +hide_when_no_media = false +max_length = 145.0 +min_length = 0.0 +title_scroll = "on_hover" + +[widget.microphone] +color = "on_surface_variant" +device = "input" +show_label = true +type = "volume" + + [widget.microphone.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Wiremix /nix/store/4676s2mkq6h817hzna8c36yldcvjhdlh-wiremix-0.11.0/bin/wiremix" + +[widget.network] +color = "on_surface_variant" +show_label = true +show_vpn_label = false +vpn_status = "both" + +[widget.performance] +color = "on_surface" +type = "adam0/performance:toggle" + +[widget.ram] +color = "primary" +show_glyph = true +show_value = false +stat = "ram_used" +type = "sysmon" +visualization = "gauge" + + [widget.ram.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Btop /nix/store/1r2dkryq028hnvaj6m505a818w184ycg-btop-1.4.7/bin/btop" + +[widget.swap] +color = "primary" +show_glyph = true +show_value = false +stat = "swap_pct" +type = "sysmon" +visualization = "gauge" + + [widget.swap.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Btop /nix/store/1r2dkryq028hnvaj6m505a818w184ycg-btop-1.4.7/bin/btop" + +[widget.tray] +detached_panel = true +drawer = true +drawer_columns = 4 +pinned = [ "Equibop", "spotify-client", "steam", "Beeper" ] + +[widget.volume] +color = "on_surface_variant" +icon_color = "on_surface" +show_label = true + + [widget.volume.actions] + middle = "exec /nix/store/fkihxwzfbxj8idja8ryx89phkx6pqdwj-xdg-terminal-exec-0.14.3/bin/xdg-terminal-exec --title=Wiremix /nix/store/4676s2mkq6h817hzna8c36yldcvjhdlh-wiremix-0.11.0/bin/wiremix" + +[widget.workspaces] +focused_output_only = true +occupied_color = "outline" +pill_scale = 0.80000000000000004 +show_labels = true diff --git a/vars.nix b/vars.nix index e6fab82..6fca103 100644 --- a/vars.nix +++ b/vars.nix @@ -17,7 +17,6 @@ rec { # keep-sorted start countryCode = "NL"; defaultLocale = "en_US.UTF-8"; - noctaliaFirstDayOfWeek = 1; regionalLocale = "nl_${countryCode}.UTF-8"; # keep-sorted end -- 2.51.2