Files
desktop-planer/README.md
2026-09-19 20:59:47 +02:00

5.4 KiB
Raw Blame History

Desktop

GNOME-Shell-Extension (GNOME 46, Ubuntu 24.04): Kalender, Todos und Notizen direkt auf dem Desktop, unter allen Fenstern, über dem Wallpaper.

Bedienung

  • Termin anlegen: in der Wochenansicht auf eine Stunde drücken und bis zur Endstunde ziehen, auch über mehrere Tage. Klick ohne Ziehen = eine Stunde. Ziehen in der Zeile „ganz“ = ganztägig. Oder Rechtsklick auf einen Tag (Monat), eine Stunde (Woche) oder die Tagesfläche: „Termin erstellen“. Popover: Titel, Von und Bis je mit Datum und Uhrzeit. Ohne Ende gilt eine Stunde, ohne Uhrzeit ganztägig.
  • Todo anlegen: Rechtsklick ins Todo-Panel oder in den Kalender, „Todo erstellen“. Text plus Datum und Uhrzeit.
  • Notiz: Rechtsklick irgendwo im Notiz-Panel, „Notiz erstellen“ fragt den Namen und öffnet den Editor. Klick in die Notizfläche bearbeitet. Mit Fokus steht der rohe Markdown-Text, ohne Fokus die formatierte Ansicht. Gespeichert wird alle paar Sekunden und beim Klick woanders hin.
  • Bearbeiten: Linksklick auf Termin, Todo oder Notiz.
  • Rechtsklick auf freie Fläche: Erstellen (Todos, Tagesansicht, Notizbaum im Wurzelordner).
  • Rechtsklick auf Ordner: Notiz oder Unterordner darin erstellen, Umbenennen, Löschen.
  • Rechtsklick auf Eintrag: Umbenennen, Löschen.
  • Popover: Enter speichert, Esc oder Klick daneben bricht ab. Keine Buttons.

Aufbau

  • desktop@marha.de/ – die Extension
    • extension.js – Layout auf dem Arbeitsbereich, Stapelung über Desktop-Icons
    • calendar.js – Monat, Woche (Drag), Tag, Termin-Popover
    • todos.js – Todo-Liste, Todo-Popover
    • notes.js – Ordnerbaum, Markdown-Anzeige, Inline-Editor, Kontextmenü
    • widgets.js – Popover (Grab, Esc, Tab, Klick daneben), Kontextmenü, Datums- und Zeitauswahl
    • markdown.js, dates.js – reine Logik, ohne Shell testbar
    • store.js – Ablage, Tombstones, Übernahme vom Server
    • sync.js – Abgleich mit dem Server (Soup, Timer)
  • backend/ – Sync-Server (FastAPI, SQLite), Dockerfile, docker-compose.yml
  • dev/ – Test-Werkzeuge

Daten

~/.local/share/desktop-app/

  • events.json – Termine
  • todos.json – Todos
  • notes/ – Notizen als .md, Ordner beliebig verschachtelt (Obsidian kann den Ordner öffnen)
  • deleted-notes.json – gelöschte Notizen mit Zeitpunkt, damit der Sync sie auch woanders löscht
  • sync.json – Server-Zugang, siehe Sync
  • sync-state.json – letzter Server-Stand

Gelöschte Termine und Todos bleiben mit deleted: true in der Datei und werden nur ausgeblendet.

Sync

Der Server (backend/, FastAPI + SQLite) hält den Kern. Jedes Gerät gleicht alle paar Sekunden ab: eigene Änderungen hoch, fremde Änderungen runter. Bei Konflikten gewinnt der Eintrag mit dem neueren updated (Notizen: Änderungszeit der Datei, ganze Datei). Offline geht weiter, beim Wiederverbinden wird nachgeliefert. Eine gerade offene Notiz wird nicht von außen überschrieben.

Zugang auf jedem Gerät in ~/.local/share/desktop-app/sync.json:

{"url": "https://planer.marha.de", "token": "<SYNC_TOKEN aus .env>", "interval": 5}

Ohne diese Datei läuft die Extension rein lokal.

Server-API (alle Aufrufe mit Authorization: Bearer <SYNC_TOKEN>):

  • POST /api/sync – {"since": <cursor>, "events": [...], "todos": [...], "notes": [...]}; Antwort: Änderungen seit since plus neuer cursor
  • GET /api/events, /api/todos, /api/notes – aktueller Stand ohne Gelöschte, für andere Anwendungen

Server starten

cp .env.example .env    # SYNC_TOKEN setzen
make dev                # lokal, http://localhost:8040 (anderer Port: make dev PORT=8050)
make prod               # auf dem Server: Docker Compose hinter Traefik, https://planer.marha.de
make stop | make logs | make down
make test               # Server-Tests

Installation

make install   # kopiert die Extension nach ~/.local/share/gnome-shell/extensions und aktiviert sie
make update    # überschreibt eine installierte Extension mit dem Stand aus diesem Ordner

Danach ab- und wieder anmelden. Unter Wayland lädt die Shell neuen Code erst nach einem neuen Login. Voraussetzung: GNOME 46 (Ubuntu 24.04).

Entwicklung

gjs -m dev/tests/run.js        # Unit-Tests für dates.js und markdown.js
dev/restart.sh                 # Test-Shell als Fenster starten (zum Selbst-Ausprobieren)
dev/restart.sh headless        # Test-Shell unsichtbar, für simulierte Eingaben
dev/tests/input.sh             # Ablauf-Tests mit echter Maus und Tastatur (headless)
dev/tests/sync.sh              # Sync-Test: lokaler Server plus headless Shell, beide Richtungen
dev/eval.sh dev/seed.js        # Testdaten einspielen
dev/eval.sh 'js'               # JavaScript in der Test-Shell ausführen (oder Dateipfad)
dev/shot.sh [datei.png]        # Screenshot der Test-Shell
dev/input.sh click X Y         # Maus und Tastatur simulieren (nur headless gefahrlos)
dev/press.sh "Text"            # Button mit diesem Text direkt auslösen
dev/stop.sh                    # Test-Shell beenden

Die Test-Shell läuft mit GSETTINGS_BACKEND=keyfile und eigenem XDG_DATA_HOME unter /tmp/desktop-app-nested/. Die echte Session bleibt unberührt.

Im Fenstermodus (nested, X11-Backend) würden virtuelle Eingabegeräte auf dem echten Desktop landen. Deshalb nutzt dev/input.sh nur den headless Modus (natives Backend). dev/fake-ding.py startet ein Fenster wie Desktop Icons, um die Stapelung zu prüfen.