mirror of https://github.com/wayvr-org/wayvr.git
per-action thresholds
This commit is contained in:
parent
638af5a608
commit
b906bc6656
|
|
@ -181,8 +181,6 @@
|
|||
"WATCH_VIEW_ANGLE_HELP": "Control how the watch fades away",
|
||||
"GRID_OPACITY": "Floor grid opacity",
|
||||
"GRID_OPACITY_HELP": "Opacity of the floor grid when the skybox is enabled",
|
||||
"XR_CLICK_SENSITIVITY": "XR trigger sensitivity",
|
||||
"XR_CLICK_SENSITIVITY_HELP": "Press and release values for analog triggers",
|
||||
"XWAYLAND_BY_DEFAULT": "Run apps in Compatibility mode by default",
|
||||
"SAVE": "Save",
|
||||
"CANCEL": "Cancel"
|
||||
|
|
|
|||
|
|
@ -316,8 +316,6 @@ enum SettingType {
|
|||
UseSkybox,
|
||||
WatchViewAngleMax,
|
||||
WatchViewAngleMin,
|
||||
XrClickSensitivity,
|
||||
XrClickSensitivityRelease,
|
||||
XwaylandByDefault,
|
||||
}
|
||||
|
||||
|
|
@ -378,8 +376,6 @@ impl SettingType {
|
|||
Self::UiRoundMultiplier => &mut config.ui_round_multiplier,
|
||||
Self::WatchViewAngleMax => &mut config.watch_view_angle_max,
|
||||
Self::WatchViewAngleMin => &mut config.watch_view_angle_min,
|
||||
Self::XrClickSensitivity => &mut config.xr_click_sensitivity,
|
||||
Self::XrClickSensitivityRelease => &mut config.xr_click_sensitivity_release,
|
||||
_ => panic!("Requested f32 for non-f32 SettingType"),
|
||||
}
|
||||
}
|
||||
|
|
@ -490,8 +486,6 @@ impl SettingType {
|
|||
Self::UseSkybox => Ok("APP_SETTINGS.USE_SKYBOX"),
|
||||
Self::WatchViewAngleMax => Ok("APP_SETTINGS.WATCH_VIEW_ANGLE"),
|
||||
Self::WatchViewAngleMin => Ok("APP_SETTINGS.WATCH_VIEW_ANGLE"),
|
||||
Self::XrClickSensitivity => Ok("APP_SETTINGS.XR_CLICK_SENSITIVITY"),
|
||||
Self::XrClickSensitivityRelease => Ok("APP_SETTINGS.XR_CLICK_SENSITIVITY"),
|
||||
Self::XwaylandByDefault => Ok("APP_SETTINGS.XWAYLAND_BY_DEFAULT"),
|
||||
}
|
||||
}
|
||||
|
|
@ -519,8 +513,6 @@ impl SettingType {
|
|||
Self::UseSkybox => Some("APP_SETTINGS.USE_SKYBOX_HELP"),
|
||||
Self::WatchViewAngleMax => Some("APP_SETTINGS.WATCH_VIEW_ANGLE_HELP"),
|
||||
Self::WatchViewAngleMin => Some("APP_SETTINGS.WATCH_VIEW_ANGLE_HELP"),
|
||||
Self::XrClickSensitivity => Some("APP_SETTINGS.XR_CLICK_SENSITIVITY_HELP"),
|
||||
Self::XrClickSensitivityRelease => Some("APP_SETTINGS.XR_CLICK_SENSITIVITY_HELP"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ use crate::{
|
|||
frontend::FrontendTasks,
|
||||
tab::settings::{
|
||||
SettingType, SettingsMountParams, SettingsTab,
|
||||
macros::{
|
||||
options_category, options_checkbox, options_dropdown, options_range_f32, options_slider_f32, options_slider_i32,
|
||||
},
|
||||
macros::{options_category, options_checkbox, options_dropdown, options_slider_f32, options_slider_i32},
|
||||
},
|
||||
views::{ViewUpdateParams, input_profiles},
|
||||
};
|
||||
|
|
@ -104,15 +102,6 @@ impl State {
|
|||
|
||||
if par.feats.openxr {
|
||||
options_slider_f32(par.mp, c, SettingType::PointerLerpFactor, 0.1, 1.0, 0.1)?;
|
||||
options_range_f32(
|
||||
par.mp,
|
||||
c,
|
||||
SettingType::XrClickSensitivityRelease,
|
||||
SettingType::XrClickSensitivity,
|
||||
0.1,
|
||||
0.9,
|
||||
0.1,
|
||||
)?;
|
||||
}
|
||||
|
||||
options_slider_i32(par.mp, c, SettingType::ClickFreezeTimeMs, 0, 500, 50)?;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use anyhow::{bail, Context};
|
||||
use anyhow::{Context, bail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::{AsRefStr, EnumProperty, EnumString};
|
||||
use wgui::i18n::Translation;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use crate::{
|
|||
tab::settings::horiz_cell,
|
||||
util::{
|
||||
openxr_bindings_schema::{
|
||||
BindingsDropdown, ClickType, Component, ControllerProfile, ParsedOpenXrInputPath, Side, SubpathKind,
|
||||
BindingsDropdown, ClickType, Component, ControllerProfile, ParsedOpenXrInputPath, Side, SubpathKind,
|
||||
},
|
||||
popup_manager::{MountPopupOnceParams, MountPopupOnceParamsExtra, PopupHolder, PopupPadding},
|
||||
wgui_simple,
|
||||
|
|
@ -40,7 +40,7 @@ enum Task {
|
|||
Save,
|
||||
Cancel,
|
||||
OpenContextMenu(glam::Vec2, Vec<context_menu::Cell>),
|
||||
UpdateThreshold(Rc<str>, f32, f32),
|
||||
UpdateThreshold(Rc<str>, Side, f32, f32),
|
||||
}
|
||||
|
||||
pub struct Params<'a> {
|
||||
|
|
@ -89,11 +89,15 @@ impl ViewTrait for View {
|
|||
blueprint: context_menu::Blueprint::Cells(cells),
|
||||
});
|
||||
}
|
||||
Task::UpdateThreshold(action_name, lo, hi) => {
|
||||
Task::UpdateThreshold(action_name, side, lo, hi) => {
|
||||
let cur_profile = &mut self.profiles[self.cur_profile_idx];
|
||||
let action_mut = get_action_mut(cur_profile, &*action_name);
|
||||
|
||||
action_mut.threshold = Some([lo, hi]);
|
||||
if matches!(side, Side::Right) {
|
||||
action_mut.threshold_right = Some([lo, hi]);
|
||||
} else {
|
||||
action_mut.threshold_left = Some([lo, hi]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -238,7 +242,13 @@ impl View {
|
|||
|
||||
for action in action_names {
|
||||
let current = get_action_mut(&mut self.profiles[self.cur_profile_idx], action);
|
||||
input_controls_for_action(&mut mp, self.list_parent, action.into(), &self.controller_profile, current)?;
|
||||
input_controls_for_action(
|
||||
&mut mp,
|
||||
self.list_parent,
|
||||
action.into(),
|
||||
&self.controller_profile,
|
||||
current,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -253,27 +263,31 @@ impl View {
|
|||
let action = cur_profile.pose.get_or_insert_default();
|
||||
|
||||
if action.left.is_none() && profile_left.is_some() {
|
||||
let path = "/user/hand/left/input/aim/pose";
|
||||
action.left = Some(OneOrMany::One(path.into()));
|
||||
let path = "/user/hand/left/input/aim/pose";
|
||||
action.left = Some(OneOrMany::One(path.into()));
|
||||
}
|
||||
|
||||
if action.right.is_none() && profile_right.is_some() {
|
||||
let path = "/user/hand/right/input/aim/pose";
|
||||
action.right = Some(OneOrMany::One(path.into()));
|
||||
let path = "/user/hand/right/input/aim/pose";
|
||||
action.right = Some(OneOrMany::One(path.into()));
|
||||
}
|
||||
|
||||
let action = cur_profile.haptic.get_or_insert_default();
|
||||
|
||||
let has_haptic = profile_left.map(|x| x.find_subpath(SubpathKind::Haptic).is_some()).unwrap_or_default();
|
||||
let has_haptic = profile_left
|
||||
.map(|x| x.find_subpath(SubpathKind::Haptic).is_some())
|
||||
.unwrap_or_default();
|
||||
if action.left.is_none() && has_haptic {
|
||||
let path = "/user/hand/left/output/haptic";
|
||||
action.left = Some(OneOrMany::One(path.into()));
|
||||
let path = "/user/hand/left/output/haptic";
|
||||
action.left = Some(OneOrMany::One(path.into()));
|
||||
}
|
||||
|
||||
let has_haptic = profile_right.map(|x| x.find_subpath(SubpathKind::Haptic).is_some()).unwrap_or_default();
|
||||
let has_haptic = profile_right
|
||||
.map(|x| x.find_subpath(SubpathKind::Haptic).is_some())
|
||||
.unwrap_or_default();
|
||||
if action.right.is_none() && has_haptic {
|
||||
let path = "/user/hand/right/output/haptic";
|
||||
action.right = Some(OneOrMany::One(path.into()));
|
||||
let path = "/user/hand/right/output/haptic";
|
||||
action.right = Some(OneOrMany::One(path.into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -381,7 +395,7 @@ fn input_controls_for_action(
|
|||
action.clone(),
|
||||
click_type,
|
||||
profile,
|
||||
current.threshold,
|
||||
current.threshold_left,
|
||||
)?;
|
||||
|
||||
let current_right = current.right.as_ref().map(|x| match x {
|
||||
|
|
@ -397,7 +411,7 @@ fn input_controls_for_action(
|
|||
action,
|
||||
click_type,
|
||||
profile,
|
||||
current.threshold,
|
||||
current.threshold_right,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -419,13 +433,19 @@ fn input_controls_for_hand(
|
|||
|
||||
let parent = horiz_cell(mp.layout, parent)?;
|
||||
|
||||
let available_components : Rc<[Component]> = current
|
||||
let available_components: Rc<[Component]> = current
|
||||
.as_ref()
|
||||
.and_then(|par| user_path.find_subpath(par.subpath))
|
||||
.map(|subp| subp.components)
|
||||
.unwrap_or_default().into();
|
||||
.unwrap_or_default()
|
||||
.into();
|
||||
|
||||
let available_subpaths : Rc<[SubpathKind]> = user_path.paths.iter().filter(|x| !x.kind.get_bool("Hidden").unwrap_or_default()).map(|x| x.kind).collect();
|
||||
let available_subpaths: Rc<[SubpathKind]> = user_path
|
||||
.paths
|
||||
.iter()
|
||||
.filter(|x| !x.kind.get_bool("Hidden").unwrap_or_default())
|
||||
.map(|x| x.kind)
|
||||
.collect();
|
||||
|
||||
subpath_dropdown(
|
||||
mp,
|
||||
|
|
@ -452,7 +472,7 @@ fn input_controls_for_hand(
|
|||
if let Some(component) = current.as_ref().map(|x| x.component)
|
||||
&& component.is_analog()
|
||||
{
|
||||
threshold_slider(mp, parent, action, threshold)?;
|
||||
threshold_slider(mp, parent, action, side, threshold)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -530,6 +550,7 @@ fn threshold_slider(
|
|||
mp: &mut MacroParams,
|
||||
parent: WidgetID,
|
||||
action: Rc<str>,
|
||||
side: Side,
|
||||
current: Option<[f32; 2]>,
|
||||
) -> anyhow::Result<()> {
|
||||
let id = mp.idx.to_string();
|
||||
|
|
@ -554,9 +575,9 @@ fn threshold_slider(
|
|||
let tasks = mp.tasks.clone();
|
||||
move |_common, e| {
|
||||
if matches!(e.index, wgui::components::slider::ValueIndex::Primary) {
|
||||
tasks.push(Task::UpdateThreshold(action.clone(), e.value, current[1]));
|
||||
tasks.push(Task::UpdateThreshold(action.clone(), side, e.value, current[1]));
|
||||
} else {
|
||||
tasks.push(Task::UpdateThreshold(action.clone(), current[0], e.value));
|
||||
tasks.push(Task::UpdateThreshold(action.clone(), side, current[0], e.value));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
|
@ -626,18 +647,23 @@ fn create_dropdown<B: 'static + BindingsDropdown>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn apply_subpath(side_mut: &mut Option<OneOrMany<String>>, side_str: &str, subpath_str: &str, profile: &ControllerProfile,) {
|
||||
let (Ok(side), Ok(subpath)) = (Side::try_from(side_str), SubpathKind::try_from(subpath_str)) else {
|
||||
return;
|
||||
};
|
||||
let Some(subpath_obj) = profile.find_userpath(side).and_then(|p| p.find_subpath(subpath)) else {
|
||||
return;
|
||||
};
|
||||
fn apply_subpath(
|
||||
side_mut: &mut Option<OneOrMany<String>>,
|
||||
side_str: &str,
|
||||
subpath_str: &str,
|
||||
profile: &ControllerProfile,
|
||||
) {
|
||||
let (Ok(side), Ok(subpath)) = (Side::try_from(side_str), SubpathKind::try_from(subpath_str)) else {
|
||||
return;
|
||||
};
|
||||
let Some(subpath_obj) = profile.find_userpath(side).and_then(|p| p.find_subpath(subpath)) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let comp : Component = if let Some(first) = side_mut.as_ref().map(|x| match x {
|
||||
OneOrMany::One(x) => x.as_str(),
|
||||
OneOrMany::Many(x) => x.first().unwrap().as_str(),
|
||||
}) {
|
||||
let comp: Component = if let Some(first) = side_mut.as_ref().map(|x| match x {
|
||||
OneOrMany::One(x) => x.as_str(),
|
||||
OneOrMany::Many(x) => x.first().unwrap().as_str(),
|
||||
}) {
|
||||
let Ok(parsed) = ParsedOpenXrInputPath::try_from(first) else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -647,34 +673,32 @@ fn apply_subpath(side_mut: &mut Option<OneOrMany<String>>, side_str: &str, subpa
|
|||
parsed_compo = *subpath_obj.components.first().unwrap();
|
||||
}
|
||||
parsed_compo
|
||||
} else {
|
||||
} else {
|
||||
*subpath_obj.components.first().unwrap()
|
||||
};
|
||||
|
||||
let comp_str = comp.as_ref().to_lowercase();
|
||||
|
||||
*side_mut = Some(OneOrMany::One(format!(
|
||||
"/user/hand/{side_str}/input/{subpath_str}/{comp_str}"
|
||||
)));
|
||||
*side_mut = Some(OneOrMany::One(format!(
|
||||
"/user/hand/{side_str}/input/{subpath_str}/{comp_str}"
|
||||
)));
|
||||
}
|
||||
|
||||
fn apply_comp(side_mut: &mut Option<OneOrMany<String>>, side: &str, comp: &str) {
|
||||
if side_mut.is_none() {
|
||||
return;
|
||||
}
|
||||
if side_mut.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let first = match side_mut.as_ref().unwrap() {
|
||||
OneOrMany::One(x) => x.as_str(),
|
||||
OneOrMany::Many(x) => x.first().unwrap().as_str(),
|
||||
};
|
||||
let first = match side_mut.as_ref().unwrap() {
|
||||
OneOrMany::One(x) => x.as_str(),
|
||||
OneOrMany::Many(x) => x.first().unwrap().as_str(),
|
||||
};
|
||||
|
||||
let Ok(parsed) = ParsedOpenXrInputPath::try_from(first) else {
|
||||
return;
|
||||
};
|
||||
let Ok(parsed) = ParsedOpenXrInputPath::try_from(first) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let subpath = parsed.subpath.as_ref().to_lowercase();
|
||||
let subpath = parsed.subpath.as_ref().to_lowercase();
|
||||
|
||||
*side_mut = Some(OneOrMany::One(format!(
|
||||
"/user/hand/{side}/input/{subpath}/{comp}"
|
||||
)));
|
||||
*side_mut = Some(OneOrMany::One(format!("/user/hand/{side}/input/{subpath}/{comp}")));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::{
|
|||
openxr_controller_profiles::OPENXR_INPUT_PROFILES,
|
||||
popup_manager::{MountPopupOnceParams, PopupHolder},
|
||||
},
|
||||
views::{self, bindings, ViewTrait, ViewUpdateParams},
|
||||
views::{self, ViewTrait, ViewUpdateParams, bindings},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ pub struct CustomClickAction {
|
|||
single: MultiClickHandler<0>,
|
||||
double: MultiClickHandler<1>,
|
||||
triple: MultiClickHandler<2>,
|
||||
threshold: [f32; 2],
|
||||
}
|
||||
|
||||
impl CustomClickAction {
|
||||
|
|
@ -127,18 +128,19 @@ impl CustomClickAction {
|
|||
single,
|
||||
double,
|
||||
triple,
|
||||
threshold: [0.5, 0.7],
|
||||
})
|
||||
}
|
||||
pub fn state(
|
||||
&mut self,
|
||||
before: bool,
|
||||
state: &XrState,
|
||||
session: &AppSession,
|
||||
) -> anyhow::Result<bool> {
|
||||
|
||||
pub fn set_threshold(&mut self, threshold: [f32; 2]) {
|
||||
self.threshold = threshold;
|
||||
}
|
||||
|
||||
pub fn state(&mut self, before: bool, state: &XrState) -> anyhow::Result<bool> {
|
||||
let threshold = if before {
|
||||
session.config.xr_click_sensitivity_release
|
||||
self.threshold[1]
|
||||
} else {
|
||||
session.config.xr_click_sensitivity
|
||||
self.threshold[0]
|
||||
};
|
||||
|
||||
Ok(self.single.check(&state.session, threshold)?
|
||||
|
|
@ -171,14 +173,13 @@ impl OpenXrInputSource {
|
|||
.instance()
|
||||
.create_action_set("wayvr", "WayVR Actions", 0)?;
|
||||
|
||||
let left_source = OpenXrHandSource::new(&mut action_set, "left")?;
|
||||
let right_source = OpenXrHandSource::new(&mut action_set, "right")?;
|
||||
let fallback_source = OpenXrHandSource::new(&mut action_set, "handsfree")?;
|
||||
let mut left_source = OpenXrHandSource::new(&mut action_set, "left")?;
|
||||
let mut right_source = OpenXrHandSource::new(&mut action_set, "right")?;
|
||||
let mut fallback_source = OpenXrHandSource::new(&mut action_set, "handsfree")?;
|
||||
|
||||
suggest_bindings(
|
||||
&xr.instance,
|
||||
&[&left_source, &right_source, &fallback_source],
|
||||
);
|
||||
let mut hands: [&mut OpenXrHandSource; 3] =
|
||||
[&mut left_source, &mut right_source, &mut fallback_source];
|
||||
suggest_bindings(&xr.instance, &mut hands);
|
||||
|
||||
xr.session.attach_action_sets(&[&action_set])?;
|
||||
|
||||
|
|
@ -381,7 +382,7 @@ impl OpenXrPointer {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
self.pointer_load_actions(pointer, xr, session)?;
|
||||
self.pointer_load_actions(pointer, xr)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -394,7 +395,7 @@ impl OpenXrPointer {
|
|||
) -> anyhow::Result<()> {
|
||||
pointer.handsfree = false;
|
||||
self.pointer_load_pose(pointer, xr, session.config.pointer_lerp_factor)?;
|
||||
self.pointer_load_actions(pointer, xr, session)?;
|
||||
self.pointer_load_actions(pointer, xr)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -431,15 +432,10 @@ impl OpenXrPointer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn pointer_load_actions(
|
||||
&mut self,
|
||||
pointer: &mut Pointer,
|
||||
xr: &XrState,
|
||||
session: &AppSession,
|
||||
) -> anyhow::Result<()> {
|
||||
pointer.now.click = self.source.click.state(pointer.before.click, xr, session)?;
|
||||
fn pointer_load_actions(&mut self, pointer: &mut Pointer, xr: &XrState) -> anyhow::Result<()> {
|
||||
pointer.now.click = self.source.click.state(pointer.before.click, xr)?;
|
||||
|
||||
pointer.now.grab = self.source.grab.state(pointer.before.grab, xr, session)?;
|
||||
pointer.now.grab = self.source.grab.state(pointer.before.grab, xr)?;
|
||||
|
||||
let scroll = self
|
||||
.source
|
||||
|
|
@ -450,50 +446,44 @@ impl OpenXrPointer {
|
|||
pointer.now.scroll_x = scroll.x;
|
||||
pointer.now.scroll_y = scroll.y;
|
||||
|
||||
pointer.now.alt_click =
|
||||
self.source
|
||||
.alt_click
|
||||
.state(pointer.before.alt_click, xr, session)?;
|
||||
pointer.now.alt_click = self.source.alt_click.state(pointer.before.alt_click, xr)?;
|
||||
|
||||
pointer.now.show_hide =
|
||||
self.source
|
||||
.show_hide
|
||||
.state(pointer.before.show_hide, xr, session)?;
|
||||
pointer.now.show_hide = self.source.show_hide.state(pointer.before.show_hide, xr)?;
|
||||
|
||||
pointer.now.click_modifier_right =
|
||||
self.source
|
||||
.modifier_right
|
||||
.state(pointer.before.click_modifier_right, xr, session)?;
|
||||
pointer.now.click_modifier_right = self
|
||||
.source
|
||||
.modifier_right
|
||||
.state(pointer.before.click_modifier_right, xr)?;
|
||||
|
||||
pointer.now.toggle_dashboard =
|
||||
self.source
|
||||
.toggle_dashboard
|
||||
.state(pointer.before.toggle_dashboard, xr, session)?;
|
||||
pointer.now.toggle_dashboard = self
|
||||
.source
|
||||
.toggle_dashboard
|
||||
.state(pointer.before.toggle_dashboard, xr)?;
|
||||
|
||||
pointer.now.click_modifier_middle =
|
||||
self.source
|
||||
.modifier_middle
|
||||
.state(pointer.before.click_modifier_middle, xr, session)?;
|
||||
pointer.now.click_modifier_middle = self
|
||||
.source
|
||||
.modifier_middle
|
||||
.state(pointer.before.click_modifier_middle, xr)?;
|
||||
|
||||
pointer.now.move_mouse =
|
||||
self.source
|
||||
.move_mouse
|
||||
.state(pointer.before.move_mouse, xr, session)?;
|
||||
pointer.now.move_mouse = self
|
||||
.source
|
||||
.move_mouse
|
||||
.state(pointer.before.move_mouse, xr)?;
|
||||
|
||||
pointer.now.space_drag =
|
||||
self.source
|
||||
.space_drag
|
||||
.state(pointer.before.space_drag, xr, session)?;
|
||||
pointer.now.space_drag = self
|
||||
.source
|
||||
.space_drag
|
||||
.state(pointer.before.space_drag, xr)?;
|
||||
|
||||
pointer.now.space_rotate =
|
||||
self.source
|
||||
.space_rotate
|
||||
.state(pointer.before.space_rotate, xr, session)?;
|
||||
pointer.now.space_rotate = self
|
||||
.source
|
||||
.space_rotate
|
||||
.state(pointer.before.space_rotate, xr)?;
|
||||
|
||||
pointer.now.space_reset =
|
||||
self.source
|
||||
.space_reset
|
||||
.state(pointer.before.space_reset, xr, session)?;
|
||||
pointer.now.space_reset = self
|
||||
.source
|
||||
.space_reset
|
||||
.state(pointer.before.space_reset, xr)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -648,7 +638,20 @@ macro_rules! add_custom_lr {
|
|||
}
|
||||
|
||||
#[allow(clippy::too_many_lines, clippy::cognitive_complexity)]
|
||||
fn suggest_bindings(instance: &xr::Instance, hands: &[&OpenXrHandSource; 3]) {
|
||||
macro_rules! set_threshold_for {
|
||||
($hands:expr, $profile_action:expr, $field:ident) => {
|
||||
if let Some(ref profile_action) = $profile_action {
|
||||
if let Some(threshold) = profile_action.threshold_left {
|
||||
$hands[0].$field.set_threshold(threshold);
|
||||
}
|
||||
if let Some(threshold) = profile_action.threshold_right {
|
||||
$hands[1].$field.set_threshold(threshold);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn suggest_bindings(instance: &xr::Instance, hands: &mut [&mut OpenXrHandSource; 3]) {
|
||||
let profiles = load_xr_input_profiles();
|
||||
|
||||
for profile in profiles {
|
||||
|
|
@ -659,69 +662,83 @@ fn suggest_bindings(instance: &xr::Instance, hands: &[&OpenXrHandSource; 3]) {
|
|||
continue;
|
||||
};
|
||||
|
||||
let mut bindings: Vec<xr::Binding> = vec![];
|
||||
|
||||
add_custom_lr!(profile.pose, pose, hands, bindings, instance);
|
||||
add_custom_lr!(profile.haptic, haptics, hands, bindings, instance);
|
||||
add_custom_lr!(profile.scroll, scroll, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.click, click, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.alt_click, alt_click, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.grab, grab, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.show_hide, show_hide, hands, bindings, instance);
|
||||
|
||||
add_custom!(
|
||||
profile.toggle_dashboard,
|
||||
toggle_dashboard,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(profile.space_drag, space_drag, hands, bindings, instance);
|
||||
|
||||
add_custom!(
|
||||
profile.space_rotate,
|
||||
space_rotate,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(profile.space_reset, space_reset, hands, bindings, instance);
|
||||
|
||||
add_custom!(
|
||||
profile.click_modifier_right,
|
||||
modifier_right,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(
|
||||
profile.click_modifier_middle,
|
||||
modifier_middle,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(profile.move_mouse, move_mouse, hands, bindings, instance);
|
||||
|
||||
if instance
|
||||
.suggest_interaction_profile_bindings(profile_path, &bindings)
|
||||
.is_err()
|
||||
{
|
||||
log::error!("Bad bindings for {}", &profile.profile[22..]);
|
||||
log::error!("Verify config: ~/.config/wayvr/openxr_actions.json5");
|
||||
} else {
|
||||
log::debug!(
|
||||
"Bindings for {} bound successfully.",
|
||||
&profile.profile[22..]
|
||||
let mut bindings: Vec<xr::Binding> = vec![];
|
||||
|
||||
add_custom_lr!(profile.pose, pose, hands, bindings, instance);
|
||||
add_custom_lr!(profile.haptic, haptics, hands, bindings, instance);
|
||||
add_custom_lr!(profile.scroll, scroll, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.click, click, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.alt_click, alt_click, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.grab, grab, hands, bindings, instance);
|
||||
|
||||
add_custom!(profile.show_hide, show_hide, hands, bindings, instance);
|
||||
|
||||
add_custom!(
|
||||
profile.toggle_dashboard,
|
||||
toggle_dashboard,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(profile.space_drag, space_drag, hands, bindings, instance);
|
||||
|
||||
add_custom!(
|
||||
profile.space_rotate,
|
||||
space_rotate,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(profile.space_reset, space_reset, hands, bindings, instance);
|
||||
|
||||
add_custom!(
|
||||
profile.click_modifier_right,
|
||||
modifier_right,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(
|
||||
profile.click_modifier_middle,
|
||||
modifier_middle,
|
||||
hands,
|
||||
bindings,
|
||||
instance
|
||||
);
|
||||
|
||||
add_custom!(profile.move_mouse, move_mouse, hands, bindings, instance);
|
||||
|
||||
if instance
|
||||
.suggest_interaction_profile_bindings(profile_path, &bindings)
|
||||
.is_err()
|
||||
{
|
||||
log::error!("Bad bindings for {}", &profile.profile[22..]);
|
||||
log::error!("Verify config: ~/.config/wayvr/openxr_actions.json5");
|
||||
} else {
|
||||
log::debug!(
|
||||
"Bindings for {} bound successfully.",
|
||||
&profile.profile[22..]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
set_threshold_for!(hands, profile.click, click);
|
||||
set_threshold_for!(hands, profile.alt_click, alt_click);
|
||||
set_threshold_for!(hands, profile.grab, grab);
|
||||
set_threshold_for!(hands, profile.show_hide, show_hide);
|
||||
set_threshold_for!(hands, profile.toggle_dashboard, toggle_dashboard);
|
||||
set_threshold_for!(hands, profile.space_drag, space_drag);
|
||||
set_threshold_for!(hands, profile.space_rotate, space_rotate);
|
||||
set_threshold_for!(hands, profile.space_reset, space_reset);
|
||||
set_threshold_for!(hands, profile.click_modifier_right, modifier_right);
|
||||
set_threshold_for!(hands, profile.click_modifier_middle, modifier_middle);
|
||||
set_threshold_for!(hands, profile.move_mouse, move_mouse);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,8 +148,6 @@ pub struct AutoSettings {
|
|||
pub enable_watch: bool,
|
||||
pub sets_on_watch: bool,
|
||||
pub hide_grab_help: bool,
|
||||
pub xr_click_sensitivity: f32,
|
||||
pub xr_click_sensitivity_release: f32,
|
||||
pub allow_sliding: bool,
|
||||
pub focus_follows_mouse_mode: bool,
|
||||
pub left_handed_mouse: bool,
|
||||
|
|
@ -210,8 +208,6 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
|
|||
enable_watch: config.enable_watch,
|
||||
sets_on_watch: config.sets_on_watch,
|
||||
hide_grab_help: config.hide_grab_help,
|
||||
xr_click_sensitivity: config.xr_click_sensitivity,
|
||||
xr_click_sensitivity_release: config.xr_click_sensitivity_release,
|
||||
allow_sliding: config.allow_sliding,
|
||||
focus_follows_mouse_mode: config.focus_follows_mouse_mode,
|
||||
left_handed_mouse: config.left_handed_mouse,
|
||||
|
|
|
|||
|
|
@ -194,11 +194,6 @@
|
|||
#invert_scroll_direction_x: false
|
||||
#invert_scroll_direction_y: false
|
||||
|
||||
## Press and release thresholds for grip & trigger
|
||||
## when using OpenXR (WiVRn, Monado)
|
||||
#xr_click_sensitivity: 0.7
|
||||
#xr_click_sensitivity_release: 0.5
|
||||
|
||||
## How many seconds to buttons need to be held
|
||||
## before it's considered a long press
|
||||
#long_press_duration: 1.0
|
||||
|
|
|
|||
|
|
@ -230,7 +230,11 @@
|
|||
move_mouse: {
|
||||
left: "/user/hand/left/input/trigger/value",
|
||||
right: "/user/hand/right/input/trigger/value",
|
||||
threshold: [
|
||||
threshold_left: [
|
||||
0.1,
|
||||
0.2
|
||||
],
|
||||
threshold_right: [
|
||||
0.1,
|
||||
0.2
|
||||
]
|
||||
|
|
@ -282,7 +286,11 @@
|
|||
move_mouse: {
|
||||
left: "/user/hand/left/input/trigger/value",
|
||||
right: "/user/hand/right/input/trigger/value",
|
||||
threshold: [
|
||||
threshold_left: [
|
||||
0.1,
|
||||
0.2
|
||||
],
|
||||
threshold_right: [
|
||||
0.1,
|
||||
0.2
|
||||
]
|
||||
|
|
@ -326,7 +334,11 @@
|
|||
move_mouse: {
|
||||
left: "/user/hand/left/input/trigger/value",
|
||||
right: "/user/hand/right/input/trigger/value",
|
||||
threshold: [
|
||||
threshold_left: [
|
||||
0.1,
|
||||
0.2
|
||||
],
|
||||
threshold_right: [
|
||||
0.1,
|
||||
0.2
|
||||
]
|
||||
|
|
@ -361,7 +373,11 @@
|
|||
move_mouse: {
|
||||
left: "/user/hand/left/input/trigger/value",
|
||||
right: "/user/hand/right/input/trigger/value",
|
||||
threshold: [
|
||||
threshold_left: [
|
||||
0.1,
|
||||
0.2
|
||||
],
|
||||
threshold_right: [
|
||||
0.1,
|
||||
0.2
|
||||
]
|
||||
|
|
@ -408,7 +424,11 @@
|
|||
move_mouse: {
|
||||
left: "/user/hand/left/input/trigger/value",
|
||||
right: "/user/hand/right/input/trigger/value",
|
||||
threshold: [
|
||||
threshold_left: [
|
||||
0.1,
|
||||
0.2
|
||||
],
|
||||
threshold_right: [
|
||||
0.1,
|
||||
0.2
|
||||
]
|
||||
|
|
|
|||
|
|
@ -292,12 +292,6 @@ pub struct GeneralConfig {
|
|||
#[serde(default)]
|
||||
pub capture_method: CaptureMethod,
|
||||
|
||||
#[serde(default = "def_point7")]
|
||||
pub xr_click_sensitivity: f32,
|
||||
|
||||
#[serde(default = "def_half")]
|
||||
pub xr_click_sensitivity_release: f32,
|
||||
|
||||
#[serde(default = "def_true")]
|
||||
pub allow_sliding: bool,
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ pub struct OpenXrInputAction {
|
|||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub handsfree: Option<OneOrMany<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub threshold: Option<[f32; 2]>,
|
||||
pub threshold_left: Option<[f32; 2]>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub threshold_right: Option<[f32; 2]>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub double_click: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
|
|||
Loading…
Reference in New Issue