Skip to content

Conversation

auscyber
Copy link

@auscyber auscyber commented Sep 8, 2025

adds a module for wallpaper and colours for darwin


adds a module for wallpaper and colours for darwin
@stylix-automation stylix-automation bot added topic: home-manager Home Manager target topic: modules /modules/ subsystem labels Sep 8, 2025
@auscyber
Copy link
Author

auscyber commented Sep 8, 2025

So, i've never made a module for stylix, and i'm getting some errors to do with callPackage not existing, and unsure if my shellScript outputs correctly but i'm unsure how i even test this?

Copy link
Contributor

@awwpotato awwpotato left a comment

Choose a reason for hiding this comment

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

this should probably go under /stylix/darwin/ instead of /modules/darwin/

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

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

@auscyber
Copy link
Author

auscyber commented Sep 8, 2025

the entire thing? or just the desktoppr?

Comment on lines 12 to 23
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>/.

Comment on lines 34 to 36
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}')

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.

@stylix-automation stylix-automation bot added topic: darwin nix-darwin target topic: stylix /stylix/ subsystem labels Sep 10, 2025
Comment on lines +1 to +37
{
stdenv,
fetchurl,
lib,
unzip,
}:
stdenv.mkDerivation {
name = "desktoppr";
version = "0.5-218";
pname = "desktoppr";
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
'';

}
Copy link
Member

Choose a reason for hiding this comment

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

This pr might be worth mentioning NixOS/nixpkgs#397284

Copy link
Member

Choose a reason for hiding this comment

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

This pr might be worth mentioning NixOS/nixpkgs#397284

Thanks for pointing that out. I suggest using the Nixpkgs module (after updating our Nixpkgs input) once it has been merged.

Comment on lines +1 to +37
{
stdenv,
fetchurl,
lib,
unzip,
}:
stdenv.mkDerivation {
name = "desktoppr";
version = "0.5-218";
pname = "desktoppr";
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
'';

}
Copy link
Member

Choose a reason for hiding this comment

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

This pr might be worth mentioning NixOS/nixpkgs#397284

Thanks for pointing that out. I suggest using the Nixpkgs module (after updating our Nixpkgs input) once it has been merged.

{
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).

Comment on lines 12 to 23
extraOptions =
{
image,
}:
{
home.activation = {
stylixBackground = ''
run ${pkgs.callPackage ./desktoppr.nix { }}/bin/desktoppr all ${image}

'';
};
};
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>/.

Comment on lines +36 to +45
pkgs.runCommand "color" { } ''
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
''
Copy link
Member

@trueNAHO trueNAHO Sep 15, 2025

Choose a reason for hiding this comment

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

It would be better to natively implement this in Nix. Also, take a look at existing Stylix modules, to find something similar as inspiration.

Copy link
Member

Choose a reason for hiding this comment

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

Like in colors.nix module that was recently merged for mkHexOpacityColor and mkHexColor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: darwin nix-darwin target topic: home-manager Home Manager target topic: modules /modules/ subsystem topic: stylix /stylix/ subsystem
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants