tanin-icons: accent-reactive folder icon theme (replaces Papirus)
New package packaging/tanin-icons/ generating 5 thin themes Tanin-<accent> that inherit Adwaita and recolour only the folder/place ramp to the muted Fuji accent (HSL shift keeping per-stop lightness; 16px rasterised so the size-exact inherited blue PNG can't win). - style.py: _set_gsettings now also sets icon-theme=Tanin-<accent_key> so folders recolour live with the accent. - desktop.py: hide Tanin-* from the manual icon picker (accent-driven, a manual pick would be overridden on the next accent change). - panel.py: pin-add icon hint Papirus -> Adwaita. - build/finish-tanin-repo.sh: tanin-icons in OWN_SIMPLE; AUR rebuilds add librewolf-bin, arch-update, timeshift-autosnap, xdg-terminal-exec, paru. - camel.toml: icon_theme=Tanin-<accent>, icons=[adwaita], tanin-icons own package + the new rebuilt_aur entries. Deliberately excludes unrelated in-flight work (calendar/gtklock/ online-accounts/overview-backdrop) still uncommitted in the tree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+119
@@ -0,0 +1,119 @@
|
|||||||
|
# TANINUX — Handover (Session 2026-06-22)
|
||||||
|
|
||||||
|
Context for a fresh instance. Repo: `~/projects/taninux` (distro codename **camel**,
|
||||||
|
niri-only GTK4/libadwaita + eww desktop). User: Karim (German; iterates visually;
|
||||||
|
hates UI jank; blanket perms in `~/projects`). UI strings are **English**.
|
||||||
|
|
||||||
|
This session did two things: (A) added packages to the `[tanin]` binary repo,
|
||||||
|
(B) built a custom **accent-reactive icon theme** to replace Papirus.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## A. New packages in the `[tanin]` repo
|
||||||
|
|
||||||
|
The `[tanin]` repo is a thin overlay on Arch (own packages + AUR rebuilds),
|
||||||
|
hosted on the Gitea Arch registry. Build/publish scripts in `packaging/`:
|
||||||
|
`build-tanin-repo.sh` (no-sudo), `finish-tanin-repo.sh` (sudo: taninux + AUR
|
||||||
|
rebuilds), `publish-tanin-repo.sh` (upload to Gitea).
|
||||||
|
|
||||||
|
Added to the AUR-rebuild list (`build-tanin-repo.sh` + `finish-tanin-repo.sh`):
|
||||||
|
- `librewolf-bin` — default browser. Also a **hard dep** of `tanin-desktop`.
|
||||||
|
⚠ Security: rebuild + republish on every LibreWolf release, else `pacman -Syu`
|
||||||
|
ships a stale (vulnerable) browser.
|
||||||
|
- `arch-update`, `timeshift` (+ `timeshift-autosnap`), `xdg-terminal-exec` —
|
||||||
|
all hard deps of `tanin-desktop` now.
|
||||||
|
- `paru` — built into the repo but stays **optdepend** (not forced).
|
||||||
|
|
||||||
|
Deliberately **rejected**: `papirus-folders` (removed). The other 20 AUR pkgs on
|
||||||
|
Karim's machine are personal apps/games/emulators/hardware → not base-OS.
|
||||||
|
`swayfx`+`scenefx0.4` are pulled by `greetd-regreet` (a leftover alt-greeter;
|
||||||
|
TANINUX uses `tanin-greet`) — candidate for removal, not done.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## B. Icon theme: Papirus → `tanin-icons` (the main work)
|
||||||
|
|
||||||
|
Karim's decision: Papirus is "too flat"; **Adwaita fits the design**, folders
|
||||||
|
should follow the Fuji accent. The 5 Fuji accents are deliberately *muted*
|
||||||
|
(`ume #8f8aac`, `shinkai #8a98ac`, `take #8aac8b`, `chikyu #aca98a`, `beni #ac8a8c`)
|
||||||
|
— so `papirus-folders` (saturated presets) and native GNOME accent-folders (preset
|
||||||
|
accents only) both can't match. Hence a custom package.
|
||||||
|
|
||||||
|
**New package `packaging/tanin-icons/`:**
|
||||||
|
- `recolor.py` — generator. Builds 5 thin themes `Tanin-<accent>` that
|
||||||
|
`Inherits=Adwaita`, recolouring **only** the folder/place icons. Algorithm:
|
||||||
|
HSL shift of the Adwaita blue ramp → keep each stop's **lightness**, swap
|
||||||
|
hue+saturation to the accent (preserves folder depth). White emblems untouched
|
||||||
|
(saturation gate). **16px PNGs are rasterised via `rsvg-convert`** because
|
||||||
|
Adwaita's only fixed-size raster is 16x16 — without an override the inherited
|
||||||
|
blue PNG wins at 16px.
|
||||||
|
- `PKGBUILD` (depends `adwaita-icon-theme`; makedepends `librsvg python`) +
|
||||||
|
`tanin-icons.install` (gtk-update-icon-cache hook). Builds clean, ~52 KB.
|
||||||
|
- ⚠ `recolor.py` was fixed to only `rmtree` its own `Tanin-<key>` subdirs, NOT
|
||||||
|
the whole `OUT` dir (it earlier wiped a shared dir when `OUT_DIR` pointed at
|
||||||
|
`~/.local/share/icons` — no data lost that time, but the bug is gone now).
|
||||||
|
- ⚠ Rebuild this package after any `adwaita-icon-theme` bump (reads
|
||||||
|
`/usr/share/icons/Adwaita` at build time).
|
||||||
|
|
||||||
|
**Integration (source only, NOT yet in the installed taninux):**
|
||||||
|
`src/taninux/gui/style.py` → `_set_gsettings()` now also sets
|
||||||
|
`icon-theme=Tanin-<accent_key>`, so folders recolour **live** when the accent
|
||||||
|
changes. Also fixed `src/taninux/gui/pages/panel.py` hint "Papirus" → "Adwaita".
|
||||||
|
|
||||||
|
**Wiring:**
|
||||||
|
- `build-tanin-repo.sh`: `tanin-icons` added to `OWN_SIMPLE`.
|
||||||
|
- `tanin-desktop/PKGBUILD`: depends `+tanin-icons`, **removed** `papirus-icon-theme`
|
||||||
|
(Adwaita is the base now), `pkgrel` 3→5.
|
||||||
|
- Distro manifests synced: `distro/camel.toml` (icon_theme, `icons=[adwaita...]`,
|
||||||
|
new `[[packages.own]] tanin-icons`), `distro/MANIFEST.md` (icon row + pkg table).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CURRENT STATE — read carefully
|
||||||
|
|
||||||
|
| Thing | State |
|
||||||
|
|---|---|
|
||||||
|
| `tanin-icons` package built (`*.pkg.tar.zst`) | ✅ in `packaging/tanin-icons/` |
|
||||||
|
| Verified GTK resolves folder @48px (svg) + @16px (png) to `Tanin-<accent>` | ✅ |
|
||||||
|
| **Active in Karim's running session** | ✅ but via a **user-dir copy** at `~/.local/share/icons/Tanin-*` + `gsettings icon-theme=Tanin-beni` (current accent). NOT the pacman package. |
|
||||||
|
| `tanin-icons` installed via pacman | ❌ (sudo needs a password; no TTY here) |
|
||||||
|
| `[tanin]` repo rebuilt + published with the new pkgs | ❌ |
|
||||||
|
| `taninux`/`tanin-desktop` rebuilt with the style.py change | ❌ → **accent→icon auto-switch is NOT live yet**; changing the accent in Settings won't move the icon-theme until taninux is reinstalled. Workaround now: `gsettings set org.gnome.desktop.interface icon-theme Tanin-<accent>`. |
|
||||||
|
| ISO rebuilt | ❌ |
|
||||||
|
|
||||||
|
So: **wired in source + manifests, but no artifacts rebuilt** → a fresh ISO/install
|
||||||
|
does NOT have it yet.
|
||||||
|
|
||||||
|
### To fully ship (needs Karim for sudo)
|
||||||
|
1. `./packaging/finish-tanin-repo.sh` — builds `tanin-icons` + the new `taninux`/
|
||||||
|
`tanin-desktop` + AUR rebuilds.
|
||||||
|
2. `./packaging/publish-tanin-repo.sh` — upload to Gitea (`TANIN_PKG_TOKEN`).
|
||||||
|
3. Rebuild the ISO (pulls the updated `[tanin]`).
|
||||||
|
4. Optional cleanup: once installed system-wide, delete the user-dir copies
|
||||||
|
`~/.local/share/icons/Tanin-*` (identical, harmlessly shadowed).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OPEN / OFFERED, not done
|
||||||
|
- **camel.toml `rebuilt_aur` list is stale** — still only eww/tiramisu/waypaper/
|
||||||
|
calamares/paru; missing `librewolf-bin`, `arch-update`, `timeshift-autosnap`,
|
||||||
|
`xdg-terminal-exec`. Offered to sync; awaiting Karim.
|
||||||
|
- **Manual icon-theme picker** (`src/taninux/gui/desktop.py`) still lists the 5
|
||||||
|
`Tanin-*` themes and a manual pick gets overridden on the next accent change.
|
||||||
|
Could filter them out — not done.
|
||||||
|
- **Accent-icon scope**: only folders/places are recoloured. Karim was asked
|
||||||
|
whether to extend to `emblem-*`/coloured mimetypes — undecided.
|
||||||
|
- `papirus-folders` still *installed* on Karim's machine (`paru -Rns papirus-folders`).
|
||||||
|
|
||||||
|
## Gotchas to respect
|
||||||
|
- NEVER run lock/session/suspend commands to "test" (locked Karim out once).
|
||||||
|
- GTK3 can't be exact-Fuji recoloured (parse-time `@define-color`); only GTK4/
|
||||||
|
libadwaita is exact. See memory `taninux-gtk-theming`.
|
||||||
|
- Lots of unrelated uncommitted changes exist in the tree (tanin-calendar,
|
||||||
|
online_accounts, gtklock, iso/*) — NOT from this session; don't bundle them.
|
||||||
|
|
||||||
|
## Files touched this session
|
||||||
|
`packaging/tanin-icons/{PKGBUILD,recolor.py,tanin-icons.install}` (new),
|
||||||
|
`packaging/{build,finish}-tanin-repo.sh`, `packaging/tanin-desktop/PKGBUILD`,
|
||||||
|
`src/taninux/gui/style.py`, `src/taninux/gui/pages/panel.py`,
|
||||||
|
`distro/{camel.toml,MANIFEST.md}`.
|
||||||
+31
-4
@@ -31,7 +31,7 @@ bg = "#0f0f0f"
|
|||||||
fg = "#f0f0f0"
|
fg = "#f0f0f0"
|
||||||
ui_font = "Inter" # Medium
|
ui_font = "Inter" # Medium
|
||||||
icon_font = "Iosevka Nerd Font" # Material Design Icons (nf-md-*)
|
icon_font = "Iosevka Nerd Font" # Material Design Icons (nf-md-*)
|
||||||
icon_theme = "Papirus" # dock app icons
|
icon_theme = "Tanin-<accent>" # Adwaita base + Fuji-accent folders (tanin-icons); set live by the accent picker
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Package sources. Standard software comes from the official Arch repos; only
|
# Package sources. Standard software comes from the official Arch repos; only
|
||||||
@@ -108,6 +108,13 @@ pkgbuild = "packaging/tanin-libadwaita/PKGBUILD" # exists
|
|||||||
status = "ready (live-verified GTK4; GTK3 partial) + ships tanin-libadwaita.service (user, watch)"
|
status = "ready (live-verified GTK4; GTK3 partial) + ships tanin-libadwaita.service (user, watch)"
|
||||||
note = "STATIC defaults + CLI (tanin-libadwaita {dark|light|auto|watch}) for greeter/first-boot. LIVE theming is driven by the taninux app: gui/style.py write_global_theme() regenerates ~/.config/gtk-{4.0,3.0}/gtk(.css)|libadwaita.css from the Appearance settings (dynamic accent + light/dark, surfaces #0f0f0f/#f0f0f0, pills). GTK4/libadwaita = full exact Fuji; GTK3/adw-gtk3 = light/dark + pills only (GTK3 @define-color is parse-time, so adw-gtk3's accent/surfaces can't be overridden — exact-Fuji GTK3 would need a standalone GTK3 theme)."
|
note = "STATIC defaults + CLI (tanin-libadwaita {dark|light|auto|watch}) for greeter/first-boot. LIVE theming is driven by the taninux app: gui/style.py write_global_theme() regenerates ~/.config/gtk-{4.0,3.0}/gtk(.css)|libadwaita.css from the Appearance settings (dynamic accent + light/dark, surfaces #0f0f0f/#f0f0f0, pills). GTK4/libadwaita = full exact Fuji; GTK3/adw-gtk3 = light/dark + pills only (GTK3 @define-color is parse-time, so adw-gtk3's accent/surfaces can't be overridden — exact-Fuji GTK3 would need a standalone GTK3 theme)."
|
||||||
|
|
||||||
|
[[packages.own]]
|
||||||
|
name = "tanin-icons"
|
||||||
|
desc = "Fuji-accent icon themes — Adwaita overlay, folders recoloured per accent (Tanin-<accent>)"
|
||||||
|
pkgbuild = "packaging/tanin-icons/PKGBUILD" # exists
|
||||||
|
status = "ready (live-verified: GTK resolves folder @48px svg + @16px png to Tanin-<accent>)"
|
||||||
|
note = "5 thin themes inheriting Adwaita; recolor.py HSL-shifts only the blue folder/place ramp to the muted Fuji hue (keeps per-stop lightness) + rasterises 16px so the size-exact inherited blue doesn't win. gui/style.py _set_gsettings now also sets icon-theme=Tanin-<accent_key>, so folders recolour live with the accent. Rebuild after an adwaita-icon-theme bump (reads /usr/share/icons/Adwaita at build). Replaces Papirus (dropped as 'too flat'); papirus-folders presets are saturated and couldn't match the muted Fuji accents."
|
||||||
|
|
||||||
[[packages.own]]
|
[[packages.own]]
|
||||||
name = "tanin-setup"
|
name = "tanin-setup"
|
||||||
desc = "first-run: seed ~/.config (eww+niri) + session target + apply theme + enable follower"
|
desc = "first-run: seed ~/.config (eww+niri) + session target + apply theme + enable follower"
|
||||||
@@ -149,10 +156,30 @@ name = "calamares"
|
|||||||
reason = "GUI installer for the ISO — AUR-only, not in official repos"
|
reason = "GUI installer for the ISO — AUR-only, not in official repos"
|
||||||
status = "in [tanin] (built without sudo — all makedeps were present)"
|
status = "in [tanin] (built without sudo — all makedeps were present)"
|
||||||
|
|
||||||
|
[[packages.rebuilt_aur]]
|
||||||
|
name = "librewolf-bin"
|
||||||
|
reason = "default browser — hard dep of tanin-desktop (AUR-only -bin package)"
|
||||||
|
status = "in [tanin]; SECURITY: rebuild+republish on every LibreWolf release"
|
||||||
|
|
||||||
|
[[packages.rebuilt_aur]]
|
||||||
|
name = "arch-update"
|
||||||
|
reason = "update notifier/helper — hard dep of tanin-desktop"
|
||||||
|
status = "in [tanin]"
|
||||||
|
|
||||||
|
[[packages.rebuilt_aur]]
|
||||||
|
name = "timeshift-autosnap"
|
||||||
|
reason = "auto-snapshot before pacman transactions — hard dep of tanin-desktop (pulls timeshift)"
|
||||||
|
status = "in [tanin]"
|
||||||
|
|
||||||
|
[[packages.rebuilt_aur]]
|
||||||
|
name = "xdg-terminal-exec"
|
||||||
|
reason = "freedesktop terminal-exec resolver — hard dep of tanin-desktop"
|
||||||
|
status = "in [tanin]"
|
||||||
|
|
||||||
[[packages.rebuilt_aur]]
|
[[packages.rebuilt_aur]]
|
||||||
name = "paru (or paru-bin)"
|
name = "paru (or paru-bin)"
|
||||||
reason = "AUR helper — wanted preinstalled on the ISO; must be in [tanin] first"
|
reason = "AUR helper — wanted preinstalled on the ISO; optdepend, not forced"
|
||||||
status = "TODO — not yet rebuilt; ISO packages.x86_64 keeps it commented until then"
|
status = "in [tanin]"
|
||||||
|
|
||||||
# cliphist + cage are in `extra` (verified) — NOT rebuilt, pulled from official repos.
|
# cliphist + cage are in `extra` (verified) — NOT rebuilt, pulled from official repos.
|
||||||
|
|
||||||
@@ -175,7 +202,7 @@ screenshot = ["grim", "slurp"]
|
|||||||
packages = ["flatpak", "pacman-contrib"] # checkupdates, paccache
|
packages = ["flatpak", "pacman-contrib"] # checkupdates, paccache
|
||||||
security = ["polkit"]
|
security = ["polkit"]
|
||||||
fonts = ["inter-font", "ttf-iosevka-nerd"] # verify nerd-font pkg name
|
fonts = ["inter-font", "ttf-iosevka-nerd"] # verify nerd-font pkg name
|
||||||
icons = ["papirus-icon-theme", "adwaita-icon-theme"]
|
icons = ["adwaita-icon-theme"] # base; Fuji-accent folders come from own tanin-icons (inherits Adwaita)
|
||||||
|
|
||||||
[packages.optional]
|
[packages.optional]
|
||||||
# optdepends — installed on demand, never required to boot.
|
# optdepends — installed on demand, never required to boot.
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ OUT="${TANIN_REPO_DIR:-$HOME/projects/tanin-repo}"
|
|||||||
DB="$OUT/tanin.db.tar.zst"
|
DB="$OUT/tanin.db.tar.zst"
|
||||||
mkdir -p "$OUT"
|
mkdir -p "$OUT"
|
||||||
|
|
||||||
OWN_SIMPLE=(tanin-greet tanin-libadwaita tanin-setup tanin-eww tanin-desktop)
|
# tanin-icons builds from the installed Adwaita theme -> needs librsvg + python.
|
||||||
|
OWN_SIMPLE=(tanin-greet tanin-libadwaita tanin-setup tanin-eww tanin-icons tanin-desktop)
|
||||||
OWN_BUILD=(taninux)
|
OWN_BUILD=(taninux)
|
||||||
AUR_REBUILD=(eww-git tiramisu-git waypaper calamares)
|
AUR_REBUILD=(eww-git tiramisu-git waypaper calamares librewolf-bin
|
||||||
|
arch-update timeshift-autosnap xdg-terminal-exec paru)
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
local p="$1"
|
local p="$1"
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ sudo pacman -S --needed --noconfirm python-build python-installer python-hatchli
|
|||||||
( cd "$HERE/taninux" && makepkg -sf --noconfirm ) \
|
( cd "$HERE/taninux" && makepkg -sf --noconfirm ) \
|
||||||
&& cp "$HERE/taninux/"*.pkg.tar.zst "$OUT/" && echo " ok" || echo " FAILED (taninux)"
|
&& cp "$HERE/taninux/"*.pkg.tar.zst "$OUT/" && echo " ok" || echo " FAILED (taninux)"
|
||||||
|
|
||||||
echo "==> AUR rebuilds: eww-git tiramisu-git waypaper calamares"
|
AUR_PKGS="eww-git tiramisu-git waypaper calamares librewolf-bin arch-update timeshift-autosnap xdg-terminal-exec paru"
|
||||||
|
echo "==> AUR rebuilds: $AUR_PKGS"
|
||||||
tmp="$(mktemp -d)"
|
tmp="$(mktemp -d)"
|
||||||
for p in eww-git tiramisu-git waypaper calamares; do
|
for p in $AUR_PKGS; do
|
||||||
echo " -- $p"
|
echo " -- $p"
|
||||||
if git clone --depth=1 "https://aur.archlinux.org/$p.git" "$tmp/$p" >/dev/null 2>&1 \
|
if git clone --depth=1 "https://aur.archlinux.org/$p.git" "$tmp/$p" >/dev/null 2>&1 \
|
||||||
&& ( cd "$tmp/$p" && makepkg -sf --noconfirm ); then
|
&& ( cd "$tmp/$p" && makepkg -sf --noconfirm ); then
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Maintainer: Karim <karim@gabrielevarano.ch>
|
||||||
|
#
|
||||||
|
# tanin-icons — Fuji-accent icon themes. Thin overlays that inherit Adwaita and
|
||||||
|
# recolour only the folder/place icons to each Fuji hue (Ume/Shinkai/Take/
|
||||||
|
# Chikyū/Beni). App-icon coverage stays exactly Adwaita's; only "containers"
|
||||||
|
# (folders, user dirs, network) follow the accent.
|
||||||
|
#
|
||||||
|
# The accent picker (taninux.gui.style) switches the GNOME icon-theme gsetting
|
||||||
|
# to Tanin-<accent>, so folders recolour live when you change the accent.
|
||||||
|
#
|
||||||
|
# Regenerate after an adwaita-icon-theme bump: rebuild this package (it reads
|
||||||
|
# /usr/share/icons/Adwaita at build time).
|
||||||
|
pkgname=tanin-icons
|
||||||
|
pkgver=0.1.0
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc="TANINUX Fuji-accent icon themes — Adwaita with folders recoloured per accent"
|
||||||
|
arch=('any')
|
||||||
|
url="https://taninux.kgva.ch"
|
||||||
|
license=('GPL-3.0-or-later')
|
||||||
|
depends=('adwaita-icon-theme')
|
||||||
|
makedepends=('librsvg' 'python') # rsvg-convert for the 16px raster
|
||||||
|
install=tanin-icons.install
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$startdir"
|
||||||
|
OUT_DIR="$srcdir/out" python recolor.py
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
install -d "$pkgdir/usr/share/icons"
|
||||||
|
cp -r "$srcdir/out/"Tanin-* "$pkgdir/usr/share/icons/"
|
||||||
|
# normalise perms (cp can carry build-user bits)
|
||||||
|
find "$pkgdir/usr/share/icons" -type d -exec chmod 755 {} +
|
||||||
|
find "$pkgdir/usr/share/icons" -type f -exec chmod 644 {} +
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate the Tanin-<accent> icon themes.
|
||||||
|
|
||||||
|
Each theme is a THIN overlay that `Inherits=Adwaita` and recolours only the
|
||||||
|
accent-bearing place/folder icons to a Fuji hue — everything else resolves
|
||||||
|
straight from Adwaita, so app-icon coverage stays exactly Adwaita's.
|
||||||
|
|
||||||
|
Recolour = HSL hue/saturation swap that KEEPS each source stop's lightness:
|
||||||
|
the Adwaita blue ramp (#62a0ea / #438de6 / #a4caee / …) is shifted to the
|
||||||
|
muted Fuji hue while the gradient depth (light front / dark back) is preserved.
|
||||||
|
White emblems (music note, download arrow) are untouched — they are
|
||||||
|
desaturated, so the saturation gate skips them.
|
||||||
|
|
||||||
|
Runs at package build time and reads the installed Adwaita theme. Override the
|
||||||
|
input/output dirs via ADWAITA_DIR / OUT_DIR.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import colorsys
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Fuji accents — keep in sync with taninux.core.theme / taninux.gui.accents.
|
||||||
|
ACCENTS = {
|
||||||
|
"ume": "#8f8aac", # violet
|
||||||
|
"shinkai": "#8a98ac", # blue
|
||||||
|
"take": "#8aac8b", # green
|
||||||
|
"chikyu": "#aca98a", # yellow
|
||||||
|
"beni": "#ac8a8c", # red
|
||||||
|
}
|
||||||
|
|
||||||
|
SRC = Path(os.environ.get("ADWAITA_DIR", "/usr/share/icons/Adwaita"))
|
||||||
|
OUT = Path(os.environ.get("OUT_DIR", "out"))
|
||||||
|
|
||||||
|
# Icons that semantically carry the accent (containers / locations). Anything
|
||||||
|
# not listed here is left to Adwaita via Inherits.
|
||||||
|
PLACES = [
|
||||||
|
"folder", "folder-documents", "folder-download", "folder-drag-accept",
|
||||||
|
"folder-music", "folder-pictures", "folder-publicshare", "folder-remote",
|
||||||
|
"folder-templates", "folder-videos",
|
||||||
|
"user-home", "user-desktop", "user-bookmarks", "network-workgroup",
|
||||||
|
]
|
||||||
|
MIMETYPES = ["inode-directory"] # the folder mimetype — same look as a folder
|
||||||
|
|
||||||
|
HEX = re.compile(r"#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b")
|
||||||
|
|
||||||
|
INDEX = """[Icon Theme]
|
||||||
|
Name=Tanin-{key}
|
||||||
|
Comment=TANINUX Fuji accent ({key}) over Adwaita
|
||||||
|
Inherits=Adwaita,hicolor
|
||||||
|
Directories=scalable/places,scalable/mimetypes,16x16/places
|
||||||
|
|
||||||
|
[scalable/places]
|
||||||
|
Context=Places
|
||||||
|
Size=128
|
||||||
|
MinSize=8
|
||||||
|
MaxSize=512
|
||||||
|
Type=Scalable
|
||||||
|
|
||||||
|
[scalable/mimetypes]
|
||||||
|
Context=MimeTypes
|
||||||
|
Size=128
|
||||||
|
MinSize=8
|
||||||
|
MaxSize=512
|
||||||
|
Type=Scalable
|
||||||
|
|
||||||
|
[16x16/places]
|
||||||
|
Context=Places
|
||||||
|
Size=16
|
||||||
|
Type=Fixed
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def _parse(h: str) -> tuple[float, float, float]:
|
||||||
|
h = h.lstrip("#")
|
||||||
|
if len(h) == 3:
|
||||||
|
h = "".join(c * 2 for c in h)
|
||||||
|
return tuple(int(h[i:i + 2], 16) / 255 for i in (0, 2, 4)) # type: ignore[return-value]
|
||||||
|
|
||||||
|
|
||||||
|
def _fmt(rgb: tuple[float, float, float]) -> str:
|
||||||
|
return "#" + "".join(f"{round(max(0.0, min(1.0, c)) * 255):02x}" for c in rgb)
|
||||||
|
|
||||||
|
|
||||||
|
def _recolour(accent_hex: str):
|
||||||
|
ar, ag, ab = _parse(accent_hex)
|
||||||
|
ah, _al, a_s = colorsys.rgb_to_hls(ar, ag, ab)
|
||||||
|
|
||||||
|
def repl(m: re.Match) -> str:
|
||||||
|
r, g, b = _parse(m.group(0))
|
||||||
|
h, l, s = colorsys.rgb_to_hls(r, g, b)
|
||||||
|
# Only the Adwaita blue family: saturated + blue hue band (~194-230°).
|
||||||
|
if s > 0.12 and 0.54 <= h <= 0.64:
|
||||||
|
return _fmt(colorsys.hls_to_rgb(ah, l, a_s))
|
||||||
|
return m.group(0)
|
||||||
|
|
||||||
|
return repl
|
||||||
|
|
||||||
|
|
||||||
|
def build_theme(key: str, accent_hex: str, rsvg: str) -> int:
|
||||||
|
repl = _recolour(accent_hex)
|
||||||
|
root = OUT / f"Tanin-{key}"
|
||||||
|
root.mkdir(parents=True, exist_ok=True)
|
||||||
|
(root / "index.theme").write_text(INDEX.format(key=key))
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
for ctx, names in (("places", PLACES), ("mimetypes", MIMETYPES)):
|
||||||
|
sdir = root / "scalable" / ctx
|
||||||
|
sdir.mkdir(parents=True, exist_ok=True)
|
||||||
|
for name in names:
|
||||||
|
src = SRC / "scalable" / ctx / f"{name}.svg"
|
||||||
|
if not src.exists():
|
||||||
|
print(f" ! missing in Adwaita: scalable/{ctx}/{name}.svg", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
(sdir / f"{name}.svg").write_text(HEX.sub(repl, src.read_text()))
|
||||||
|
n += 1
|
||||||
|
|
||||||
|
# 16x16 raster: size-exact, else the inherited Adwaita blue PNG wins at 16px.
|
||||||
|
pdir = root / "16x16" / "places"
|
||||||
|
pdir.mkdir(parents=True, exist_ok=True)
|
||||||
|
for name in PLACES:
|
||||||
|
svg = root / "scalable" / "places" / f"{name}.svg"
|
||||||
|
if not svg.exists():
|
||||||
|
continue
|
||||||
|
subprocess.run([rsvg, "-w", "16", "-h", "16", "-o",
|
||||||
|
str(pdir / f"{name}.png"), str(svg)], check=True)
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if not SRC.is_dir():
|
||||||
|
sys.exit(f"Adwaita theme not found at {SRC} (install adwaita-icon-theme)")
|
||||||
|
rsvg = shutil.which("rsvg-convert")
|
||||||
|
if not rsvg:
|
||||||
|
sys.exit("rsvg-convert not found (install librsvg) — needed for 16px folders")
|
||||||
|
# Only ever touch our own Tanin-<key> dirs — OUT may be a shared icon dir
|
||||||
|
# (e.g. ~/.local/share/icons), never rmtree the whole thing.
|
||||||
|
for key, hexv in ACCENTS.items():
|
||||||
|
old = OUT / f"Tanin-{key}"
|
||||||
|
if old.exists():
|
||||||
|
shutil.rmtree(old)
|
||||||
|
n = build_theme(key, hexv, rsvg)
|
||||||
|
print(f"==> Tanin-{key:<8} {hexv} ({n} svg recoloured + 16px raster)")
|
||||||
|
print(f"== {len(ACCENTS)} themes written to {OUT} ==")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Refresh the icon caches so GTK picks up the Tanin-<accent> themes.
|
||||||
|
_themes() {
|
||||||
|
for t in ume shinkai take chikyu beni; do
|
||||||
|
gtk-update-icon-cache -qtf "/usr/share/icons/Tanin-$t" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
post_install() { _themes; }
|
||||||
|
post_upgrade() { _themes; }
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
# Vor Publish: url + license bestätigen, source auf GitHub-Tag setzen.
|
# Vor Publish: url + license bestätigen, source auf GitHub-Tag setzen.
|
||||||
pkgname=taninux
|
pkgname=taninux
|
||||||
pkgver=0.2.0
|
pkgver=0.2.0
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Central Linux management for Arch — GTK System Settings, Software Hub and TUI"
|
pkgdesc="Central Linux management for Arch — GTK System Settings, Software Hub and TUI"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
url="https://taninux.kgva.ch"
|
url="https://taninux.kgva.ch"
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ def list_icon_themes() -> list[str]:
|
|||||||
for t in d.iterdir():
|
for t in d.iterdir():
|
||||||
if t.name in _SKIP_ICONS:
|
if t.name in _SKIP_ICONS:
|
||||||
continue
|
continue
|
||||||
|
# Tanin-<accent> themes are driven by the Fuji accent (style.py),
|
||||||
|
# not picked by hand — a manual pick is overridden on the next
|
||||||
|
# accent change, so keep them out of the picker.
|
||||||
|
if t.name.startswith("Tanin-"):
|
||||||
|
continue
|
||||||
idx = t / "index.theme"
|
idx = t / "index.theme"
|
||||||
if not idx.is_file():
|
if not idx.is_file():
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ def _pins_group() -> Adw.PreferencesGroup:
|
|||||||
_add_row = Adw.ExpanderRow(title="Add app", subtitle="exec · class · icon")
|
_add_row = Adw.ExpanderRow(title="Add app", subtitle="exec · class · icon")
|
||||||
e_exec = Adw.EntryRow(title="Exec (command)")
|
e_exec = Adw.EntryRow(title="Exec (command)")
|
||||||
e_class = Adw.EntryRow(title="Window class (app_id / WM_CLASS)")
|
e_class = Adw.EntryRow(title="Window class (app_id / WM_CLASS)")
|
||||||
e_icon = Adw.EntryRow(title="Icon name (Papirus)")
|
e_icon = Adw.EntryRow(title="Icon name (Adwaita)")
|
||||||
_add_row.add_row(e_exec)
|
_add_row.add_row(e_exec)
|
||||||
_add_row.add_row(e_class)
|
_add_row.add_row(e_class)
|
||||||
_add_row.add_row(e_icon)
|
_add_row.add_row(e_icon)
|
||||||
|
|||||||
@@ -219,6 +219,9 @@ def _set_gsettings(dark: bool, system: bool, accent_key: str) -> None:
|
|||||||
("color-scheme", "default" if system else ("prefer-dark" if dark else "prefer-light")),
|
("color-scheme", "default" if system else ("prefer-dark" if dark else "prefer-light")),
|
||||||
("gtk-theme", "adw-gtk3-dark" if dark else "adw-gtk3"),
|
("gtk-theme", "adw-gtk3-dark" if dark else "adw-gtk3"),
|
||||||
("accent-color", _ACCENT_PRESET.get(accent_key, "purple")),
|
("accent-color", _ACCENT_PRESET.get(accent_key, "purple")),
|
||||||
|
# Fuji-accent folder icons (tanin-icons): Adwaita overlay whose folders
|
||||||
|
# are recoloured to this hue. Switches live with the accent.
|
||||||
|
("icon-theme", f"Tanin-{accent_key}"),
|
||||||
]
|
]
|
||||||
for key, val in pairs:
|
for key, val in pairs:
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user