Add configurable native glass window backgrounds

This commit is contained in:
karl committed 2026-10-13 10:12:25 +02:00
1 parent 19d949fd13
commit 981991bac0
14 files changed
+687 -5

No files matched your search

+99
View File
@@ -4,6 +4,7 @@
compile_error!("Release desktop builds require --features custom-protocol to embed the frontend");
mod ai_commands;
mod appearance;
mod data_directory;
mod model_download;
mod semantic_commands;
@@ -32,6 +33,7 @@ use tauri_plugin_global_shortcut::{GlobalShortcutExt, ShortcutState};
use tauri_plugin_opener::OpenerExt;
struct AppState {
appearance: Arc<Mutex<appearance::AppearanceStatus>>,
ai: Arc<AiSession>,
database: PathBuf,
lexical: Arc<Mutex<SearchIndex>>,
@@ -85,6 +87,7 @@ fn measured_outcome(
#[derive(Serialize)]
struct DesktopStatus {
appearance: appearance::AppearanceStatus,
settings: Settings,
indexing: bool,
shortcut_status: String,
@@ -94,6 +97,11 @@ struct DesktopStatus {
#[tauri::command]
fn desktop_status(state: State<'_, AppState>) -> Result<DesktopStatus, String> {
Ok(DesktopStatus {
appearance: state
.appearance
.lock()
.map_err(|_| "Appearance is unavailable.")?
.clone(),
settings: state
.settings
.lock()
@@ -124,6 +132,92 @@ fn set_cpu_threads(threads: usize, state: State<'_, AppState>) -> Result<Setting
Ok(store.value.clone())
}
#[tauri::command]
async fn set_appearance(
material: settings::BackgroundMaterial,
opacity: u8,
high_contrast: bool,
app: tauri::AppHandle,
state: State<'_, AppState>,
) -> Result<appearance::AppearanceStatus, String> {
{
let mut store = state
.settings
.lock()
.map_err(|_| "Settings are unavailable.")?;
let mut next = store.value.clone();
next.background_material = material;
next.background_opacity = opacity;
store.save(next)?;
}
apply_saved_appearance(
app,
state.appearance.clone(),
material,
opacity,
high_contrast,
)
.await
}
#[tauri::command]
async fn apply_appearance(
high_contrast: bool,
app: tauri::AppHandle,
state: State<'_, AppState>,
) -> Result<appearance::AppearanceStatus, String> {
let (material, opacity) = {
let store = state
.settings
.lock()
.map_err(|_| "Settings are unavailable.")?;
(
store.value.background_material,
store.value.background_opacity,
)
};
apply_saved_appearance(
app,
state.appearance.clone(),
material,
opacity,
high_contrast,
)
.await
}
async fn apply_saved_appearance(
app: tauri::AppHandle,
current: Arc<Mutex<appearance::AppearanceStatus>>,
material: settings::BackgroundMaterial,
opacity: u8,
high_contrast: bool,
) -> Result<appearance::AppearanceStatus, String> {
let window = app
.get_webview_window("main")
.ok_or("Main window is unavailable.")?;
let (sender, receiver) = std::sync::mpsc::sync_channel(1);
app.run_on_main_thread(move || {
let status = appearance::apply(&window, material, opacity, high_contrast);
let result = current
.lock()
.map_err(|_| "Appearance is unavailable.".to_string())
.map(|mut current| {
*current = status.clone();
status
});
let _ = sender.send(result);
})
.map_err(|error| error.to_string())?;
tauri::async_runtime::spawn_blocking(move || {
receiver
.recv_timeout(std::time::Duration::from_secs(5))
.map_err(|_| "Appearance update was cancelled.".to_string())?
})
.await
.map_err(|error| error.to_string())?
}
#[derive(Default, Deserialize)]
struct Filters {
#[serde(default)]
@@ -557,7 +651,10 @@ fn main() {
Err(error) => format!("Global shortcut unavailable: {error}"),
}
};
let window = app.get_webview_window("main").ok_or_else(|| std::io::Error::other("Main window is unavailable."))?;
let appearance = appearance::apply(&window, settings.value.background_material, settings.value.background_opacity, false);
app.manage(AppState {
appearance: Arc::new(Mutex::new(appearance)),
ai: Arc::new(AiSession::default()),
database,
lexical,
@@ -582,6 +679,8 @@ fn main() {
prepare_media_preview,
desktop_status,
set_cpu_threads,
set_appearance,
apply_appearance,
semantic_status,
setup_model,
index_embeddings,