Initial commit — TANINUX (camel): management app + distro packaging
- app: GTK System Settings (tsettings) + Software Hub (thub) + TUI - distro/: camel.toml manifest + MANIFEST.md (Arch + [tanin] repo model) - packaging/: taninux, tanin-desktop (niri metapackage), tanin-greet, tanin-libadwaita, tanin-setup - docs/, data/, LICENSE (GPL-3.0-or-later) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# TANINUX — Verteilung als „Distro"
|
||||
|
||||
Ziel: ein Calamares-Installer, der eine fertige TANINUX-Umgebung aufsetzt.
|
||||
Modell: **eigenes Binär-Repo `[tanin]` nur für eigene Pakete**, alles Standard
|
||||
aus den **offiziellen Arch-Repos** (wie CachyOS/EndeavourOS).
|
||||
|
||||
## Pakete
|
||||
|
||||
| Paket | Repo | Inhalt |
|
||||
|------------------|-------------|-----------------------------------------------------|
|
||||
| `taninux` | `[tanin]` | App: tsettings + thub + TUI, Helper, polkit, .desktop |
|
||||
| `tanin-eww` | `[tanin]` | eww Panel/Dock-Config + Scripts (→ /usr/share) |
|
||||
| `tanin-setup` | `[tanin]` | seedet `~/.config` aus /usr/share + Portal/Session-Fix |
|
||||
| `tanin-desktop` | `[tanin]` | **Metapackage**: depends = eigene + Arch-Pakete |
|
||||
|
||||
`tanin-desktop` zieht per `depends` die Arch-Pakete aus den normalen Repos und
|
||||
die eigenen aus `[tanin]`. AUR bleibt Opt-in → `paru` ist `optdepends`, kein
|
||||
hartes `depends` (Metapackage baut also nichts aus dem AUR).
|
||||
|
||||
## Dotfile-Auslieferung (wichtig)
|
||||
|
||||
AUR/Binär-Pakete dürfen **nicht** nach `/home` schreiben. Daher:
|
||||
1. Default-Configs ins Paket nach `/usr/share/tanin/` (oder `/etc/skel/`).
|
||||
2. `tanin-setup` kopiert sie beim ersten Start nach `~/.config` (idempotent,
|
||||
überschreibt nichts ohne `--force`) und richtet das Session-Portal ein
|
||||
(siehe „Dark Mode / Portal" unten).
|
||||
|
||||
## Phasen
|
||||
|
||||
1. **Fundament** — `packaging/taninux/PKGBUILD` (fertig), LICENSE wählen,
|
||||
`cd packaging/taninux && makepkg -si` lokal testen.
|
||||
2. **Meta + Config** — `tanin-desktop` (Skelett da), `tanin-eww`, `tanin-setup`.
|
||||
3. **Eigenes Repo `[tanin]`**. Hosts:
|
||||
- **Code** → `git.openbureau.ch/karim/taninux` (PKGBUILD-`source`, woher `makepkg` klont)
|
||||
- **Projekt + Repo** → `taninux.kgva.ch` (PKGBUILD-`url`/Homepage **und** pacman-`Server`)
|
||||
|
||||
DB bauen + signieren:
|
||||
```sh
|
||||
repo-add -s tanin.db.tar.zst *.pkg.tar.zst # -s signiert mit Packager-Key
|
||||
```
|
||||
Hosten — zwei Optionen:
|
||||
- **Gitea/Forgejo Arch-Registry** (falls git.openbureau.ch das kann): Pakete
|
||||
pushen, `Server = https://git.openbureau.ch/api/packages/karim/arch/<repo>`.
|
||||
`taninux.kgva.ch` als Reverse-Proxy/Vanity davor.
|
||||
- **Statisches Verzeichnis** hinter `taninux.kgva.ch`: `*.pkg.tar.zst` + `tanin.db`.
|
||||
|
||||
`pacman.conf`-Snippet für User:
|
||||
```ini
|
||||
[tanin]
|
||||
SigLevel = Optional TrustAll # später: Required + Key importieren
|
||||
Server = https://taninux.kgva.ch/$arch
|
||||
```
|
||||
4. **Calamares / ISO** — `archiso`-Profil mit `[tanin]` vorkonfiguriert +
|
||||
Calamares `packages`-Modul, das `tanin-desktop` installiert.
|
||||
|
||||
## Dark Mode / Portal (Session-Fix)
|
||||
|
||||
libadwaita-Apps (Nautilus etc.) lesen Hell/Dunkel über
|
||||
`org.freedesktop.portal.Settings`. Damit das Portal startet, muss die Session
|
||||
`graphical-session.target` aktivieren. `tanin-setup` legt dafür
|
||||
`~/.config/systemd/user/<wm>-session.target` an und ergänzt die Compositor-
|
||||
Autostarts:
|
||||
```sh
|
||||
exec-once = dbus-update-activation-environment --systemd --all
|
||||
exec-once = systemctl --user start <wm>-session.target
|
||||
```
|
||||
|
||||
## Hosts
|
||||
|
||||
- **Code:** `git.openbureau.ch/karim/taninux` (+ Repo für die eww-Config,
|
||||
Absprache mit der eww-Instanz).
|
||||
- **Projekt/Repo:** `taninux.kgva.ch` (Homepage + `[tanin]`-pacman-Server).
|
||||
|
||||
## Offene Voraussetzungen
|
||||
|
||||
- **LICENSE**-Datei ablegen (Vorschlag GPL-3.0-or-later):
|
||||
`curl -L https://www.gnu.org/licenses/gpl-3.0.txt -o LICENSE`.
|
||||
- `taninux.kgva.ch` ans Repo-Hosting hängen (Gitea-Arch-Registry oder statisch).
|
||||
@@ -0,0 +1,122 @@
|
||||
# TANINUX → eww: Akzent-Integration (Handoff)
|
||||
|
||||
**Für die Instanz, die an `~/eww` arbeitet.** Diese Datei ist der Vertrag, wie
|
||||
die eww-Bar ihren Akzent von der TANINUX-Appearance-App bekommt.
|
||||
|
||||
---
|
||||
|
||||
## TL;DR (Kurzanleitung)
|
||||
|
||||
1. **Lies** `~/.local/share/taninux/gui.json`.
|
||||
2. **Nimm** das Feld `accent_hex` (fertiger Hex-String, z. B. `#8aac8b`).
|
||||
3. **Setz** damit deine eww-Akzentvariablen (`$accent`, `$accent-dim`, die
|
||||
`$accent-08/14/22`-Washes) und mach `eww reload`.
|
||||
4. **Reagiere auf Änderungen**: watch die Datei (inotify) — TANINUX schreibt sie
|
||||
bei jedem Akzent-Wechsel neu.
|
||||
|
||||
Das war's. Der Rest hier ist Detail/Begründung.
|
||||
|
||||
---
|
||||
|
||||
## Quelle der Wahrheit
|
||||
|
||||
**Datei:** `~/.local/share/taninux/gui.json`
|
||||
(exakt: `$XDG_DATA_HOME/taninux/gui.json`, Fallback `~/.local/share/...`)
|
||||
|
||||
**Schema:**
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"color_scheme": "dark",
|
||||
"accent": "take",
|
||||
"accent_hex": "#8aac8b",
|
||||
"accent_label": "Take · green"
|
||||
}
|
||||
```
|
||||
|
||||
| Feld | Bedeutung |
|
||||
|----------------|------------------------------------------------------------------|
|
||||
| `accent_hex` | **Das relevante Feld.** Fertiger Hex des gewählten Fuji-Akzents. |
|
||||
| `accent` | interner Key (`ume`/`shinkai`/`take`/`chikyu`/`beni`). |
|
||||
| `accent_label` | menschlicher Name, nur fürs Anzeigen. |
|
||||
| `color_scheme` | `system` / `light` / `dark` — **NICHT für deinen Akzent nötig**, siehe unten. |
|
||||
|
||||
Die Datei existiert erst, nachdem in TANINUX einmal ein Setting geändert wurde.
|
||||
Wenn sie fehlt: Default-Akzent `ume` / `#8f8aac` annehmen.
|
||||
|
||||
---
|
||||
|
||||
## Was du in eww damit machst
|
||||
|
||||
Deine `~/eww/eww.scss` hat oben den Variablenblock. Akzent-relevant sind:
|
||||
|
||||
```scss
|
||||
$accent: #a39ec4; // bright
|
||||
$accent-dim: #8f8aac; // muted ← entspricht direkt accent_hex
|
||||
$accent-08: rgba(163, 158, 196, 0.08);
|
||||
$accent-14: rgba(163, 158, 196, 0.14);
|
||||
$accent-22: rgba(163, 158, 196, 0.22);
|
||||
$acc-l: $accent-dim;
|
||||
```
|
||||
|
||||
`accent_hex` ist der **gedämpfte** Fuji-Ton (= dein bisheriges `$accent-dim`).
|
||||
Mapping-Vorschlag:
|
||||
|
||||
- `$accent-dim` = `accent_hex` (1:1)
|
||||
- `$accent` = `accent_hex` ~18 % Richtung Weiß aufgehellt (bright)
|
||||
- `$accent-08/14/22` = `rgba(R, G, B, 0.08/0.14/0.22)` aus den RGB von `accent_hex`
|
||||
(oder vom bright — wie es bei dir besser aussieht)
|
||||
|
||||
In SCSS kannst du das selbst ableiten, ohne die bright-Werte vorzuberechnen:
|
||||
```scss
|
||||
$accent-dim: #8aac8b; // = accent_hex aus gui.json
|
||||
$accent: lighten($accent-dim, 8%);
|
||||
$accent-08: rgba($accent-dim, 0.08);
|
||||
$accent-14: rgba($accent-dim, 0.14);
|
||||
$accent-22: rgba($accent-dim, 0.22);
|
||||
```
|
||||
Du musst also nur **eine Zeile** (`$accent-dim`) aus `gui.json` regenerieren.
|
||||
|
||||
### Die 5 Fuji-Akzente (falls du sie vorab kennen willst)
|
||||
|
||||
| key | label | accent_hex (dim) | bright (Referenz) |
|
||||
|-----------|------------------|------------------|-------------------|
|
||||
| `ume` | Ume · violet | `#8f8aac` | `#a39ec4` |
|
||||
| `shinkai` | Shinkai · blue | `#8a98ac` | `#9fabbb` |
|
||||
| `take` | Take · green | `#8aac8b` | `#9fbba0` |
|
||||
| `chikyu` | Chikyū · yellow | `#aca98a` | `#bbb89f` |
|
||||
| `beni` | Beni · red | `#ac8a8c` | `#bb9fa1` |
|
||||
|
||||
(Quelle der Hexes: `taninux/core/theme.py` — identisch zur TUI. `ume`-bright
|
||||
entspricht deinem aktuellen `$accent`.)
|
||||
|
||||
---
|
||||
|
||||
## Hell/Dunkel — NICHT dein Akzent-Job
|
||||
|
||||
Das globale Hell/Dunkel läuft über `gsettings org.gnome.desktop.interface
|
||||
color-scheme` (steht auf `prefer-dark`). TANINUX **steuert das nicht über
|
||||
gui.json** und fasst es bewusst nicht an. Dein eww-Hell/Dunkel (`.light`-Klasse +
|
||||
`-l`-Variablen) bleibt **vollständig deine Sache** — TANINUX mischt sich da nicht
|
||||
ein. `color_scheme` in der JSON ist nur informativ; ignorier es für den Akzent.
|
||||
|
||||
---
|
||||
|
||||
## Reload-Trigger — bitte abstimmen
|
||||
|
||||
TANINUX schreibt `gui.json` bei jeder Änderung, ruft aktuell aber **kein
|
||||
`eww reload`** auf. Zwei Optionen, einigt euch auf eine:
|
||||
|
||||
- **(A) eww-Seite watcht** `gui.json` (z. B. `inotifywait` / ein eww-`deflisten`
|
||||
/ kleines Script) und macht selbst `eww reload`. → empfohlen, hält eww autark.
|
||||
- **(B) TANINUX triggert** nach dem Schreiben `eww reload`. Sag Bescheid, dann
|
||||
baue ich das in den Appearance-`persist()` ein (best-effort, nur wenn eww läuft).
|
||||
|
||||
---
|
||||
|
||||
## Grenzen (wichtig)
|
||||
|
||||
- TANINUX fasst `~/eww/**` **nicht** an. Die scss-Verdrahtung machst du.
|
||||
- TANINUX besitzt zusätzlich `~/.config/gtk-4.0/libadwaita.css` (globaler
|
||||
GTK4/libadwaita-Akzent via `@define-color`) — das ist für **GTK-Apps**, nicht
|
||||
für eww. Nicht damit verwechseln; eww liest `gui.json`.
|
||||
@@ -0,0 +1,145 @@
|
||||
# eww ↔ TANINUX — Arbeits- & Koordinationsanleitung (für die TANINUX-Instanz)
|
||||
|
||||
**Lies das, bevor du irgendetwas anfasst, das die Bar/das Dock/eww betrifft.**
|
||||
Es ist die verbindliche Spielregel zwischen dir (TANINUX-Instanz) und der
|
||||
eww-Instanz, die `~/eww` besitzt. Es gibt sonst Chaos — wir hatten es schon.
|
||||
|
||||
---
|
||||
|
||||
## 0. Die EINE Regel
|
||||
|
||||
> **Fass `~/eww/**` nicht direkt an. Steuere Bar/Dock ausschließlich über
|
||||
> Config-Dateien. Lass keinen Porter / Sync / Format-on-save über `~/eww`
|
||||
> laufen.**
|
||||
|
||||
Warum so hart? Während gemeinsamer Arbeit hat *etwas auf deiner Seite*
|
||||
(ein Sway-Porter o.ä.) `eww.yuck`, `eww.scss`, `launch.sh`, `dock.sh` **live
|
||||
umgeschrieben — mitten zwischen Lesen und Schreiben der eww-Instanz.** Folge:
|
||||
jeder Fix (Box-in-Box, Dock-Autohide, Flackern) wurde Sekunden später wieder
|
||||
überschrieben. **Zwei Editoren auf derselben Datei = der einzige Fall, der
|
||||
garantiert kaputtgeht.** Settings laufen über Config-Dateien → du brauchst eww
|
||||
nie hand zu editieren.
|
||||
|
||||
---
|
||||
|
||||
## 1. Wenn du eww trotzdem ändern MUSST (Feature/Layout, kein Setting)
|
||||
|
||||
Es ist EIN Projekt — Code-Arbeit an der Bar ist kein Tabu. Aber:
|
||||
|
||||
1. **Niemals automatisiert** (kein Porter, kein Watcher, der `~/eww/**` schreibt).
|
||||
2. **Einer nach dem anderen.** Sag der eww-Instanz Bescheid bzw. mach es selbst,
|
||||
aber nicht *während* die eww-Instanz dieselbe Datei bearbeitet.
|
||||
3. **eww ist bereits compositor-agnostisch** (siehe §4). **Portiere es nicht auf
|
||||
Sway-only zurück** — das bricht es auf Hyprland und macht genau die Bugs.
|
||||
|
||||
---
|
||||
|
||||
## 2. Die Integrations-Schnittstelle (so steuerst du eww — ohne es anzufassen)
|
||||
|
||||
Drei Config-Dateien + ein Launcher. Detail-Verträge:
|
||||
`eww-accent-integration.md`, `eww-panel-dock-integration.md`, `eww-integration.md`.
|
||||
|
||||
| Thema | Du schreibst | eww zieht nach via |
|
||||
|------------------|------------------------------------------------|-----------------------------------------------------|
|
||||
| **Akzentfarbe** | `~/.local/share/taninux/gui.json` → `accent_hex` (`#rrggbb`) | `scripts/accent.sh watch` → `$accent-dim` in scss, reload |
|
||||
| **Hell/Dunkel** | `gsettings …interface color-scheme` (NICHT die JSON) | `scripts/colorscheme.sh` (defpoll) → `.light`-Klasse |
|
||||
| **Panel & Dock** | `~/.local/share/taninux/panel.json` | `scripts/panelcfg.sh watch` → `eww update` (live) |
|
||||
| **Dock-Pins** | `~/.config/eww/dock-pins` (Zeilen `exec\|class\|icon`) | Poll alle 2 s, automatisch |
|
||||
| **Settings öffnen** | *(Ziel ist deine App)* | Control-Center-Zahnrad → `scripts/settings.sh` → `taninux-gtk` |
|
||||
|
||||
**`panel.json`-Schema** (v1, alles live, kein Reload):
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"dock": { "autohide": true, "icon_size": 42, "hide_delay": 1.2 },
|
||||
"bar": { "clock_format": "%H:%M %A, %d.%m.%Y",
|
||||
"modules": { "music": true, "sys": true, "updates": true,
|
||||
"net": true, "bt": true, "vol": true } }
|
||||
}
|
||||
```
|
||||
- `dock.icon_size`: int 24–64 · `dock.hide_delay`: 0.2–5.0 s · `dock.autohide`: bool
|
||||
- `bar.clock_format`: strftime · `bar.modules`: bool je Modul (`music sys updates net bt vol`)
|
||||
- Anwenden: Datei schreiben → Watcher zieht in ≤2 s nach. Für „sofort":
|
||||
`~/eww/scripts/panelcfg.sh apply`.
|
||||
- **Noch nicht im Schema:** `dock.position`, feste Bar/Dock-Größen (= Reload/
|
||||
Geometrie-Neubau). Wenn du das in der GUI willst → bei der eww-Instanz anfragen,
|
||||
nicht selbst in eww bauen.
|
||||
|
||||
**Grenze:** `gui.json`/`panel.json`/`dock-pins` gehören dir (schreib sie frei).
|
||||
`~/.config/gtk-4.0/libadwaita.css` ist *dein* GTK-App-Akzent — **nicht** für eww.
|
||||
`~/eww/**` gehört der eww-Instanz.
|
||||
|
||||
---
|
||||
|
||||
## 3. Wie ich das in TANINUX einordnen würde (Vorschlag)
|
||||
|
||||
Eine Seite **„Panel & Dock"** in *Personalization*, zwei Gruppen:
|
||||
- **Top bar** — `bar.modules` (Toggles), `bar.clock_format`.
|
||||
- **Dock** — `dock.autohide`, `dock.icon_size` (Slider 24–64),
|
||||
`dock.hide_delay`, gepinnte Apps (liest/schreibt `~/.config/eww/dock-pins`).
|
||||
|
||||
`core/panel.py` = Read/Write `panel.json` (+ `dock-pins`), Apply = Datei
|
||||
schreiben **und optional** `~/eww/scripts/panelcfg.sh apply` feuern. Das ist
|
||||
exakt die Akzent-Kette, nur mit mehr Keys. Du musst die eww-Variablennamen
|
||||
**nicht** kennen.
|
||||
|
||||
---
|
||||
|
||||
## 4. Was in eww schon gebaut & getestet ist (Kontext, nicht ändern)
|
||||
|
||||
- **Compositor-Abstraktion** `~/eww/scripts/wm.sh`: erkennt Hyprland/Sway (`$WM`)
|
||||
und kapselt alle WM-Befehle (`wm_clients/wm_focus/wm_goto_ws/wm_cursor_y/
|
||||
wm_outputs/wm_lock/wm_exit/wm_blur_layer`). **dock.sh, power.sh, ws.sh,
|
||||
workspaces.sh, launch.sh nutzen das.** → eww läuft auf beiden Compositoren.
|
||||
- **Auto-hide ist compositor-aware:** Hyprland = **Cursor-Polling**
|
||||
(`dock.sh watch`, kein GTK-Hover); Sway = **Hover-Trigger** (`dock-trigger`,
|
||||
weil Sway kein cursorpos-IPC hat). `launch.sh` startet automatisch das Richtige.
|
||||
- Akzent (gui.json), Hell/Dunkel (gsettings → Shibui-Weiß), Now-Playing im
|
||||
Control Center, Updates-Panel, Power-Dropdown, Settings-Zahnrad,
|
||||
Multi-Instanz-Rechtsklick, ESC/Klick-daneben-Dismiss — alles vorhanden.
|
||||
|
||||
---
|
||||
|
||||
## 5. NICHT wieder einbauen — die Bugs, die ständig zurückkamen
|
||||
|
||||
Wenn du (oder ein Porter) eww doch anfasst, **reintroduziere diese nicht:**
|
||||
|
||||
1. **Dock „Box-in-Box".** Ursache: ein **Drop-Shadow auf `.dock`**. Auf der
|
||||
halbtransparenten, geblurrten Dock-Ebene blüht er in die Margin und rendert
|
||||
als faler äußerer Kasten (bei opaken Panels passiert das nicht).
|
||||
→ `.dock` darf **nur** `box-shadow: inset 0 1px 0 …` haben, **keinen Drop-Shadow**.
|
||||
Zusätzlich: `window/.background/decoration { background: transparent;
|
||||
box-shadow: none }` und `eventbox { background: transparent }` müssen bleiben.
|
||||
2. **Dock flackert / bleibt offen auf Hyprland.** Ursache: GTK-Hover-Autohide
|
||||
(`eventbox onhover/onhoverlost`). Kindbuttons feuern Enter/Leave (NotifyInferior)
|
||||
→ Dauer-Toggle. → Auf Hyprland **Cursor-Polling** (`dock.sh watch`), NICHT Hover.
|
||||
Genau deshalb ist die Sway-Hover-Variante **nicht** für Hyprland.
|
||||
3. **Hell/Dunkel reagiert nicht.** Ursache: `gsettings monitor`-deflisten stirbt
|
||||
in eww's Spawn-Env. → **defpoll** nutzen. Und: nach so einem Wechsel **vollen
|
||||
eww-Neustart** (`launch.sh`), `eww reload` reicht nicht.
|
||||
4. **Nerd-Font-Glyphen unsichtbar.** `button :text "glyph"` rendert nicht →
|
||||
Glyphe als `label`-Kind im Button.
|
||||
5. **Hyprland-Dispatch ist Lua.** `hyprctl dispatch "hl.dsp.focus({…})"`, nicht die
|
||||
klassische Textsyntax. (In `wm.sh` schon gekapselt.)
|
||||
|
||||
---
|
||||
|
||||
## 6. Offene Sway-Punkte (wenn du DE-light auf swayfx fertigstellst)
|
||||
|
||||
- `swaylock` + `swayidle` installieren (für `power.sh` Lock).
|
||||
- SwayFX-Dock-Blur zuverlässig: `layer_effects "gtk-layer-shell" blur enable` in
|
||||
die Sway-Config (statt nur `wm_blur_layer`-Laufzeitversuch).
|
||||
- eww-Keybinds (ESC-Dismiss, SUPER+A/N Panels) von `hyprland.lua` in die
|
||||
Sway-Config übernehmen.
|
||||
- Dann unter echtem Sway gegentesten — die `$WM=sway`-Zweige sind da, aber bisher
|
||||
nur auf Hyprland verifiziert.
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
1. eww nie automatisiert/parallel editieren. **Kein Porter über `~/eww`.**
|
||||
2. Bar/Dock nur über `gui.json` + `panel.json` + `dock-pins` steuern.
|
||||
3. eww ist schon dual (Hyprland+Sway) — **nicht** auf Sway-only zurückbauen.
|
||||
4. Wenn du eww-Code wirklich brauchst: koordiniert, einer nach dem anderen,
|
||||
und die §5-Bugs nicht wieder reinbauen.
|
||||
@@ -0,0 +1,176 @@
|
||||
# eww ↔ TANINUX — Integrations-Vertrag (Handover)
|
||||
|
||||
**Zweck:** Ab jetzt werden die **eww-Bar** (`~/eww`, symlinked nach `~/.config/eww`)
|
||||
und die **TANINUX-Settings-App** *zusammen gedacht*. Dieses Dokument ist der
|
||||
Vertrag: was über welche Datei fließt, wer was besitzt, und was man beim Ändern
|
||||
der einen Seite auf der anderen beachten muss.
|
||||
|
||||
Gegenstück: `docs/eww-accent-integration.md` (der ursprüngliche Accent-Handoff
|
||||
TANINUX → eww). Dieses Dokument hier ist die **vollständige, gelebte** Sicht.
|
||||
|
||||
---
|
||||
|
||||
## TL;DR — die Schnittstellen
|
||||
|
||||
| # | Thema | Quelle der Wahrheit (TANINUX schreibt) | eww liest / reagiert via |
|
||||
|---|----------------|-----------------------------------------------------|--------------------------------------------------|
|
||||
| 1 | **Akzentfarbe**| `~/.local/share/taninux/gui.json` → `accent_hex` | `~/eww/scripts/accent.sh watch` → setzt `$accent-dim` in `eww.scss`, `eww reload` |
|
||||
| 2 | **Hell/Dunkel**| `gsettings org.gnome.desktop.interface color-scheme`| `~/eww/scripts/colorscheme.sh get` (defpoll 2 s) → `.light`-Klasse an den Panels |
|
||||
| 3 | **Compositor** | *(unabhängig erkannt — keine Datei)* | `~/eww/scripts/wm.sh` erkennt `hyprland`/`sway` selbst |
|
||||
| 4 | **Settings öffnen** | *(App ist das Ziel)* | eww Control-Center-Zahnrad → `~/eww/scripts/settings.sh` → `taninux-gtk` |
|
||||
|
||||
Kurz: **Akzent läuft über die JSON, Hell/Dunkel über gsettings, Compositor
|
||||
erkennt jede Seite selbst.** Diese drei Achsen müssen konsistent bleiben.
|
||||
|
||||
---
|
||||
|
||||
## 1. Akzentfarbe — `gui.json` → eww
|
||||
|
||||
- **TANINUX schreibt** bei jeder Akzent-Änderung `~/.local/share/taninux/gui.json`,
|
||||
Feld `accent_hex` (fertiger Hex, z. B. `#8f8aac`). Schema siehe
|
||||
`eww-accent-integration.md`.
|
||||
- **eww** hat einen Watcher `scripts/accent.sh watch` (gestartet aus
|
||||
`~/eww/launch.sh`), der `gui.json` alle 2 s auf mtime-Änderung pollt und bei
|
||||
Änderung:
|
||||
- `accent_hex` liest (Fallback `#8f8aac`, wenn Datei/Feld fehlt/ungültig),
|
||||
- damit **nur die eine Zeile** `$accent-dim:` in `~/eww/eww.scss` neu schreibt,
|
||||
- `eww reload` auslöst.
|
||||
- In der SCSS leiten sich **alle** Akzent-Werte aus `$accent-dim` ab:
|
||||
```scss
|
||||
$accent-dim: #8f8aac; // = accent_hex (von accent.sh verwaltet)
|
||||
$accent: lighten($accent-dim, 8%);
|
||||
$accent-08: rgba($accent, 0.08);
|
||||
$accent-14: rgba($accent, 0.14);
|
||||
$accent-22: rgba($accent, 0.22);
|
||||
```
|
||||
- **Verifiziert:** Akzent in der App auf z. B. `take`/grün stellen → Bar/Panels/
|
||||
Dock tinten innerhalb ~2 s nach.
|
||||
|
||||
**Wenn TANINUX hier etwas ändert:** Solange `accent_hex` ein `#rrggbb` bleibt,
|
||||
muss eww **nichts** angepasst werden. Neue Akzent-Keys (über die 5 Fuji-Töne
|
||||
hinaus) brauchen nur einen gültigen Hex — eww ist farbagnostisch.
|
||||
|
||||
---
|
||||
|
||||
## 2. Hell/Dunkel — gsettings (NICHT die JSON)
|
||||
|
||||
**Klare Abgrenzung:** Hell/Dunkel läuft **global über
|
||||
`gsettings org.gnome.desktop.interface color-scheme`** (`prefer-dark` /
|
||||
`prefer-light` / `default`). Das `color_scheme`-Feld in `gui.json` ist für eww
|
||||
**nur informativ und wird ignoriert.**
|
||||
|
||||
- **TANINUX** setzt beim Umschalten die gsettings-Keys (`gui/desktop.py`,
|
||||
`gsettings set …`). Das ist der globale Standard und greift für alle GTK-Apps.
|
||||
- **eww** pollt `scripts/colorscheme.sh get` (defpoll, 2 s) → `light`/`dark` und
|
||||
hängt eine `.light`-Klasse an alle Panels/Dock (Bar bleibt immer dunkel).
|
||||
Hell = „Shibui"-Weiß-Palette in `eww.scss` (`$bg-l`, `$fg-l`, …).
|
||||
- **Wichtig (Lesson learned):** Ein `gsettings monitor`-Deflisten **stirbt** in
|
||||
eww's Spawn-Umgebung — deshalb **defpoll**, nicht monitor. Und: ein
|
||||
`deflisten→defpoll`-Wechsel braucht einen **vollen eww-Neustart**
|
||||
(`launch.sh`), ein `eww reload` reicht nicht.
|
||||
|
||||
**Vertrag:** Damit eww dem App-Umschalter folgt, **muss TANINUX die gsettings
|
||||
tatsächlich setzen** (nicht nur `gui.json.color_scheme`). Tut es das nicht,
|
||||
bleibt eww auf dem alten Modus — das ist dann ein TANINUX-Bug, kein eww-Bug.
|
||||
(Beobachtet: einmal stand `gui.json=light`, aber `gsettings=prefer-dark` →
|
||||
eww blieb korrekterweise dunkel.)
|
||||
|
||||
---
|
||||
|
||||
## 3. Compositor-Erkennung — beide Seiten, unabhängig
|
||||
|
||||
Beide Apps müssen auf **Hyprland UND Sway/SwayFX** laufen. Es gibt **keine
|
||||
geteilte Datei** dafür — jede Seite erkennt selbst:
|
||||
|
||||
- **TANINUX:** eigene Compositor-Erkennung (von dir gebaut).
|
||||
- **eww:** `~/eww/scripts/wm.sh` — eine sourcebare Abstraktion. Erkennt über
|
||||
`$HYPRLAND_INSTANCE_SIGNATURE` / `$SWAYSOCK` / `pgrep` und setzt `$WM`.
|
||||
Bietet einheitliche Funktionen, die alle eww-Scripts nutzen:
|
||||
|
||||
| Funktion | Hyprland | Sway / SwayFX |
|
||||
|-----------------------|---------------------------------------|---------------------------------------|
|
||||
| `wm_clients` | `hyprctl clients -j` | `swaymsg -t get_tree` |
|
||||
| `wm_focus <id>` | `hl.dsp.focus({window="address:…"})` | `[con_id=…] focus` |
|
||||
| `wm_goto_ws` / `cycle`| `hl.dsp.focus({workspace=…})` | `workspace number …` |
|
||||
| `wm_cursor_y` | `hyprctl cursorpos` | *(kein Cursor-IPC → Menü zentriert)* |
|
||||
| `wm_outputs` | `hyprctl monitors` | `swaymsg -t get_outputs` |
|
||||
| `wm_lock` / `wm_exit` | `hyprlock` / `hl.dsp.exit()` | `swaylock -f` / `swaymsg exit` |
|
||||
| `wm_blur_layer` | `hyprctl keyword layerrule blur,…` | SwayFX `layer_effects … blur enable` |
|
||||
|
||||
Genutzt von: `dock.sh`, `power.sh`, `ws.sh`, `workspaces.sh`, `launch.sh`.
|
||||
|
||||
**Hyprland-Eigenheit:** Dispatch läuft auf diesem Setup über die **Lua-API**
|
||||
(`hyprctl dispatch "hl.dsp.…()"`), nicht über die klassische Textsyntax.
|
||||
`hl.dsp.focus` springt automatisch auf den Workspace des Fensters.
|
||||
|
||||
**Konsistenz-Regel:** Wenn TANINUX seine Compositor-Erkennung ändert (neue
|
||||
Compositor, andere Detektion), sollte `wm.sh` dieselbe Logik spiegeln, damit
|
||||
beide Apps nie auseinanderlaufen. Idealerweise teilt man sich später *eine*
|
||||
Detektionsquelle — aktuell bewusst getrennt (keine harte Kopplung).
|
||||
|
||||
---
|
||||
|
||||
## 4. eww startet die Settings-App
|
||||
|
||||
Das **Zahnrad oben rechts im Control Center** öffnet die TANINUX-GUI:
|
||||
`~/eww/scripts/settings.sh` → `cd ~/projects/taninux && setsid -f env
|
||||
PYTHONPATH=src /usr/bin/python -m taninux.gui`.
|
||||
|
||||
- **System-Python**, nicht das venv — das venv hat **kein `gi`/PyGObject**
|
||||
(Systempaket). Entry point laut `pyproject.toml`: `taninux-gtk =
|
||||
taninux.gui.app:main`.
|
||||
- Single-Instance über die GTK-App-ID `ch.gabrielevarano.Taninux` → zweiter
|
||||
Klick fokussiert nur.
|
||||
|
||||
**Wenn TANINUX die Startweise ändert** (z. B. richtig installiertes
|
||||
`taninux-gtk` mit `gi` im venv, oder ein `.desktop`/Binary auf dem PATH):
|
||||
`scripts/settings.sh` entsprechend anpassen — am besten auf `taninux-gtk`,
|
||||
sobald es ohne `PYTHONPATH=src`-Hack läuft.
|
||||
|
||||
---
|
||||
|
||||
## Datei- & Besitz-Karte
|
||||
|
||||
| Pfad | Besitzer | Rolle |
|
||||
|----------------------------------------------|-----------|-------|
|
||||
| `~/.local/share/taninux/gui.json` | TANINUX | Akzent (`accent_hex`) — eww liest |
|
||||
| `gsettings …interface color-scheme` | TANINUX | Hell/Dunkel global — eww liest |
|
||||
| `~/.config/gtk-4.0/libadwaita.css` | TANINUX | **GTK-App-Akzent** — *nicht* für eww, nicht anfassen |
|
||||
| `~/eww/**` (yuck, scss, scripts) | **eww** | Bar/Panels/Dock — TANINUX fasst das **nie** an |
|
||||
| `~/eww/scripts/wm.sh` | eww | Compositor-Abstraktion |
|
||||
| `~/eww/scripts/accent.sh` | eww | gui.json → `$accent-dim` |
|
||||
| `~/eww/scripts/colorscheme.sh` | eww | gsettings → light/dark |
|
||||
| `~/eww/scripts/settings.sh` | eww | startet TANINUX-GUI |
|
||||
|
||||
**Goldene Regel:** TANINUX schreibt **nie** in `~/eww/**`; eww schreibt **nie**
|
||||
in TANINUX-Dateien (außer es liest `gui.json` und startet die GUI). Die
|
||||
SCSS-Verdrahtung gehört eww, die Settings-Logik gehört TANINUX.
|
||||
|
||||
---
|
||||
|
||||
## Checkliste beim Ändern
|
||||
|
||||
**TANINUX-Seite ändert Akzent-Format?** → nur prüfen, dass `accent_hex` ein
|
||||
`#rrggbb` bleibt. Sonst nichts.
|
||||
|
||||
**TANINUX-Seite ändert Hell/Dunkel-Mechanik?** → muss weiterhin `gsettings
|
||||
color-scheme` setzen. eww hängt daran.
|
||||
|
||||
**Neuer Compositor unterstützt?** → `wm.sh` um einen `$WM`-Zweig erweitern
|
||||
(dieselben Funktionen implementieren). Sonst läuft die Bar dort nicht.
|
||||
|
||||
**Settings-Startweg ändert sich?** → `~/eww/scripts/settings.sh` anpassen.
|
||||
|
||||
---
|
||||
|
||||
## Status (Stand dieser Übergabe)
|
||||
|
||||
- ✅ Akzent live aus `gui.json` (getestet: ume/violet ↔ take/green).
|
||||
- ✅ Hell/Dunkel live aus gsettings (Shibui-Hell-Palette, Bar bleibt dunkel).
|
||||
- ✅ Compositor-Abstraktion `wm.sh` — auf **Hyprland verifiziert**; Sway-Zweige
|
||||
implementiert (final unter Sway noch gegenzutesten).
|
||||
- ✅ Settings-Zahnrad startet `taninux-gtk` (System-Python).
|
||||
- ⚠️ Für Sway fehlen noch **`swaylock` + `swayidle`** (Pakete installieren).
|
||||
- ⚠️ SwayFX-Blur fürs Dock: `wm_blur_layer` versucht `layer_effects` live;
|
||||
zuverlässiger ist die Regel in der SwayFX-Config (`layer_effects
|
||||
"gtk-layer-shell" blur enable`).
|
||||
@@ -0,0 +1,134 @@
|
||||
# TANINUX → eww: Panel & Dock — Settings-Vertrag (Handover)
|
||||
|
||||
**Für die TANINUX-Instanz, die die „Panel & Dock"-Seite baut.** Analog zur
|
||||
Akzent-Kette: **TANINUX schreibt EINE Config-Datei, eww konsumiert sie.** Die
|
||||
eww-Seite (Variablen, `:style`/`:visible`, Watcher) ist **bereits gebaut** — du
|
||||
brauchst nur die Datei zu schreiben.
|
||||
|
||||
Gegenstücke: `eww-accent-integration.md` (Akzent), `eww-integration.md` (Gesamtvertrag).
|
||||
|
||||
---
|
||||
|
||||
## 1. Wo die Werte liegen
|
||||
|
||||
**Datei:** `~/.local/share/taninux/panel.json`
|
||||
(`$XDG_DATA_HOME/taninux/panel.json`, Fallback `~/.local/share/...`) — JSON,
|
||||
**eine** Datei, neben `gui.json`. Existiert mit Defaults; eww seedet sie zur Not.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"dock": {
|
||||
"autohide": true,
|
||||
"icon_size": 42,
|
||||
"hide_delay": 1.2
|
||||
},
|
||||
"bar": {
|
||||
"clock_format": "%H:%M %A, %d.%m.%Y",
|
||||
"modules": {
|
||||
"music": true, "sys": true, "updates": true,
|
||||
"net": true, "bt": true, "vol": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Die Knöpfe (Keys, Typ, erlaubte Werte)
|
||||
|
||||
| Key | Typ | Werte / Range | Wirkung in eww | Live? |
|
||||
|----------------------|----------------|--------------------------|-------------------------------------------------|-------|
|
||||
| `dock.autohide` | bool | `true` / `false` | `false` = Dock immer sichtbar; `true` = Hover-Trigger | live |
|
||||
| `dock.icon_size` | int | **24 – 64** (px) | Icon-Größe im Dock (`:style min-width/height`) | live |
|
||||
| `dock.hide_delay` | number | **0.2 – 5.0** (Sekunden) | Nachhall, bis das Dock nach Verlassen schließt | next-hide |
|
||||
| `bar.clock_format` | string | strftime (z.B. `%H:%M`) | Format der Uhr in der Bar-Mitte | ≤10 s |
|
||||
| `bar.modules` | object<bool> | Keys: `music sys updates net bt vol` | Welche Rechts-Module die Bar zeigt | live |
|
||||
| `updates.include_aur`| bool | `true`/`false` (Default false) | AUR im Update-Scope (Zähler+Liste). Opt-in, braucht paru | poll |
|
||||
|
||||
- **`updates.include_aur`** (Top-Level-Sektion `updates`): TANINUX-Hub macht AUR
|
||||
zum Opt-in (Default Repo+Flatpak). `scripts/updates.sh` soll diesen Key lesen
|
||||
und nur dann `paru -Qua` mitzählen/-listen. JSON-Schema der Liste bleibt
|
||||
`[{name, old, new}]` (gern + `src`). Beispiel-Lesen:
|
||||
`inc=$(jq -r '.updates.include_aur // false' "$PANEL_JSON")`.
|
||||
- **`bar.modules`** ist ein Objekt `{ "<modul>": true/false }` (nicht Liste) —
|
||||
fehlt ein Key, gilt er als sichtbar. Module: `music` (Now-Playing-Mini),
|
||||
`sys` (CPU/RAM), `updates` (Update-Zähler), `net`, `bt`, `vol`.
|
||||
- Clamping macht eww defensiv (icon_size 24–64, ungültiges → Default). Trotzdem
|
||||
bitte in der GUI validieren (Spin 24–64, Slider 0.2–5.0).
|
||||
|
||||
**Noch nicht im v1 (bewusst):** `dock.position` (left/bottom/right) und feste
|
||||
Größen der Bar/Dock-Fenster. Die brauchen `eww reload` + Geometrie-Neubau
|
||||
(Orientierungswechsel bei bottom). Sag Bescheid, wenn du das willst — dann
|
||||
erweitere ich die eww-Seite und dieses Doc; bis dahin nicht in der GUI anbieten.
|
||||
|
||||
---
|
||||
|
||||
## 3. Wie man anwendet
|
||||
|
||||
Du schreibst `panel.json` — **mehr nicht**. eww zieht nach, auf zwei Wegen:
|
||||
|
||||
1. **Automatisch:** ein Watcher (`scripts/panelcfg.sh watch`, läuft aus
|
||||
`launch.sh`) pollt die Datei alle 2 s und wendet Änderungen an.
|
||||
2. **Sofort (optional, empfohlen für „Apply"):** nach dem Schreiben einmal
|
||||
```
|
||||
~/eww/scripts/panelcfg.sh apply
|
||||
```
|
||||
feuern — dann greift es ohne die 2-s-Latenz. (Best-effort, schadet nie.)
|
||||
|
||||
**Kein `eww reload` nötig** für die v1-Knöpfe. Intern macht `panelcfg.sh`:
|
||||
`eww update cfg-icon-size=… cfg-modules=…`, schaltet Autohide imperativ, und
|
||||
`clock_format`/`hide_delay` werden on-demand gelesen. (Du musst die
|
||||
eww-Variablennamen **nicht** kennen — nur `panel.json` schreiben.)
|
||||
|
||||
---
|
||||
|
||||
## 4. Die Grenze — wer schreibt was
|
||||
|
||||
- **`panel.json` gehört dir (TANINUX).** Schreib es frei. eww liest es nur.
|
||||
- **Gepinnte Dock-Apps** liegen NICHT in `panel.json`, sondern in
|
||||
`~/.config/eww/dock-pins` — eine simple Zeilen-Datei, Format **`exec|class|icon`**:
|
||||
```
|
||||
librewolf|librewolf|librewolf
|
||||
kitty|kitty|kitty
|
||||
code|Code|code-oss
|
||||
```
|
||||
- `exec` = Startbefehl, `class` = Fensterklasse (app_id/WM_CLASS), `icon` =
|
||||
Icon-Name (Papirus). eww spiegelt Änderungen automatisch (Poll alle 2 s).
|
||||
- **Die Zeilen-REIHENFOLGE = die Dock-Reihenfolge.** → **Drag & Drop bitte hier
|
||||
bauen:** Die „Dock"-Gruppe zeigt die gepinnten Apps als ziehbare GTK-Liste;
|
||||
beim Loslassen schreibst du `dock-pins` in der neuen Reihenfolge neu. eww
|
||||
sortiert das Dock in ≤2 s nach. Echtes DnD im eww-Dock selbst geht nicht
|
||||
(eww/GTK3 hat keine Drag-Primitiven) — deshalb gehört das in deine GTK-Seite.
|
||||
(eww bietet zusätzlich „Move up/Move down" im Dock-Rechtsklick als
|
||||
Schnell-Option — die schreibt dieselbe Datei.)
|
||||
- **Du darfst diese Datei direkt lesen UND schreiben** (z.B. die Pin-Liste in
|
||||
der GUI verwalten). eww mutiert sie auch selbst (Dock-Rechtsklick →
|
||||
Pin/Unpin). Zwei-Wege ist ok, weil das Format trivial und idempotent ist —
|
||||
schreib die ganze Datei neu, eww liest sie beim nächsten Poll.
|
||||
- Falls du lieber Befehle feuerst statt zu schreiben:
|
||||
`~/eww/scripts/dock.sh pin <class>` / `unpin <class>`.
|
||||
- **`~/eww/**` (yuck/scss/andere scripts)** ist eww-intern. Für *Settings*
|
||||
brauchst du das nie anzufassen — alles läuft über `panel.json` + `dock-pins`.
|
||||
|
||||
### Darfst du eww trotzdem direkt anfassen?
|
||||
Ja — für *Code/Feature*-Arbeit an der Bar selbst (neue Widgets, Layout) ist es
|
||||
EIN Projekt, kein Tabu. **Einzige harte Regel: nie zwei Editoren gleichzeitig
|
||||
auf derselben Datei** (genau das hat beim Hyprland→Sway-Umbau Chaos gemacht).
|
||||
Für *Settings* aber gilt: über `panel.json` gehen, nicht eww hand-editieren —
|
||||
sonst ist jede GUI-Änderung ein yuck-Edit (brittle + Race-Gefahr).
|
||||
|
||||
---
|
||||
|
||||
## Status (gebaut & getestet)
|
||||
|
||||
- ✅ `panel.json` (Default vorhanden) + `scripts/panelcfg.sh` (apply/watch/get).
|
||||
- ✅ `dock.icon_size` live (24–64, getestet 42↔56), `bar.modules` live,
|
||||
`dock.autohide` imperativ, `bar.clock_format` via `scripts/clock.sh`,
|
||||
`dock.hide_delay` aus der JSON gelesen.
|
||||
- ✅ Watcher in `launch.sh` eingetragen.
|
||||
- ⏳ `dock.position`/Fenstergrößen = Reload-Thema, auf Anfrage.
|
||||
|
||||
Damit kannst du `core/panel.py` (Read/Write `panel.json` + optional `dock-pins`,
|
||||
Apply = Datei schreiben + `panelcfg.sh apply`) und die GTK-Seite „Panel & Dock"
|
||||
(Gruppen *Top bar* / *Dock*) direkt bauen.
|
||||
Reference in New Issue
Block a user