Side pills: local AI chat, system monitor, home (clock, Munich weather, iCloud calendar), notifications daemon with popups and history

This commit is contained in:
server2
2026-10-15 12:52:55 +02:00
parent 6399844731
commit bbe184ab97
12 changed files with 3388 additions and 3 deletions
+63
View File
@@ -497,6 +497,68 @@ settings! {
media_check_ms: u64 = 300, 50..=5000; "How often the song is checked for a change, for the island's peek"
}
}
pills {
layout {
gap: f32 = 10.0, 0..=200; "Space between the island's pill and the small pills beside it"
spacing: f32 = 8.0, 0..=100; "Space between the small pills on one side"
icon: f32 = 16.0, 6..=40; "Size of the small pills' icons"
open_ms: u64 = 420, 0..=5000; "How long a small pill takes to open into its card, and to close"
radius: f32 = 22.0, 0..=60; "Corner radius of the opened cards"
pad: f32 = 18.0, 0..=60; "Padding inside the opened cards"
}
ai {
width: f32 = 440.0, 280..=1200; "Width of the AI card"
height: f32 = 520.0, 200..=1200; "Height of the AI card"
server: String = String::from("http://localhost:11434"); "The Ollama server the AI card talks to"
model: String = String::from("gemma4:e4b"); "The Ollama model to chat with, with its tag (ollama list shows them)"
start_service: bool = true; "Start the local ollama service (doas rc-service ollama start) when it isn't answering"
system: String = String::from("You are a helpful assistant inside a Linux desktop shell. Answer briefly and plainly."); "What the model is told before every chat"
}
monitor {
width: f32 = 420.0, 280..=1200; "Width of the system monitor card"
interval_ms: u64 = 1000, 200..=10000; "How often the system monitor reads the system"
history: usize = 60, 10..=600; "How many readings the graphs show"
graph_height: f32 = 34.0, 10..=200; "Height of each graph"
temperatures: usize = 6, 0..=20; "How many temperature sensors to show, hottest first"
terminal: String = String::from("ghostty"); "The terminal that runs the process list"
processes: String = String::from("btm --default_widget_type proc --expanded"); "The process list command, opened on a special workspace"
workspace: String = String::from("processes"); "The special workspace the process list opens on"
}
home {
width: f32 = 460.0, 300..=1200; "Width of the home card"
clock_size: f32 = 64.0, 20..=200; "Size of the big clock"
seconds: bool = false; "Show seconds on the big clock"
avatar: String = String::from("~/.face"); "The picture shown as the user's avatar; a drawn person without one"
city: String = String::from("Munich"); "The weather's place, as shown"
latitude: f32 = 48.137, -90.0..=90.0; "The weather's latitude"
longitude: f32 = 11.575, -180.0..=180.0; "The weather's longitude"
weather_minutes: u64 = 20, 5..=360; "How often the weather is fetched, in minutes"
}
calendar {
server: String = String::from("https://caldav.icloud.com/"); "The CalDAV server; iCloud's by default"
account: String = String::new(); "The Apple ID (or CalDAV user). Sign in from the home card; the app-specific password goes to the keyring, never here"
days: u64 = 14, 1..=90; "How many days ahead the calendar shows events"
sync_minutes: u64 = 15, 1..=360; "How often the calendar is synced, in minutes"
events: usize = 6, 1..=30; "How many upcoming events the home card lists"
}
}
notifications {
popups {
enabled: bool = true; "Show notifications as popups; off is do not disturb (they still go to the history)"
timeout_ms: u64 = 6000, 1000..=60000; "How long a normal notification's popup stays"
low_timeout_ms: u64 = 4000, 1000..=60000; "How long a low-urgency popup stays"
critical_stays: bool = true; "Critical notifications stay until dismissed"
width: f32 = 380.0, 240..=900; "Width of the popups"
count: usize = 4, 1..=10; "How many popups show at once"
icon: f32 = 40.0, 16..=128; "Size of a notification's icon or picture"
}
history {
width: f32 = 420.0, 280..=1200; "Width of the notification card"
height: f32 = 560.0, 200..=1400; "Height of the notification card"
}
}
}
// what config.toml set, by path; a missing or bad setting takes its default
@@ -864,6 +926,7 @@ pub fn modules() -> Vec<&'static str> {
pub fn title(id: &str) -> String {
match id {
"control" => String::from("Control centre"),
"pills" => String::from("Side pills"),
"bar" => String::from("Bar hiding"),
"input-capture" => String::from("Input capture"),
"opengl" => String::from("OpenGL"),