feat(nightlight): scheduled blue-light filter via hyprsunset
Add nomarchy.nightlight (opt-in): a scheduled colour-temperature shift via the HM services.hyprsunset module -- warm (.temperature, default 4000K) at night, identity (no shift) by day, switching at .sunset / .sunrise. Two time-based hyprsunset profiles, so hyprsunset handles the schedule and the on-login state. New modules/home/nightlight.nix, imported in the home module. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,7 @@ examples: **[docs/OVERRIDES.md](docs/OVERRIDES.md)**.
|
|||||||
| `nomarchy.keyboard.variant` | `""` | XKB variant for the session |
|
| `nomarchy.keyboard.variant` | `""` | XKB variant for the session |
|
||||||
| `nomarchy.keyboard.devices` | `{}` | Per-device layout overrides (Hyprland `device` blocks keyed by `hyprctl devices` name) — e.g. an external keyboard with its own layout/variant |
|
| `nomarchy.keyboard.devices` | `{}` | Per-device layout overrides (Hyprland `device` blocks keyed by `hyprctl devices` name) — e.g. an external keyboard with its own layout/variant |
|
||||||
| `nomarchy.keyboard.layouts` | `[]` | Extra candidate layouts; when set, a watcher prompts (rofi) for a layout on a newly-connected keyboard and remembers it per-device |
|
| `nomarchy.keyboard.layouts` | `[]` | Extra candidate layouts; when set, a watcher prompts (rofi) for a layout on a newly-connected keyboard and remembers it per-device |
|
||||||
|
| `nomarchy.nightlight.enable` | `false` | Scheduled blue-light filter (hyprsunset) — warm at night (`.temperature`, default 4000K) between `.sunset`/`.sunrise`, no shift by day |
|
||||||
| `nomarchy.hyprland.enable` | `true` | Nomarchy's Hyprland config |
|
| `nomarchy.hyprland.enable` | `true` | Nomarchy's Hyprland config |
|
||||||
| `nomarchy.waybar.enable` | `true` | Nomarchy's Waybar |
|
| `nomarchy.waybar.enable` | `true` | Nomarchy's Waybar |
|
||||||
| `nomarchy.rofi.enable` | `true` | Themed rofi launcher + `nomarchy-menu` dispatcher |
|
| `nomarchy.rofi.enable` | `true` | Themed rofi launcher + `nomarchy-menu` dispatcher |
|
||||||
|
|||||||
@@ -289,9 +289,15 @@ how to override it. Items marked ✓ are shipped.
|
|||||||
switching** of the *same* outputs (Hyprland's per-output rules cover the
|
switching** of the *same* outputs (Hyprland's per-output rules cover the
|
||||||
common "external connects → arrange" case, not multi-layout toggles), and
|
common "external connects → arrange" case, not multi-layout toggles), and
|
||||||
optionally workspace-to-monitor binding.
|
optionally workspace-to-monitor binding.
|
||||||
- **Night light / blue-light filter:** schedulable colour-temperature shift
|
- ✓ **Night light / blue-light filter:** `nomarchy.nightlight` (opt-in) —
|
||||||
via `hyprsunset` (Hyprland-native; wlsunset/gammastep are alternatives) —
|
a scheduled colour-temperature shift via `hyprsunset` (Hyprland-native),
|
||||||
sunset/sunrise or a fixed schedule, with a menu + Waybar toggle.
|
warm at night, identity (no shift) by day. `modules/home/nightlight.nix`
|
||||||
|
drives the HM `services.hyprsunset` with two time-based profiles
|
||||||
|
(`sunrise` → identity, `sunset` → `temperature`), so hyprsunset handles the
|
||||||
|
schedule and the on-login state. Needs an on-hardware check that hyprsunset
|
||||||
|
applies the active profile at session start. Remaining (optional): a menu +
|
||||||
|
Waybar toggle to force it on/off, and geo (lat/long) auto sunset/sunrise
|
||||||
|
(would mean wlsunset, which schedules by location).
|
||||||
- **Keyboard layouts (per-device + switching):**
|
- **Keyboard layouts (per-device + switching):**
|
||||||
- ✓ **Per-device declarative layout:** `nomarchy.keyboard.devices`
|
- ✓ **Per-device declarative layout:** `nomarchy.keyboard.devices`
|
||||||
(`{ "<hyprctl-device-name>" = { layout; variant; }; }`) generates Hyprland
|
(`{ "<hyprctl-device-name>" = { layout; variant; }; }`) generates Hyprland
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
./idle.nix # hyprlock + hypridle, themed from the same JSON
|
./idle.nix # hyprlock + hypridle, themed from the same JSON
|
||||||
./yazi.nix # flagship TUI file manager, themed + plugins
|
./yazi.nix # flagship TUI file manager, themed + plugins
|
||||||
./osd.nix # swayosd volume/brightness OSD, themed
|
./osd.nix # swayosd volume/brightness OSD, themed
|
||||||
|
./nightlight.nix # scheduled blue-light filter (hyprsunset), opt-in
|
||||||
./shell.nix # zsh + starship + bat/eza/zoxide, themed
|
./shell.nix # zsh + starship + bat/eza/zoxide, themed
|
||||||
./keys.nix # gpg-agent (fronts SSH) + pinentry-qt
|
./keys.nix # gpg-agent (fronts SSH) + pinentry-qt
|
||||||
./fastfetch.nix # system info with the themed Nomarchy logo
|
./fastfetch.nix # system info with the themed Nomarchy logo
|
||||||
|
|||||||
25
modules/home/nightlight.nix
Normal file
25
modules/home/nightlight.nix
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Night light — a scheduled blue-light filter via hyprsunset (Hyprland's own
|
||||||
|
# gamma/temperature tool). Warm at night, identity (no shift) by day;
|
||||||
|
# hyprsunset's time-based `profile` entries handle the schedule and pick the
|
||||||
|
# right state on session start. Opt-in via nomarchy.nightlight.enable.
|
||||||
|
#
|
||||||
|
# The hyprsunset HM service module is provided by home-manager; this only
|
||||||
|
# configures it. Override anything with plain services.hyprsunset.* options.
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.nomarchy.nightlight;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.hyprsunset = {
|
||||||
|
enable = true;
|
||||||
|
settings.profile = [
|
||||||
|
# Daytime: identity = no colour change.
|
||||||
|
{ time = cfg.sunrise; identity = true; }
|
||||||
|
# Night: shift to the warm temperature.
|
||||||
|
{ time = cfg.sunset; temperature = cfg.temperature; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -157,6 +157,33 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nightlight = {
|
||||||
|
enable = lib.mkEnableOption ''
|
||||||
|
a scheduled blue-light filter (hyprsunset): warm at night, no shift
|
||||||
|
by day. Opt-in; tune the temperature + sunrise/sunset below'';
|
||||||
|
|
||||||
|
temperature = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 4000;
|
||||||
|
example = 3500;
|
||||||
|
description = "Warm colour temperature (K) applied at night — lower is warmer.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sunrise = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "07:00";
|
||||||
|
example = "06:30";
|
||||||
|
description = "Time (HH:MM) the filter turns OFF — daytime, no colour shift.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sunset = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "20:00";
|
||||||
|
example = "21:00";
|
||||||
|
description = "Time (HH:MM) the filter turns ON — warm.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
monitors = lib.mkOption {
|
monitors = lib.mkOption {
|
||||||
type = lib.types.listOf monitorType;
|
type = lib.types.listOf monitorType;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
|||||||
Reference in New Issue
Block a user