From eac7db529925b324b3a7eee2f0eff2662b7aa629 Mon Sep 17 00:00:00 2001 From: eythaann Date: Wed, 11 Dec 2024 01:23:21 -0500 Subject: [PATCH] fix(settings): cancel and save buttons behaviors --- changelog.md | 6 +- package-lock.json | 8 +- .../modules/ByMonitor/infra/index.tsx | 15 +- .../settings/modules/shared/store/infra.ts | 18 +- .../settings/modules/shared/store/storeApi.ts | 8 +- src/background/exposed.rs | 1 + src/background/modules/cli/application/mod.rs | 11 +- src/background/state/application/events.rs | 12 +- src/background/state/application/mod.rs | 87 +---- src/background/state/application/settings.rs | 48 +++ src/background/state/domain/settings.rs | 369 ------------------ src/background/state/infrastructure.rs | 11 + 12 files changed, 112 insertions(+), 482 deletions(-) create mode 100644 src/background/state/application/settings.rs delete mode 100644 src/background/state/domain/settings.rs diff --git a/changelog.md b/changelog.md index 793185cc..11d23c75 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,10 @@ # Changelog -## [Unreleased] +## [Unreleased] +### fixes +- fix settings `cancel` button not working correctly. +- fix settings `save` button not saving the monitor settings correctly. + ## [2.0.9] ### enhancements - add `XboxGameBarWidgets.exe` to the bundled apps settings list. diff --git a/package-lock.json b/package-lock.json index 777d742a..7ad801cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,7 @@ "react-redux": "^9.1.0", "readable-types": "^4.0.0", "redux": "^5.0.1", - "seelen-core": "npm:@seelen-ui/lib@next", + "seelen-core": "npm:@seelen-ui/lib@^0.1.2-next.20241208094817", "toml": "^3.0.0", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", @@ -9047,9 +9047,9 @@ }, "node_modules/seelen-core": { "name": "@seelen-ui/lib", - "version": "0.1.2-next.20241206064958", - "resolved": "https://registry.npmjs.org/@seelen-ui/lib/-/lib-0.1.2-next.20241206064958.tgz", - "integrity": "sha512-PgJt5EEjMbYlgoB6CfrsVjgyo3awlPmm+vSAzo9dXmBdHBMVEDMxtqGucL6MeIkaei1Td+wjC4LNr8C7PNmbTw==", + "version": "0.1.2-next.20241208094817", + "resolved": "https://registry.npmjs.org/@seelen-ui/lib/-/lib-0.1.2-next.20241208094817.tgz", + "integrity": "sha512-rXAHqT4Ok/m7fvdrCLiTlIU4OK1+HXyL977Bs9wqIv7xTNNF++23ql7teNwLpNboSbDfwm+Yr3nrHJUB9Hk1Jw==", "dev": true, "dependencies": { "@tauri-apps/api": "^2.1.1" diff --git a/src/apps/settings/modules/ByMonitor/infra/index.tsx b/src/apps/settings/modules/ByMonitor/infra/index.tsx index 3f7f0a24..850ea709 100644 --- a/src/apps/settings/modules/ByMonitor/infra/index.tsx +++ b/src/apps/settings/modules/ByMonitor/infra/index.tsx @@ -147,14 +147,14 @@ export function MonitorConfig({ device, config, onChange }: MonitorConfigProps) export function SettingsByMonitor() { const devices = useSelector(newSelectors.connectedMonitors); - const monitors = useSelector(newSelectors.monitorsV2); + const settingsByMonitor = useSelector(newSelectors.monitorsV2); const dispatch = useDispatch(); function onMonitorChange(id: string, monitor: MonitorConfiguration) { dispatch( RootActions.setMonitors({ - ...monitors, + ...settingsByMonitor, [id]: monitor, }), ); @@ -162,17 +162,14 @@ export function SettingsByMonitor() { return ( <> - {Object.entries(monitors).map(([id, monitor]) => { - let device = devices.find((d) => d.id === id); - if (!device) { - return null; - } + {devices.map((device) => { + let monitor = settingsByMonitor[device.id] || new MonitorConfiguration(); return ( ); })} diff --git a/src/apps/settings/modules/shared/store/infra.ts b/src/apps/settings/modules/shared/store/infra.ts index 2950bbeb..65b3111a 100644 --- a/src/apps/settings/modules/shared/store/infra.ts +++ b/src/apps/settings/modules/shared/store/infra.ts @@ -5,7 +5,6 @@ import { cloneDeep } from 'lodash'; import { AppConfiguration, ConnectedMonitorList, - MonitorConfiguration, PluginList, ProfileList, SeelenEvent, @@ -44,16 +43,7 @@ export type store = { // ====================== function setMonitorsOnState(list: ConnectedMonitorList) { - const monitors = list.all(); - store.dispatch(RootActions.setConnectedMonitors(monitors)); - const settingsByMonitor = { ...store.getState().monitorsV2 }; - for (const monitor of monitors) { - if (!settingsByMonitor[monitor.id]) { - settingsByMonitor[monitor.id] = new MonitorConfiguration(); - } - } - console.log({ monitors, settingsByMonitor }); - store.dispatch(RootActions.setMonitorsV2(settingsByMonitor)); + store.dispatch(RootActions.setConnectedMonitors(list.all())); } async function initUIColors() { @@ -122,13 +112,17 @@ export const LoadSettingsToStore = async (customPath?: string) => { const currentState = store.getState(); const newState = StaticSettingsToState(userSettings, currentState); - newState.lastLoaded = cloneDeep(newState); store.dispatch(RootActions.setState(newState)); store.dispatch(RootActions.setPlugins((await PluginList.getAsync()).all())); store.dispatch(RootActions.setWidgets((await WidgetList.getAsync()).all())); store.dispatch(RootActions.setProfiles((await ProfileList.getAsync()).toArray())); setMonitorsOnState(await ConnectedMonitorList.getAsync()); + + const state = { ...store.getState() }; + state.lastLoaded = cloneDeep(state); + state.toBeSaved = false; + store.dispatch(RootActions.setState(state)); }; export const SaveStore = async () => { diff --git a/src/apps/settings/modules/shared/store/storeApi.ts b/src/apps/settings/modules/shared/store/storeApi.ts index 3bfd8878..3d694551 100644 --- a/src/apps/settings/modules/shared/store/storeApi.ts +++ b/src/apps/settings/modules/shared/store/storeApi.ts @@ -7,7 +7,6 @@ import { resolveDataPath } from '../config/infra'; import { dialog, fs } from '../tauri/infra'; import { UserSettings } from '../../../../../shared.interfaces'; -import { VariableConvention } from '../../../../shared/schemas'; export class UserSettingsLoader { private _withUserApps: boolean = false; @@ -86,11 +85,8 @@ export class UserSettingsLoader { } export async function saveJsonSettings(settings: UserSettings['jsonSettings']) { - const json_route = await resolveDataPath('settings.json'); - await fs.writeTextFile( - json_route, - JSON.stringify(VariableConvention.fromCamelToSnake(settings), null, 2), - ); + // TODO add command to SeelenCommand enum list and replace here + await invoke('state_write_settings', { settings }); } export async function saveUserSettings( diff --git a/src/background/exposed.rs b/src/background/exposed.rs index ffe61e71..df3ee044 100644 --- a/src/background/exposed.rs +++ b/src/background/exposed.rs @@ -187,6 +187,7 @@ pub fn register_invoke_handler(app_builder: Builder) -> Builder { state_get_layouts, state_get_weg_items, state_get_settings, + state_write_settings, state_get_specific_apps_configurations, state_get_wallpaper, state_set_wallpaper, diff --git a/src/background/modules/cli/application/mod.rs b/src/background/modules/cli/application/mod.rs index 28687f76..3e5e0a42 100644 --- a/src/background/modules/cli/application/mod.rs +++ b/src/background/modules/cli/application/mod.rs @@ -12,6 +12,7 @@ use parking_lot::Mutex; use windows::Win32::System::Console::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS}; use crate::error_handler::Result; +use crate::modules::cli::domain::Resource; use crate::modules::virtual_desk::{VirtualDesktopManager, VIRTUAL_DESKTOP_MANAGER}; use crate::seelen::{Seelen, SEELEN}; use crate::seelen_bar::FancyToolbar; @@ -173,10 +174,12 @@ pub fn process_uri(uri: &str) -> Result<()> { let engine = base64::engine::general_purpose::URL_SAFE_NO_PAD; let decoded = engine.decode(contents.as_bytes())?; - - let mut state = FULL_STATE.load().cloned(); - state.load_resource(serde_yaml::from_slice(&decoded)?)?; - state.store(); + let resource: Resource = serde_yaml::from_slice(&decoded)?; + FULL_STATE.rcu(|state| { + let mut state = state.cloned(); + let _ = state.load_resource(resource.clone()); + state + }); Ok(()) } diff --git a/src/background/state/application/events.rs b/src/background/state/application/events.rs index 32052283..6a208705 100644 --- a/src/background/state/application/events.rs +++ b/src/background/state/application/events.rs @@ -2,21 +2,11 @@ use itertools::Itertools; use seelen_core::{handlers::SeelenEvent, state::WegItems}; use tauri::Emitter; -use crate::{ - error_handler::Result, - seelen::{get_app_handle, SEELEN}, - trace_lock, -}; +use crate::{error_handler::Result, seelen::get_app_handle, trace_lock}; use super::FullState; impl FullState { - pub(super) fn emit_settings(&self) -> Result<()> { - get_app_handle().emit(SeelenEvent::StateSettingsChanged, self.settings())?; - trace_lock!(SEELEN).on_settings_change()?; - Ok(()) - } - pub fn emit_weg_items(&self, items: &WegItems) -> Result<()> { get_app_handle().emit(SeelenEvent::StateWegItemsChanged, items)?; Ok(()) diff --git a/src/background/state/application/mod.rs b/src/background/state/application/mod.rs index 38ddbc0e..97047758 100644 --- a/src/background/state/application/mod.rs +++ b/src/background/state/application/mod.rs @@ -3,6 +3,7 @@ mod events; mod icons; mod plugins; mod profiles; +mod settings; mod widgets; use arc_swap::ArcSwap; @@ -16,12 +17,11 @@ use notify_debouncer_full::{ }; use parking_lot::Mutex; use seelen_core::state::{ - IconPack, Plugin, PluginId, Profile, VirtualDesktopStrategy, WegItems, Widget, WidgetId, - WindowManagerLayout, + IconPack, Plugin, PluginId, Profile, WegItems, Widget, WidgetId, WindowManagerLayout, }; use std::{ collections::{HashMap, VecDeque}, - fs::{File, OpenOptions}, + fs::OpenOptions, io::{Seek, Write}, path::{Path, PathBuf}, sync::{ @@ -34,7 +34,7 @@ use tauri::Manager; use crate::{ error_handler::Result, log_error, modules::cli::domain::Resource, seelen::get_app_handle, - trace_lock, utils::is_virtual_desktop_supported, windows_api::WindowsApi, + trace_lock, windows_api::WindowsApi, }; use super::domain::{AppConfig, Placeholder, Settings, Theme}; @@ -45,19 +45,8 @@ lazy_static! { log::trace!("Creating new State Manager"); FullState::new().expect("Failed to create State Manager") })); - static ref OPEN_OPTIONS: OpenOptions = { - let mut options = OpenOptions::new(); - options.write(true).create(true); - options - }; - static ref USER_SETTINGS_PATH: PathBuf = DATA_DIR.join("settings.json"); - static ref USER_SETTINGS_FILE: Arc> = Arc::new(Mutex::new( - OPEN_OPTIONS.open(USER_SETTINGS_PATH.as_path()).unwrap() - )); + pub static ref USER_SETTINGS_PATH: PathBuf = DATA_DIR.join("settings.json"); static ref WEG_ITEMS_PATH: PathBuf = DATA_DIR.join("seelenweg_items.yaml"); - static ref WEG_ITEMS_FILE: Arc> = Arc::new(Mutex::new( - OPEN_OPTIONS.open(WEG_ITEMS_PATH.as_path()).unwrap() - )); } static FILE_LISTENER_PAUSED: AtomicBool = AtomicBool::new(false); @@ -112,20 +101,13 @@ impl FullState { Ok(manager) } - /// shorthand of `FullState::clone` on Arc reference + /// Shorthand of `FullState::clone` on Arc reference + /// + /// Intended to be used with `ArcSwap::rcu` to mofify the state pub fn cloned(&self) -> Self { self.clone() } - /// store `self` as the static `FULL_STATE` instance - pub fn store(self) { - FULL_STATE.store(Arc::new(self)); - } - - pub fn store_cloned(&self) { - FULL_STATE.store(Arc::new(self.cloned())); - } - fn process_event(&mut self, event: DebouncedEvent) -> Result<()> { let event = event.event; @@ -152,28 +134,24 @@ impl FullState { if event.paths.contains(&self.icon_packs_folder()) { log::info!("Icons Packs changed"); self.load_icons_packs()?; - self.store_cloned(); self.emit_icon_packs()?; } if event.paths.contains(&WEG_ITEMS_PATH) { log::info!("Weg Items changed"); self.load_weg_items()?; - self.store_cloned(); self.emit_weg_items(&*trace_lock!(self.weg_items))?; } if event.paths.contains(&history_path) { log::info!("History changed"); self.load_history()?; - self.store_cloned(); self.emit_history()?; } if event.paths.contains(&USER_SETTINGS_PATH) { log::info!("Seelen Settings changed"); - self.load_settings()?; - self.store_cloned(); + self.read_settings()?; self.emit_settings()?; } @@ -184,7 +162,6 @@ impl FullState { { log::info!("Theme changed"); self.load_themes()?; - self.store_cloned(); self.emit_themes()?; } @@ -195,7 +172,6 @@ impl FullState { { log::info!("Placeholder changed"); self.load_placeholders()?; - self.store_cloned(); self.emit_placeholders()?; } @@ -206,7 +182,6 @@ impl FullState { { log::info!("Layouts changed"); self.load_layouts()?; - self.store_cloned(); self.emit_layouts()?; } @@ -217,7 +192,6 @@ impl FullState { { log::info!("Specific App Configuration changed"); self.load_settings_by_app()?; - self.store_cloned(); self.emit_settings_by_app()?; } @@ -228,7 +202,6 @@ impl FullState { { log::info!("Plugins changed"); self.load_plugins()?; - self.store_cloned(); self.emit_plugins()?; } @@ -239,7 +212,6 @@ impl FullState { { log::info!("Widgets changed"); self.load_widgets()?; - self.store_cloned(); self.emit_widgets()?; } @@ -255,9 +227,12 @@ impl FullState { Ok(events) => { // log::info!("Seelen UI File Watcher events: {:?}", events); if !FILE_LISTENER_PAUSED.load(Ordering::Acquire) { - let mut state = FULL_STATE.load().cloned(); for event in events { - log_error!(state.process_event(event)); + FULL_STATE.rcu(move |state| { + let mut state = state.cloned(); + log_error!(state.process_event(event.clone())); + state + }); } } } @@ -305,23 +280,6 @@ impl FullState { } } - fn load_settings(&mut self) -> Result<()> { - let path_exists = USER_SETTINGS_PATH.exists(); - if path_exists { - self.settings = Self::get_settings_from_path(&USER_SETTINGS_PATH)?; - self.settings.sanitize(); - } - - if !is_virtual_desktop_supported() { - self.settings.virtual_desktop_strategy = VirtualDesktopStrategy::Seelen; - } - - if !path_exists { - self.save_settings()?; - } - Ok(()) - } - fn load_weg_items(&mut self) -> Result<()> { let mut current = trace_lock!(self.weg_items); if WEG_ITEMS_PATH.exists() { @@ -553,7 +511,7 @@ impl FullState { } fn load_all(&mut self) -> Result<()> { - self.load_settings()?; + self.read_settings()?; self.load_weg_items()?; self.load_themes()?; self.load_icons_packs()?; @@ -567,15 +525,12 @@ impl FullState { Ok(()) } - pub fn save_settings(&self) -> Result<()> { - let mut file = trace_lock!(USER_SETTINGS_FILE); - file.rewind()?; - file.write_all(serde_json::to_string_pretty(&self.settings)?.as_bytes())?; - Ok(()) - } - pub fn save_weg_items(&self, items: &WegItems) -> Result<()> { - let mut file = trace_lock!(WEG_ITEMS_FILE); + let mut file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(WEG_ITEMS_PATH.clone())?; file.rewind()?; file.write_all(serde_yaml::to_string(items)?.as_bytes())?; file.flush()?; @@ -628,7 +583,7 @@ impl FullState { self.settings.window_manager.default_layout = format!("{id}.yml"); } - self.save_settings()?; + self.write_settings()?; Ok(()) } } diff --git a/src/background/state/application/settings.rs b/src/background/state/application/settings.rs new file mode 100644 index 00000000..699ccabf --- /dev/null +++ b/src/background/state/application/settings.rs @@ -0,0 +1,48 @@ +use std::{fs::OpenOptions, io::Write}; + +use seelen_core::{handlers::SeelenEvent, state::VirtualDesktopStrategy}; +use tauri::Emitter; + +use crate::{ + error_handler::Result, + seelen::{get_app_handle, SEELEN}, + trace_lock, + utils::is_virtual_desktop_supported, +}; + +use super::{FullState, USER_SETTINGS_PATH}; + +impl FullState { + pub(super) fn emit_settings(&self) -> Result<()> { + get_app_handle().emit(SeelenEvent::StateSettingsChanged, self.settings())?; + trace_lock!(SEELEN).on_settings_change()?; + Ok(()) + } + + pub(super) fn read_settings(&mut self) -> Result<()> { + let path_exists = USER_SETTINGS_PATH.exists(); + if path_exists { + self.settings = Self::get_settings_from_path(&USER_SETTINGS_PATH)?; + self.settings.sanitize(); + } + if !is_virtual_desktop_supported() { + self.settings.virtual_desktop_strategy = VirtualDesktopStrategy::Seelen; + } + // create settings file + if !path_exists { + self.write_settings()?; + } + Ok(()) + } + + pub fn write_settings(&self) -> Result<()> { + let mut temp_file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(USER_SETTINGS_PATH.as_path())?; + temp_file.write_all(serde_json::to_string_pretty(&self.settings)?.as_bytes())?; + temp_file.flush()?; + Ok(()) + } +} diff --git a/src/background/state/domain/settings.rs b/src/background/state/domain/settings.rs deleted file mode 100644 index 14ef1682..00000000 --- a/src/background/state/domain/settings.rs +++ /dev/null @@ -1,369 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use seelen_core::rect::Rect; - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct Settings { - /// fancy toolbar config - pub fancy_toolbar: FancyToolbarSettings, - /// seelenweg (dock/taskbar) config - pub seelenweg: SeelenWegSettings, - /// window manager config - pub window_manager: WindowManagerSettings, - /// list of monitors - pub monitors: Vec, - /// enable or disable ahk - pub ahk_enabled: bool, - /// ahk variables - pub ahk_variables: AhkVarList, - /// list of selected themes - pub selected_theme: Vec, - /// enable or disable dev tools tab in settings - pub dev_tools: bool, - /// language to use, if null the system locale is used - pub language: Option, -} - -impl Default for Settings { - fn default() -> Self { - Self { - ahk_enabled: true, - selected_theme: vec!["default".to_string()], - language: None, // default language is added in the webview using system locale - monitors: vec![Monitor::default()], - fancy_toolbar: FancyToolbarSettings::default(), - seelenweg: SeelenWegSettings::default(), - window_manager: WindowManagerSettings::default(), - ahk_variables: AhkVarList::default(), - dev_tools: false, - } - } -} - -// ============== Fancy Toolbar Settings ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct FancyToolbarSettings { - /// enable or disable the fancy toolbar - pub enabled: bool, - /// height of the fancy toolbar - pub height: u32, - /// default placeholder for the fancy toolbar - pub placeholder: Option, -} - -impl Default for FancyToolbarSettings { - fn default() -> Self { - Self { - enabled: true, - height: 30, - placeholder: None, - } - } -} - -// ============== SeelenWeg Settings ============== - -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum SeelenWegMode { - #[serde(rename = "Full-Width")] - FullWidth, - #[serde(rename = "Min-Content")] - MinContent, -} - -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum SeelenWegHideMode { - /// never hide - Never, - /// auto-hide always on - Always, - /// auto-hide only if is overlaped by the focused window - #[serde(rename = "On-Overlap")] - OnOverlap, -} - -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum SeelenWegSide { - Left, - Right, - Top, - Bottom, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct SeelenWegSettings { - /// enable or disable the seelenweg - pub enabled: bool, - /// Dock/Taskbar mode - pub mode: SeelenWegMode, - /// When to hide the dock - pub hide_mode: SeelenWegHideMode, - /// Dock position - pub position: SeelenWegSide, - /// enable or disable separators visibility - pub visible_separators: bool, - /// item size in px - pub size: u32, - /// zoomed item size in px - pub zoom_size: u32, - /// Dock/Taskbar margin in px - pub margin: u32, - /// Dock/Taskbar padding in px - pub padding: u32, - /// space between items in px - pub space_between_items: u32, -} - -impl Default for SeelenWegSettings { - fn default() -> Self { - Self { - enabled: true, - mode: SeelenWegMode::MinContent, - hide_mode: SeelenWegHideMode::OnOverlap, - position: SeelenWegSide::Bottom, - visible_separators: true, - size: 40, - zoom_size: 70, - margin: 8, - padding: 8, - space_between_items: 8, - } - } -} - -// ============== Window Manager Settings ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct Border { - pub enabled: bool, - pub width: f64, - pub offset: f64, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct FloatingWindowSettings { - pub width: f64, - pub height: f64, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct WindowManagerSettings { - /// enable or disable the window manager - pub enabled: bool, - /// enable or disable auto stacking by category - pub auto_stacking_by_category: bool, - /// window manager border - pub border: Border, - /// the resize size in % to be used when resizing via cli - pub resize_delta: f64, - /// default gap between containers - pub workspace_gap: f64, - /// default workspace padding - pub workspace_padding: f64, - /// default workspace margin - pub global_work_area_offset: Rect, - /// floating window settings - pub floating: FloatingWindowSettings, - /// default layout - pub default_layout: Option, -} - -impl Default for Border { - fn default() -> Self { - Self { - enabled: true, - width: 3.0, - offset: -1.0, - } - } -} - -impl Default for FloatingWindowSettings { - fn default() -> Self { - Self { - width: 800.0, - height: 500.0, - } - } -} - -impl Default for WindowManagerSettings { - fn default() -> Self { - Self { - enabled: false, - auto_stacking_by_category: true, - border: Border::default(), - resize_delta: 10.0, - workspace_gap: 10.0, - workspace_padding: 10.0, - global_work_area_offset: Rect::default(), - floating: FloatingWindowSettings::default(), - default_layout: None, // added in frontend - } - } -} -// ============== Settings by Monitor ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct Workspace { - pub name: String, - pub layout: String, - pub padding: Option, - pub gap: Option, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct Monitor { - pub workspaces: Vec, - pub work_area_offset: Option, -} - -impl Default for Workspace { - fn default() -> Self { - Self { - name: "New Workspace".to_string(), - layout: "BSP".to_string(), - padding: None, - gap: None, - } - } -} - -impl Default for Monitor { - fn default() -> Self { - Self { - workspaces: vec![Workspace::default()], - work_area_offset: None, - } - } -} - -// ============== Ahk Variables ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct AhkVar { - pub fancy: String, - pub ahk: String, -} - -impl AhkVar { - pub fn new(f: &str, ahk: &str) -> Self { - Self { - fancy: f.to_string(), - ahk: ahk.to_string(), - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct AhkVarList { - pub reserve_top: AhkVar, - pub reserve_bottom: AhkVar, - pub reserve_left: AhkVar, - pub reserve_right: AhkVar, - pub reserve_float: AhkVar, - pub reserve_stack: AhkVar, - pub focus_top: AhkVar, - pub focus_bottom: AhkVar, - pub focus_left: AhkVar, - pub focus_right: AhkVar, - pub focus_latest: AhkVar, - pub increase_width: AhkVar, - pub decrease_width: AhkVar, - pub increase_height: AhkVar, - pub decrease_height: AhkVar, - pub restore_sizes: AhkVar, - pub switch_workspace_0: AhkVar, - pub switch_workspace_1: AhkVar, - pub switch_workspace_2: AhkVar, - pub switch_workspace_3: AhkVar, - pub switch_workspace_4: AhkVar, - pub switch_workspace_5: AhkVar, - pub switch_workspace_6: AhkVar, - pub switch_workspace_7: AhkVar, - pub switch_workspace_8: AhkVar, - pub switch_workspace_9: AhkVar, - pub move_to_workspace_0: AhkVar, - pub move_to_workspace_1: AhkVar, - pub move_to_workspace_2: AhkVar, - pub move_to_workspace_3: AhkVar, - pub move_to_workspace_4: AhkVar, - pub move_to_workspace_5: AhkVar, - pub move_to_workspace_6: AhkVar, - pub move_to_workspace_7: AhkVar, - pub move_to_workspace_8: AhkVar, - pub move_to_workspace_9: AhkVar, - pub send_to_workspace_0: AhkVar, - pub send_to_workspace_1: AhkVar, - pub send_to_workspace_2: AhkVar, - pub send_to_workspace_3: AhkVar, - pub send_to_workspace_4: AhkVar, - pub send_to_workspace_5: AhkVar, - pub send_to_workspace_6: AhkVar, - pub send_to_workspace_7: AhkVar, - pub send_to_workspace_8: AhkVar, - pub send_to_workspace_9: AhkVar, -} - -impl Default for AhkVarList { - fn default() -> Self { - Self { - reserve_top: AhkVar::new("Win + Shift + I", "#+i"), - reserve_bottom: AhkVar::new("Win + Shift + K", "#+k"), - reserve_left: AhkVar::new("Win + Shift + J", "#+j"), - reserve_right: AhkVar::new("Win + Shift + L", "#+l"), - reserve_float: AhkVar::new("Win + Shift + U", "#+u"), - reserve_stack: AhkVar::new("Win + Shift + O", "#+o"), - focus_top: AhkVar::new("Win + Shift + W", "#+w"), - focus_bottom: AhkVar::new("Win + Shift + S", "#+s"), - focus_left: AhkVar::new("Win + Shift + A", "#+a"), - focus_right: AhkVar::new("Win + Shift + D", "#+d"), - focus_latest: AhkVar::new("Win + Shift + E", "#+e"), - increase_width: AhkVar::new("Win + Alt + =", "#!="), - decrease_width: AhkVar::new("Win + Alt + -", "#!-"), - increase_height: AhkVar::new("Win + Shift + =", "#+="), - decrease_height: AhkVar::new("Win + Shift + -", "#+-"), - restore_sizes: AhkVar::new("Win + Alt + 0", "#!0"), - switch_workspace_0: AhkVar::new("Alt + 1", "!1"), - switch_workspace_1: AhkVar::new("Alt + 2", "!2"), - switch_workspace_2: AhkVar::new("Alt + 3", "!3"), - switch_workspace_3: AhkVar::new("Alt + 4", "!4"), - switch_workspace_4: AhkVar::new("Alt + 5", "!5"), - switch_workspace_5: AhkVar::new("Alt + 6", "!6"), - switch_workspace_6: AhkVar::new("Alt + 7", "!7"), - switch_workspace_7: AhkVar::new("Alt + 8", "!8"), - switch_workspace_8: AhkVar::new("Alt + 9", "!9"), - switch_workspace_9: AhkVar::new("Alt + 0", "!0"), - move_to_workspace_0: AhkVar::new("Alt + Shift + 1", "!+1"), - move_to_workspace_1: AhkVar::new("Alt + Shift + 2", "!+2"), - move_to_workspace_2: AhkVar::new("Alt + Shift + 3", "!+3"), - move_to_workspace_3: AhkVar::new("Alt + Shift + 4", "!+4"), - move_to_workspace_4: AhkVar::new("Alt + Shift + 5", "!+5"), - move_to_workspace_5: AhkVar::new("Alt + Shift + 6", "!+6"), - move_to_workspace_6: AhkVar::new("Alt + Shift + 7", "!+7"), - move_to_workspace_7: AhkVar::new("Alt + Shift + 8", "!+8"), - move_to_workspace_8: AhkVar::new("Alt + Shift + 9", "!+9"), - move_to_workspace_9: AhkVar::new("Alt + Shift + 0", "!+0"), - send_to_workspace_0: AhkVar::new("Win + Shift + 1", "#+1"), - send_to_workspace_1: AhkVar::new("Win + Shift + 2", "#+2"), - send_to_workspace_2: AhkVar::new("Win + Shift + 3", "#+3"), - send_to_workspace_3: AhkVar::new("Win + Shift + 4", "#+4"), - send_to_workspace_4: AhkVar::new("Win + Shift + 5", "#+5"), - send_to_workspace_5: AhkVar::new("Win + Shift + 6", "#+6"), - send_to_workspace_6: AhkVar::new("Win + Shift + 7", "#+7"), - send_to_workspace_7: AhkVar::new("Win + Shift + 8", "#+8"), - send_to_workspace_8: AhkVar::new("Win + Shift + 9", "#+9"), - send_to_workspace_9: AhkVar::new("Win + Shift + 0", "#+0"), - } - } -} diff --git a/src/background/state/infrastructure.rs b/src/background/state/infrastructure.rs index 727ae4dd..a18f18ea 100644 --- a/src/background/state/infrastructure.rs +++ b/src/background/state/infrastructure.rs @@ -53,6 +53,17 @@ pub fn state_get_settings(path: Option) -> Result { } } +#[tauri::command(async)] +pub fn state_write_settings(settings: Settings) -> Result<()> { + FULL_STATE.rcu(move |state| { + let mut state = state.cloned(); + state.settings = settings.clone(); + state + }); + FULL_STATE.load().write_settings()?; + Ok(()) +} + #[tauri::command(async)] pub fn state_get_specific_apps_configurations() -> Vec { FULL_STATE