config_io: Support wayvr.conf.d directory, refactoring (#139)

This commit is contained in:
Aleksander
2025-01-20 15:26:17 +01:00
committed by GitHub
parent b209f79188
commit 3c792608e7
10 changed files with 86 additions and 54 deletions

View File

@@ -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"))?;

View File

@@ -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) {

View File

@@ -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: {}",

View File

@@ -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<()> {

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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
}

View File

@@ -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(

View File

@@ -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();