mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-04-20 11:35:48 +00:00
Merge branch 'main' into feat/stardust
This commit is contained in:
commit
21d84252ca
37 changed files with 354 additions and 191 deletions
|
@ -22,7 +22,7 @@ cargo:test:
|
|||
script:
|
||||
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
||||
- apt-get update
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
||||
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||
- chmod +x /tmp/rustup.sh
|
||||
|
@ -41,7 +41,7 @@ appimage:
|
|||
script:
|
||||
- echo 'deb http://deb.debian.org/debian experimental main' > /etc/apt/sources.list.d/experimental.list
|
||||
- apt-get update
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
||||
- apt-get -t experimental install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev -y
|
||||
- apt-get install meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||
- chmod +x /tmp/rustup.sh
|
||||
|
|
36
Cargo.lock
generated
36
Cargo.lock
generated
|
@ -301,7 +301,6 @@ dependencies = [
|
|||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sourceview5",
|
||||
"tracker",
|
||||
"uuid",
|
||||
"zoha-vte4",
|
||||
|
@ -1877,41 +1876,6 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sourceview5"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88c5f976a113e947bc5ec67758b2960c0db4ca76f80fb410d7cd86cd456d9ee5"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"gdk-pixbuf",
|
||||
"gdk4",
|
||||
"gio",
|
||||
"glib",
|
||||
"gtk4",
|
||||
"libc",
|
||||
"pango",
|
||||
"sourceview5-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sourceview5-sys"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29637cccd56075a37ba72c0cc8b8d599dbc1d857e30dadea97eaacbc29b7fd46"
|
||||
dependencies = [
|
||||
"gdk-pixbuf-sys",
|
||||
"gdk4-sys",
|
||||
"gio-sys",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk4-sys",
|
||||
"libc",
|
||||
"pango-sys",
|
||||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
|
|
|
@ -36,9 +36,6 @@ serde = { version = "1.0.188", features = [
|
|||
"derive"
|
||||
] }
|
||||
serde_json = "1.0.106"
|
||||
sourceview5 = { version = "0.7.1", features = [
|
||||
"v5_6"
|
||||
] }
|
||||
tracker = "0.2.1"
|
||||
uuid = { version = "1.4.1", features = ["v4", "fast-rng"] }
|
||||
zoha-vte4 = { version = "0.0.2", features = ["v0_72"] }
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
.padded {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.sourceview-transparent-bg, .sourceview-transparent-bg * {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
|
2
dist/arch/PKGBUILD
vendored
2
dist/arch/PKGBUILD
vendored
|
@ -9,7 +9,6 @@ url='https://gitlab.com/gabmus/envision'
|
|||
license=(GPL)
|
||||
depends=(
|
||||
gtk4
|
||||
gtksourceview5
|
||||
libadwaita
|
||||
openxr
|
||||
libgl
|
||||
|
@ -23,6 +22,7 @@ depends=(
|
|||
ninja
|
||||
shaderc
|
||||
vulkan-headers
|
||||
vte4
|
||||
)
|
||||
makedepends=(
|
||||
meson
|
||||
|
|
|
@ -18,7 +18,7 @@ description = 'GUI for Monado' # temporary
|
|||
dependency('glib-2.0', version: '>= 2.66')
|
||||
dependency('gio-2.0', version: '>= 2.66')
|
||||
dependency('gtk4', version: '>= 4.10.0')
|
||||
dependency('gtksourceview-5', version: '>= 5.6.0')
|
||||
dependency('vte-2.91-gtk4', version: '>= 0.72.0')
|
||||
|
||||
glib_compile_resources = find_program('glib-compile-resources', required: true)
|
||||
# glib_compile_schemas = find_program('glib-compile-schemas', required: true)
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::path::Path;
|
|||
pub struct Git {
|
||||
pub repo: String,
|
||||
pub dir: String,
|
||||
pub default_branch: String,
|
||||
pub branch: String,
|
||||
}
|
||||
|
||||
impl Git {
|
||||
|
@ -88,7 +88,7 @@ impl Git {
|
|||
}
|
||||
|
||||
pub fn get_checkout_ref_job(&self) -> WorkerJob {
|
||||
let gref = self.get_ref().unwrap_or(self.default_branch.clone());
|
||||
let gref = self.get_ref().unwrap_or(self.branch.clone());
|
||||
self.cmd(vec!["checkout".into(), gref])
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,10 @@ pub fn get_build_basalt_jobs(profile: &Profile, clean_build: bool) -> VecDeque<W
|
|||
None => "https://gitlab.freedesktop.org/mateosss/basalt.git".into(),
|
||||
},
|
||||
dir: profile.features.basalt.path.as_ref().unwrap().clone(),
|
||||
default_branch: "main".into(),
|
||||
branch: match profile.features.basalt.branch.as_ref() {
|
||||
Some(r) => r.clone(),
|
||||
None => "main".into(),
|
||||
},
|
||||
};
|
||||
|
||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||
|
|
|
@ -18,7 +18,10 @@ pub fn get_build_libsurvive_jobs(profile: &Profile, clean_build: bool) -> VecDeq
|
|||
None => "https://github.com/cntools/libsurvive".into(),
|
||||
},
|
||||
dir: profile.features.libsurvive.path.as_ref().unwrap().clone(),
|
||||
default_branch: "master".into(),
|
||||
branch: match profile.features.libsurvive.branch.as_ref() {
|
||||
Some(r) => r.clone(),
|
||||
None => "master".into(),
|
||||
},
|
||||
};
|
||||
|
||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||
|
|
|
@ -22,7 +22,10 @@ pub fn get_build_monado_jobs(
|
|||
None => "https://gitlab.freedesktop.org/monado/monado".into(),
|
||||
},
|
||||
dir: profile.xrservice_path.clone(),
|
||||
default_branch: "main".into(),
|
||||
branch: match profile.xrservice_branch.as_ref() {
|
||||
Some(r) => r.clone(),
|
||||
None => "main".into(),
|
||||
},
|
||||
};
|
||||
|
||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||
|
|
|
@ -22,7 +22,10 @@ pub fn get_build_opencomposite_jobs(
|
|||
None => "https://gitlab.com/znixian/OpenOVR.git".into(),
|
||||
},
|
||||
dir: profile.opencomposite_path.clone(),
|
||||
default_branch: "openxr".into(),
|
||||
branch: match profile.opencomposite_branch.as_ref() {
|
||||
Some(r) => r.clone(),
|
||||
None => "openxr".into(),
|
||||
},
|
||||
};
|
||||
|
||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||
|
|
|
@ -18,7 +18,10 @@ pub fn get_build_openhmd_jobs(profile: &Profile, clean_build: bool) -> VecDeque<
|
|||
None => "https://github.com/OpenHMD/OpenHMD".into(),
|
||||
},
|
||||
dir: profile.features.openhmd.path.as_ref().unwrap().clone(),
|
||||
default_branch: "master".into(),
|
||||
branch: match profile.features.openhmd.branch.as_ref() {
|
||||
Some(r) => r.clone(),
|
||||
None => "master".into(),
|
||||
},
|
||||
};
|
||||
|
||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||
|
|
|
@ -22,7 +22,10 @@ pub fn get_build_wivrn_jobs(
|
|||
None => "https://github.com/Meumeu/WiVRn".into(),
|
||||
},
|
||||
dir: profile.xrservice_path.clone(),
|
||||
default_branch: "master".into(),
|
||||
branch: match profile.xrservice_branch.as_ref() {
|
||||
Some(r) => r.clone(),
|
||||
None => "master".into(),
|
||||
},
|
||||
};
|
||||
|
||||
jobs.extend(git.get_pre_build_jobs(profile.pull_on_build));
|
||||
|
|
|
@ -40,6 +40,16 @@ fn monado_deps() -> Vec<Dependency> {
|
|||
]),
|
||||
},
|
||||
dep_glslang_validator(),
|
||||
Dependency {
|
||||
name: "sdl2".into(),
|
||||
dep_type: DepType::SharedObject,
|
||||
filename: "libSDL2.so".into(),
|
||||
packages: HashMap::from([
|
||||
(LinuxDistro::Arch, "sdl2".into()),
|
||||
(LinuxDistro::Debian, "libsdl2".into()),
|
||||
(LinuxDistro::Fedora, "SDL2".into()),
|
||||
]),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ pub static ENV_VAR_DESCRIPTIONS: Map<&str, &str> = phf_map! {
|
|||
"XRT_DEBUG_GUI" => "Set to 1 to enable the Monado debug UI.",
|
||||
"XRT_CURATED_GUI" => "Set to 1 to enable the Monado preview UI. Requires XRT_DEBUG_GUI=1 to work.",
|
||||
"XRT_JSON_LOG" => "Set to 1 to enable JSON logging for Monado. This enables better log visualization and log level filtering.",
|
||||
"QWERTY_ENABLE" => "Set to 1 to enable QWERTY Simulation driver. This enables simulated driver that allows you to use Monado without HMD and controllers. It's also possible to mix and match different profiles with this.",
|
||||
"LH_DRIVER" => "Lighthouse driver, this overrides the \"Lighthouse driver option in the profile\"; Valid options are: \"vive\" for the default built-in driver, \"survive\" for Libsurvive, \"steamvr\" for the SteamVR based implementation.",
|
||||
"LH_LOG" => "Lighthouse log level. Can be one of: \"trace\", \"debug\", \"info\", \"warn\", \"error\".",
|
||||
"LIGHTHOUSE_LOG" => "Lighthouse driver log level. Can be one of: \"trace\", \"debug\", \"info\", \"warn\", \"error\"."
|
||||
|
|
|
@ -85,6 +85,10 @@ pub struct WivrnConfEncoder {
|
|||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub height: Option<f32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub offset_x: Option<f32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub offset_y: Option<f32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub group: Option<i32>,
|
||||
}
|
||||
|
||||
|
@ -96,6 +100,8 @@ impl Default for WivrnConfEncoder {
|
|||
bitrate: None,
|
||||
width: None,
|
||||
height: None,
|
||||
offset_x: None,
|
||||
offset_y: None,
|
||||
group: None,
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +124,8 @@ impl Default for WivrnConfig {
|
|||
bitrate: Some(100000000),
|
||||
width: Some(1.0),
|
||||
height: Some(1.0),
|
||||
offset_x: Some(0.0),
|
||||
offset_y: Some(0.0),
|
||||
group: None,
|
||||
}],
|
||||
}
|
||||
|
@ -162,5 +170,7 @@ mod tests {
|
|||
assert_eq!(conf.encoders.get(0).unwrap().bitrate, Some(100000000));
|
||||
assert_eq!(conf.encoders.get(0).unwrap().width, Some(1.0));
|
||||
assert_eq!(conf.encoders.get(0).unwrap().height, Some(1.0));
|
||||
assert_eq!(conf.encoders.get(0).unwrap().offset_x, Some(0.0));
|
||||
assert_eq!(conf.encoders.get(0).unwrap().offset_y, Some(0.0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ pub struct ProfileFeature {
|
|||
pub enabled: bool,
|
||||
pub path: Option<String>,
|
||||
pub repo: Option<String>,
|
||||
pub branch: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for ProfileFeature {
|
||||
|
@ -99,6 +100,7 @@ impl Default for ProfileFeature {
|
|||
enabled: false,
|
||||
path: None,
|
||||
repo: None,
|
||||
branch: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,10 +212,12 @@ pub struct Profile {
|
|||
pub xrservice_type: XRServiceType,
|
||||
pub xrservice_path: String,
|
||||
pub xrservice_repo: Option<String>,
|
||||
pub xrservice_branch: Option<String>,
|
||||
#[serde(default = "HashMap::<String, String>::default")]
|
||||
pub xrservice_cmake_flags: HashMap<String, String>,
|
||||
pub opencomposite_path: String,
|
||||
pub opencomposite_repo: Option<String>,
|
||||
pub opencomposite_branch: Option<String>,
|
||||
pub features: ProfileFeatures,
|
||||
pub environment: HashMap<String, String>,
|
||||
/** Install prefix */
|
||||
|
@ -243,24 +247,28 @@ impl Default for Profile {
|
|||
xrservice_path: format!("{}/xrservice", profile_dir),
|
||||
xrservice_type: XRServiceType::Monado,
|
||||
xrservice_repo: None,
|
||||
xrservice_branch: None,
|
||||
xrservice_cmake_flags: HashMap::<String, String>::default(),
|
||||
features: ProfileFeatures {
|
||||
libsurvive: ProfileFeature {
|
||||
enabled: false,
|
||||
path: Some(format!("{}/libsurvive", profile_dir)),
|
||||
repo: None,
|
||||
branch: None,
|
||||
feature_type: ProfileFeatureType::Libsurvive,
|
||||
},
|
||||
basalt: ProfileFeature {
|
||||
enabled: false,
|
||||
path: Some(format!("{}/basalt", profile_dir)),
|
||||
repo: None,
|
||||
branch: None,
|
||||
feature_type: ProfileFeatureType::Basalt,
|
||||
},
|
||||
openhmd: ProfileFeature {
|
||||
enabled: false,
|
||||
path: Some(format!("{}/openhmd", profile_dir)),
|
||||
repo: None,
|
||||
branch: None,
|
||||
feature_type: ProfileFeatureType::OpenHmd,
|
||||
},
|
||||
mercury_enabled: false,
|
||||
|
@ -269,8 +277,9 @@ impl Default for Profile {
|
|||
prefix: format!("{}/prefixes/{}", get_data_dir(), uuid),
|
||||
can_be_built: true,
|
||||
pull_on_build: true,
|
||||
opencomposite_repo: None,
|
||||
opencomposite_path: format!("{}/opencomposite", profile_dir),
|
||||
opencomposite_repo: None,
|
||||
opencomposite_branch: None,
|
||||
editable: true,
|
||||
lighthouse_driver: LighthouseDriver::default(),
|
||||
xrservice_launch_options: String::default(),
|
||||
|
@ -337,17 +346,28 @@ impl Profile {
|
|||
dup.name = format!("Duplicate of {}", self.name);
|
||||
dup.xrservice_type = self.xrservice_type.clone();
|
||||
dup.xrservice_repo = self.xrservice_repo.clone();
|
||||
dup.xrservice_branch = self.xrservice_branch.clone();
|
||||
dup.xrservice_cmake_flags = self.xrservice_cmake_flags.clone();
|
||||
dup.features.libsurvive.enabled = self.features.libsurvive.enabled;
|
||||
dup.features.libsurvive.repo = self.features.libsurvive.repo.clone();
|
||||
dup.features.libsurvive.branch = self.features.libsurvive.branch.clone();
|
||||
dup.features.basalt.enabled = self.features.basalt.enabled;
|
||||
dup.features.basalt.repo = self.features.basalt.repo.clone();
|
||||
dup.features.basalt.branch = self.features.basalt.branch.clone();
|
||||
dup.features.openhmd.enabled = self.features.openhmd.enabled;
|
||||
dup.features.openhmd.repo = self.features.openhmd.repo.clone();
|
||||
dup.features.openhmd.branch = self.features.openhmd.branch.clone();
|
||||
dup.features.mercury_enabled = self.features.mercury_enabled;
|
||||
dup.environment = self.environment.clone();
|
||||
if dup.environment.contains_key("LD_LIBRARY_PATH".into()) {
|
||||
dup.environment.insert(
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
prepare_ld_library_path(&dup.prefix),
|
||||
);
|
||||
}
|
||||
dup.pull_on_build = self.pull_on_build;
|
||||
dup.opencomposite_repo = self.opencomposite_repo.clone();
|
||||
dup.opencomposite_branch = self.opencomposite_branch.clone();
|
||||
dup.lighthouse_driver = self.lighthouse_driver;
|
||||
dup.xrservice_launch_options = self.xrservice_launch_options.clone();
|
||||
dup
|
||||
|
@ -467,6 +487,7 @@ mod tests {
|
|||
enabled: true,
|
||||
path: Some(String::from("/home/user/libsurvive")),
|
||||
repo: None,
|
||||
branch: None,
|
||||
},
|
||||
basalt: ProfileFeature::default_basalt(),
|
||||
openhmd: ProfileFeature::default_openhmd(),
|
||||
|
@ -494,3 +515,7 @@ mod tests {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prepare_ld_library_path(prefix: &str) -> String {
|
||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
constants::APP_NAME,
|
||||
paths::{data_monado_path, data_opencomposite_path, get_data_dir},
|
||||
profile::{LighthouseDriver, Profile, ProfileFeatures, XRServiceType},
|
||||
profile::{prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeatures, XRServiceType},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@ -15,10 +15,7 @@ pub fn lighthouse_profile() -> Profile {
|
|||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||
environment.insert(
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
||||
);
|
||||
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||
Profile {
|
||||
uuid: "lighthouse-default".into(),
|
||||
name: format!("Lighthouse Driver - {name} Default", name = APP_NAME),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
pub mod lighthouse;
|
||||
pub mod openhmd;
|
||||
pub mod simulated;
|
||||
pub mod survive;
|
||||
pub mod wivrn;
|
||||
pub mod wmr;
|
||||
|
|
|
@ -2,8 +2,8 @@ use crate::{
|
|||
constants::APP_NAME,
|
||||
paths::{data_monado_path, data_opencomposite_path, data_openhmd_path, get_data_dir},
|
||||
profile::{
|
||||
LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures,
|
||||
XRServiceType,
|
||||
prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType,
|
||||
ProfileFeatures, XRServiceType,
|
||||
},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
@ -18,10 +18,7 @@ pub fn openhmd_profile() -> Profile {
|
|||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||
environment.insert(
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
||||
);
|
||||
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||
Profile {
|
||||
uuid: "openhmd-default".into(),
|
||||
name: format!("OpenHMD - {name} Default", name = APP_NAME),
|
||||
|
@ -34,6 +31,7 @@ pub fn openhmd_profile() -> Profile {
|
|||
enabled: true,
|
||||
path: Some(data_openhmd_path()),
|
||||
repo: None,
|
||||
branch: None,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
|
|
36
src/profiles/simulated.rs
Normal file
36
src/profiles/simulated.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use crate::{
|
||||
constants::APP_NAME,
|
||||
paths::{data_monado_path, data_opencomposite_path, get_data_dir},
|
||||
profile::{Profile, ProfileFeatures, XRServiceType},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn simulated_profile() -> Profile {
|
||||
let data_dir = get_data_dir();
|
||||
let prefix = format!("{data}/prefixes/simulated_default", data = data_dir);
|
||||
let mut environment: HashMap<String, String> = HashMap::new();
|
||||
environment.insert("QWERTY_ENABLE".into(), "1".into());
|
||||
environment.insert("XRT_JSON_LOG".into(), "1".into());
|
||||
environment.insert("XRT_COMPOSITOR_SCALE_PERCENTAGE".into(), "140".into());
|
||||
environment.insert("XRT_COMPOSITOR_COMPUTE".into(), "1".into());
|
||||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||
environment.insert(
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
||||
);
|
||||
Profile {
|
||||
uuid: "simulated-default".into(),
|
||||
name: format!("Simulated Driver - {name} Default", name = APP_NAME),
|
||||
xrservice_path: data_monado_path(),
|
||||
xrservice_type: XRServiceType::Monado,
|
||||
opencomposite_path: data_opencomposite_path(),
|
||||
features: ProfileFeatures::default(),
|
||||
environment,
|
||||
prefix,
|
||||
can_be_built: true,
|
||||
editable: false,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ use crate::{
|
|||
constants::APP_NAME,
|
||||
paths::{data_libsurvive_path, data_monado_path, data_opencomposite_path, get_data_dir},
|
||||
profile::{
|
||||
LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures,
|
||||
XRServiceType,
|
||||
prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType,
|
||||
ProfileFeatures, XRServiceType,
|
||||
},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
@ -20,10 +20,7 @@ pub fn survive_profile() -> Profile {
|
|||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||
environment.insert(
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
||||
);
|
||||
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||
Profile {
|
||||
uuid: "survive-default".into(),
|
||||
name: format!("Survive - {name} Default", name = APP_NAME),
|
||||
|
@ -36,6 +33,7 @@ pub fn survive_profile() -> Profile {
|
|||
enabled: true,
|
||||
path: Some(data_libsurvive_path()),
|
||||
repo: None,
|
||||
branch: None,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
constants::APP_NAME,
|
||||
paths::{data_opencomposite_path, data_wivrn_path, get_data_dir},
|
||||
profile::{Profile, ProfileFeatures, XRServiceType},
|
||||
profile::{prepare_ld_library_path, Profile, ProfileFeatures, XRServiceType},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@ -9,10 +9,7 @@ pub fn wivrn_profile() -> Profile {
|
|||
let data_dir = get_data_dir();
|
||||
let prefix = format!("{data}/prefixes/wivrn_default", data = data_dir);
|
||||
let mut environment: HashMap<String, String> = HashMap::new();
|
||||
environment.insert(
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
||||
);
|
||||
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||
|
|
|
@ -2,8 +2,8 @@ use crate::{
|
|||
constants::APP_NAME,
|
||||
paths::{data_basalt_path, data_monado_path, data_opencomposite_path, get_data_dir},
|
||||
profile::{
|
||||
LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures,
|
||||
XRServiceType,
|
||||
prepare_ld_library_path, LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType,
|
||||
ProfileFeatures, XRServiceType,
|
||||
},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
@ -18,10 +18,7 @@ pub fn wmr_profile() -> Profile {
|
|||
environment.insert("XRT_DEBUG_GUI".into(), "1".into());
|
||||
environment.insert("XRT_CURATED_GUI".into(), "1".into());
|
||||
environment.insert("U_PACING_APP_USE_MIN_FRAME_PERIOD".into(), "1".into());
|
||||
environment.insert(
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
format!("{pfx}/lib:{pfx}/lib64", pfx = prefix),
|
||||
);
|
||||
environment.insert("LD_LIBRARY_PATH".into(), prepare_ld_library_path(&prefix));
|
||||
Profile {
|
||||
uuid: "wmr-default".into(),
|
||||
name: format!("WMR - {name} Default", name = APP_NAME),
|
||||
|
@ -34,6 +31,7 @@ pub fn wmr_profile() -> Profile {
|
|||
enabled: true,
|
||||
path: Some(data_basalt_path()),
|
||||
repo: None,
|
||||
branch: None,
|
||||
},
|
||||
mercury_enabled: true,
|
||||
..Default::default()
|
||||
|
|
|
@ -40,6 +40,7 @@ use crate::paths::{get_data_dir, get_ipc_file_path};
|
|||
use crate::profile::{Profile, XRServiceType};
|
||||
use crate::profiles::lighthouse::lighthouse_profile;
|
||||
use crate::profiles::openhmd::openhmd_profile;
|
||||
use crate::profiles::simulated::simulated_profile;
|
||||
use crate::profiles::survive::survive_profile;
|
||||
use crate::profiles::wivrn::wivrn_profile;
|
||||
use crate::profiles::wmr::wmr_profile;
|
||||
|
@ -256,6 +257,7 @@ impl App {
|
|||
wivrn_profile(),
|
||||
wmr_profile(),
|
||||
openhmd_profile(),
|
||||
simulated_profile(),
|
||||
];
|
||||
profiles.extend(config.user_profiles.clone());
|
||||
profiles.sort_unstable_by(|a, b| a.name.cmp(&b.name));
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use super::term_widget::TermWidget;
|
||||
use gtk::prelude::*;
|
||||
use relm4::prelude::*;
|
||||
|
||||
|
@ -11,20 +12,15 @@ pub enum BuildStatus {
|
|||
#[tracker::track]
|
||||
pub struct BuildWindow {
|
||||
title: String,
|
||||
content: String,
|
||||
can_close: bool,
|
||||
build_status: BuildStatus,
|
||||
|
||||
#[tracker::do_not_track]
|
||||
pub textbuf: gtk::TextBuffer,
|
||||
#[tracker::do_not_track]
|
||||
pub textview: Option<gtk::TextView>,
|
||||
#[tracker::do_not_track]
|
||||
pub win: Option<adw::Window>,
|
||||
#[tracker::do_not_track]
|
||||
build_status_label: Option<gtk::Label>,
|
||||
#[tracker::do_not_track]
|
||||
scrolledwin: Option<gtk::ScrolledWindow>,
|
||||
term: TermWidget,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -108,26 +104,7 @@ impl SimpleComponent for BuildWindow {
|
|||
}
|
||||
},
|
||||
},
|
||||
#[name(scrolledwin)]
|
||||
gtk::ScrolledWindow {
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
set_margin_all: 12,
|
||||
add_css_class: "card",
|
||||
set_overflow: gtk::Overflow::Hidden,
|
||||
#[name(textview)]
|
||||
gtk::TextView {
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
set_editable: false,
|
||||
set_monospace: true,
|
||||
set_left_margin: 6,
|
||||
set_right_margin: 6,
|
||||
set_top_margin: 6,
|
||||
set_bottom_margin: 6,
|
||||
set_buffer: Some(&model.textbuf),
|
||||
},
|
||||
},
|
||||
model.term.container.clone(),
|
||||
},
|
||||
add_bottom_bar: bottom_bar = >k::Button {
|
||||
add_css_class: "pill",
|
||||
|
@ -150,10 +127,10 @@ impl SimpleComponent for BuildWindow {
|
|||
|
||||
match message {
|
||||
Self::Input::Present => {
|
||||
self.win.as_ref().unwrap().present();
|
||||
self.term.set_color_scheme();
|
||||
sender.input(BuildWindowMsg::UpdateBuildStatus(BuildStatus::Building));
|
||||
self.set_content("".into());
|
||||
self.textbuf.set_text("");
|
||||
self.term.clear();
|
||||
self.win.as_ref().unwrap().present();
|
||||
}
|
||||
Self::Input::UpdateTitle(t) => {
|
||||
self.set_title(t);
|
||||
|
@ -161,17 +138,7 @@ impl SimpleComponent for BuildWindow {
|
|||
Self::Input::UpdateContent(c) => {
|
||||
if !c.is_empty() {
|
||||
let n_lines = c.concat();
|
||||
let mut n_content = self.content.clone();
|
||||
n_content.push_str(n_lines.as_str());
|
||||
self.set_content(n_content);
|
||||
self.textbuf
|
||||
.insert(&mut self.textbuf.end_iter(), n_lines.as_str());
|
||||
let textbuf = self.textbuf.clone();
|
||||
let textview = self.textview.as_ref().unwrap().clone();
|
||||
gtk::glib::idle_add_local_once(move || {
|
||||
let end_mark = textbuf.create_mark(None, &textbuf.end_iter(), false);
|
||||
textview.scroll_mark_onscreen(&end_mark);
|
||||
});
|
||||
self.term.feed(&n_lines);
|
||||
}
|
||||
}
|
||||
Self::Input::UpdateBuildStatus(status) => {
|
||||
|
@ -202,20 +169,21 @@ impl SimpleComponent for BuildWindow {
|
|||
let mut model = Self {
|
||||
tracker: 0,
|
||||
title: "".into(),
|
||||
content: "".into(),
|
||||
can_close: false,
|
||||
textbuf: gtk::TextBuffer::builder().enable_undo(false).build(),
|
||||
textview: None,
|
||||
build_status: BuildStatus::Building,
|
||||
win: None,
|
||||
scrolledwin: None,
|
||||
build_status_label: None,
|
||||
term: {
|
||||
let t = TermWidget::new();
|
||||
t.container.add_css_class("card");
|
||||
t.container.set_margin_all(12);
|
||||
t.container.set_overflow(gtk::Overflow::Hidden);
|
||||
t
|
||||
},
|
||||
};
|
||||
let widgets = view_output!();
|
||||
model.win = Some(widgets.win.clone());
|
||||
model.build_status_label = Some(widgets.build_status_label.clone());
|
||||
model.textview = Some(widgets.textview.clone());
|
||||
model.scrolledwin = Some(widgets.scrolledwin.clone());
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ use gtk::glib::clone;
|
|||
use gtk::prelude::*;
|
||||
use relm4::prelude::*;
|
||||
use relm4::{ComponentSender, SimpleComponent};
|
||||
use zoha_vte4::{Terminal, TerminalExt};
|
||||
use zoha_vte4::TerminalExt;
|
||||
|
||||
use super::term_widget::TermWidget;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SearchDirection {
|
||||
|
@ -37,13 +39,11 @@ pub struct DebugView {
|
|||
#[tracker::do_not_track]
|
||||
log_level: LogLevel,
|
||||
#[tracker::do_not_track]
|
||||
vte_terminal: Terminal,
|
||||
term: TermWidget,
|
||||
}
|
||||
|
||||
pub struct DebugViewInit {}
|
||||
|
||||
const MAX_SCROLLBACK: u32 = 2000;
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for DebugView {
|
||||
type Init = DebugViewInit;
|
||||
|
@ -115,16 +115,11 @@ impl SimpleComponent for DebugView {
|
|||
},
|
||||
connect_entry: &search_entry,
|
||||
},
|
||||
#[wrap(Some)]
|
||||
set_content: sw = >k::ScrolledWindow {
|
||||
set_hexpand: true,
|
||||
set_vexpand: true,
|
||||
model.vte_terminal.clone(),
|
||||
}
|
||||
set_content: Some(&model.term.container),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
|
||||
self.reset();
|
||||
|
||||
match message {
|
||||
|
@ -142,19 +137,17 @@ impl SimpleComponent for DebugView {
|
|||
let search_entry = self.search_entry.as_ref().unwrap().clone();
|
||||
let search_text = search_entry.text().to_string();
|
||||
if searchbar.is_search_mode() && !search_text.is_empty() {
|
||||
if let Ok(regex) = zoha_vte4::Regex::for_search(&search_text, 0) {
|
||||
self.vte_terminal.search_set_regex(Some(®ex), 0);
|
||||
}
|
||||
self.term.set_search_term(Some(&search_text));
|
||||
} else {
|
||||
self.vte_terminal.search_set_regex(None, 0);
|
||||
self.term.set_search_term(None);
|
||||
}
|
||||
}
|
||||
Self::Input::SearchFindMatch(direction) => match direction {
|
||||
SearchDirection::Forward => {
|
||||
self.vte_terminal.search_find_next();
|
||||
self.term.search_next();
|
||||
}
|
||||
SearchDirection::Backward => {
|
||||
self.vte_terminal.search_find_previous();
|
||||
self.term.search_prev();
|
||||
}
|
||||
},
|
||||
Self::Input::LogUpdated(n_log) => {
|
||||
|
@ -173,15 +166,15 @@ impl SimpleComponent for DebugView {
|
|||
None => Some(row),
|
||||
};
|
||||
if let Some(t) = txt {
|
||||
self.vte_terminal.feed(t.as_bytes())
|
||||
self.term.feed(&t);
|
||||
}
|
||||
}
|
||||
}
|
||||
Self::Input::ClearLog => {
|
||||
self.vte_terminal.feed("\x1bc".as_bytes());
|
||||
self.term.clear();
|
||||
}
|
||||
Self::Input::SetColorScheme => {
|
||||
Self::set_color_scheme(&self.vte_terminal);
|
||||
self.term.set_color_scheme();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,24 +216,13 @@ impl SimpleComponent for DebugView {
|
|||
search_entry: None,
|
||||
dropdown: None,
|
||||
log_level: LogLevel::Trace,
|
||||
vte_terminal: {
|
||||
let t = Terminal::builder()
|
||||
.scroll_on_output(true)
|
||||
.scrollback_lines(MAX_SCROLLBACK)
|
||||
.scroll_unit_is_pixels(true)
|
||||
.vexpand(true)
|
||||
.hexpand(true)
|
||||
.build();
|
||||
t.set_clear_background(false);
|
||||
t.search_set_wrap_around(true);
|
||||
Self::set_color_scheme(&t);
|
||||
t
|
||||
},
|
||||
term: TermWidget::new(),
|
||||
};
|
||||
model.term.set_color_scheme();
|
||||
|
||||
{
|
||||
let sc = gtk::ShortcutController::new();
|
||||
let term = model.vte_terminal.clone();
|
||||
let term = model.term.term.clone();
|
||||
sc.add_shortcut(gtk::Shortcut::new(
|
||||
gtk::ShortcutTrigger::parse_string("<Control>c"),
|
||||
Some(gtk::CallbackAction::new(move |_, _| {
|
||||
|
@ -250,7 +232,7 @@ impl SimpleComponent for DebugView {
|
|||
true
|
||||
})),
|
||||
));
|
||||
let term = model.vte_terminal.clone();
|
||||
let term = model.term.term.clone();
|
||||
sc.add_shortcut(gtk::Shortcut::new(
|
||||
gtk::ShortcutTrigger::parse_string("<Control>a"),
|
||||
Some(gtk::CallbackAction::new(move |_, _| {
|
||||
|
@ -258,7 +240,7 @@ impl SimpleComponent for DebugView {
|
|||
true
|
||||
})),
|
||||
));
|
||||
model.vte_terminal.add_controller(sc);
|
||||
model.term.term.add_controller(sc);
|
||||
}
|
||||
|
||||
let widgets = view_output!();
|
||||
|
@ -269,13 +251,3 @@ impl SimpleComponent for DebugView {
|
|||
ComponentParts { model, widgets }
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugView {
|
||||
fn set_color_scheme(term: &Terminal) {
|
||||
if adw::StyleManager::default().is_dark() {
|
||||
term.set_color_foreground(>k::gdk::RGBA::new(1.0, 1.0, 1.0, 1.0));
|
||||
} else {
|
||||
term.set_color_foreground(>k::gdk::RGBA::new(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
|||
file_builders::wivrn_config::{Codec, Encoder, WivrnConfEncoder},
|
||||
ui::{
|
||||
preference_rows::{combo_row, number_entry_row, spin_row},
|
||||
util::{bits_from_mbits, bits_to_mbits},
|
||||
wivrn_conf_editor::WivrnConfEditorMsg,
|
||||
},
|
||||
};
|
||||
|
@ -24,6 +25,8 @@ pub enum WivrnEncoderModelMsg {
|
|||
BitrateChanged(Option<u32>),
|
||||
WidthChanged(Option<f32>),
|
||||
HeightChanged(Option<f32>),
|
||||
OffsetXChanged(Option<f32>),
|
||||
OffsetYChanged(Option<f32>),
|
||||
GroupChanged(Option<i32>),
|
||||
Delete,
|
||||
}
|
||||
|
@ -83,9 +86,13 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
|||
}
|
||||
) -> adw::ComboRow,
|
||||
add: bitrate_row = &number_entry_row(
|
||||
"Bitrate",
|
||||
"Bitrate (Mbps)",
|
||||
&self.encoder_conf.bitrate
|
||||
.and_then(|n| Some(n.to_string()))
|
||||
.and_then(|n| if let Some(mbits) = bits_to_mbits(n) {
|
||||
Some(mbits.to_string())
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
false,
|
||||
{
|
||||
|
@ -96,7 +103,10 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
|||
if txt.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(txt.parse::<u32>().unwrap())
|
||||
match txt.parse::<u32>() {
|
||||
Ok(bits) => bits_from_mbits(bits),
|
||||
Err(e) => None,
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
@ -134,6 +144,38 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
|||
}
|
||||
}
|
||||
) -> adw::SpinRow,
|
||||
add: offset_x_row = &spin_row(
|
||||
"Offset X",
|
||||
None,
|
||||
self.encoder_conf.offset_x.unwrap_or(0.0).into(),
|
||||
0.0,
|
||||
1.0,
|
||||
0.01,
|
||||
{
|
||||
let sender = sender.clone();
|
||||
move |adj| {
|
||||
sender.input(Self::Input::OffsetXChanged(
|
||||
Some(adj.value() as f32)
|
||||
));
|
||||
}
|
||||
}
|
||||
) -> adw::SpinRow,
|
||||
add: offset_y_row = &spin_row(
|
||||
"Offset Y",
|
||||
None,
|
||||
self.encoder_conf.offset_y.unwrap_or(0.0).into(),
|
||||
0.0,
|
||||
1.0,
|
||||
0.01,
|
||||
{
|
||||
let sender = sender.clone();
|
||||
move |adj| {
|
||||
sender.input(Self::Input::OffsetYChanged(
|
||||
Some(adj.value() as f32)
|
||||
));
|
||||
}
|
||||
}
|
||||
) -> adw::SpinRow,
|
||||
add: group_row = &spin_row(
|
||||
"Group",
|
||||
None,
|
||||
|
@ -170,6 +212,12 @@ impl AsyncFactoryComponent for WivrnEncoderModel {
|
|||
Self::Input::HeightChanged(val) => {
|
||||
self.encoder_conf.height = val;
|
||||
}
|
||||
Self::Input::OffsetXChanged(val) => {
|
||||
self.encoder_conf.offset_x = val;
|
||||
}
|
||||
Self::Input::OffsetYChanged(val) => {
|
||||
self.encoder_conf.offset_y = val;
|
||||
}
|
||||
Self::Input::GroupChanged(val) => {
|
||||
self.encoder_conf.group = val;
|
||||
}
|
||||
|
|
|
@ -174,11 +174,11 @@ impl InternalJobWorker {
|
|||
let mut launch_opts = prof.xrservice_launch_options.trim();
|
||||
let debug_launch_opts = if debug {
|
||||
if launch_opts.contains(LAUNCH_OPTS_CMD_PLACEHOLDER) {
|
||||
format!("{} {}", "gdb -batch -ex run -ex bt --args", launch_opts)
|
||||
format!("{} {}", "gdbserver localhost:9000", launch_opts)
|
||||
} else {
|
||||
format!(
|
||||
"{} {} {}",
|
||||
"gdb -batch -ex run -ex bt --args", LAUNCH_OPTS_CMD_PLACEHOLDER, launch_opts
|
||||
"gdbserver localhost:9000", LAUNCH_OPTS_CMD_PLACEHOLDER, launch_opts
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use crate::{cmd_runner::CmdRunner, profile::Profile, runner::Runner};
|
||||
use super::alert::alert;
|
||||
use crate::{
|
||||
cmd_runner::CmdRunner,
|
||||
profile::{prepare_ld_library_path, Profile},
|
||||
runner::Runner,
|
||||
};
|
||||
use adw::prelude::*;
|
||||
use gtk::glib;
|
||||
use relm4::prelude::*;
|
||||
use std::{cell::Cell, collections::HashMap, path::Path, rc::Rc, time::Duration};
|
||||
|
||||
use super::alert::alert;
|
||||
|
||||
const NO_FILE_MSG: &str = "(No file selected)";
|
||||
const CALIBRATION_RUN_TIME_SECONDS: f64 = 30.0;
|
||||
|
||||
|
@ -57,9 +60,10 @@ impl LibsurviveSetupWindow {
|
|||
fn create_calibration_runner(&mut self, survive_cli_path: String) -> CmdRunner {
|
||||
let lh_path = self.steam_lighthouse_path.clone();
|
||||
let mut env = HashMap::new();
|
||||
let profile_prefix = &self.profile.as_ref().unwrap().prefix;
|
||||
env.insert(
|
||||
"LD_LIBRARY_PATH".to_string(),
|
||||
format!("{pfx}/lib", pfx = self.profile.as_ref().unwrap().prefix),
|
||||
"LD_LIBRARY_PATH".into(),
|
||||
prepare_ld_library_path(&profile_prefix),
|
||||
);
|
||||
CmdRunner::new(
|
||||
Some(env),
|
||||
|
|
|
@ -185,7 +185,7 @@ impl SimpleComponent for MainView {
|
|||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_label: "Start with GDB",
|
||||
set_label: "Start with gdbserver",
|
||||
#[track = "model.changed(Self::xrservice_active()) || model.changed(Self::enable_debug_view())"]
|
||||
set_visible: model.enable_debug_view && !model.xrservice_active,
|
||||
connect_clicked[sender] => move |_| {
|
||||
|
|
|
@ -16,5 +16,6 @@ pub mod profile_editor;
|
|||
pub mod stardust;
|
||||
pub mod steam_launch_options_box;
|
||||
mod steamvr_calibration_box;
|
||||
pub mod term_widget;
|
||||
pub mod util;
|
||||
pub mod wivrn_conf_editor;
|
||||
|
|
|
@ -176,6 +176,14 @@ impl SimpleComponent for ProfileEditor {
|
|||
prof.borrow_mut().xrservice_repo = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
add: &entry_row(
|
||||
"XR Service Branch",
|
||||
model.profile.borrow().xrservice_branch.clone().unwrap_or_default().as_str(),
|
||||
clone!(@strong prof => move |row| {
|
||||
let n_val = row.text().to_string();
|
||||
prof.borrow_mut().xrservice_branch = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
},
|
||||
add: model.xrservice_cmake_flags_rows.widget(),
|
||||
add: opencompgrp = &adw::PreferencesGroup {
|
||||
|
@ -197,6 +205,14 @@ impl SimpleComponent for ProfileEditor {
|
|||
prof.borrow_mut().opencomposite_repo = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
add: &entry_row(
|
||||
"OpenComposite Branch",
|
||||
model.profile.borrow().opencomposite_branch.clone().unwrap_or_default().as_str(),
|
||||
clone!(@strong prof => move |row| {
|
||||
let n_val = row.text().to_string();
|
||||
prof.borrow_mut().opencomposite_branch = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
},
|
||||
add: libsurvivegrp = &adw::PreferencesGroup {
|
||||
set_title: "Libsurvive",
|
||||
|
@ -225,6 +241,14 @@ impl SimpleComponent for ProfileEditor {
|
|||
prof.borrow_mut().features.libsurvive.repo = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
add: &entry_row(
|
||||
"Libsurvive Branch",
|
||||
model.profile.borrow().features.libsurvive.branch.clone().unwrap_or_default().as_str(),
|
||||
clone!(@strong prof => move |row| {
|
||||
let n_val = row.text().to_string();
|
||||
prof.borrow_mut().features.libsurvive.branch = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
},
|
||||
add: openhmdgrp = &adw::PreferencesGroup {
|
||||
set_title: "OpenHMD",
|
||||
|
@ -253,6 +277,14 @@ impl SimpleComponent for ProfileEditor {
|
|||
prof.borrow_mut().features.openhmd.repo = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
add: &entry_row(
|
||||
"OpenHMD Branch",
|
||||
model.profile.borrow().features.openhmd.branch.clone().unwrap_or_default().as_str(),
|
||||
clone!(@strong prof => move |row| {
|
||||
let n_val = row.text().to_string();
|
||||
prof.borrow_mut().features.openhmd.branch = (!n_val.is_empty()).then_some(n_val);
|
||||
})
|
||||
),
|
||||
},
|
||||
add: basaltgrp = &adw::PreferencesGroup {
|
||||
set_title: "Basalt",
|
||||
|
@ -281,6 +313,14 @@ impl SimpleComponent for ProfileEditor {
|
|||
prof.borrow_mut().features.basalt.repo = n_val.is_empty().then_some(n_val);
|
||||
})
|
||||
),
|
||||
add: &entry_row(
|
||||
"Basalt Branch",
|
||||
model.profile.borrow().features.basalt.branch.clone().unwrap_or_default().as_str(),
|
||||
clone!(@strong prof => move |row| {
|
||||
let n_val = row.text().to_string();
|
||||
prof.borrow_mut().features.basalt.branch = n_val.is_empty().then_some(n_val);
|
||||
})
|
||||
),
|
||||
},
|
||||
add: mercurygrp = &adw::PreferencesGroup {
|
||||
set_title: "Mercury",
|
||||
|
|
68
src/ui/term_widget.rs
Normal file
68
src/ui/term_widget.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use gtk4::gdk;
|
||||
use relm4::adw;
|
||||
use zoha_vte4::{Terminal, TerminalExt};
|
||||
|
||||
const MAX_SCROLLBACK: u32 = 2000;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TermWidget {
|
||||
pub container: gtk4::ScrolledWindow,
|
||||
pub term: Terminal,
|
||||
}
|
||||
|
||||
impl TermWidget {
|
||||
pub fn new() -> Self {
|
||||
let term = Terminal::builder()
|
||||
.scroll_on_output(true)
|
||||
.scrollback_lines(MAX_SCROLLBACK)
|
||||
.scroll_unit_is_pixels(true)
|
||||
.vexpand(true)
|
||||
.hexpand(true)
|
||||
.build();
|
||||
term.set_clear_background(false);
|
||||
term.search_set_wrap_around(true);
|
||||
let container = gtk4::ScrolledWindow::builder()
|
||||
.hexpand(true)
|
||||
.vexpand(true)
|
||||
.child(&term)
|
||||
.build();
|
||||
let this = Self { container, term };
|
||||
this
|
||||
}
|
||||
|
||||
pub fn set_color_scheme(&self) {
|
||||
// TODO: use theme colors
|
||||
if adw::StyleManager::default().is_dark() {
|
||||
self.term
|
||||
.set_color_foreground(&gdk::RGBA::new(1.0, 1.0, 1.0, 1.0));
|
||||
} else {
|
||||
self.term
|
||||
.set_color_foreground(&gdk::RGBA::new(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn feed(&self, txt: &str) {
|
||||
self.term.feed(txt.replace('\n', "\r\n").as_bytes())
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
self.term.feed("\x1bc".as_bytes());
|
||||
}
|
||||
|
||||
pub fn set_search_term(&self, term: Option<&str>) {
|
||||
self.term.search_set_regex(
|
||||
term.map(|txt| zoha_vte4::Regex::for_search(txt, 0).ok())
|
||||
.flatten()
|
||||
.as_ref(),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn search_next(&self) {
|
||||
self.term.search_find_next();
|
||||
}
|
||||
|
||||
pub fn search_prev(&self) {
|
||||
self.term.search_find_previous();
|
||||
}
|
||||
}
|
|
@ -61,3 +61,11 @@ pub fn copy_text(txt: &str) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bits_to_mbits(bits: u32) -> Option<u32> {
|
||||
bits.checked_div(1000000)
|
||||
}
|
||||
|
||||
pub fn bits_from_mbits(mbits: u32) -> Option<u32> {
|
||||
mbits.checked_mul(1000000)
|
||||
}
|
||||
|
|
|
@ -4,20 +4,24 @@
|
|||
"xrservice_type": "Monado",
|
||||
"xrservice_path": "/home/user/monado",
|
||||
"xrservice_repo": null,
|
||||
"xrservice_branch": null,
|
||||
"opencomposite_path": "/home/user/opencomposite",
|
||||
"opencomposite_repo": null,
|
||||
"opencomposite_branch": null,
|
||||
"features": {
|
||||
"libsurvive": {
|
||||
"feature_type": "Libsurvive",
|
||||
"enabled": true,
|
||||
"path": "/home/user/libsurvive",
|
||||
"repo": null
|
||||
"repo": null,
|
||||
"branch": null
|
||||
},
|
||||
"basalt": {
|
||||
"feature_type": "Basalt",
|
||||
"enabled": false,
|
||||
"path": null,
|
||||
"repo": null
|
||||
"repo": null,
|
||||
"branch": null
|
||||
},
|
||||
"mercury_enabled": false
|
||||
},
|
||||
|
@ -30,4 +34,4 @@
|
|||
"can_be_built": true,
|
||||
"editable": true,
|
||||
"pull_on_build": true
|
||||
}
|
||||
}
|
|
@ -6,7 +6,9 @@
|
|||
"codec": "h264",
|
||||
"bitrate": 100000000,
|
||||
"width": 1.0,
|
||||
"height": 1.0
|
||||
"height": 1.0,
|
||||
"offset_x": 0.0,
|
||||
"offset_y": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue