settings tab buttons; autorestart
This commit is contained in:
@@ -26,8 +26,12 @@
|
|||||||
<RadioBox text="${text}" translation="${translation}" value="${value}" tooltip="${tooltip}" />
|
<RadioBox text="${text}" translation="${translation}" value="${value}" tooltip="${tooltip}" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="DangerButton">
|
||||||
|
<Button id="${id}" color="#AA3333" height="32" width="100%" sprite_src_builtin="${icon}" translation="${translation}" tooltip="${translation}_HELP" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<elements>
|
<elements>
|
||||||
<TabTitle translation="SETTINGS" icon="dashboard/settings.svg" />
|
<TabTitle translation="SETTINGS" icon="dashboard/settings.svg" />
|
||||||
<div flex_wrap="wrap" justify_content="stretch" gap="4" id="settings_root" />
|
<div flex_wrap="wrap" justify_content="stretch" gap="4" id="settings_root" />
|
||||||
</elements>
|
</elements>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@@ -57,7 +57,19 @@
|
|||||||
"BLOCK_GAME_INPUT_IGNORE_WATCH_HELP": "Do not block input when watch is hovered",
|
"BLOCK_GAME_INPUT_IGNORE_WATCH_HELP": "Do not block input when watch is hovered",
|
||||||
"USE_SKYBOX_HELP": "Show a skybox if there's no scene app or passthrough",
|
"USE_SKYBOX_HELP": "Show a skybox if there's no scene app or passthrough",
|
||||||
"USE_PASSTHROUGH_HELP": "Allow passthrough if the XR runtime supports it",
|
"USE_PASSTHROUGH_HELP": "Allow passthrough if the XR runtime supports it",
|
||||||
"SCREEN_RENDER_DOWN_HELP": "Helps with aliasing on high-res screens"
|
"SCREEN_RENDER_DOWN_HELP": "Helps with aliasing on high-res screens",
|
||||||
|
|
||||||
|
"TROUBLESHOOTING": "Troubleshooting",
|
||||||
|
|
||||||
|
"CLEAR_SAVED_STATE": "Clear saved state",
|
||||||
|
"CLEAR_PIPEWIRE_TOKENS": "Clear PipeWire tokens",
|
||||||
|
"DELETE_ALL_CONFIGS": "Wipe configuration",
|
||||||
|
"RESTART_SOFTWARE": "Restart software",
|
||||||
|
|
||||||
|
"CLEAR_SAVED_STATE_HELP": "Reset sets & overlay positions",
|
||||||
|
"CLEAR_PIPEWIRE_TOKENS_HELP": "Prompt for screen selection on next start",
|
||||||
|
"DELETE_ALL_CONFIGS_HELP": "Remove all configuration files from conf.d",
|
||||||
|
"RESTART_SOFTWARE_HELP": "Apply settings that require a restart"
|
||||||
},
|
},
|
||||||
"APPLICATION_LAUNCHER": "Application launcher",
|
"APPLICATION_LAUNCHER": "Application launcher",
|
||||||
"APPLICATION_STARTED": "Application started",
|
"APPLICATION_STARTED": "Application started",
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
use std::{collections::HashMap, marker::PhantomData, rc::Rc};
|
use std::{collections::HashMap, marker::PhantomData, os::unix::process::CommandExt, process::Command, rc::Rc};
|
||||||
|
|
||||||
use strum::AsRefStr;
|
use strum::AsRefStr;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
assets::AssetPath,
|
assets::AssetPath,
|
||||||
components::{checkbox::ComponentCheckbox, slider::ComponentSlider},
|
components::{button::ComponentButton, checkbox::ComponentCheckbox, slider::ComponentSlider},
|
||||||
layout::{Layout, WidgetID},
|
layout::{Layout, WidgetID},
|
||||||
|
log::LogErr,
|
||||||
parser::{Fetchable, ParseDocumentParams, ParserState},
|
parser::{Fetchable, ParseDocumentParams, ParserState},
|
||||||
task::Tasks,
|
task::Tasks,
|
||||||
};
|
};
|
||||||
use wlx_common::config::GeneralConfig;
|
use wlx_common::{config::GeneralConfig, config_io::ConfigRoot};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::{Frontend, FrontendTask},
|
frontend::{Frontend, FrontendTask},
|
||||||
@@ -19,6 +20,10 @@ enum Task {
|
|||||||
UpdateBool(SettingType, bool),
|
UpdateBool(SettingType, bool),
|
||||||
UpdateFloat(SettingType, f32),
|
UpdateFloat(SettingType, f32),
|
||||||
UpdateInt(SettingType, i32),
|
UpdateInt(SettingType, i32),
|
||||||
|
ClearPipewireTokens,
|
||||||
|
ClearSavedState,
|
||||||
|
DeleteAllConfigs,
|
||||||
|
RestartSoftware,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TabSettings<T> {
|
pub struct TabSettings<T> {
|
||||||
@@ -54,6 +59,23 @@ impl<T> Tab<T> for TabSettings<T> {
|
|||||||
*setting.mut_i32(config) = n;
|
*setting.mut_i32(config) = n;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
Task::ClearPipewireTokens => {
|
||||||
|
let _ = std::fs::remove_file(ConfigRoot::Generic.get_conf_d_path().join("pw_tokens.yaml"))
|
||||||
|
.log_err("Could not remove pw_tokens.yaml");
|
||||||
|
}
|
||||||
|
Task::ClearSavedState => {
|
||||||
|
let _ = std::fs::remove_file(ConfigRoot::Generic.get_conf_d_path().join("zz-saved-state.json5"))
|
||||||
|
.log_err("Could not remove zz-saved-state.json5");
|
||||||
|
}
|
||||||
|
Task::DeleteAllConfigs => {
|
||||||
|
let path = ConfigRoot::Generic.get_conf_d_path();
|
||||||
|
std::fs::remove_dir_all(&path)?;
|
||||||
|
std::fs::create_dir(&path)?;
|
||||||
|
}
|
||||||
|
Task::RestartSoftware => {
|
||||||
|
frontend.interface.restart(data);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
@@ -359,6 +381,31 @@ macro_rules! slider_i32 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! button {
|
||||||
|
($mp:expr, $root:expr, $translation:expr, $icon:expr, $task:expr) => {
|
||||||
|
let id = $mp.idx.to_string();
|
||||||
|
$mp.idx += 1;
|
||||||
|
|
||||||
|
let mut params: HashMap<Rc<str>, Rc<str>> = HashMap::new();
|
||||||
|
params.insert(Rc::from("id"), Rc::from(id.as_ref()));
|
||||||
|
params.insert(Rc::from("translation"), Rc::from($translation));
|
||||||
|
params.insert(Rc::from("icon"), Rc::from($icon));
|
||||||
|
|
||||||
|
$mp
|
||||||
|
.parser_state
|
||||||
|
.instantiate_template($mp.doc_params, "DangerButton", $mp.layout, $root, params)?;
|
||||||
|
|
||||||
|
let btn = $mp.parser_state.fetch_component_as::<ComponentButton>(&id)?;
|
||||||
|
btn.on_click(Box::new({
|
||||||
|
let tasks = $mp.tasks.clone();
|
||||||
|
move |_common, _e| {
|
||||||
|
tasks.push($task);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
struct MacroParams<'a> {
|
struct MacroParams<'a> {
|
||||||
layout: &'a mut Layout,
|
layout: &'a mut Layout,
|
||||||
parser_state: &'a mut ParserState,
|
parser_state: &'a mut ParserState,
|
||||||
@@ -428,6 +475,36 @@ impl<T> TabSettings<T> {
|
|||||||
checkbox!(mp, c, SettingType::DoubleCursorFix);
|
checkbox!(mp, c, SettingType::DoubleCursorFix);
|
||||||
checkbox!(mp, c, SettingType::ScreenRenderDown);
|
checkbox!(mp, c, SettingType::ScreenRenderDown);
|
||||||
|
|
||||||
|
let c = category!(mp, root, "APP_SETTINGS.TROUBLESHOOTING", "dashboard/blocks.svg")?;
|
||||||
|
button!(
|
||||||
|
mp,
|
||||||
|
c,
|
||||||
|
"APP_SETTINGS.CLEAR_SAVED_STATE",
|
||||||
|
"dashboard/remove_circle.svg",
|
||||||
|
Task::ClearSavedState
|
||||||
|
);
|
||||||
|
button!(
|
||||||
|
mp,
|
||||||
|
c,
|
||||||
|
"APP_SETTINGS.CLEAR_PIPEWIRE_TOKENS",
|
||||||
|
"dashboard/remove_circle.svg",
|
||||||
|
Task::ClearPipewireTokens
|
||||||
|
);
|
||||||
|
button!(
|
||||||
|
mp,
|
||||||
|
c,
|
||||||
|
"APP_SETTINGS.DELETE_ALL_CONFIGS",
|
||||||
|
"dashboard/remove_circle.svg",
|
||||||
|
Task::DeleteAllConfigs
|
||||||
|
);
|
||||||
|
button!(
|
||||||
|
mp,
|
||||||
|
c,
|
||||||
|
"APP_SETTINGS.RESTART_SOFTWARE",
|
||||||
|
"dashboard/refresh.svg",
|
||||||
|
Task::RestartSoftware
|
||||||
|
);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
tasks: mp.tasks,
|
tasks: mp.tasks,
|
||||||
state: parser_state,
|
state: parser_state,
|
||||||
|
|||||||
54
wlx-common/src/config_io.rs
Normal file
54
wlx-common/src/config_io.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
use log::error;
|
||||||
|
use std::{path::PathBuf, sync::LazyLock};
|
||||||
|
|
||||||
|
pub enum ConfigRoot {
|
||||||
|
Generic,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
WayVR,
|
||||||
|
}
|
||||||
|
|
||||||
|
const FALLBACK_CONFIG_PATH: &str = "/tmp/wlxoverlay";
|
||||||
|
|
||||||
|
static CONFIG_ROOT_PATH: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||||
|
if let Some(mut dir) = xdg::BaseDirectories::new().get_config_home() {
|
||||||
|
dir.push("wlxoverlay");
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
//Return fallback config path
|
||||||
|
error!("Err: Failed to find config path, using {FALLBACK_CONFIG_PATH}");
|
||||||
|
PathBuf::from(FALLBACK_CONFIG_PATH)
|
||||||
|
});
|
||||||
|
|
||||||
|
pub fn get_config_root() -> PathBuf {
|
||||||
|
CONFIG_ROOT_PATH.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigRoot {
|
||||||
|
pub fn get_conf_d_path(&self) -> PathBuf {
|
||||||
|
get_config_root().join(match self {
|
||||||
|
Self::Generic => "conf.d",
|
||||||
|
Self::WayVR => "wayvr.conf.d",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
std::fs::read_to_string(path).ok()
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ pub trait DashInterface<T> {
|
|||||||
fn desktop_finder<'a>(&'a mut self, data: &'a mut T) -> &'a mut DesktopFinder;
|
fn desktop_finder<'a>(&'a mut self, data: &'a mut T) -> &'a mut DesktopFinder;
|
||||||
fn general_config<'a>(&'a mut self, data: &'a mut T) -> &'a mut GeneralConfig;
|
fn general_config<'a>(&'a mut self, data: &'a mut T) -> &'a mut GeneralConfig;
|
||||||
fn config_changed(&mut self, data: &mut T);
|
fn config_changed(&mut self, data: &mut T);
|
||||||
|
fn restart(&mut self, data: &mut T);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BoxDashInterface<T> = Box<dyn DashInterface<T>>;
|
pub type BoxDashInterface<T> = Box<dyn DashInterface<T>>;
|
||||||
|
|||||||
@@ -180,4 +180,6 @@ impl DashInterface<()> for DashInterfaceEmulated {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn config_changed(&mut self, _: &mut ()) {}
|
fn config_changed(&mut self, _: &mut ()) {}
|
||||||
|
|
||||||
|
fn restart(&mut self, data: &mut ()) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ pub mod audio;
|
|||||||
pub mod cache_dir;
|
pub mod cache_dir;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod config_io;
|
||||||
pub mod dash_interface;
|
pub mod dash_interface;
|
||||||
pub mod dash_interface_emulated;
|
pub mod dash_interface_emulated;
|
||||||
pub mod desktop_finder;
|
pub mod desktop_finder;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
<Hmd idx="0" />
|
<Hmd idx="0" />
|
||||||
<LeftHand idx="1" />
|
<LeftHand idx="1" />
|
||||||
<RightHand idx="2" />
|
<RightHand idx="2" />
|
||||||
<Track idx="3" />
|
<Tracker idx="3" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- All other elements inside the container -->
|
<!-- All other elements inside the container -->
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ use ovr_overlay::{
|
|||||||
},
|
},
|
||||||
system::SystemManager,
|
system::SystemManager,
|
||||||
};
|
};
|
||||||
|
use wlx_common::config_io;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{Haptics, TrackedDevice, TrackedDeviceRole},
|
backend::input::{Haptics, TrackedDevice, TrackedDeviceRole},
|
||||||
config_io,
|
|
||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use anyhow::{Context, bail};
|
|||||||
use json::{array, object};
|
use json::{array, object};
|
||||||
use ovr_overlay::applications::ApplicationsManager;
|
use ovr_overlay::applications::ApplicationsManager;
|
||||||
|
|
||||||
use crate::config_io;
|
use wlx_common::config_io;
|
||||||
|
|
||||||
const APP_KEY: &str = "galister.wlxoverlay-s";
|
const APP_KEY: &str = "galister.wlxoverlay-s";
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ use glam::{Affine3A, Quat, Vec3, bool};
|
|||||||
use libmonado as mnd;
|
use libmonado as mnd;
|
||||||
use openxr::{self as xr, Quaternionf, Vector2f, Vector3f};
|
use openxr::{self as xr, Quaternionf, Vector2f, Vector3f};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use wlx_common::config_io;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{Haptics, Pointer, TrackedDevice, TrackedDeviceRole},
|
backend::input::{Haptics, Pointer, TrackedDevice, TrackedDeviceRole},
|
||||||
config_io,
|
|
||||||
state::{AppSession, AppState},
|
state::{AppSession, AppState},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ use vulkano::{
|
|||||||
pipeline::graphics::color_blend::AttachmentBlend,
|
pipeline::graphics::color_blend::AttachmentBlend,
|
||||||
};
|
};
|
||||||
use wgui::gfx::{cmd::WGfxClearMode, pipeline::WPipelineCreateInfo};
|
use wgui::gfx::{cmd::WGfxClearMode, pipeline::WPipelineCreateInfo};
|
||||||
|
use wlx_common::config_io;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::openxr::{helpers::translation_rotation_to_posef, swapchain::SwapchainOpts},
|
backend::openxr::{helpers::translation_rotation_to_posef, swapchain::SwapchainOpts},
|
||||||
config_io,
|
|
||||||
graphics::{ExtentExt, GpuFutures, dds::WlxCommandBufferDds},
|
graphics::{ExtentExt, GpuFutures, dds::WlxCommandBufferDds},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use crate::config_io;
|
|
||||||
use config::{Config, File};
|
use config::{Config, File};
|
||||||
use log::error;
|
use log::error;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -6,6 +5,7 @@ use std::path::PathBuf;
|
|||||||
use wlx_common::{
|
use wlx_common::{
|
||||||
astr_containers::AStrMap,
|
astr_containers::AStrMap,
|
||||||
config::{GeneralConfig, SerializedWindowSet, SerializedWindowStates},
|
config::{GeneralConfig, SerializedWindowSet, SerializedWindowStates},
|
||||||
|
config_io,
|
||||||
overlays::BackendAttribValue,
|
overlays::BackendAttribValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
use log::error;
|
|
||||||
use std::{path::PathBuf, sync::LazyLock};
|
|
||||||
|
|
||||||
pub enum ConfigRoot {
|
|
||||||
Generic,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
WayVR,
|
|
||||||
}
|
|
||||||
|
|
||||||
const FALLBACK_CONFIG_PATH: &str = "/tmp/wlxoverlay";
|
|
||||||
|
|
||||||
static CONFIG_ROOT_PATH: LazyLock<PathBuf> = LazyLock::new(|| {
|
|
||||||
if let Some(mut dir) = xdg::BaseDirectories::new().get_config_home() {
|
|
||||||
dir.push("wlxoverlay");
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
//Return fallback config path
|
|
||||||
error!("Err: Failed to find config path, using {FALLBACK_CONFIG_PATH}");
|
|
||||||
PathBuf::from(FALLBACK_CONFIG_PATH)
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn get_config_root() -> PathBuf {
|
|
||||||
CONFIG_ROOT_PATH.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConfigRoot {
|
|
||||||
pub fn get_conf_d_path(&self) -> PathBuf {
|
|
||||||
get_config_root().join(match self {
|
|
||||||
Self::Generic => "conf.d",
|
|
||||||
Self::WayVR => "wayvr.conf.d",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
std::fs::read_to_string(path).ok()
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@ use std::{
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use wgui::gfx::WGfx;
|
use wgui::gfx::WGfx;
|
||||||
use wlx_common::{common::LeftRight, config::GeneralConfig, windowing::Positioning};
|
use wlx_common::{common::LeftRight, config::GeneralConfig, config_io, windowing::Positioning};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
@@ -17,7 +17,6 @@ use crate::{
|
|||||||
wayvr::{self, WvrServerState},
|
wayvr::{self, WvrServerState},
|
||||||
},
|
},
|
||||||
config::load_config_with_conf_d,
|
config::load_config_with_conf_d,
|
||||||
config_io,
|
|
||||||
graphics::WGfxExtras,
|
graphics::WGfxExtras,
|
||||||
ipc::{event_queue::SyncEventQueue, signal::WayVRSignal},
|
ipc::{event_queue::SyncEventQueue, signal::WayVRSignal},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,9 +25,8 @@ use wgui::{
|
|||||||
use wlx_common::overlays::ToastTopic;
|
use wlx_common::overlays::ToastTopic;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
RUNNING,
|
RESTART, RUNNING,
|
||||||
backend::{
|
backend::{
|
||||||
XrBackend,
|
|
||||||
task::{OverlayTask, PlayspaceTask, TaskType, ToggleMode},
|
task::{OverlayTask, PlayspaceTask, TaskType, ToggleMode},
|
||||||
wayvr::process::KillSignal,
|
wayvr::process::KillSignal,
|
||||||
},
|
},
|
||||||
@@ -572,16 +571,8 @@ pub(super) fn setup_custom_button<S: 'static>(
|
|||||||
if !test_button(data) || !test_duration(&button, app) {
|
if !test_button(data) || !test_duration(&button, app) {
|
||||||
return Ok(EventResult::Pass);
|
return Ok(EventResult::Pass);
|
||||||
}
|
}
|
||||||
|
RUNNING.store(false, Ordering::Relaxed);
|
||||||
let runtime = match app.xr_backend {
|
RESTART.store(true, Ordering::Relaxed);
|
||||||
XrBackend::OpenVR => "--openvr",
|
|
||||||
XrBackend::OpenXR => "--openxr",
|
|
||||||
};
|
|
||||||
|
|
||||||
Command::new("/proc/self/exe")
|
|
||||||
.arg(runtime) // ensure same runtime
|
|
||||||
.arg("--replace") // SIGTERM the previous process
|
|
||||||
.arg("--show");
|
|
||||||
|
|
||||||
Ok(EventResult::Consumed)
|
Ok(EventResult::Consumed)
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
mod app_misc;
|
mod app_misc;
|
||||||
mod backend;
|
mod backend;
|
||||||
mod config;
|
mod config;
|
||||||
mod config_io;
|
|
||||||
mod graphics;
|
mod graphics;
|
||||||
mod gui;
|
mod gui;
|
||||||
mod ipc;
|
mod ipc;
|
||||||
@@ -34,7 +33,9 @@ mod windowing;
|
|||||||
mod config_wayvr;
|
mod config_wayvr;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
os::unix::process::CommandExt,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
process::Command,
|
||||||
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
|
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,10 +46,11 @@ use sysinfo::Pid;
|
|||||||
use tracing::level_filters::LevelFilter;
|
use tracing::level_filters::LevelFilter;
|
||||||
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
use crate::subsystem::dbus::DbusConnector;
|
use crate::{backend::XrBackend, subsystem::dbus::DbusConnector};
|
||||||
|
|
||||||
pub static FRAME_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
pub static FRAME_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||||
pub static RUNNING: AtomicBool = AtomicBool::new(true);
|
pub static RUNNING: AtomicBool = AtomicBool::new(true);
|
||||||
|
pub static RESTART: AtomicBool = AtomicBool::new(false);
|
||||||
pub static KEYMAP_CHANGE: AtomicBool = AtomicBool::new(false);
|
pub static KEYMAP_CHANGE: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
/// The lightweight desktop overlay for OpenVR and OpenXR
|
/// The lightweight desktop overlay for OpenVR and OpenXR
|
||||||
@@ -121,13 +123,29 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
setup_signal_hooks()?;
|
setup_signal_hooks()?;
|
||||||
|
|
||||||
auto_run(args);
|
let mut used_backend = None;
|
||||||
|
|
||||||
|
auto_run(args, &mut used_backend);
|
||||||
|
|
||||||
|
if RESTART.load(Ordering::Relaxed) {
|
||||||
|
log::warn!("Restarting...");
|
||||||
|
let exe = std::env::current_exe()?;
|
||||||
|
let mut args = vec!["--replace", "--show"];
|
||||||
|
|
||||||
|
match used_backend {
|
||||||
|
Some(XrBackend::OpenXR) => args.push("--openxr"),
|
||||||
|
Some(XrBackend::OpenVR) => args.push("--openvr"),
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = Command::new(exe).args(args).spawn();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_mut, clippy::similar_names)]
|
#[allow(unused_mut, clippy::similar_names)]
|
||||||
fn auto_run(args: Args) {
|
fn auto_run(args: Args, used_backend: &mut Option<XrBackend>) {
|
||||||
let mut tried_xr = false;
|
let mut tried_xr = false;
|
||||||
let mut tried_vr = false;
|
let mut tried_vr = false;
|
||||||
|
|
||||||
@@ -136,9 +154,13 @@ fn auto_run(args: Args) {
|
|||||||
use crate::backend::{BackendError, openxr::openxr_run};
|
use crate::backend::{BackendError, openxr::openxr_run};
|
||||||
tried_xr = true;
|
tried_xr = true;
|
||||||
match openxr_run(args.show, args.headless) {
|
match openxr_run(args.show, args.headless) {
|
||||||
Ok(()) => return,
|
Ok(()) => {
|
||||||
|
used_backend.replace(XrBackend::OpenXR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Err(BackendError::NotSupported) => (),
|
Err(BackendError::NotSupported) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
used_backend.replace(XrBackend::OpenXR);
|
||||||
log::error!("{e:?}");
|
log::error!("{e:?}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -150,9 +172,13 @@ fn auto_run(args: Args) {
|
|||||||
use crate::backend::{BackendError, openvr::openvr_run};
|
use crate::backend::{BackendError, openvr::openvr_run};
|
||||||
tried_vr = true;
|
tried_vr = true;
|
||||||
match openvr_run(args.show, args.headless) {
|
match openvr_run(args.show, args.headless) {
|
||||||
Ok(()) => return,
|
Ok(()) => {
|
||||||
|
used_backend.replace(XrBackend::OpenVR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Err(BackendError::NotSupported) => (),
|
Err(BackendError::NotSupported) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
used_backend.replace(XrBackend::OpenVR);
|
||||||
log::error!("{e:?}");
|
log::error!("{e:?}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use dash_frontend::frontend::{self, FrontendTask, FrontendUpdateParams};
|
use dash_frontend::frontend::{self, FrontendTask, FrontendUpdateParams};
|
||||||
use glam::{Affine2, Affine3A, Vec2, vec2, vec3};
|
use glam::{Affine2, Affine3A, Vec2, vec2, vec3};
|
||||||
use wayvr_ipc::{
|
use wayvr_ipc::{
|
||||||
@@ -23,6 +25,7 @@ use wlx_common::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
RESTART, RUNNING,
|
||||||
backend::{
|
backend::{
|
||||||
input::{Haptics, HoverResult, PointerHit, PointerMode},
|
input::{Haptics, HoverResult, PointerHit, PointerMode},
|
||||||
task::{OverlayTask, PlayspaceTask, TaskType, ToggleMode},
|
task::{OverlayTask, PlayspaceTask, TaskType, ToggleMode},
|
||||||
@@ -418,4 +421,9 @@ impl DashInterface<AppState> for DashInterfaceLive {
|
|||||||
data.tasks
|
data.tasks
|
||||||
.enqueue(TaskType::Overlay(OverlayTask::SettingsChanged));
|
.enqueue(TaskType::Overlay(OverlayTask::SettingsChanged));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn restart(&mut self, _data: &mut AppState) {
|
||||||
|
RUNNING.store(false, Ordering::Relaxed);
|
||||||
|
RESTART.store(true, Ordering::Relaxed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,12 @@ use wlx_capture::{
|
|||||||
pipewire::{PipewireCapture, PipewireSelectScreenResult},
|
pipewire::{PipewireCapture, PipewireSelectScreenResult},
|
||||||
wayland::WlxOutput,
|
wayland::WlxOutput,
|
||||||
};
|
};
|
||||||
use wlx_common::config::{PwTokenMap, def_pw_tokens};
|
use wlx_common::{
|
||||||
|
config::{PwTokenMap, def_pw_tokens},
|
||||||
|
config_io,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{config_io, state::AppState, subsystem::dbus::DbusConnector};
|
use crate::{state::AppState, subsystem::dbus::DbusConnector};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
backend::ScreenBackend,
|
backend::ScreenBackend,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use wgui::{
|
|||||||
use wlx_common::{
|
use wlx_common::{
|
||||||
audio,
|
audio,
|
||||||
config::GeneralConfig,
|
config::GeneralConfig,
|
||||||
|
config_io::{self, get_config_file_path},
|
||||||
desktop_finder::DesktopFinder,
|
desktop_finder::DesktopFinder,
|
||||||
overlays::{ToastDisplayMethod, ToastTopic},
|
overlays::{ToastDisplayMethod, ToastTopic},
|
||||||
};
|
};
|
||||||
@@ -24,7 +25,6 @@ use crate::subsystem::osc::OscSender;
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{XrBackend, input::InputState, task::TaskContainer},
|
backend::{XrBackend, input::InputState, task::TaskContainer},
|
||||||
config::load_general_config,
|
config::load_general_config,
|
||||||
config_io::{self, get_config_file_path},
|
|
||||||
graphics::WGfxExtras,
|
graphics::WGfxExtras,
|
||||||
gui,
|
gui,
|
||||||
ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal},
|
ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal},
|
||||||
|
|||||||
Reference in New Issue
Block a user