Terminal: Output-Batching (8 ms) + helle Themes, Projekt-Icons in der Liste, neues App-Icon inkl. Tray-Template, build.sh: Dev-Bundle nach .noindex

This commit is contained in:
marcus.hinz
2026-07-05 12:16:16 +02:00
parent 09488ae5ea
commit 23aa315b8f
55 changed files with 282 additions and 6 deletions
+30 -1
View File
@@ -123,17 +123,46 @@ pub fn term_start(
let label = window.label().to_string();
let app = window.app_handle().clone();
// Output gebündelt emittieren statt pro read(): der Reader schiebt Chunks
// in einen Channel, der Emitter sammelt alles, was innerhalb von 8 ms
// ankommt, zu einem Event zusammen. Bei Output-Fluten (Scrollen, TUI-
// Redraws) sinkt die Zahl der IPC-Events um Größenordnungen; die 8 ms
// Zusatzlatenz beim Tasten-Echo liegen unter einem Frame.
let (tx, rx) = std::sync::mpsc::channel::<Vec<u8>>();
std::thread::spawn(move || {
let mut buf = [0u8; 8192];
loop {
match reader.read(&mut buf) {
Ok(0) | Err(_) => break,
Ok(n) => {
let _ = app.emit_to(&label, "pty-output", STANDARD.encode(&buf[..n]));
if tx.send(buf[..n].to_vec()).is_err() {
break;
}
}
}
}
let _ = child.wait();
// tx wird hier gedroppt — der Emitter sieht den geschlossenen Channel
// erst, nachdem er alle Rest-Chunks emittiert hat.
});
std::thread::spawn(move || {
const FLUSH: std::time::Duration = std::time::Duration::from_millis(8);
while let Ok(first) = rx.recv() {
let mut chunk = first;
let deadline = std::time::Instant::now() + FLUSH;
loop {
let now = std::time::Instant::now();
if now >= deadline {
break;
}
match rx.recv_timeout(deadline - now) {
Ok(more) => chunk.extend_from_slice(&more),
Err(_) => break,
}
}
let _ = app.emit_to(&label, "pty-output", STANDARD.encode(&chunk));
}
let _ = app.emit_to(&label, "pty-exit", ());
});