ui+app: Day 5+6 — Settings → Vocabulary panel + Wayland self-relaunch

VOCABULARY PANEL (Day 5):
src/lib/pages/SettingsPage.svelte gains a new collapsible "Vocabulary"
section between Audio and Transcription. Wires the dictionary commands
shipped in 1cce567:
- list_dictionary_command on mount + onfocus refresh
- add_dictionary_entry_command (term + optional note)
- delete_dictionary_entry_command
- Inline error feedback via vocabularyError
- Empty-state copy + per-entry remove button with aria-label

The dictionary terms are intended to be injected into the LLM cleanup
prompt so the model preserves user-specific vocabulary (medication
names, place names, jargon, names of people in the user's support
network — particularly important for the ND audience). The LLM client
itself is currently a stub (crates/ai-formatting/src/llm_client.rs);
when it lands, it can import list_dictionary from kon_storage and
inject terms into the prompt suffix.

WAYLAND SELF-RELAUNCH (Day 6):
src-tauri/src/lib.rs gains ensure_x11_on_wayland() which runs before
tauri::Builder. On Linux Wayland sessions (XDG_SESSION_TYPE=wayland) it
sets GDK_BACKEND=x11, WINIT_UNIX_BACKEND=x11, and
WEBKIT_DISABLE_DMABUF_RENDERER=1 — the env vars HANDOVER.md documents
the user manually prefixing.

Drops the "users have to remember the env-var prefix" friction.
Idempotent: existing values are respected. Inspired by Open-Whispr's
Chromium --ozone-platform=x11 self-relaunch.

Compile-checked: cargo check -p kon-storage clean. Settings.svelte
$state / #if balanced (28 state, 34/34 if/endif).

NEXT: Phase 6 — dogfooding readiness doc with Jake test instructions.
This commit is contained in:
2026-04-17 13:16:07 +01:00
parent 0e22ec591d
commit 9f3be5c007
2 changed files with 162 additions and 0 deletions

View File

@@ -68,8 +68,53 @@ async fn save_preferences(
.map_err(|e| e.to_string())
}
/// On Linux Wayland sessions (KDE, GNOME) WebKitGTK + DMABUF rendering hits
/// known crashes that the HANDOVER documents working around with a manual
/// env-var prefix:
///
/// env GDK_BACKEND=x11 WINIT_UNIX_BACKEND=x11 \
/// WEBKIT_DISABLE_DMABUF_RENDERER=1 npm run tauri dev
///
/// Detect the Wayland session at startup and apply the env vars before
/// anything else loads, so users do not need to remember the prefix and
/// the dev launcher / packaged app both work out of the box.
///
/// Inspired by Open-Whispr's similar Chromium self-relaunch (with
/// --ozone-platform=x11). Day 6 of the upgrade plan.
#[cfg(target_os = "linux")]
fn ensure_x11_on_wayland() {
// If the user explicitly opted in to Wayland (XDG_SESSION_TYPE set by
// their session, KDE / GNOME compositor flags), force WebKitGTK + GDK
// onto X11 via XWayland. Idempotent: if a value is already set, keep
// it (the user knows best).
let session_type = std::env::var("XDG_SESSION_TYPE").unwrap_or_default();
let is_wayland = session_type.eq_ignore_ascii_case("wayland");
if !is_wayland {
return;
}
let set_if_unset = |key: &str, value: &str| {
if std::env::var_os(key).is_none() {
// SAFETY: setting env vars before any threads spawn (we are
// pre-Tauri-Builder here). This block is the only place these
// are written.
unsafe { std::env::set_var(key, value); }
eprintln!("[startup] Wayland workaround: {key}={value}");
}
};
set_if_unset("GDK_BACKEND", "x11");
set_if_unset("WINIT_UNIX_BACKEND", "x11");
set_if_unset("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
// PipeWire screen-capture portal still works fine through XWayland;
// we only redirect the GUI rendering path.
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
#[cfg(target_os = "linux")]
ensure_x11_on_wayland();
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_dialog::init())