settings saving

This commit is contained in:
galister
2026-01-08 03:21:33 +09:00
parent 5f4ab341fe
commit 150e6c4e40
8 changed files with 113 additions and 33 deletions

View File

@@ -1,4 +1,4 @@
use std::{collections::HashMap, marker::PhantomData, os::unix::process::CommandExt, process::Command, rc::Rc};
use std::{collections::HashMap, marker::PhantomData, rc::Rc};
use strum::AsRefStr;
use wgui::{

View File

@@ -181,5 +181,5 @@ impl DashInterface<()> for DashInterfaceEmulated {
fn config_changed(&mut self, _: &mut ()) {}
fn restart(&mut self, data: &mut ()) {}
fn restart(&mut self, _data: &mut ()) {}
}

View File

@@ -28,7 +28,7 @@ use crate::{
},
task::{OpenVrTask, OverlayTask, TaskType},
},
config::save_state,
config::{save_settings, save_state},
graphics::{GpuFutures, init_openvr_graphics},
overlays::{
toast::Toast,
@@ -337,6 +337,10 @@ pub fn openvr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
if let Err(e) = save_state(&app.session.config) {
log::error!("Could not save state: {e:?}");
}
if app.session.config_dirty {
save_settings(&app.session.config)?;
app.session.config_dirty = false;
}
log::warn!("OpenVR shutdown");
// context.shutdown() called by Drop

View File

@@ -21,7 +21,7 @@ use crate::{
openxr::{lines::LinePool, overlay::OpenXrOverlayData},
task::{OverlayTask, TaskType},
},
config::save_state,
config::{save_settings, save_state},
graphics::{GpuFutures, init_openxr_graphics},
overlays::{
toast::Toast,
@@ -513,6 +513,10 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
if let Err(e) = save_state(&app.session.config) {
log::error!("Could not save state: {e:?}");
}
if app.session.config_dirty {
save_settings(&app.session.config)?;
app.session.config_dirty = false;
}
Ok(())
}

View File

@@ -105,12 +105,39 @@ pub fn load_general_config() -> GeneralConfig {
#[derive(Serialize)]
pub struct AutoSettings {
pub watch_view_angle_min: f32,
pub watch_view_angle_max: f32,
pub animation_speed: f32,
pub round_multiplier: f32,
pub click_freeze_time_ms: i32,
pub invert_scroll_direction_x: bool,
pub invert_scroll_direction_y: bool,
pub scroll_speed: f32,
pub long_press_duration: f32,
pub notifications_enabled: bool,
pub notifications_sound_enabled: bool,
pub keyboard_sound_enabled: bool,
pub upright_screen_fix: bool,
pub double_cursor_fix: bool,
pub sets_on_watch: bool,
pub hide_grab_help: bool,
pub xr_click_sensitivity: f32,
pub xr_click_sensitivity_release: f32,
pub allow_sliding: bool,
pub focus_follows_mouse_mode: bool,
pub left_handed_mouse: bool,
pub block_game_input: bool,
pub block_game_input_ignore_watch: bool,
pub space_drag_multiplier: f32,
pub use_skybox: bool,
pub use_passthrough: bool,
pub screen_render_down: bool,
pub pointer_lerp_factor: f32,
pub space_drag_unlocked: bool,
pub space_rotate_unlocked: bool,
pub clock_12h: bool,
pub hide_username: bool,
pub opaque_background: bool,
pub xwayland_by_default: bool,
pub context_menu_hold_and_release: bool,
}
fn get_settings_path() -> PathBuf {
@@ -121,17 +148,45 @@ fn get_settings_path() -> PathBuf {
pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
let conf = AutoSettings {
watch_view_angle_min: config.watch_view_angle_min,
watch_view_angle_max: config.watch_view_angle_max,
animation_speed: config.animation_speed,
round_multiplier: config.round_multiplier,
click_freeze_time_ms: config.click_freeze_time_ms,
invert_scroll_direction_x: config.invert_scroll_direction_x,
invert_scroll_direction_y: config.invert_scroll_direction_y,
scroll_speed: config.scroll_speed,
long_press_duration: config.long_press_duration,
notifications_enabled: config.notifications_enabled,
notifications_sound_enabled: config.notifications_sound_enabled,
keyboard_sound_enabled: config.keyboard_sound_enabled,
upright_screen_fix: config.upright_screen_fix,
double_cursor_fix: config.double_cursor_fix,
sets_on_watch: config.sets_on_watch,
hide_grab_help: config.hide_grab_help,
xr_click_sensitivity: config.xr_click_sensitivity,
xr_click_sensitivity_release: config.xr_click_sensitivity_release,
allow_sliding: config.allow_sliding,
focus_follows_mouse_mode: config.focus_follows_mouse_mode,
left_handed_mouse: config.left_handed_mouse,
block_game_input: config.block_game_input,
block_game_input_ignore_watch: config.block_game_input_ignore_watch,
space_drag_multiplier: config.space_drag_multiplier,
use_skybox: config.use_skybox,
use_passthrough: config.use_passthrough,
screen_render_down: config.screen_render_down,
pointer_lerp_factor: config.pointer_lerp_factor,
space_drag_unlocked: config.space_drag_unlocked,
space_rotate_unlocked: config.space_rotate_unlocked,
clock_12h: config.clock_12h,
hide_username: config.hide_username,
opaque_background: config.opaque_background,
xwayland_by_default: config.xwayland_by_default,
context_menu_hold_and_release: config.context_menu_hold_and_release,
};
let json = serde_json::to_string_pretty(&conf).unwrap(); // want panic
std::fs::write(get_settings_path(), json)?;
log::info!("Saved settings.");
Ok(())
}

View File

@@ -34,6 +34,7 @@ use crate::{
window::WindowHandle,
},
},
config::save_settings,
ipc::ipc_server::{gen_args_vec, gen_env_vec},
state::AppState,
subsystem::hid::WheelDelta,
@@ -125,7 +126,12 @@ impl OverlayBackend for DashFrontend {
Ok(())
}
fn pause(&mut self, _app: &mut AppState) -> anyhow::Result<()> {
fn pause(&mut self, app: &mut AppState) -> anyhow::Result<()> {
if app.session.config_dirty {
save_settings(&app.session.config)?;
app.session.config_dirty = false;
}
Ok(())
}
@@ -418,6 +424,7 @@ impl DashInterface<AppState> for DashInterfaceLive {
}
fn config_changed(&mut self, data: &mut AppState) {
data.session.config_dirty = true;
data.tasks
.enqueue(TaskType::Overlay(OverlayTask::SettingsChanged));
}

View File

@@ -54,9 +54,6 @@ struct WatchState {
clock_12h: bool,
}
#[allow(clippy::significant_drop_tightening)]
#[allow(clippy::too_many_lines)]
#[allow(clippy::cognitive_complexity)]
pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
let state = WatchState {
clock_12h: app.session.config.clock_12h,
@@ -67,6 +64,10 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
let mut panel =
GuiPanel::new_from_template(app, watch_xml, state, NewGuiPanelParams::default())?;
let mut alterables = EventAlterables::default();
sets_or_overlays(&panel, app, &mut alterables);
panel.layout.process_alterables(alterables)?;
let doc_params = ParseDocumentParams {
globals: panel.layout.state.globals.clone(),
path: AssetPath::FileOrBuiltIn(watch_xml),
@@ -115,27 +116,7 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
}
OverlayEventData::SettingsChanged => {
panel.layout.mark_redraw();
let display = if app.session.config.sets_on_watch {
[taffy::Display::None, taffy::Display::Flex]
} else {
[taffy::Display::Flex, taffy::Display::None]
};
let widget = [
panel
.parser_state
.get_widget_id("panels_root")
.unwrap_or_default(),
panel
.parser_state
.get_widget_id("sets_root")
.unwrap_or_default(),
];
for i in 0..2 {
alterables.set_style(widget[i], StyleSetRequest::Display(display[i]));
}
sets_or_overlays(panel, app, &mut alterables);
if app.session.config.clock_12h != panel.state.clock_12h {
panel.state.clock_12h = app.session.config.clock_12h;
@@ -196,6 +177,33 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
})
}
fn sets_or_overlays(
panel: &GuiPanel<WatchState>,
app: &mut AppState,
alterables: &mut EventAlterables,
) {
let display = if app.session.config.sets_on_watch {
[taffy::Display::None, taffy::Display::Flex]
} else {
[taffy::Display::Flex, taffy::Display::None]
};
let widget = [
panel
.parser_state
.get_widget_id("panels_root")
.unwrap_or_default(),
panel
.parser_state
.get_widget_id("sets_root")
.unwrap_or_default(),
];
for i in 0..2 {
alterables.set_style(widget[i], StyleSetRequest::Display(display[i]));
}
}
pub fn watch_fade<D>(app: &mut AppState, watch: &mut OverlayWindowData<D>) {
let Some(state) = watch.config.active_state.as_mut() else {
return;

View File

@@ -178,6 +178,7 @@ impl AppState {
pub struct AppSession {
pub config: GeneralConfig,
pub config_dirty: bool,
#[cfg(feature = "wayvr")]
pub wayvr_config: WayVRConfig, // TODO: rename to "wayland_server_config"
@@ -209,6 +210,7 @@ impl AppSession {
#[cfg(feature = "wayvr")]
wayvr_config,
toast_topics,
config_dirty: false,
}
}
}