Files
VitosUpdater/src-tauri/src/lib.rs
T

147 lines
5.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! VitosUpdater – einheitliche Paketverwaltung für Windows.
pub mod commands;
pub mod error;
pub mod logging;
pub mod managers;
pub mod models;
pub mod process;
pub mod settings;
pub mod updater;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use tauri::{Manager, PhysicalPosition, PhysicalSize, WebviewWindow, WindowEvent};
use settings::WindowState;
/// Letzte normale (nicht maximierte) Geometrie und Zähler für das Entprellen des Speicherns.
struct WindowTracker {
dir: PathBuf,
normal: Mutex<Option<WindowState>>,
generation: AtomicU64,
}
fn restore_window(window: &WebviewWindow, saved: Option<WindowState>) {
if let Some(state) = saved {
let monitors: Vec<(i32, i32, u32, u32)> = window
.available_monitors()
.unwrap_or_default()
.iter()
.map(|m| (m.position().x, m.position().y, m.size().width, m.size().height))
.collect();
if settings::is_visible_on(&state, &monitors) {
let _ = window.set_size(PhysicalSize::new(state.width, state.height));
let _ = window.set_position(PhysicalPosition::new(state.x, state.y));
}
if state.maximized {
let _ = window.maximize();
}
}
let _ = window.show();
}
fn track_window(window: &WebviewWindow, tracker: &Arc<WindowTracker>) {
let maximized = window.is_maximized().unwrap_or(false);
let minimized = window.is_minimized().unwrap_or(false);
if minimized {
return;
}
{
let mut normal = tracker.normal.lock().unwrap_or_else(|e| e.into_inner());
if !maximized {
if let (Ok(pos), Ok(size)) = (window.outer_position(), window.inner_size()) {
*normal = Some(WindowState { x: pos.x, y: pos.y, width: size.width, height: size.height, maximized: false });
}
} else if let Some(state) = normal.as_mut() {
state.maximized = true;
}
}
let generation = tracker.generation.fetch_add(1, Ordering::SeqCst) + 1;
let tracker = Arc::clone(tracker);
tauri::async_runtime::spawn(async move {
tokio::time::sleep(Duration::from_millis(500)).await;
if tracker.generation.load(Ordering::SeqCst) != generation {
return;
}
let snapshot = *tracker.normal.lock().unwrap_or_else(|e| e.into_inner());
if let Some(mut state) = snapshot {
state.maximized = maximized;
if let Err(err) = settings::save_window_state(&tracker.dir, &state) {
tracing::warn!(%err, "Fensterzustand konnte nicht gespeichert werden");
}
}
});
}
/// Startet die Anwendung.
pub fn run() {
let dir = logging::data_dir();
let _guard = logging::init(&dir);
tracing::info!(version = env!("CARGO_PKG_VERSION"), "VitosUpdater startet");
let tracker = Arc::new(WindowTracker {
dir: dir.clone(),
normal: Mutex::new(settings::load_window_state(&dir)),
generation: AtomicU64::new(0),
});
let saved = settings::load_window_state(&dir);
let event_tracker = Arc::clone(&tracker);
let result = tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
if let Some(window) = app.get_webview_window("main") {
let _ = window.unminimize();
let _ = window.show();
let _ = window.set_focus();
}
}))
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.manage(commands::Registry::new())
.manage(updater::UpdaterState::new(dir.clone()))
.invoke_handler(tauri::generate_handler![
commands::detect_managers,
commands::search_packages,
commands::list_installed,
commands::list_updates,
commands::get_package_details,
commands::list_sources,
commands::install_winget_module,
commands::install_app_installer,
updater::updater_ready,
updater::get_updater_status,
updater::get_update_offer,
updater::check_for_update,
updater::snooze_update,
updater::skip_update,
updater::clear_skipped_version,
updater::set_update_interval,
updater::install_update,
updater::take_update_notice,
])
.setup(move |app| {
if let Some(window) = app.get_webview_window("main") {
restore_window(&window, saved);
}
Ok(())
})
.on_window_event(move |window, event| {
if matches!(event, WindowEvent::Moved(_) | WindowEvent::Resized(_)) {
if let Some(webview) = window.app_handle().get_webview_window(window.label()) {
track_window(&webview, &event_tracker);
}
}
})
.run(tauri::generate_context!());
if let Err(err) = result {
tracing::error!(%err, "Anwendung wurde mit einem Fehler beendet");
std::process::exit(1);
}
}