Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions modules/darwin/desktoppr.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
stdenv,
fetchurl,
lib,
unzip,
}:
stdenv.mkDerivation {
name = "hln";
version = "0.5-218";
pname = "hln";
src = fetchurl {
url = "https://github.com/scriptingosx/desktoppr/releases/download/v0.5/desktoppr-0.5-218.zip";
hash = "sha256-Oa9gAQjOaJHYyT5JBUiFCxL1sQP1dqlFBm+GdmLHNNM=";
};

buildInputs = [
unzip
];

unpackPhase = ''
runHook preUnpack

unzip $src

runHook postUnpack
'';

installPhase = ''
runHook preInstall

mkdir -p $out/bin
cp -r desktoppr $out/bin

runHook postInstall
'';

}
53 changes: 53 additions & 0 deletions modules/darwin/hm.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
mkTarget,
config,
lib,
pkgs,
...
}:

mkTarget {
name = "darwin";
humanName = "Darwin";
extraOptions =
{
image,
}:
{
home.activation = {
stylixBackground = ''
run ${pkgs.callPackage ./desktoppr.nix { }}/bin/desktoppr all ${image}

'';
};
};
Copy link
Member

@MattSturgeon MattSturgeon Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm getting some errors to do with callPackage not existing

this is probably due to the doc eval, cc @MattSturgeon

extraOptions is for declaring options. You haven't used lib.mkOption or any of its wrappers, so this looks a lot more like a config definition that should go in configElements.

The reason pkgs.callPackage doesn't exist when declaring options is to ensure it is not accidentally used in option docs (i.e. option examples, defaultText, etc). See #1212

Could you clarify what you're trying to achieve here?


You may find Writing NixOS Modules helpful, in particular the distinction between declaring and defining options.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm familiar with the distinction and have written many modules, i was just very unsure how this mkStylixModule system works

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understandable. Too many layers of abstraction can make it difficult to understand what things actually do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm familiar with the distinction and have written many modules, i was just very unsure how this mkStylixModule system works

Did you already take a look at

stylix/doc/src/modules.md

Lines 42 to 115 in 0ce0103

## Module template
Modules should be created using the `mkTarget` function whenever possible (see
the [`/stylix/mk-target.nix`](
https://github.com/nix-community/stylix/blob/-/stylix/mk-target.nix) in-source
documentation for more details):
```nix
{ config, lib, mkTarget ... }:
mkTarget {
name = "«name»";
humanName = "«human readable name»";
configElements =
{ colors }:
{
programs.«name».theme.background = colors.base00;
};
}
```
> [!IMPORTANT]
> The `mkTarget` argument is only available to modules imported by Stylix's
> [autoload
> system](https://github.com/nix-community/stylix/blob/-/stylix/autoload.nix),
> e.g., `modules/«target»/«platform».nix` modules.
>
> I.e., it is not available to normal modules imported via the `imports` list.
When the `mkTarget` function cannot be used, modules must manually replicate its
safeguarding behaviour:
```nix
{ config, lib, ... }:
{
options.stylix.targets.«name».enable =
config.lib.stylix.mkEnableTarget "«human readable name»" true;
config =
lib.mkIf (config.stylix.enable && config.stylix.targets.«name».enable)
{
programs.«name».backgroundColor = config.lib.stylix.colors.base00;
};
}
```
> [!CAUTION]
> If not using `mkTarget`, you **must** check _both_ `config.stylix.enable`
> _and_ your target's own`enable` option before defining any config.
>
> In the above example this is done using
> `config = lib.mkIf (config.stylix.enable && config.stylix.targets.«name».enable)`.
The human readable name will be inserted into the following sentence:
> Whether to enable theming for «human readable name».
If your module will touch options outside of `programs.«name»` or
`services.«name»`, it should include an additional condition in `mkIf` to
prevent any effects when the target is not installed.
The boolean value after `mkEnableTarget` should be changed to `false` if one of
the following applies:
- The module requires further manual setup to work correctly.
- There is no reliable way to detect whether the target is installed, *and*
enabling it unconditionally would cause problems.
> [!CAUTION]
> The boolean value after `mkEnableTarget` should usually be a static `true` or
> `false` literal.
>
> Using a dynamic value requires you to document the dynamic expression using
> `mkEnableTargetWith`'s `autoEnableExpr` argument.

Understandable. Too many layers of abstraction can make it difficult to understand what things actually do.

Yes, the mkTarget documentation is currently too technical and the implementation is too complex to quickly understand. Once the mkTarget behavior has further solidified after merging #1721, improving the documentation is planned. Note that the currently pending commit 300f48d ("stylix/mk-target: polish implementation and improve error reporting") from #1721 attempts to improve and drastically simplify the implementation.

Aside from the mkTarget documentation, take a look at existing mkTarget examples in /modules/<MODULE>/.


configElements = [

(
{
colors,
}:
let
value = pkgs.runCommand "color" { } ''

full=$((16#${colors.base00}))
red=$((($full >> 16) & 0xff))
red=$(echo "scale=10; $red.0 / 255.0 " | bc |awk '{printf "%f", $0}')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: the indentation seems off here:

Suggested change
full=$((16#${colors.base00}))
red=$((($full >> 16) & 0xff))
red=$(echo "scale=10; $red.0 / 255.0 " | bc |awk '{printf "%f", $0}')
full=$((16#${colors.base00}))
red=$((($full >> 16) & 0xff))
red=$(echo "scale=10; $red.0 / 255.0 " | bc |awk '{printf "%f", $0}')

green=$((($full >> 8) & 0xff))
green=$(echo "scale=10; $green.0 / 255.0 " | bc | awk '{printf "%f", $0}')
blue=$(($full & 0xff))
blue=$(echo "scale=10; $blue.0 / 255.0 " | bc | awk '{printf "%f", $0}')
echo "$red $green $blue 1.0" > $out

'';

in
{

targets.darwin.defaults."Apple Global Domain".AppleIconAppearanceCustomTintColor = value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why you would bind the color package to value in a let block, but then only use it once.

Why not just bind it directly here in the config definition? I.e. inline value.

}
)
];

}
5 changes: 5 additions & 0 deletions modules/darwin/meta.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
name = "Darwin";
homepage = "https://github.com/nix-darwin/nix-darwin";
maintainers = [ ];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stylix/doc/src/modules.md

Lines 228 to 264 in 0ce0103

### Maintainers
New modules must have at least one maintainer.
If you are not already listed in the Nixpkgs `/maintainers/maintainer-list.nix`
maintainer list, add yourself to `/stylix/maintainers.nix`.
Add yourself as a maintainer in one of the following ways, depending on the
number of maintainers:
- ```nix
{ lib, ... }:
{
maintainers = [ lib.maintainers.danth ];
}
```
- ```nix
{ lib, ... }:
{
maintainers = with lib.maintainers; [
awwpotato
danth
naho
];
}
```
The main responsibility of module maintainers is to update and fix their
modules.
> [!NOTE]
> If this is the first time you're adding yourself as a maintainer in Stylix,
> the `/generated/all-maintainers.nix` file will need to be updated by running
> `nix run .#all-maintainers`
> ([pre-commit](./development_environment.md#pre-commit) will also automatically
> regenerate it).

}
Loading