9de58d43e8
Trilium-Integration komplett zurückgenommen (Revert von 47951a6): keine
verwaltete Instanz, kein Runtime-Download, kein ETAPI, kein Keyring-Token,
kein Setup-Wizard. Das Archiv sind wieder Markdown-Dateien unter archiveHome
samt FTS5-Suche und Wikilinks.
Notizmodell (an Trilium orientiert, ohne dessen Überbau):
- Jeder Knoten besitzt eine Textdatei — ensure_node_texts legt fehlende beim
Seitenaufbau an (Ordner: gleichnamiges .md daneben, Wurzel: index.md);
Ordner und Zwillingsdatei sind EINE Notiz mit Inhalt und Kindern.
- Der angezeigte Titel steht im Frontmatter der Datei, der Datei-/Ordnername
ist technischer Verwaltungsname; move_folder nimmt den Knotentext mit.
Archiv-Ansicht (wiki-view):
- Baum links: Knoten- und Blatt-Symbole, Führungslinien pro Ebene, Dokumente
näher an der Linie als Ordner; ganze Zeile wählt aus, nur der Pfeil klappt.
- Notiz-Ansicht rechts: großer Titel (Klick bearbeitet ihn → archive_set_title),
Zurück-Knopf mit Auswahl-Verlauf, Details als Popup am Info-Knopf, Kindliste
als abgesetzter Karten-Block mit Anlage-/Änderungsdatum.
- Bearbeiten in place: Split-View aus Rohtext und Live-Vorschau, Speichern per
Knopf oder Ctrl+S (archive_read/archive_write; Frontmatter bleibt).
- Rechte Maustaste im Baum als einziger Aktionsweg (eigenes Kontextmenü,
Standard-Menü des Webviews aus); Anlegen/Umbenennen über modale Dialoge.
Feste Flächenaufteilung statt Ablösen/Andocken:
- Angedocktes Panel = Session-Begleiter (ToDo, Befehle, flüchtiger Entwurf);
der Dokument-Tab ist aus der Leiste raus.
- Archiv-Fenster = Archiv + Suche, Größe und Position einmalig beim Öffnen
aus dem Monitor des rufenden Terminal-Fensters (85 % / 92 %); Öffner-Klick
bei stehendem Fenster fokussiert und schaltet den Tab (panel-mode).
- Terminal-Fenster zu → Archiv-Fenster geht mit.
Neue Commands: archive_read, archive_write, archive_set_title.
127 lines
4.5 KiB
Rust
127 lines
4.5 KiB
Rust
//! Linux: Desktop-Erkennung, Secret-Service-Helper, D-Bus-/SNI-Tray.
|
|
//! Der Klick-Weg unterscheidet sich je Desktop (GNOME-Extension vs.
|
|
//! StatusNotifierItem), das Ergebnis ist überall dasselbe Popup-Fenster.
|
|
|
|
mod cinnamon;
|
|
mod desktop;
|
|
mod gnome;
|
|
mod kwin;
|
|
mod tray_sni;
|
|
|
|
pub(crate) use desktop::{remove_terminal_desktop, sync_all_desktops, write_terminal_desktop};
|
|
|
|
use std::path::Path;
|
|
use std::process::Command;
|
|
|
|
use crate::domain::credentials::APIKEY_SERVICE;
|
|
use crate::domain::pool::APIKEY_FILE;
|
|
use crate::platform::TrayCallbacks;
|
|
|
|
// ---------- Aktivierung / Fokus / Icons ----------
|
|
|
|
/// Linux kennt keine kooperative Aktivierungsabtretung.
|
|
pub(crate) fn yield_activation(_bundle_id: &str) {}
|
|
|
|
/// Fenster ohne NSApplication über die Tauri-API fokussieren.
|
|
pub(crate) fn activate_self(app: &tauri::AppHandle) {
|
|
use tauri::Manager;
|
|
if let Some(window) = app.webview_windows().values().next() {
|
|
window.set_focus().expect("Terminal-Fenster nicht fokussierbar");
|
|
}
|
|
}
|
|
|
|
/// Linux kennt kein Dock-Icon pro Prozess — das Icon kommt über die
|
|
/// .desktop-Datei (StartupWMClass/app_id, siehe desktop.rs).
|
|
pub(crate) fn set_dock_icon(_path: &str) {}
|
|
|
|
/// Fremdprozess-Fokus über die PID steht ohne NSRunningApplication nicht zur
|
|
/// Verfügung.
|
|
pub(crate) fn focus_terminal(_pid: u32) {}
|
|
|
|
/// Wayland-app_id des Prozesses (muss vor dem GTK-Init gesetzt sein) —
|
|
/// darüber ordnen GNOME/dash-to-dock dem Fenster die .desktop-Datei zu.
|
|
pub(crate) fn set_app_id(name: &str) {
|
|
glib::set_prgname(Some(name));
|
|
}
|
|
|
|
pub(crate) fn reveal_path(path: &Path) {
|
|
let target = path.parent().unwrap_or(path);
|
|
let _ = Command::new("xdg-open").arg(target).spawn();
|
|
}
|
|
|
|
/// Selbstinstallation gibt es nur unter macOS — hier installieren deb/rpm.
|
|
pub(crate) fn offer_move_to_applications(_paths: &crate::domain::paths::Paths) {}
|
|
|
|
// ---------- Desktop-Erkennung ----------
|
|
|
|
/// GNOME-Session? (XDG_CURRENT_DESKTOP enthält „GNOME"). Steuert
|
|
/// AppImage-Sperre und Extension-Aktivierung.
|
|
pub(crate) fn is_gnome() -> bool {
|
|
std::env::var("XDG_CURRENT_DESKTOP")
|
|
.map(|d| d.to_uppercase().contains("GNOME"))
|
|
.unwrap_or(false)
|
|
}
|
|
|
|
fn is_kde() -> bool {
|
|
std::env::var("XDG_CURRENT_DESKTOP")
|
|
.map(|d| d.to_uppercase().contains("KDE"))
|
|
.unwrap_or(false)
|
|
}
|
|
|
|
/// Cinnamon meldet sich je nach Session als „X-Cinnamon" oder „Cinnamon".
|
|
fn is_cinnamon() -> bool {
|
|
std::env::var("XDG_CURRENT_DESKTOP")
|
|
.map(|d| d.to_uppercase().contains("CINNAMON"))
|
|
.unwrap_or(false)
|
|
}
|
|
|
|
// ---------- Secrets ----------
|
|
|
|
/// apiKeyHelper-Kommando eines apikey-Pools: liest den Key aus dem Keyring
|
|
/// (dieselben service/username-Attribute, die die keyring-Crate anlegt),
|
|
/// bei fehlendem Eintrag aus der Key-Datei.
|
|
pub(crate) fn apikey_helper_command(dir: &Path, pool_id: &str) -> String {
|
|
format!(
|
|
"secret-tool lookup service {APIKEY_SERVICE} username {pool_id} 2>/dev/null || cat '{}'",
|
|
dir.join(APIKEY_FILE).display()
|
|
)
|
|
}
|
|
|
|
/// claudes OAuth-Credentials liegen unter Linux nicht in einem per
|
|
/// security-CLI prüfbaren Keychain — Status/Reset sind hier nicht verfügbar.
|
|
pub(crate) fn oauth_keychain_exists(_service: &str) -> Result<bool, String> {
|
|
Err("OAuth-Keychain-Status unter Linux nicht verfügbar".into())
|
|
}
|
|
|
|
pub(crate) fn oauth_keychain_delete(_service: &str) -> Result<(), String> {
|
|
Err("OAuth-Keychain-Reset unter Linux nicht verfügbar".into())
|
|
}
|
|
|
|
// ---------- Tray ----------
|
|
|
|
/// Überall dasselbe Ergebnis — Klick aufs Tray-Icon zeigt das Popup, nie ein
|
|
/// Menü. Nur der Weg zum Klick unterscheidet sich: GNOME hat kein Tray, daher
|
|
/// die Shell-Extension (D-Bus-Relay); KDE/XFCE/Cinnamon haben ein
|
|
/// Standard-Tray (StatusNotifierItem), dessen Activate direkt gemeldet wird.
|
|
pub(crate) fn init_tray(app: &tauri::AppHandle, cb: TrayCallbacks) -> Result<(), String> {
|
|
if is_gnome() {
|
|
// Die Extension liegt systemweit (aus dem Paket), aktiviert wird sie pro
|
|
// Benutzer in dconf — das erledigt die im Benutzerkontext laufende App.
|
|
let _ = Command::new("gnome-extensions")
|
|
.args(["enable", "ai-control-popup@local"])
|
|
.status();
|
|
gnome::spawn_dbus_service(app.clone(), cb);
|
|
} else {
|
|
tray_sni::spawn(app.clone(), cb);
|
|
// KDE-Wayland: das Popup-Positionieren übernimmt das KWin-Script.
|
|
if is_kde() {
|
|
kwin::enable_script();
|
|
} else if is_cinnamon() {
|
|
// Wayland-Platzierung + X11-Fokus kommen aus der Cinnamon-Extension;
|
|
// sie liegt systemweit aus dem Paket, aktiviert wird pro Benutzer.
|
|
cinnamon::enable_extension();
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|