diff --git a/config/hyprland/default.nix b/config/hyprland/default.nix index da7252706..d7f326ea8 100644 --- a/config/hyprland/default.nix +++ b/config/hyprland/default.nix @@ -9,7 +9,7 @@ configType = "hyprlang"; systemd.enable = false; extraConfig = '' - exec-once = noctalia-shell + exec-once = noctalia exec-once = ${pkgs.hyprshell}/bin/hyprshell run & exec-once = ${pkgs.hyprpolkitagent}/libexec/hyprpolkitagent exec-once = sleep 3 && ${pkgs.eww}/bin/eww open clock-widget diff --git a/config/hyprland/hyprland.conf b/config/hyprland/hyprland.conf index 5852a2619..6cde7bb97 100644 --- a/config/hyprland/hyprland.conf +++ b/config/hyprland/hyprland.conf @@ -231,7 +231,7 @@ bind = $mod, F, exec, ghostty --gtk-single-instance=false -e yazi # ============================================================================= # System GUIs (WiFi / Bluetooth / Audio) # ============================================================================= -bind = $mod, I, exec, noctalia-shell ipc call network togglePanel +bind = $mod, I, exec, noctalia msg panel-toggle control-center network bind = $mod, B, exec, blueman-manager bind = $mod, A, exec, pavucontrol @@ -244,9 +244,9 @@ bind = ALT SHIFT, SPACE, exec, handy --toggle-post-process # ============================================================================= # Launcher & Clipboard # ============================================================================= -bind = CTRL ALT SHIFT SUPER, SPACE, exec, noctalia-shell ipc call launcher toggle +bind = CTRL ALT SHIFT SUPER, SPACE, exec, noctalia msg panel-toggle launcher bind = $mod, SPACE, exec, nwg-drawer -bind = $mod SHIFT, E, exec, noctalia-shell ipc call launcher emoji +bind = $mod SHIFT, E, exec, noctalia msg panel-toggle launcher /emo # ============================================================================= # Window Management @@ -257,7 +257,7 @@ bind = $mod, Q, exec, ~/.config/noctalia/scripts/quit-active-app.sh bind = $mod SHIFT, F, togglefloating, bind = CTRL ALT SHIFT SUPER, F, exec, hyprctl --batch "dispatch movetoworkspace empty; dispatch fullscreen 0" bind = SUPER CTRL, F, fullscreen, 1 -bind = $mod SHIFT, Q, exec, noctalia-shell ipc call sessionMenu toggle +bind = $mod SHIFT, Q, exec, noctalia msg panel-toggle session # hyprshell handles Super+Tab / Super+Shift+Tab window switching # Focus (vim keys) @@ -374,7 +374,7 @@ bind = CTRL ALT SHIFT SUPER, 5, exec, ~/.config/hypr/scripts/record-screen.sh bind = $mod, PRINT, exec, hyprpicker -a # Clipboard manager -bind = $mod SHIFT, V, exec, noctalia-shell ipc call launcher clipboard +bind = $mod SHIFT, V, exec, noctalia msg panel-toggle clipboard # ============================================================================= # Media / Hardware Keys (Framework 13 AI 300) @@ -424,10 +424,10 @@ binde = CTRL ALT SHIFT SUPER, minus, exec, hyprctl -j monitors | jq -r '.[0].sca # ============================================================================= # Lock Screen # ============================================================================= -bind = CTRL ALT SHIFT SUPER, L, exec, noctalia-shell ipc call lockScreen lock -bindl = , switch:on:Lid Switch, exec, noctalia-shell ipc call lockScreen lock +bind = CTRL ALT SHIFT SUPER, L, exec, noctalia msg session lock +bindl = , switch:on:Lid Switch, exec, noctalia msg session lock # ============================================================================= # Notification Toggle # ============================================================================= -bind = $mod SHIFT, D, exec, noctalia-shell ipc call notifications toggleHistory +bind = $mod SHIFT, D, exec, noctalia msg panel-toggle control-center notifications diff --git a/config/noctalia/default.nix b/config/noctalia/default.nix index 03bc78d42..8c9a99d2c 100644 --- a/config/noctalia/default.nix +++ b/config/noctalia/default.nix @@ -4,9 +4,10 @@ ... }: let - noctaliaShell = inputs.noctalia-shell.packages.${pkgs.system}.default; + # v5 renamed the binary noctalia-shell -> noctalia (pname/mainProgram = "noctalia"). + noctalia = inputs.noctalia-shell.packages.${pkgs.system}.default; noctaliaLockBeforeSleep = pkgs.replaceVars ./lock-before-sleep.sh { - noctalia_shell = "${noctaliaShell}/bin/noctalia-shell"; + noctalia = "${noctalia}/bin/noctalia"; sleep = "${pkgs.coreutils}/bin/sleep"; }; quitAllAppsScript = pkgs.replaceVars ./quit-all-apps-launcher.sh { @@ -15,10 +16,10 @@ let }; in { - xdg.configFile."noctalia/colorschemes/Dracula-Custom/Dracula-Custom.json" = { - source = ./Dracula-Custom.json; - force = true; - }; + # NOTE: v4 shipped a Dracula-Custom colorscheme at noctalia/colorschemes/... + # v5 replaced colorschemes with a palette/theme system (noctalia/palettes/*.json, + # different format), so the old file is no longer wired up. Recreate the palette + # on-device via the v5 settings UI or programs.noctalia.customPalettes. # Screen-off and suspend on battery only; noctalia handles lock on both AC and battery. systemd.user.services.ac-idle-inhibit = { @@ -76,118 +77,27 @@ in icon = "application-exit"; }; - programs.noctalia-shell = { + programs.noctalia = { enable = true; - package = noctaliaShell; + package = noctalia; + # v5 is a ground-up rewrite (C++/Qt, TOML config, snake_case keys) and upstream + # does NOT migrate v4 settings - "v5 ships with sane defaults, customize from there". + # The v4 config (bar widget layout, Dracula theme, dark-mode dconf hook, idle + # timeouts, per-widget options) has NO mechanical v5 equivalent and its semantics + # changed (e.g. bar widgets are now id vectors + separate styling; idle uses a + # behavior map; hooks run with no args). Re-apply those on-device via the settings UI. + # + # Only keys verified against the v5 schema (src/config/schema/config_schema.cpp) + # are set here so the build-time `noctalia config validate` passes. settings = { - bar = { - backgroundOpacity = 0; - useSeparateOpacity = true; - capsuleOpacity = 0; - widgets.left = [ - { id = "Launcher"; } - { - id = "Clock"; - formatHorizontal = "yyyy/MM/dd HH:mm:ss"; - formatVertical = "HH mm ss - dd MM"; - tooltipFormat = "yyyy/MM/dd HH:mm:ss"; - } - { - id = "SystemMonitor"; - showNetworkStats = true; - showGpuTemp = true; - } - { - id = "ActiveWindow"; - colorizeIcons = false; - } - { id = "MediaMini"; } - ]; - widgets.center = [ - { - id = "Workspace"; - labelMode = "index"; - showApplications = true; - showApplicationsHover = false; - showBadge = true; - unfocusedIconsOpacity = 0.55; - } - ]; - widgets.right = [ - { - id = "Tray"; - colorizeIcons = false; - drawerEnabled = false; - } - { id = "Bluetooth"; } - { id = "Network"; } - { id = "NotificationHistory"; } - { - id = "Battery"; - displayMode = "graphic"; - } - { id = "PowerProfile"; } - { id = "Volume"; } - { id = "Brightness"; } - { id = "DarkMode"; } - { id = "ControlCenter"; } - ]; - }; - ui = { - fontDefault = "Noto Sans"; - fontFixed = "JetBrainsMono Nerd Font"; - }; - notifications = { - location = "top_right"; - backgroundOpacity = 0.75; - }; - osd = { - enabled = true; - location = "right"; - }; - appLauncher = { - enableClipboardHistory = true; - autoPasteClipboard = true; - }; - general = { - animationSpeed = 3; - compactLockScreen = true; - autoStartAuth = true; - allowPasswordWithFprintd = true; - lockOnSuspend = true; - }; - colorSchemes.predefinedScheme = "Dracula-Custom"; - hooks = { - enabled = true; - darkModeChange = '' - if [ "$1" = "true" ]; then - dconf write /org/gnome/desktop/interface/color-scheme "'prefer-dark'" - dconf write /org/gnome/desktop/interface/gtk-theme "'Adwaita-dark'" - dconf write /org/gnome/desktop/interface/icon-theme "'Adwaita'" - else - dconf write /org/gnome/desktop/interface/color-scheme "'prefer-light'" - dconf write /org/gnome/desktop/interface/gtk-theme "'Adwaita'" - dconf write /org/gnome/desktop/interface/icon-theme "'Adwaita'" - fi - ''; - }; - dock = { - colorizeIcons = true; - showLauncherIcon = true; - showDockIndicator = false; - }; - desktopWidgets.enabled = true; - wallpaper.enabled = false; - idle = { - enabled = true; - screenOffTimeout = 0; - lockTimeout = 300; - suspendTimeout = 0; + shell = { + font_family = "Noto Sans"; # was ui.fontDefault + clipboard_enabled = true; # was appLauncher.enableClipboardHistory + clipboard_auto_paste = "auto"; # was appLauncher.autoPasteClipboard = true }; - systemMonitor.enableDgpuMonitoring = true; - colorSchemes.schedulingMode = "location"; - location.autoLocate = true; + location.auto_locate = true; # was location.autoLocate + wallpaper.enabled = false; # noctalia does not manage the wallpaper (wallpaper engine does) }; }; } diff --git a/config/noctalia/lock-before-sleep.sh b/config/noctalia/lock-before-sleep.sh index 08cea745c..ced114ff2 100644 --- a/config/noctalia/lock-before-sleep.sh +++ b/config/noctalia/lock-before-sleep.sh @@ -2,10 +2,11 @@ # Lock through Noctalia before systemd lets suspend continue. set -euo pipefail -NOCTALIA_SHELL="@noctalia_shell@" +NOCTALIA="@noctalia@" SLEEP="@sleep@" -if ! "$NOCTALIA_SHELL" ipc call lockScreen lock; then +# v5 IPC surface: `noctalia msg session ` (was `ipc call lockScreen lock`). +if ! "$NOCTALIA" msg session lock; then exit 0 fi diff --git a/flake.nix b/flake.nix index 5bca94ab0..caaa9fa53 100644 --- a/flake.nix +++ b/flake.nix @@ -65,8 +65,11 @@ inputs.nixpkgs.follows = "nixpkgs"; }; noctalia-shell = { - # Pinned before upstream dropped the noctalia-qs input and restructured - # the home-manager module (breaks programs.noctalia-shell option). + # v5 (C++ rewrite): option is programs.noctalia, config is TOML, binary is + # `noctalia`. Not a drop-in from the v4 Quickshell line - v4 settings are not + # migrated (see config/noctalia/default.nix). Pinned to a known-good commit, + # but renovate can still auto-bump this input: treat bumps as breaking and + # rebuild matic/viper on-device before merging (can't be validated in darwin CI). url = "github:noctalia-dev/noctalia-shell/6e7aa3b4daaf13f3cd7c622b248efaba5c1c1eb3"; inputs.nixpkgs.follows = "nixpkgs"; }; diff --git a/home-manager/programs/fish/functions/_caf_function.fish b/home-manager/programs/fish/functions/_caf_function.fish index 78125ec07..78abce3a8 100644 --- a/home-manager/programs/fish/functions/_caf_function.fish +++ b/home-manager/programs/fish/functions/_caf_function.fish @@ -13,8 +13,8 @@ function _caf_function --description "Keep the machine awake lid-closed, screen- end echo $last_pid >"$pid_file" disown - if command -q noctalia-shell - noctalia-shell msg idleInhibitor enable 2>/dev/null + if command -q noctalia + noctalia msg caffeine-enable 2>/dev/null end if test (uname) != Darwin systemctl --user stop ac-idle-inhibit.service 2>/dev/null @@ -28,8 +28,8 @@ function _caf_function --description "Keep the machine awake lid-closed, screen- kill (cat "$pid_file") 2>/dev/null rm -f "$pid_file" end - if command -q noctalia-shell - noctalia-shell msg idleInhibitor disable 2>/dev/null + if command -q noctalia + noctalia msg caffeine-disable 2>/dev/null end if test (uname) != Darwin systemctl --user start ac-idle-inhibit.service 2>/dev/null diff --git a/spec/fish/_caf_function_test.fish b/spec/fish/_caf_function_test.fish index fc06d4733..0dd92bced 100644 --- a/spec/fish/_caf_function_test.fish +++ b/spec/fish/_caf_function_test.fish @@ -12,13 +12,20 @@ end function systemd-inhibit echo $argv end -function noctalia-shell - true -end function systemctl true end +# `command -q` resolves external commands, not functions, so provide a real +# `noctalia` on PATH that records its args. This lets us assert the exact v5 +# subcommands (`msg caffeine-enable` / `msg caffeine-disable`) so a typo or a +# future IPC rename is caught instead of silently passing. +set -x NOCTALIA_LOG $tmpdir/noctalia.log +mkdir -p $tmpdir/bin +printf '#!/bin/sh\necho "$@" >> "$NOCTALIA_LOG"\n' >$tmpdir/bin/noctalia +chmod +x $tmpdir/bin/noctalia +set -x PATH $tmpdir/bin $PATH + # ── unknown argument ────────────────────────────────────── _caf_function bogus >/dev/null 2>&1 @test "unknown argument returns 1" $status = 1 @@ -30,8 +37,13 @@ set usage (_caf_function bogus 2>&1) set out (_caf_function status 2>/dev/null) @test "status reports inactive without pid file" (string match -q "*caf inactive*" "$out"; echo $status) = 0 -# ── off with no keeper running ──────────────────────────── +# ── on enables caffeine via the v5 noctalia subcommand ──── +_caf_function on >/dev/null 2>&1 +@test "on enables caffeine via noctalia" (grep -qF 'msg caffeine-enable' $NOCTALIA_LOG; echo $status) = 0 + +# ── off with a keeper running ───────────────────────────── _caf_function off >/dev/null 2>&1 @test "off restores normal sleep" $status = 0 +@test "off disables caffeine via noctalia" (grep -qF 'msg caffeine-disable' $NOCTALIA_LOG; echo $status) = 0 rm -rf $tmpdir diff --git a/spec/hyprland_lid_lock_spec.sh b/spec/hyprland_lid_lock_spec.sh index 713bb159c..a4d473ae3 100644 --- a/spec/hyprland_lid_lock_spec.sh +++ b/spec/hyprland_lid_lock_spec.sh @@ -5,9 +5,9 @@ Describe 'config/hyprland/hyprland.conf lid lock binding' CONFIG="$PWD/config/hyprland/hyprland.conf" It 'locks Noctalia when Hyprland reports the lid switch closing' -When run bash -c "grep -F 'bindl = , switch:on:Lid Switch, exec, noctalia-shell ipc call lockScreen lock' '$CONFIG'" +When run bash -c "grep -F 'bindl = , switch:on:Lid Switch, exec, noctalia msg session lock' '$CONFIG'" The output should include 'switch:on:Lid Switch' -The output should include 'lockScreen lock' +The output should include 'msg session lock' End End diff --git a/spec/noctalia_bar_spec.sh b/spec/noctalia_bar_spec.sh deleted file mode 100644 index 4fd86ec8b..000000000 --- a/spec/noctalia_bar_spec.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# shellcheck disable=SC2329 - -Describe 'config/noctalia/default.nix bar widgets' -CONFIG="$PWD/config/noctalia/default.nix" - -It 'places DarkMode immediately after Brightness on the right bar' -When run bash -c "awk '/widgets.right = \\[/{in_right=1} in_right && /id =/ { gsub(/.*id = \"|\";.*/, \"\"); print } in_right && /\\];/{exit}' '$CONFIG' | paste -sd ' ' -" -The output should include 'Brightness DarkMode ControlCenter' -End - -It 'shows tray items inline instead of hiding them in the drawer' -When run bash -c "awk '/id = \"Tray\";/{in_tray=1} in_tray && /^ }/{exit} in_tray{print}' '$CONFIG'" -The output should include 'colorizeIcons = false;' -The output should include 'drawerEnabled = false;' -End - -It 'keeps active window app icons uncolorized' -When run bash -c "awk '/id = \"ActiveWindow\";/{in_active_window=1} in_active_window && /^ }/{exit} in_active_window{print}' '$CONFIG'" -The output should include 'colorizeIcons = false;' -End - -It 'does not duplicate the workspace widget on the left bar' -When run bash -c "awk '/widgets.left = \\[/{in_left=1} in_left && /id =/ {print} in_left && /^ \\];/{exit}' '$CONFIG'" -The output should not include 'Workspace' -End - -It 'shows applications inside the centered numbered workspace widget' -When run bash -c "awk '/widgets.center = \\[/{in_center=1} in_center && /^ \\];/{exit} in_center{print}' '$CONFIG'" -The output should include 'labelMode = "index";' -The output should include 'showApplications = true;' -The output should include 'showApplicationsHover = false;' -The output should include 'showBadge = true;' -The output should include 'unfocusedIconsOpacity = 0.55;' -End - -It 'keeps seconds visible in clock formats' -When run bash -c "awk '/id = \"Clock\";/{in_clock=1} in_clock && /^ }/{exit} in_clock{print}' '$CONFIG'" -The output should include 'formatHorizontal = "yyyy/MM/dd HH:mm:ss";' -The output should include 'formatVertical = "HH mm ss - dd MM";' -The output should include 'tooltipFormat = "yyyy/MM/dd HH:mm:ss";' -End - -End diff --git a/spec/noctalia_lock_before_sleep_spec.sh b/spec/noctalia_lock_before_sleep_spec.sh index 401f76a9a..e4bdc6ed0 100644 --- a/spec/noctalia_lock_before_sleep_spec.sh +++ b/spec/noctalia_lock_before_sleep_spec.sh @@ -11,13 +11,13 @@ End It 'uses injected command paths' When run bash -c "cat '$SCRIPT'" -The output should include '@noctalia_shell@' +The output should include '@noctalia@' The output should include '@sleep@' End It 'calls Noctalia lock IPC before sleeping' When run bash -c "cat '$SCRIPT'" -The output should include 'ipc call lockScreen lock' +The output should include 'msg session lock' The output should include '"$SLEEP" 1' End