config_io: Support wayvr.conf.d directory, refactoring (#139)
This commit is contained in:
@@ -13,7 +13,7 @@ use ovr_overlay::{
|
||||
|
||||
use crate::{
|
||||
backend::input::{Haptics, TrackedDevice, TrackedDeviceRole},
|
||||
config_io::CONFIG_ROOT_PATH,
|
||||
config_io,
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
@@ -325,7 +325,7 @@ fn get_tracked_device(
|
||||
}
|
||||
|
||||
pub fn set_action_manifest(input: &mut InputManager) -> anyhow::Result<()> {
|
||||
let action_path = CONFIG_ROOT_PATH.join("actions.json");
|
||||
let action_path = config_io::get_config_root().join("actions.json");
|
||||
|
||||
if let Err(e) = File::create(&action_path)
|
||||
.and_then(|mut f| f.write_all(include_bytes!("../../res/actions.json")))
|
||||
@@ -333,19 +333,19 @@ pub fn set_action_manifest(input: &mut InputManager) -> anyhow::Result<()> {
|
||||
log::warn!("Could not write action manifest: {}", e);
|
||||
}
|
||||
|
||||
let binding_path = CONFIG_ROOT_PATH.join("actions_binding_knuckles.json");
|
||||
let binding_path = config_io::get_config_root().join("actions_binding_knuckles.json");
|
||||
if !binding_path.is_file() {
|
||||
File::create(&binding_path)?
|
||||
.write_all(include_bytes!("../../res/actions_binding_knuckles.json"))?;
|
||||
}
|
||||
|
||||
let binding_path = CONFIG_ROOT_PATH.join("actions_binding_vive.json");
|
||||
let binding_path = config_io::get_config_root().join("actions_binding_vive.json");
|
||||
if !binding_path.is_file() {
|
||||
File::create(&binding_path)?
|
||||
.write_all(include_bytes!("../../res/actions_binding_vive.json"))?;
|
||||
}
|
||||
|
||||
let binding_path = CONFIG_ROOT_PATH.join("actions_binding_oculus.json");
|
||||
let binding_path = config_io::get_config_root().join("actions_binding_oculus.json");
|
||||
if !binding_path.is_file() {
|
||||
File::create(&binding_path)?
|
||||
.write_all(include_bytes!("../../res/actions_binding_oculus.json"))?;
|
||||
|
||||
@@ -4,12 +4,12 @@ use anyhow::bail;
|
||||
use json::{array, object};
|
||||
use ovr_overlay::applications::ApplicationsManager;
|
||||
|
||||
use crate::config_io::CONFIG_ROOT_PATH;
|
||||
use crate::config_io;
|
||||
|
||||
const APP_KEY: &str = "galister.wlxoverlay-s";
|
||||
|
||||
pub(super) fn install_manifest(app_mgr: &mut ApplicationsManager) -> anyhow::Result<()> {
|
||||
let manifest_path = CONFIG_ROOT_PATH.join("wlx-overlay-s.vrmanifest");
|
||||
let manifest_path = config_io::get_config_root().join("wlx-overlay-s.vrmanifest");
|
||||
|
||||
let appimage_path = std::env::var("APPIMAGE");
|
||||
let executable_pathbuf = std::env::current_exe()?;
|
||||
@@ -76,7 +76,7 @@ pub(super) fn install_manifest(app_mgr: &mut ApplicationsManager) -> anyhow::Res
|
||||
}
|
||||
|
||||
pub(super) fn uninstall_manifest(app_mgr: &mut ApplicationsManager) -> anyhow::Result<()> {
|
||||
let manifest_path = CONFIG_ROOT_PATH.join("wlx-overlay-s.vrmanifest");
|
||||
let manifest_path = config_io::get_config_root().join("wlx-overlay-s.vrmanifest");
|
||||
|
||||
if let Ok(true) = app_mgr.is_application_installed(APP_KEY) {
|
||||
if let Err(e) = app_mgr.remove_application_manifest(&manifest_path) {
|
||||
|
||||
@@ -7,7 +7,7 @@ use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
||||
|
||||
use crate::{
|
||||
backend::openxr::{helpers::translation_rotation_to_posef, swapchain::SwapchainOpts},
|
||||
config_io::CONFIG_ROOT_PATH,
|
||||
config_io,
|
||||
graphics::{dds::WlxCommandBufferDds, format_is_srgb, WlxCommandBuffer},
|
||||
state::AppState,
|
||||
};
|
||||
@@ -35,7 +35,7 @@ impl Skybox {
|
||||
break 'custom_tex;
|
||||
}
|
||||
|
||||
let real_path = CONFIG_ROOT_PATH.join(&*app.session.config.skybox_texture);
|
||||
let real_path = config_io::get_config_root().join(&*app.session.config.skybox_texture);
|
||||
let Ok(f) = File::open(real_path) else {
|
||||
log::warn!(
|
||||
"Could not open custom skybox texture at: {}",
|
||||
|
||||
@@ -2,8 +2,6 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::config_io;
|
||||
use crate::config_io::get_conf_d_path;
|
||||
use crate::config_io::CONFIG_ROOT_PATH;
|
||||
use crate::gui::modular::ModularUiConfig;
|
||||
use crate::overlays::toast::DisplayMethod;
|
||||
use crate::overlays::toast::ToastTopic;
|
||||
@@ -390,14 +388,20 @@ pub fn load_custom_ui(name: &str) -> anyhow::Result<ModularUiConfig> {
|
||||
Ok(serde_yaml::from_str(&yaml_data)?)
|
||||
}
|
||||
|
||||
pub fn load_general() -> GeneralConfig {
|
||||
pub fn load_config_with_conf_d<ConfigData>(
|
||||
root_config_filename: &str,
|
||||
ctype: config_io::ConfigRoot,
|
||||
) -> ConfigData
|
||||
where
|
||||
ConfigData: for<'de> Deserialize<'de>,
|
||||
{
|
||||
let mut settings_builder = Config::builder();
|
||||
|
||||
// Add files from conf.d directory
|
||||
let path_conf_d = get_conf_d_path();
|
||||
let path_conf_d = ctype.get_conf_d_path();
|
||||
|
||||
for mut base_conf in [CONFIG_ROOT_PATH.clone(), path_conf_d.clone()] {
|
||||
base_conf.push("config.yaml");
|
||||
for mut base_conf in [config_io::get_config_root(), path_conf_d.clone()] {
|
||||
base_conf.push(root_config_filename);
|
||||
if base_conf.exists() {
|
||||
log::info!("Loading config file: {}", base_conf.to_string_lossy());
|
||||
settings_builder = settings_builder.add_source(File::from(base_conf));
|
||||
@@ -423,7 +427,7 @@ pub fn load_general() -> GeneralConfig {
|
||||
}
|
||||
|
||||
match settings_builder.build() {
|
||||
Ok(settings) => match settings.try_deserialize::<GeneralConfig>() {
|
||||
Ok(settings) => match settings.try_deserialize::<ConfigData>() {
|
||||
Ok(config) => config,
|
||||
Err(e) => {
|
||||
panic!("Failed to deserialize settings: {}", e);
|
||||
@@ -435,6 +439,10 @@ pub fn load_general() -> GeneralConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_general() -> GeneralConfig {
|
||||
load_config_with_conf_d::<GeneralConfig>("config.yaml", config_io::ConfigRoot::Generic)
|
||||
}
|
||||
|
||||
// Config that is saved from the settings panel
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -452,10 +460,11 @@ pub struct AutoSettings {
|
||||
}
|
||||
|
||||
fn get_settings_path() -> PathBuf {
|
||||
let mut path = config_io::get_conf_d_path();
|
||||
path.push("zz-saved-config.json5");
|
||||
path
|
||||
config_io::ConfigRoot::Generic
|
||||
.get_conf_d_path()
|
||||
.join("zz-saved-config.json5")
|
||||
}
|
||||
|
||||
pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
|
||||
let conf = AutoSettings {
|
||||
watch_pos: config.watch_pos,
|
||||
@@ -486,9 +495,9 @@ pub struct AutoState {
|
||||
}
|
||||
|
||||
fn get_state_path() -> PathBuf {
|
||||
let mut path = config_io::get_conf_d_path();
|
||||
path.push("zz-saved-state.json5");
|
||||
path
|
||||
config_io::ConfigRoot::Generic
|
||||
.get_conf_d_path()
|
||||
.join("zz-saved-state.json5")
|
||||
}
|
||||
|
||||
pub fn save_layout(config: &GeneralConfig) -> anyhow::Result<()> {
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
use log::error;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{
|
||||
fs::{self, create_dir},
|
||||
path::PathBuf,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub enum ConfigRoot {
|
||||
Generic,
|
||||
#[allow(dead_code)]
|
||||
WayVR,
|
||||
}
|
||||
|
||||
const FALLBACK_CONFIG_PATH: &str = "/tmp/wlxoverlay";
|
||||
|
||||
pub static CONFIG_ROOT_PATH: Lazy<PathBuf> = Lazy::new(|| {
|
||||
static CONFIG_ROOT_PATH: Lazy<PathBuf> = Lazy::new(|| {
|
||||
if let Ok(xdg_dirs) = xdg::BaseDirectories::new() {
|
||||
let mut dir = xdg_dirs.get_config_home();
|
||||
dir.push("wlxoverlay");
|
||||
@@ -21,33 +24,38 @@ pub static CONFIG_ROOT_PATH: Lazy<PathBuf> = Lazy::new(|| {
|
||||
PathBuf::from(FALLBACK_CONFIG_PATH)
|
||||
});
|
||||
|
||||
pub fn get_conf_d_path() -> PathBuf {
|
||||
let mut config_root = CONFIG_ROOT_PATH.clone();
|
||||
config_root.push("conf.d");
|
||||
config_root
|
||||
pub fn get_config_root() -> PathBuf {
|
||||
CONFIG_ROOT_PATH.clone()
|
||||
}
|
||||
|
||||
// Make sure config directory is present and return root config path
|
||||
pub fn ensure_config_root() -> PathBuf {
|
||||
let path = CONFIG_ROOT_PATH.clone();
|
||||
let _ = create_dir(&path);
|
||||
impl ConfigRoot {
|
||||
pub fn get_conf_d_path(&self) -> PathBuf {
|
||||
get_config_root().join(match self {
|
||||
ConfigRoot::Generic => "conf.d",
|
||||
ConfigRoot::WayVR => "wayvr.conf.d",
|
||||
})
|
||||
}
|
||||
|
||||
let path_conf_d = get_conf_d_path();
|
||||
let _ = create_dir(path_conf_d);
|
||||
path
|
||||
// Make sure config directory is present and return root config path
|
||||
pub fn ensure_dir(&self) -> PathBuf {
|
||||
let path = get_config_root();
|
||||
let _ = std::fs::create_dir(&path);
|
||||
|
||||
let path_conf_d = self.get_conf_d_path();
|
||||
let _ = std::fs::create_dir(path_conf_d);
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
fn get_config_file_path(filename: &str) -> PathBuf {
|
||||
let mut config_root = CONFIG_ROOT_PATH.clone();
|
||||
config_root.push(filename);
|
||||
config_root
|
||||
pub fn get_config_file_path(filename: &str) -> PathBuf {
|
||||
get_config_root().join(filename)
|
||||
}
|
||||
|
||||
pub fn load(filename: &str) -> Option<String> {
|
||||
let path = get_config_file_path(filename);
|
||||
log::info!("Loading config {}", path.to_string_lossy());
|
||||
log::info!("Loading config: {}", path.to_string_lossy());
|
||||
|
||||
if let Ok(data) = fs::read_to_string(path) {
|
||||
if let Ok(data) = std::fs::read_to_string(path) {
|
||||
Some(data)
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -16,7 +16,8 @@ use crate::{
|
||||
task::{TaskContainer, TaskType},
|
||||
wayvr,
|
||||
},
|
||||
config::{load_known_yaml, ConfigType},
|
||||
config::load_config_with_conf_d,
|
||||
config_io,
|
||||
gui::modular::button::WayVRAction,
|
||||
overlays::wayvr::WayVRData,
|
||||
};
|
||||
@@ -120,7 +121,7 @@ pub struct WayVRConfig {
|
||||
pub run_compositor_at_start: bool,
|
||||
pub catalogs: HashMap<String, WayVRCatalog>,
|
||||
pub displays: BTreeMap<String, WayVRDisplay>, // sorted alphabetically
|
||||
pub dashboard: WayVRDashboard,
|
||||
pub dashboard: Option<WayVRDashboard>,
|
||||
|
||||
#[serde(default = "def_true")]
|
||||
pub auto_hide: bool,
|
||||
@@ -212,7 +213,15 @@ impl WayVRConfig {
|
||||
}
|
||||
|
||||
pub fn load_wayvr() -> WayVRConfig {
|
||||
let config = load_known_yaml::<WayVRConfig>(ConfigType::WayVR);
|
||||
let config_root_path = config_io::ConfigRoot::WayVR.ensure_dir();
|
||||
log::info!("WayVR Config root path: {:?}", config_root_path);
|
||||
log::info!(
|
||||
"WayVR conf.d path: {:?}",
|
||||
config_io::ConfigRoot::WayVR.get_conf_d_path()
|
||||
);
|
||||
|
||||
let config = load_config_with_conf_d::<WayVRConfig>("wayvr.yaml", config_io::ConfigRoot::WayVR);
|
||||
|
||||
if config.version != 1 {
|
||||
panic!("WayVR config version {} is not supported", config.version);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use serde::Deserialize;
|
||||
use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView};
|
||||
|
||||
use crate::{
|
||||
backend::common::OverlaySelector, config::AStrMapExt, config_io::CONFIG_ROOT_PATH,
|
||||
backend::common::OverlaySelector, config::AStrMapExt, config_io,
|
||||
graphics::dds::WlxCommandBufferDds, state::AppState,
|
||||
};
|
||||
|
||||
@@ -545,7 +545,7 @@ fn sprite_from_path(path: Arc<str>, app: &mut AppState) -> anyhow::Result<Arc<Im
|
||||
return Ok(view.clone());
|
||||
}
|
||||
|
||||
let real_path = CONFIG_ROOT_PATH.join(&*path);
|
||||
let real_path = config_io::get_config_root().join(&*path);
|
||||
|
||||
let Ok(f) = File::open(real_path) else {
|
||||
anyhow::bail!("Could not open custom sprite at: {}", path);
|
||||
|
||||
@@ -751,7 +751,7 @@ pub struct TokenConf {
|
||||
|
||||
#[cfg(feature = "pipewire")]
|
||||
fn get_pw_token_path() -> PathBuf {
|
||||
let mut path = config_io::get_conf_d_path();
|
||||
let mut path = config_io::ConfigRoot::Generic.get_conf_d_path();
|
||||
path.push("pw_tokens.yaml");
|
||||
path
|
||||
}
|
||||
|
||||
@@ -244,6 +244,10 @@ where
|
||||
{
|
||||
let conf_dash = &app.session.wayvr_config.dashboard;
|
||||
|
||||
let Some(conf_dash) = &conf_dash else {
|
||||
anyhow::bail!("Dashboard is not configured");
|
||||
};
|
||||
|
||||
if !wayvr.dashboard_executed && !executable_exists_in_path(&conf_dash.exec) {
|
||||
anyhow::bail!("Executable \"{}\" not found", &conf_dash.exec);
|
||||
}
|
||||
@@ -280,7 +284,9 @@ where
|
||||
overlay.state.z_order = Z_ORDER_DASHBOARD;
|
||||
overlay.state.reset(app, true);
|
||||
|
||||
let conf_dash = &app.session.wayvr_config.dashboard;
|
||||
let Some(conf_dash) = &app.session.wayvr_config.dashboard else {
|
||||
unreachable!(); /* safe, not possible to trigger */
|
||||
};
|
||||
|
||||
// FIXME: overlay curvature needs to be dispatched for some unknown reason, this value is not set otherwise
|
||||
app.tasks.enqueue(TaskType::Overlay(
|
||||
|
||||
@@ -146,8 +146,8 @@ pub struct AppSession {
|
||||
|
||||
impl AppSession {
|
||||
pub fn load() -> Self {
|
||||
let config_root_path = config_io::ensure_config_root();
|
||||
log::info!("Config root path: {}", config_root_path.to_string_lossy());
|
||||
let config_root_path = config_io::ConfigRoot::Generic.ensure_dir();
|
||||
log::info!("Config root path: {:?}", config_root_path);
|
||||
let config = GeneralConfig::load_from_disk();
|
||||
|
||||
let mut toast_topics = IdMap::new();
|
||||
|
||||
Reference in New Issue
Block a user