mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
refactor(flake): split the flake
This extracts the package, home module and nixos systemd service from the flake into distinct Nix modules. Additionally, the package is updated to use default the qt wrapper rather than the custom one previously used; this conforms to current best practices in packaging Qt apps. Several improvements are made to the Nix style as well.
This commit is contained in:
@@ -11,287 +11,47 @@
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
systems,
|
||||
quickshell,
|
||||
...
|
||||
}:
|
||||
let
|
||||
eachSystem = nixpkgs.lib.genAttrs (import systems);
|
||||
in
|
||||
{
|
||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
systems,
|
||||
quickshell,
|
||||
...
|
||||
}: let
|
||||
eachSystem = nixpkgs.lib.genAttrs (import systems);
|
||||
in {
|
||||
formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
|
||||
|
||||
packages = eachSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
qs = quickshell.packages.${system}.default.override {
|
||||
packages = eachSystem (
|
||||
system: let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
default = pkgs.callPackage ./nix/package.nix {
|
||||
version = self.rev or self.dirtyRev or "dirty";
|
||||
quickshell = quickshell.packages.${system}.default.override {
|
||||
withX11 = false;
|
||||
withI3 = true;
|
||||
};
|
||||
|
||||
runtimeDeps =
|
||||
with pkgs;
|
||||
[
|
||||
bash
|
||||
bluez
|
||||
brightnessctl
|
||||
cava
|
||||
cliphist
|
||||
coreutils
|
||||
ddcutil
|
||||
file
|
||||
findutils
|
||||
libnotify
|
||||
matugen
|
||||
networkmanager
|
||||
wlsunset
|
||||
wl-clipboard
|
||||
]
|
||||
++ lib.optionals (pkgs.stdenv.hostPlatform.isx86_64) [ gpu-screen-recorder ];
|
||||
|
||||
fontconfig = pkgs.makeFontsConf {
|
||||
fontDirectories = [
|
||||
pkgs.roboto
|
||||
pkgs.inter-nerdfont
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
default = pkgs.stdenv.mkDerivation {
|
||||
pname = "noctalia-shell";
|
||||
version = self.rev or self.dirtyRev or "dirty";
|
||||
src = ./.;
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkgs.gcc
|
||||
pkgs.makeWrapper
|
||||
pkgs.qt6.wrapQtAppsHook
|
||||
];
|
||||
buildInputs = [
|
||||
qs
|
||||
pkgs.xkeyboard_config
|
||||
pkgs.qt6.qtbase
|
||||
];
|
||||
propagatedBuildInputs = runtimeDeps;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/noctalia-shell
|
||||
cp -r ./* $out/share/noctalia-shell
|
||||
|
||||
makeWrapper ${qs}/bin/qs $out/bin/noctalia-shell \
|
||||
--prefix PATH : "${pkgs.lib.makeBinPath runtimeDeps}" \
|
||||
--set FONTCONFIG_FILE "${fontconfig}" \
|
||||
--add-flags "-p $out/share/noctalia-shell"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "A sleek and minimal desktop shell thoughtfully crafted for Wayland, built with Quickshell.";
|
||||
homepage = "https://github.com/noctalia-dev/noctalia-shell";
|
||||
license = pkgs.lib.licenses.mit;
|
||||
mainProgram = "noctalia-shell";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
defaultPackage = eachSystem (system: self.packages.${system}.default);
|
||||
|
||||
homeModules.default =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.programs.noctalia-shell;
|
||||
defaultSettings = builtins.fromJSON (builtins.readFile ./Assets/settings-default.json);
|
||||
|
||||
# Deep merge user settings with defaults
|
||||
mergedSettings =
|
||||
if cfg.settings == null then
|
||||
defaultSettings
|
||||
else if builtins.isAttrs cfg.settings then
|
||||
lib.recursiveUpdate defaultSettings cfg.settings
|
||||
else
|
||||
cfg.settings; # Pass through strings/paths as-is
|
||||
in
|
||||
{
|
||||
options.programs.noctalia-shell = {
|
||||
enable = lib.mkEnableOption "Noctalia shell configuration";
|
||||
|
||||
settings = lib.mkOption {
|
||||
type =
|
||||
with lib.types;
|
||||
nullOr (oneOf [
|
||||
attrs
|
||||
str
|
||||
path
|
||||
]);
|
||||
default = null;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
bar = {
|
||||
position = "bottom";
|
||||
floating = true;
|
||||
backgroundOpacity = 0.95;
|
||||
};
|
||||
general = {
|
||||
animationSpeed = 1.5;
|
||||
radiusRatio = 1.2;
|
||||
};
|
||||
colorSchemes = {
|
||||
darkMode = true;
|
||||
useWallpaperColors = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Noctalia shell configuration settings as an attribute set, string
|
||||
or filepath, to be written to ~/.config/noctalia/settings.json.
|
||||
When provided as an attribute set, it will be deep-merged with
|
||||
the default settings.
|
||||
'';
|
||||
};
|
||||
|
||||
colors = lib.mkOption {
|
||||
type =
|
||||
with lib.types;
|
||||
nullOr (oneOf [
|
||||
attrs
|
||||
str
|
||||
path
|
||||
]);
|
||||
default = null;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
mError = "#dddddd";
|
||||
mOnError = "#111111";
|
||||
mOnPrimary = "#111111";
|
||||
mOnSecondary = "#111111";
|
||||
mOnSurface = "#828282";
|
||||
mOnSurfaceVariant = "#5d5d5d";
|
||||
mOnTertiary = "#111111";
|
||||
mOutline = "#3c3c3c";
|
||||
mPrimary = "#aaaaaa";
|
||||
mSecondary = "#a7a7a7";
|
||||
mShadow = "#000000";
|
||||
mSurface = "#111111";
|
||||
mSurfaceVariant = "#191919";
|
||||
mTertiary = "#cccccc";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Noctalia shell color configuration as an attribute set, string
|
||||
or filepath, to be written to ~/.config/noctalia/colors.json.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
restart = ''
|
||||
${pkgs.systemd}/bin/systemctl --user try-restart noctalia-shell.service 2>/dev/null || true
|
||||
'';
|
||||
useApp2Unit = mergedSettings.appLauncher.useApp2Unit or false;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
home.packages = lib.optional useApp2Unit pkgs.app2unit;
|
||||
|
||||
xdg.configFile = {
|
||||
"noctalia/settings.json" = {
|
||||
onChange = restart;
|
||||
}
|
||||
// (
|
||||
if builtins.isAttrs mergedSettings then
|
||||
{ text = builtins.toJSON mergedSettings + "\n"; }
|
||||
else if builtins.isString mergedSettings then
|
||||
{ text = mergedSettings; }
|
||||
else
|
||||
{ source = mergedSettings; }
|
||||
);
|
||||
"noctalia/colors.json" = lib.mkIf (cfg.colors != null) (
|
||||
{
|
||||
onChange = restart;
|
||||
}
|
||||
// (
|
||||
if builtins.isAttrs cfg.colors then
|
||||
{ text = builtins.toJSON cfg.colors; }
|
||||
else if builtins.isString cfg.colors then
|
||||
{ text = cfg.colors; }
|
||||
else
|
||||
{ source = cfg.colors; }
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
nixosModules.default =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.noctalia-shell;
|
||||
in
|
||||
{
|
||||
options.services.noctalia-shell = {
|
||||
enable = lib.mkEnableOption "Noctalia shell systemd service";
|
||||
defaultPackage = eachSystem (system: self.packages.${system}.default);
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = self.packages.${pkgs.system}.default;
|
||||
description = "The noctalia-shell package to use";
|
||||
};
|
||||
|
||||
target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "graphical-session.target";
|
||||
example = "hyprland-session.target";
|
||||
description = "The systemd target for the noctalia-shell service.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.user.services.noctalia-shell = {
|
||||
description = "Noctalia Shell - Wayland desktop shell";
|
||||
documentation = [ "https://github.com/noctalia-dev/noctalia-shell" ];
|
||||
after = [ cfg.target ];
|
||||
partOf = [ cfg.target ];
|
||||
wantedBy = [ cfg.target ];
|
||||
restartTriggers = [ cfg.package ];
|
||||
|
||||
environment = {
|
||||
PATH = lib.mkForce null;
|
||||
};
|
||||
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = 60;
|
||||
StartLimitBurst = 3;
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/noctalia-shell";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 3;
|
||||
TimeoutStartSec = 10;
|
||||
TimeoutStopSec = 5;
|
||||
Environment = [
|
||||
"NOCTALIA_SETTINGS_FALLBACK=%h/.config/noctalia/gui-settings.json"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
};
|
||||
};
|
||||
homeModules.default = {
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [./nix/home-module.nix];
|
||||
programs.noctalia-shell.app2unit.package =
|
||||
lib.mkDefault
|
||||
nixpkgs.legacyPackages.${pkgs.system}.app2unit;
|
||||
};
|
||||
|
||||
nixosModules.default = {pkgs, ...}: {
|
||||
imports = [./nix/nixos-module.nix];
|
||||
services.noctalia-shell.package = self.packages.${pkgs.system}.default;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.programs.noctalia-shell;
|
||||
defaultSettings = builtins.fromJSON (builtins.readFile ../Assets/settings-default.json);
|
||||
extractAttrs = x:
|
||||
if builtins.isAttrs x
|
||||
then x
|
||||
else if builtins.isString x
|
||||
then builtins.fromJson x
|
||||
else builtins.fromJson (builtins.readFile x);
|
||||
in {
|
||||
options.programs.noctalia-shell = {
|
||||
enable = lib.mkEnableOption "Noctalia shell configuration";
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = with lib.types;
|
||||
nullOr (oneOf [
|
||||
attrs
|
||||
str
|
||||
path
|
||||
]);
|
||||
default = {};
|
||||
apply = x: lib.recursiveUpdate defaultSettings (extractAttrs x);
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
bar = {
|
||||
position = "bottom";
|
||||
floating = true;
|
||||
backgroundOpacity = 0.95;
|
||||
};
|
||||
general = {
|
||||
animationSpeed = 1.5;
|
||||
radiusRatio = 1.2;
|
||||
};
|
||||
colorSchemes = {
|
||||
darkMode = true;
|
||||
useWallpaperColors = true;
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Noctalia shell configuration settings as an attribute set, string
|
||||
or filepath, to be written to ~/.config/noctalia/settings.json.
|
||||
When provided as an attribute set, it will be deep-merged with
|
||||
the default settings.
|
||||
'';
|
||||
};
|
||||
|
||||
colors = lib.mkOption {
|
||||
type = with lib.types;
|
||||
nullOr (oneOf [
|
||||
attrs
|
||||
str
|
||||
path
|
||||
]);
|
||||
default = {};
|
||||
apply = extractAttrs;
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
mError = "#dddddd";
|
||||
mOnError = "#111111";
|
||||
mOnPrimary = "#111111";
|
||||
mOnSecondary = "#111111";
|
||||
mOnSurface = "#828282";
|
||||
mOnSurfaceVariant = "#5d5d5d";
|
||||
mOnTertiary = "#111111";
|
||||
mOutline = "#3c3c3c";
|
||||
mPrimary = "#aaaaaa";
|
||||
mSecondary = "#a7a7a7";
|
||||
mShadow = "#000000";
|
||||
mSurface = "#111111";
|
||||
mSurfaceVariant = "#191919";
|
||||
mTertiary = "#cccccc";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Noctalia shell color configuration as an attribute set, string
|
||||
or filepath, to be written to ~/.config/noctalia/colors.json.
|
||||
'';
|
||||
};
|
||||
|
||||
app2unit.package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
description = ''
|
||||
The app2unit package to use when appLauncher.useApp2Unit is enabled.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
restart = ''
|
||||
${pkgs.systemd}/bin/systemctl --user try-restart noctalia-shell.service 2>/dev/null || true
|
||||
'';
|
||||
useApp2Unit = cfg.settings.appLauncher.useApp2Unit or false;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
home.packages = lib.optional useApp2Unit cfg.app2unit.package;
|
||||
|
||||
xdg.configFile = {
|
||||
"noctalia/settings.json" = {
|
||||
onChange = restart;
|
||||
text = builtins.toJSON cfg.settings;
|
||||
};
|
||||
"noctalia/colors.json" = lib.mkIf (cfg.colors != {}) {
|
||||
onChange = restart;
|
||||
text = builtins.toJSON cfg.colors;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.services.noctalia-shell;
|
||||
in {
|
||||
options.services.noctalia-shell = {
|
||||
enable = lib.mkEnableOption "Noctalia shell systemd service";
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
description = "The noctalia-shell package to use";
|
||||
};
|
||||
|
||||
target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "graphical-session.target";
|
||||
example = "hyprland-session.target";
|
||||
description = "The systemd target for the noctalia-shell service.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.user.services.noctalia-shell = {
|
||||
description = "Noctalia Shell - Wayland desktop shell";
|
||||
documentation = ["https://github.com/noctalia-dev/noctalia-shell"];
|
||||
after = [cfg.target];
|
||||
partOf = [cfg.target];
|
||||
wantedBy = [cfg.target];
|
||||
restartTriggers = [cfg.package];
|
||||
|
||||
environment = {
|
||||
PATH = lib.mkForce null;
|
||||
};
|
||||
|
||||
unitConfig = {
|
||||
StartLimitIntervalSec = 60;
|
||||
StartLimitBurst = 3;
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/noctalia-shell";
|
||||
Restart = "on-failure";
|
||||
RestartSec = 3;
|
||||
TimeoutStartSec = 10;
|
||||
TimeoutStopSec = 5;
|
||||
Environment = [
|
||||
"NOCTALIA_SETTINGS_FALLBACK=%h/.config/noctalia/gui-settings.json"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [cfg.package];
|
||||
};
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
{
|
||||
version ? "dirty",
|
||||
lib,
|
||||
stdenv,
|
||||
# build
|
||||
gcc,
|
||||
qt6,
|
||||
quickshell,
|
||||
xkeyboard_config,
|
||||
# runtime deps
|
||||
bash,
|
||||
bluez,
|
||||
brightnessctl,
|
||||
cava,
|
||||
cliphist,
|
||||
coreutils,
|
||||
ddcutil,
|
||||
file,
|
||||
findutils,
|
||||
libnotify,
|
||||
matugen,
|
||||
networkmanager,
|
||||
wlsunset,
|
||||
wl-clipboard,
|
||||
gpu-screen-recorder, # optional
|
||||
# fonts
|
||||
makeFontsConf,
|
||||
roboto,
|
||||
inter-nerdfont,
|
||||
}: let
|
||||
src = lib.cleanSourceWith {
|
||||
src = ../.;
|
||||
filter = path: type:
|
||||
!(builtins.any (prefix: lib.path.hasPrefix (../. + prefix) (/. + path)) [
|
||||
/.github
|
||||
/Assets/Screenshots
|
||||
/Assets/Wallpaper
|
||||
/Bin/dev
|
||||
/nix
|
||||
/LICENSE
|
||||
/README.md
|
||||
/flake.nix
|
||||
/flake.lock
|
||||
]);
|
||||
};
|
||||
|
||||
runtimeDeps =
|
||||
[
|
||||
bash
|
||||
bluez
|
||||
brightnessctl
|
||||
cava
|
||||
cliphist
|
||||
coreutils
|
||||
ddcutil
|
||||
file
|
||||
findutils
|
||||
libnotify
|
||||
matugen
|
||||
networkmanager
|
||||
wlsunset
|
||||
wl-clipboard
|
||||
]
|
||||
++ lib.optionals (stdenv.hostPlatform.isx86_64) [gpu-screen-recorder];
|
||||
|
||||
fontconfig = makeFontsConf {
|
||||
fontDirectories = [
|
||||
roboto
|
||||
inter-nerdfont
|
||||
];
|
||||
};
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "noctalia-shell";
|
||||
inherit version src;
|
||||
|
||||
nativeBuildInputs = [
|
||||
gcc
|
||||
qt6.wrapQtAppsHook
|
||||
];
|
||||
buildInputs = [
|
||||
quickshell
|
||||
xkeyboard_config
|
||||
qt6.qtbase
|
||||
];
|
||||
propagatedBuildInputs = runtimeDeps;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/share/noctalia-shell $out/bin
|
||||
cp -r ./* $out/share/noctalia-shell
|
||||
cp ${quickshell}/bin/qs $out/bin/noctalia-shell
|
||||
'';
|
||||
|
||||
preFixup = ''
|
||||
qtWrapperArgs+=(
|
||||
--prefix PATH : ${lib.makeBinPath runtimeDeps}
|
||||
--set FONTCONFIG_FILE ${fontconfig}
|
||||
--add-flags "-p $out/share/noctalia-shell"
|
||||
)
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "A sleek and minimal desktop shell thoughtfully crafted for Wayland, built with Quickshell.";
|
||||
homepage = "https://github.com/noctalia-dev/noctalia-shell";
|
||||
license = lib.licenses.mit;
|
||||
mainProgram = "noctalia-shell";
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user