Add configurable native glass window backgrounds
This commit is contained in:
1 parent
19d949fd13
commit
981991bac0
14 files changed
+687
-5
No files matched your search
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user