diff --git a/README.md b/README.md index 04cb95c..3a93cb5 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,8 @@ Flat on purpose. Two module trees, one options file each, no hidden layers. │ ├── rofi.nix # launcher + nomarchy-menu (power, clip) │ ├── swaync.nix # notifications, same JSON │ ├── idle.nix # hyprlock + hypridle, same JSON -│ └── yazi.nix # flagship TUI file manager + plugins +│ ├── yazi.nix # flagship TUI file manager + plugins +│ └── osd.nix # swayosd volume/brightness OSD ├── hosts/ │ ├── default/ # reference machine (thin: boot, user, hostname) │ └── live.nix # bootable live ISO (try the distro, no install) @@ -176,6 +177,7 @@ examples: **[docs/OVERRIDES.md](docs/OVERRIDES.md)**. | `nomarchy.swaync.enable` | `true` | swaync notifications, themed | | `nomarchy.idle.enable` | `true` | hyprlock + hypridle (idle lock 5 min, display off 10, suspend 30) | | `nomarchy.yazi.enable` | `true` | yazi TUI file manager, themed + curated plugins | +| `nomarchy.osd.enable` | `true` | swayosd on-screen display for volume/brightness/mute | | `nomarchy.ghostty.enable` | `true` | Nomarchy's Ghostty | | `nomarchy.btop.enable` | `true` | btop with per-theme colors | | `nomarchy.stylix.enable` | `true` | GTK/Qt/cursor theming | @@ -302,7 +304,8 @@ close · `SUPER+1..9` workspaces · `Print` region screenshot. v1: `nomarchy.system.plymouth.*`, background tinted from the state file) - Installer round 2: multi-disk BTRFS RAID, impermanence, BIOS/legacy boot (v1 `nomarchy-install` is single-disk UEFI — see `pkgs/nomarchy-install`) -- swayosd (volume/brightness OSD), launch-or-focus UX scripts +- launch-or-focus UX scripts (swayosd volume/brightness OSD ships since v1: + `nomarchy.osd.*`, media keys drive `swayosd-client`, themed from the JSON) - **Distro branding, round 2:** `distroName = "Nomarchy"` ships (os-release `PRETTY_NAME`, systemd-boot entries, ISO menu label). Remaining: `isoImage.splashImage`/`grubTheme` art for the ISO boot diff --git a/modules/home/default.nix b/modules/home/default.nix index 4cefbfa..861e789 100644 --- a/modules/home/default.nix +++ b/modules/home/default.nix @@ -16,6 +16,7 @@ ./swaync.nix # notification daemon, themed from the same JSON ./idle.nix # hyprlock + hypridle, themed from the same JSON ./yazi.nix # flagship TUI file manager, themed + plugins + ./osd.nix # swayosd volume/brightness OSD, themed ]; # Clipboard history (wl-paste watcher); browsed via the SUPER+CTRL+V diff --git a/modules/home/hyprland.nix b/modules/home/hyprland.nix index 1a57669..30fd8b1 100644 --- a/modules/home/hyprland.nix +++ b/modules/home/hyprland.nix @@ -161,19 +161,19 @@ in ", Print, exec, grim -g \"$(slurp)\" - | wl-copy" ] ++ workspaceBinds; - # Media keys: wpctl talks to wireplumber directly (no - # pipewire-pulse shim like pamixer); e = repeat, l = also on a - # locked screen — the standard flags for hardware keys. + # Media keys via swayosd-client: it performs the action AND shows + # the on-screen display (the nomarchy.osd module). e = repeat, + # l = also on a locked screen — the standard flags for hardware keys. bindel = [ - ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+" - ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" - ", XF86MonBrightnessUp, exec, brightnessctl set +5%" - ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" + ", XF86AudioRaiseVolume, exec, swayosd-client --output-volume raise" + ", XF86AudioLowerVolume, exec, swayosd-client --output-volume lower" + ", XF86MonBrightnessUp, exec, swayosd-client --brightness raise" + ", XF86MonBrightnessDown, exec, swayosd-client --brightness lower" ]; bindl = [ - ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" - ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" + ", XF86AudioMute, exec, swayosd-client --output-volume mute-toggle" + ", XF86AudioMicMute, exec, swayosd-client --input-volume mute-toggle" ", XF86AudioPlay, exec, playerctl play-pause" ", XF86AudioPause, exec, playerctl play-pause" ", XF86AudioNext, exec, playerctl next" diff --git a/modules/home/options.nix b/modules/home/options.nix index 34c0432..64ccf49 100644 --- a/modules/home/options.nix +++ b/modules/home/options.nix @@ -67,6 +67,7 @@ swaync.enable = lib.mkEnableOption "swaync notifications, themed from the state file" // { default = true; }; idle.enable = lib.mkEnableOption "hyprlock + hypridle (idle lock, display off, suspend)" // { default = true; }; yazi.enable = lib.mkEnableOption "the yazi TUI file manager, themed with a curated plugin set" // { default = true; }; + osd.enable = lib.mkEnableOption "swayosd on-screen display for volume/brightness/mute" // { default = true; }; ghostty.enable = lib.mkEnableOption "Nomarchy's Ghostty configuration" // { default = true; }; btop.enable = lib.mkEnableOption "btop with the per-theme nomarchy theme" // { default = true; }; stylix.enable = lib.mkEnableOption "Stylix theming for the long tail of apps (GTK, Qt, cursors)" // { default = true; }; diff --git a/modules/home/osd.nix b/modules/home/osd.nix new file mode 100644 index 0000000..df82ed1 --- /dev/null +++ b/modules/home/osd.nix @@ -0,0 +1,55 @@ +# swayosd — on-screen display for volume / brightness / mute (and caps +# lock). The media keys drive it via swayosd-client (it performs the +# action AND shows the OSD), so changing volume or brightness gives the +# visual feedback that bare wpctl/brightnessctl didn't. Themed from +# theme-state.json. Brightness needs the backlight udev rule shipped +# system-side (modules/nixos/default.nix → services.udev.packages). +{ config, lib, pkgs, ... }: + +let + cfg = config.nomarchy; + t = cfg.theme; + c = t.colors; + + style = pkgs.writeText "swayosd-style.css" '' + window#osd { + border-radius: ${toString t.ui.rounding}px; + border: ${toString t.ui.borderSize}px solid ${c.accent}; + background: alpha(${c.base}, 0.92); + } + window#osd #container { margin: 16px; } + window#osd image, + window#osd label { color: ${c.text}; } + window#osd progressbar:disabled, + window#osd image:disabled { opacity: 0.5; } + window#osd progressbar, + window#osd segmentedprogress { + min-height: 8px; + border-radius: 999px; + background: transparent; + border: none; + } + window#osd trough, + window#osd segment { + min-height: inherit; + border-radius: inherit; + border: none; + background: ${c.surface}; + } + window#osd progress, + window#osd segment.active { + min-height: inherit; + border-radius: inherit; + border: none; + background: ${c.accent}; + } + ''; +in +{ + config = lib.mkIf cfg.osd.enable { + services.swayosd = { + enable = true; + stylePath = style; + }; + }; +} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 286b1bb..4e0b62b 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -189,6 +189,11 @@ in # Don't let boot entries fill the ESP over the years. boot.loader.systemd-boot.configurationLimit = lib.mkDefault 10; + # Backlight udev rule (chgrp video + g+w on /sys/class/backlight) so + # the desktop's swayosd brightness control works for video-group + # users without root. Harmless baseline even if the OSD is disabled. + services.udev.packages = [ pkgs.swayosd ]; + # ── Nix itself ─────────────────────────────────────────────────── nix = { settings = {