diff --git a/src/background/modules/start/application.rs b/src/background/modules/start/application.rs index 3e6b4ad6..327041f1 100644 --- a/src/background/modules/start/application.rs +++ b/src/background/modules/start/application.rs @@ -4,18 +4,44 @@ use arc_swap::ArcSwap; use lazy_static::lazy_static; use tauri::{path::BaseDirectory, Manager}; -use crate::{error_handler::Result, seelen::get_app_handle, windows_api::WindowsApi}; +use crate::{ + error_handler::Result, seelen::get_app_handle, utils::constants::SEELEN_COMMON, + windows_api::WindowsApi, +}; use super::domain::StartMenuItem; lazy_static! { - pub static ref START_MENU_ITEMS: ArcSwap> = - ArcSwap::from_pointee(StartMenuManager::get_items().unwrap()); + pub static ref START_MENU_ITEMS: ArcSwap> = ArcSwap::from_pointee({ + let mut manager = StartMenuManager::new(); + manager.init().unwrap(); + manager.list + }); } -pub struct StartMenuManager {} +pub struct StartMenuManager { + list: Vec, + cache_path: PathBuf, +} impl StartMenuManager { + pub fn new() -> StartMenuManager { + StartMenuManager { + list: Vec::new(), + cache_path: SEELEN_COMMON.app_cache_dir().join("start_menu.json"), + } + } + + fn init(&mut self) -> Result<()> { + if self.cache_path.exists() { + self.load_cache()?; + } else { + self.read_start_menu_folders()?; + self.store_cache()?; + } + Ok(()) + } + pub fn common_items_path() -> PathBuf { PathBuf::from(r"C:\ProgramData\Microsoft\Windows\Start Menu\Programs") } @@ -30,6 +56,18 @@ impl StartMenuManager { .expect("Failed to resolve user start menu path") } + pub fn store_cache(&self) -> Result<()> { + let writer = std::fs::File::create(&self.cache_path)?; + serde_json::to_writer(writer, &self.list)?; + Ok(()) + } + + pub fn load_cache(&mut self) -> Result<()> { + let reader = std::fs::File::open(&self.cache_path)?; + self.list = serde_json::from_reader(reader)?; + Ok(()) + } + fn _get_items(dir: &Path) -> Result> { let mut items = Vec::new(); for entry in std::fs::read_dir(dir)?.flatten() { @@ -49,10 +87,11 @@ impl StartMenuManager { Ok(items) } - pub fn get_items() -> Result> { + pub fn read_start_menu_folders(&mut self) -> Result<()> { let mut items = vec![]; items.extend(Self::_get_items(&Self::common_items_path())?); items.extend(Self::_get_items(&Self::user_items_path())?); - Ok(items) + self.list = items; + Ok(()) } } diff --git a/src/background/modules/start/domain.rs b/src/background/modules/start/domain.rs index d7e8df14..a7964148 100644 --- a/src/background/modules/start/domain.rs +++ b/src/background/modules/start/domain.rs @@ -1,6 +1,8 @@ use std::path::PathBuf; -#[derive(Debug, Clone)] +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct StartMenuItem { pub path: PathBuf, pub umid: Option, diff --git a/src/background/restoration_and_migrations/mod.rs b/src/background/restoration_and_migrations/mod.rs index 9e948c4f..56afbe12 100644 --- a/src/background/restoration_and_migrations/mod.rs +++ b/src/background/restoration_and_migrations/mod.rs @@ -37,6 +37,9 @@ impl RestorationAndMigration { std::fs::remove_dir_all(&old_path)?; } + // temporal folder to group artifacts + std::fs::create_dir_all(SEELEN_COMMON.app_temp_dir())?; + let create_if_needed = move |folder: &str| -> Result<()> { let path = data_path.join(folder); if !path.exists() { @@ -44,7 +47,6 @@ impl RestorationAndMigration { } Ok(()) }; - create_if_needed("themes")?; create_if_needed("layouts")?; create_if_needed("placeholders")?; diff --git a/src/background/seelen.rs b/src/background/seelen.rs index a7cc4770..e0caca9f 100644 --- a/src/background/seelen.rs +++ b/src/background/seelen.rs @@ -29,7 +29,7 @@ use crate::{ state::application::{FullState, FULL_STATE}, system::{declare_system_events_handlers, release_system_events_handlers}, trace_lock, - utils::{ahk::AutoHotKey, is_running_as_appx_package, PERFORMANCE_HELPER}, + utils::{ahk::AutoHotKey, is_running_as_appx_package}, windows_api::WindowsApi, APP_HANDLE, }; @@ -175,14 +175,6 @@ impl Seelen { } async fn start_async() -> Result<()> { - if FULL_STATE.load().is_weg_enabled() { - SeelenWeg::enumerate_all_windows()?; - } - - if FULL_STATE.load().is_window_manager_enabled() { - WindowManagerV2::enumerate_all_windows()?; - } - Self::start_ahk_shortcuts()?; Self::refresh_path_environment()?; Self::refresh_auto_start_path().await?; @@ -214,12 +206,19 @@ impl Seelen { MonitorManager::subscribe(Self::on_monitor_event); tauri::async_runtime::spawn(async { - trace_lock!(PERFORMANCE_HELPER).start("lazy setup"); log_error!(Self::start_async().await); - trace_lock!(PERFORMANCE_HELPER).end("lazy setup"); }); self.refresh_windows_positions()?; + + if FULL_STATE.load().is_weg_enabled() { + SeelenWeg::enumerate_all_windows()?; + } + + if FULL_STATE.load().is_window_manager_enabled() { + WindowManagerV2::enumerate_all_windows()?; + } + register_win_hook()?; Ok(()) } diff --git a/src/background/utils/constants.rs b/src/background/utils/constants.rs index f90ff7b4..550086b9 100644 --- a/src/background/utils/constants.rs +++ b/src/background/utils/constants.rs @@ -59,6 +59,12 @@ impl Icons { } pub struct SeelenCommon { + // general + resource_dir: PathBuf, + data_dir: PathBuf, + cache_dir: PathBuf, + temp_dir: PathBuf, + // specifits history: PathBuf, settings: PathBuf, weg_items: PathBuf, @@ -82,15 +88,14 @@ pub struct SeelenCommon { impl SeelenCommon { pub fn new() -> Self { - let handle = get_app_handle(); - let data_dir = handle - .path() - .app_data_dir() - .expect("Failed to get app data dir"); - let resource_dir = handle - .path() - .resource_dir() - .expect("Failed to get resource dir"); + let resolver = get_app_handle().path(); + let data_dir = resolver.app_data_dir().expect("Failed to get app data dir"); + let resource_dir = resolver.resource_dir().expect("Failed to get resource dir"); + let cache_dir = resolver.app_cache_dir().expect("Failed to get cache dir"); + let temp_dir = resolver + .temp_dir() + .expect("Failed to get temp dir") + .join("com.seelen.seelen-ui"); Self { history: data_dir.join("history"), @@ -112,9 +117,30 @@ impl SeelenCommon { wallpapers: data_dir.join("wallpapers"), profiles: data_dir.join("profiles"), bundled_profiles: resource_dir.join("static/profiles"), + // general + data_dir, + resource_dir, + cache_dir, + temp_dir, } } + pub fn app_resource_dir(&self) -> &Path { + &self.resource_dir + } + + pub fn app_data_dir(&self) -> &Path { + &self.data_dir + } + + pub fn app_cache_dir(&self) -> &Path { + &self.cache_dir + } + + pub fn app_temp_dir(&self) -> &Path { + &self.temp_dir + } + pub fn settings_path(&self) -> &Path { &self.settings }