grab-help panel, FollowHand align_to_hmd

This commit is contained in:
galister
2025-12-21 16:00:45 +09:00
parent 8e62e11d65
commit 1c6ebc745d
23 changed files with 578 additions and 66 deletions

View File

@@ -0,0 +1 @@
../../../wlx-overlay-s/src/assets/grab-help/controller-grip-b.svg

View File

@@ -0,0 +1 @@
../../../wlx-overlay-s/src/assets/grab-help/controller-grip-joy.svg

View File

@@ -0,0 +1 @@
../../../wlx-overlay-s/src/assets/grab-help/controller-grip-trigger-joy.svg

View File

@@ -0,0 +1 @@
../../../wlx-overlay-s/src/assets/grab-help/controller.svg

View File

@@ -59,22 +59,6 @@ const fn def_osc_port() -> u16 {
9000
}
const fn def_empty_vec_string() -> Vec<String> {
Vec::new()
}
const fn def_sets() -> Vec<SerializedWindowSet> {
Vec::new()
}
fn def_global_set() -> SerializedWindowStates {
HashMap::new()
}
const fn def_zero_u32() -> u32 {
0
}
fn def_timezones() -> Vec<String> {
const EMEA: i32 = -60 * 60; // UTC-1
const APAC: i32 = 5 * 60 * 60; // UTC+5
@@ -87,14 +71,6 @@ fn def_timezones() -> Vec<String> {
}
}
const fn def_astrset_empty() -> AStrSet {
AStrSet::new()
}
const fn def_attribs() -> AStrMap<Vec<BackendAttribValue>> {
AStrMap::new()
}
fn def_auto() -> Arc<str> {
"auto".into()
}
@@ -107,14 +83,6 @@ fn def_theme_path() -> Arc<str> {
"theme".into()
}
fn def_toast_topics() -> IdMap<ToastTopic, ToastDisplayMethod> {
IdMap::new()
}
fn def_font() -> Arc<str> {
"LiberationSans:style=Bold".into()
}
const fn def_max_height() -> u16 {
1440
}
@@ -129,7 +97,7 @@ pub struct GeneralConfig {
pub color_faded: Option<String>,
pub default_keymap: Option<String>,
#[serde(default = "def_attribs")]
#[serde(default)]
pub attribs: AStrMap<Vec<BackendAttribValue>>,
#[serde(default = "def_click_freeze_time_ms")]
@@ -153,7 +121,7 @@ pub struct GeneralConfig {
#[serde(default = "def_true")]
pub notifications_sound_enabled: bool,
#[serde(default = "def_toast_topics")]
#[serde(default)]
pub notification_topics: IdMap<ToastTopic, ToastDisplayMethod>,
#[serde(default = "def_empty")]
@@ -189,7 +157,7 @@ pub struct GeneralConfig {
#[serde(default = "def_false")]
pub single_set_mode: bool,
#[serde(default = "def_astrset_empty")]
#[serde(default)]
pub custom_panels: AStrSet,
#[serde(default = "def_auto")]
@@ -231,9 +199,6 @@ pub struct GeneralConfig {
#[serde(default = "def_true")]
pub block_game_input_ignore_watch: bool,
#[serde(default = "def_font")]
pub primary_font: Arc<str>,
#[serde(default = "def_one")]
pub space_drag_multiplier: f32,
@@ -258,10 +223,10 @@ pub struct GeneralConfig {
#[serde(default = "def_false")]
pub space_rotate_unlocked: bool,
#[serde(default = "def_empty_vec_string")]
#[serde(default)]
pub alt_click_down: Vec<String>,
#[serde(default = "def_empty_vec_string")]
#[serde(default)]
pub alt_click_up: Vec<String>,
#[serde(default = "def_timezones")]
@@ -270,12 +235,12 @@ pub struct GeneralConfig {
#[serde(default = "def_false")]
pub clock_12h: bool,
#[serde(default = "def_sets")]
#[serde(default)]
pub sets: Vec<SerializedWindowSet>,
#[serde(default = "def_global_set")]
#[serde(default)]
pub global_set: SerializedWindowStates,
#[serde(default = "def_zero_u32")]
#[serde(default)]
pub last_set: u32,
}

View File

@@ -13,9 +13,18 @@ pub enum Positioning {
/// Stays in place, no recentering
Static,
/// Following HMD
FollowHead { lerp: f32 },
FollowHead {
#[serde(default)]
lerp: f32,
},
/// Following hand
FollowHand { hand: LeftRight, lerp: f32 },
FollowHand {
hand: LeftRight,
#[serde(default)]
lerp: f32,
#[serde(default)]
align_to_hmd: bool,
},
}
impl Positioning {
@@ -37,6 +46,21 @@ impl Positioning {
}
self
}
pub const fn get_align(self) -> Option<bool> {
match self {
Self::FollowHand { align_to_hmd, .. } => Some(align_to_hmd),
Self::FollowHead { .. } | Self::Floating | Self::Anchored | Self::Static => None,
}
}
pub const fn with_align(mut self, value: bool) -> Self {
match self {
Self::FollowHand {
ref mut align_to_hmd, ..
} => *align_to_hmd = value,
Self::FollowHead { .. } | Self::Floating | Self::Anchored | Self::Static => {}
}
self
}
}
// Contains the window state for a given set

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="75.935417mm"
height="68.791664mm"
viewBox="0 0 75.935417 68.791665"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="controller-grip-trigger.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="4"
inkscape:cx="111.5"
inkscape:cy="102.25"
inkscape:window-width="2560"
inkscape:window-height="1402"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs1"><linearGradient
id="swatch16"><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop16" /></linearGradient></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.39905,75.40123)"
style="display:inline"><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 15.012773,-72.181304 c 4.141941,1.165078 6.086576,2.414944 6.712672,4.024907 0.626097,1.609963 0.532157,5.63487 1.158257,6.887063 0.626096,1.252194 11.090856,14.31078 14.757992,20.482305 19.5826,32.9560887 1.940566,46.9631356 -20.124533,14.221339 -2.772715,-4.114351 -5.903199,-8.67591 -5.903199,-8.67591 7.715983,-4.216191 2.220624,-15.211608 -8.6759118,-8.049816 -3.64367111,-0.976319 -18.5054902,-0.644302 -24.5966542,-5.992639 -3.667137,-3.219925 -0.983866,-11.269739 6.529294,-16.54684 3.79522,-2.66569 8.9369945,-4.920567 14.36466896,-6.16513 0.95789449,-0.728747 4.81005894,-2.710092 8.86028994,-1.038028 2.3914361,0.0083 4.7273841,0.275454 6.9171241,0.852749 z"
id="path1"
sodipodi:nodetypes="cssssccssccc"
inkscape:label="body" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -22.35135,-57.629297 c -5.37272,17.781146 57.911292,-1.040404 38.136925,-14.293441 m -37.525677,22.610968 c 16.5101581,4.815856 44.696096,-6.498025 43.705588,-17.980194"
id="path2"
sodipodi:nodetypes="cccc"
inkscape:label="top" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 8.4696007,-69.999045 c 2.3386083,0.982215 0.1403173,3.578071 -2.3619957,4.162723 -2.5857858,0.604155 -6.75857671,0.701583 -5.332026,-2.104747 l 1.1747355,-0.0274 c 0,0 -0.5433107,1.57088 2.9879877,0.91607 3.2577056,-0.604078 2.3853805,-2.245064 2.3853805,-2.245064 z"
id="path6"
sodipodi:nodetypes="csccscc"
inkscape:label="joy-base" /><path
fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 1.8279533,-42.497011 c 4.1159492,3.040191 4.9110767,3.718387 6.1739259,8.72301 13.5171568,-3.297438 6.5948758,-18.428236 -6.1739259,-8.72301 z"
id="path3"
sodipodi:nodetypes="ccc"
inkscape:label="hl-grip" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -15.964545,-46.015944 c 6.6145833,1.35599 14.0559895,2.182813 14.0559895,2.182813 0,0 -13.3649255,7.92086 -13.1464845,2.182812 0.131183,-3.445925 -0.909505,-4.365625 -0.909505,-4.365625 z"
id="path4"
sodipodi:nodetypes="ccsc"
inkscape:label="hl-trigger" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 1.5398836,-73.13221 c 6.2774078,-2.004824 11.3269874,1.97254 4.3821614,4.415234 -6.9448262,2.442695 -10.6595692,-2.41041 -4.3821614,-4.415234 z"
id="path5"
sodipodi:nodetypes="zzz"
inkscape:label="hl-joy" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 41.159507,11.014845 c 2.958338,-0.958829 1.987976,-3.0362826 -1.555174,-1.9995099 -3.54315,1.0367729 -1.403164,2.9583399 1.555174,1.9995099 z"
id="path7"
sodipodi:nodetypes="zzz"
transform="translate(-26.39905,-75.40123)"
inkscape:label="hl-menu" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 0.22640605,-59.030165 c 4.86880725,-1.82141 3.65160965,-4.247017 -1.87696025,-2.457122 -5.52857,1.789893 -2.9918455,4.27853 1.87696025,2.457122 z m 3.52775625,-1.89786 c -0.3237027,-2.843818 -10.0455509,0.09118 -8.511249,2.342119 -0.8691671,4.327638 11.3624299,1.320218 8.511249,-2.342119 z"
id="path8"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-a" /><path
fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -10.257709,-61.742144 c 4.8688076,-1.82141 3.65161,-4.247017 -1.87696,-2.457122 -5.52857,1.789893 -2.991845,4.27853 1.87696,2.457122 z m 3.5277566,-1.89786 c -0.3237027,-2.843818 -10.0455506,0.09118 -8.5112486,2.342119 -0.869167,4.327638 11.3624295,1.320218 8.5112486,-2.342119 z"
id="path16"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-b" /></g></svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="75.935417mm"
height="68.791664mm"
viewBox="0 0 75.935417 68.791665"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="controller-grip-trigger.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="4"
inkscape:cx="111.5"
inkscape:cy="102.25"
inkscape:window-width="2560"
inkscape:window-height="1402"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs1"><linearGradient
id="swatch16"><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop16" /></linearGradient></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.39905,75.40123)"
style="display:inline"><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 15.012773,-72.181304 c 4.141941,1.165078 6.086576,2.414944 6.712672,4.024907 0.626097,1.609963 0.532157,5.63487 1.158257,6.887063 0.626096,1.252194 11.090856,14.31078 14.757992,20.482305 19.5826,32.9560887 1.940566,46.9631356 -20.124533,14.221339 -2.772715,-4.114351 -5.903199,-8.67591 -5.903199,-8.67591 7.715983,-4.216191 2.220624,-15.211608 -8.6759118,-8.049816 -3.64367111,-0.976319 -18.5054902,-0.644302 -24.5966542,-5.992639 -3.667137,-3.219925 -0.983866,-11.269739 6.529294,-16.54684 3.79522,-2.66569 8.9369945,-4.920567 14.36466896,-6.16513 0.95789449,-0.728747 4.81005894,-2.710092 8.86028994,-1.038028 2.3914361,0.0083 4.7273841,0.275454 6.9171241,0.852749 z"
id="path1"
sodipodi:nodetypes="cssssccssccc"
inkscape:label="body" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -22.35135,-57.629297 c -5.37272,17.781146 57.911292,-1.040404 38.136925,-14.293441 m -37.525677,22.610968 c 16.5101581,4.815856 44.696096,-6.498025 43.705588,-17.980194"
id="path2"
sodipodi:nodetypes="cccc"
inkscape:label="top" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 8.4696007,-69.999045 c 2.3386083,0.982215 0.1403173,3.578071 -2.3619957,4.162723 -2.5857858,0.604155 -6.75857671,0.701583 -5.332026,-2.104747 l 1.1747355,-0.0274 c 0,0 -0.5433107,1.57088 2.9879877,0.91607 3.2577056,-0.604078 2.3853805,-2.245064 2.3853805,-2.245064 z"
id="path6"
sodipodi:nodetypes="csccscc"
inkscape:label="joy-base" /><path
fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 1.8279533,-42.497011 c 4.1159492,3.040191 4.9110767,3.718387 6.1739259,8.72301 13.5171568,-3.297438 6.5948758,-18.428236 -6.1739259,-8.72301 z"
id="path3"
sodipodi:nodetypes="ccc"
inkscape:label="hl-grip" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -15.964545,-46.015944 c 6.6145833,1.35599 14.0559895,2.182813 14.0559895,2.182813 0,0 -13.3649255,7.92086 -13.1464845,2.182812 0.131183,-3.445925 -0.909505,-4.365625 -0.909505,-4.365625 z"
id="path4"
sodipodi:nodetypes="ccsc"
inkscape:label="hl-trigger" /><path
fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 1.5398836,-73.13221 c 6.2774078,-2.004824 11.3269874,1.97254 4.3821614,4.415234 -6.9448262,2.442695 -10.6595692,-2.41041 -4.3821614,-4.415234 z"
id="path5"
sodipodi:nodetypes="zzz"
inkscape:label="hl-joy" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 41.159507,11.014845 c 2.958338,-0.958829 1.987976,-3.0362826 -1.555174,-1.9995099 -3.54315,1.0367729 -1.403164,2.9583399 1.555174,1.9995099 z"
id="path7"
sodipodi:nodetypes="zzz"
transform="translate(-26.39905,-75.40123)"
inkscape:label="hl-menu" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 0.22640605,-59.030165 c 4.86880725,-1.82141 3.65160965,-4.247017 -1.87696025,-2.457122 -5.52857,1.789893 -2.9918455,4.27853 1.87696025,2.457122 z m 3.52775625,-1.89786 c -0.3237027,-2.843818 -10.0455509,0.09118 -8.511249,2.342119 -0.8691671,4.327638 11.3624299,1.320218 8.511249,-2.342119 z"
id="path8"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-a" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -10.257709,-61.742144 c 4.8688076,-1.82141 3.65161,-4.247017 -1.87696,-2.457122 -5.52857,1.789893 -2.991845,4.27853 1.87696,2.457122 z m 3.5277566,-1.89786 c -0.3237027,-2.843818 -10.0455506,0.09118 -8.5112486,2.342119 -0.869167,4.327638 11.3624295,1.320218 8.5112486,-2.342119 z"
id="path16"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-b" /></g></svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="75.935417mm"
height="68.791664mm"
viewBox="0 0 75.935417 68.791665"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="controller-grip-trigger.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="4"
inkscape:cx="111.5"
inkscape:cy="102.25"
inkscape:window-width="2560"
inkscape:window-height="1402"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs1"><linearGradient
id="swatch16"><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop16" /></linearGradient></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.39905,75.40123)"
style="display:inline"><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 15.012773,-72.181304 c 4.141941,1.165078 6.086576,2.414944 6.712672,4.024907 0.626097,1.609963 0.532157,5.63487 1.158257,6.887063 0.626096,1.252194 11.090856,14.31078 14.757992,20.482305 19.5826,32.9560887 1.940566,46.9631356 -20.124533,14.221339 -2.772715,-4.114351 -5.903199,-8.67591 -5.903199,-8.67591 7.715983,-4.216191 2.220624,-15.211608 -8.6759118,-8.049816 -3.64367111,-0.976319 -18.5054902,-0.644302 -24.5966542,-5.992639 -3.667137,-3.219925 -0.983866,-11.269739 6.529294,-16.54684 3.79522,-2.66569 8.9369945,-4.920567 14.36466896,-6.16513 0.95789449,-0.728747 4.81005894,-2.710092 8.86028994,-1.038028 2.3914361,0.0083 4.7273841,0.275454 6.9171241,0.852749 z"
id="path1"
sodipodi:nodetypes="cssssccssccc"
inkscape:label="body" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -22.35135,-57.629297 c -5.37272,17.781146 57.911292,-1.040404 38.136925,-14.293441 m -37.525677,22.610968 c 16.5101581,4.815856 44.696096,-6.498025 43.705588,-17.980194"
id="path2"
sodipodi:nodetypes="cccc"
inkscape:label="top" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 8.4696007,-69.999045 c 2.3386083,0.982215 0.1403173,3.578071 -2.3619957,4.162723 -2.5857858,0.604155 -6.75857671,0.701583 -5.332026,-2.104747 l 1.1747355,-0.0274 c 0,0 -0.5433107,1.57088 2.9879877,0.91607 3.2577056,-0.604078 2.3853805,-2.245064 2.3853805,-2.245064 z"
id="path6"
sodipodi:nodetypes="csccscc"
inkscape:label="joy-base" /><path
fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 1.8279533,-42.497011 c 4.1159492,3.040191 4.9110767,3.718387 6.1739259,8.72301 13.5171568,-3.297438 6.5948758,-18.428236 -6.1739259,-8.72301 z"
id="path3"
sodipodi:nodetypes="ccc"
inkscape:label="hl-grip" /><path
fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -15.964545,-46.015944 c 6.6145833,1.35599 14.0559895,2.182813 14.0559895,2.182813 0,0 -13.3649255,7.92086 -13.1464845,2.182812 0.131183,-3.445925 -0.909505,-4.365625 -0.909505,-4.365625 z"
id="path4"
sodipodi:nodetypes="ccsc"
inkscape:label="hl-trigger" /><path
fill="currentColor" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 1.5398836,-73.13221 c 6.2774078,-2.004824 11.3269874,1.97254 4.3821614,4.415234 -6.9448262,2.442695 -10.6595692,-2.41041 -4.3821614,-4.415234 z"
id="path5"
sodipodi:nodetypes="zzz"
inkscape:label="hl-joy" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 41.159507,11.014845 c 2.958338,-0.958829 1.987976,-3.0362826 -1.555174,-1.9995099 -3.54315,1.0367729 -1.403164,2.9583399 1.555174,1.9995099 z"
id="path7"
sodipodi:nodetypes="zzz"
transform="translate(-26.39905,-75.40123)"
inkscape:label="hl-menu" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m 0.22640605,-59.030165 c 4.86880725,-1.82141 3.65160965,-4.247017 -1.87696025,-2.457122 -5.52857,1.789893 -2.9918455,4.27853 1.87696025,2.457122 z m 3.52775625,-1.89786 c -0.3237027,-2.843818 -10.0455509,0.09118 -8.511249,2.342119 -0.8691671,4.327638 11.3624299,1.320218 8.511249,-2.342119 z"
id="path8"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-a" /><path
fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
d="m -10.257709,-61.742144 c 4.8688076,-1.82141 3.65161,-4.247017 -1.87696,-2.457122 -5.52857,1.789893 -2.991845,4.27853 1.87696,2.457122 z m 3.5277566,-1.89786 c -0.3237027,-2.843818 -10.0455506,0.09118 -8.5112486,2.342119 -0.869167,4.327638 11.3624295,1.320218 8.5112486,-2.342119 z"
id="path16"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-b" /></g></svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="75.935417mm"
height="68.791664mm"
viewBox="0 0 75.935417 68.791665"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="controller.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="4"
inkscape:cx="111.5"
inkscape:cy="102.25"
inkscape:window-width="2560"
inkscape:window-height="1402"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs1" /><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(26.39905,75.40123)"
style="display:inline"><path
style="fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="m 15.012773,-72.181304 c 4.141941,1.165078 6.086576,2.414944 6.712672,4.024907 0.626097,1.609963 0.532157,5.63487 1.158257,6.887063 0.626096,1.252194 11.090856,14.31078 14.757992,20.482305 19.5826,32.9560887 1.940566,46.9631356 -20.124533,14.221339 -2.772715,-4.114351 -5.903199,-8.67591 -5.903199,-8.67591 7.715983,-4.216191 2.220624,-15.211608 -8.6759118,-8.049816 -3.64367111,-0.976319 -18.5054902,-0.644302 -24.5966542,-5.992639 -3.667137,-3.219925 -0.983866,-11.269739 6.529294,-16.54684 3.79522,-2.66569 8.9369945,-4.920567 14.36466896,-6.16513 0.95789449,-0.728747 4.81005894,-2.710092 8.86028994,-1.038028 2.3914361,0.0083 4.7273841,0.275454 6.9171241,0.852749 z"
id="path1"
sodipodi:nodetypes="cssssccssccc"
inkscape:label="body" /><path
style="fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="m -22.35135,-57.629297 c -5.37272,17.781146 57.911292,-1.040404 38.136925,-14.293441 m -37.525677,22.610968 c 16.5101581,4.815856 44.696096,-6.498025 43.705588,-17.980194"
id="path2"
sodipodi:nodetypes="cccc"
inkscape:label="top" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="m 8.4696007,-69.999045 c 2.3386083,0.982215 0.1403173,3.578071 -2.3619957,4.162723 -2.5857858,0.604155 -6.75857671,0.701583 -5.332026,-2.104747 l 1.1747355,-0.0274 c 0,0 -0.5433107,1.57088 2.9879877,0.91607 3.2577056,-0.604078 2.3853805,-2.245064 2.3853805,-2.245064 z"
id="path6"
sodipodi:nodetypes="csccscc"
inkscape:label="joy-base" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="m 1.8279533,-42.497011 c 4.1159492,3.040191 4.9110767,3.718387 6.1739259,8.72301 13.5171568,-3.297438 6.5948758,-18.428236 -6.1739259,-8.72301 z"
id="path3"
sodipodi:nodetypes="ccc"
inkscape:label="hl-grip" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="m -15.964545,-46.015944 c 6.6145833,1.35599 14.0559895,2.182813 14.0559895,2.182813 0,0 -13.3649255,7.92086 -13.1464845,2.182812 0.131183,-3.445925 -0.909505,-4.365625 -0.909505,-4.365625 z"
id="path4"
sodipodi:nodetypes="ccsc"
inkscape:label="hl-trigger" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="m 1.5398836,-73.13221 c 6.2774078,-2.004824 11.3269874,1.97254 4.3821614,4.415234 -6.9448262,2.442695 -10.6595692,-2.41041 -4.3821614,-4.415234 z"
id="path5"
sodipodi:nodetypes="zzz"
inkscape:label="hl-joy" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="m 41.159507,11.014845 c 2.958338,-0.958829 1.987976,-3.0362826 -1.555174,-1.9995099 -3.54315,1.0367729 -1.403164,2.9583399 1.555174,1.9995099 z"
id="path7"
sodipodi:nodetypes="zzz"
transform="translate(-26.39905,-75.40123)"
inkscape:label="hl-menu" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.19341;stroke-dasharray:none;stroke-opacity:1"
d="m 0.22640605,-59.030165 c 4.86880725,-1.82141 3.65160965,-4.247017 -1.87696025,-2.457122 -5.52857,1.789893 -2.9918455,4.27853 1.87696025,2.457122 z m 3.52775625,-1.89786 c -0.3237027,-2.843818 -10.0455509,0.09118 -8.511249,2.342119 -0.8691671,4.327638 11.3624299,1.320218 8.511249,-2.342119 z"
id="path8"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-a" /><path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.19341;stroke-dasharray:none;stroke-opacity:1"
d="m -10.257709,-61.742144 c 4.8688076,-1.82141 3.65161,-4.247017 -1.87696,-2.457122 -5.52857,1.789893 -2.991845,4.27853 1.87696,2.457122 z m 3.5277566,-1.89786 c -0.3237027,-2.843818 -10.0455506,0.09118 -8.5112486,2.342119 -0.869167,4.327638 11.3624295,1.320218 8.5112486,-2.342119 z"
id="path16"
sodipodi:nodetypes="zzzccc"
inkscape:label="hl-b" /></g></svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -64,9 +64,14 @@
<PosButton id="pos_hand_l" src="watch/controller_l.svg" tooltip="EDIT_MODE.POS_HAND_L" press="::EditModeSetPos hand_l" />
<PosButton id="pos_hand_r" src="watch/controller_r.svg" tooltip="EDIT_MODE.POS_HAND_R" press="::EditModeSetPos hand_r" />
</div>
<div id="pos_interpolation" padding="8" gap="8" justify_content="center" align_items="center">
<label translation="EDIT_MODE.INTERPOLATION" />
<Slider id="lerp_slider" width="250" height="16" min_value="0.05" max_value="1" value="1" step="0.05" />
<div flex_direction="row" gap="8" justify_content="center" align_items="center">
<div id="pos_interpolation" gap="6">
<label translation="EDIT_MODE.INTERPOLATION" />
<Slider id="lerp_slider" width="250" height="16" min_value="0.05" max_value="1" value="1" step="0.05" />
</div>
<div id="pos_align_to_hmd" >
<CheckBox id="align_box" translation="EDIT_MODE.ALIGN_TO_HMD" tooltip_side="bottom" />
</div>
</div>
</div>
<div id="tab_stereo" display="none" height="100" flex_direction="column">

View File

@@ -0,0 +1,27 @@
<layout>
<elements>
<div interactable="0">
<rectangle
max_width="500"
padding="16"
flex_direction="column"
gap="8"
color="#000000c0" border_color="~color_accent" border="2" round="8">
<div flex_direction="row" align_items="center" gap="8">
<sprite src="grab-help/controller-grip-joy.svg" min_width="128" min_height="128" max_width="128" max_height="128" flex_grow="1" />
<label wrap="1" size="25" padding_left="16" padding_right="16" translation="GRAB.ADJUST_DISTANCE" />
</div>
<div flex_direction="row" align_items="center" gap="8">
<sprite src="grab-help/controller-grip-trigger-joy.svg" min_width="128" min_height="128" max_width="128" max_height="128" flex_grow="1" />
<label wrap="1" size="25" padding_left="16" padding_right="16" translation="GRAB.ADJUST_SIZE" />
</div>
<div flex_direction="row" align_items="center" gap="8">
<sprite src="grab-help/controller-grip-b.svg" min_width="128" min_height="128" max_width="128" max_height="128" flex_grow="1" />
<label wrap="1" size="25" padding_left="16" padding_right="16" translation="GRAB.UNRESTRICTED_MOVEMENT" />
</div>
</rectangle>
</div>
</elements>
</layout>

View File

@@ -2,6 +2,7 @@
"ANCHOR": {
"CENTER": "Center"
},
"DEFAULT": "Default",
"DISABLED": "Disabled",
"EDIT_MODE": {
"ADJUST_CURVATURE": "Adjust curvature",
@@ -12,6 +13,7 @@
"DISABLE_GRAB": "Disable grab",
"HINT_POINT_WINDOW": "Point at a window to change its parameters.\nOnce done, leave edit mode using the button on the right.",
"INTERPOLATION": "Interpolation",
"ALIGN_TO_HMD": "Align to HMD",
"KEYBOARD": "Keyboard",
"LEAVE": "Leave edit mode",
"LOCK_INTERACTION": "Lock interaction",
@@ -31,8 +33,24 @@
"SPLIT_RIGHT_LEFT": "RIGHT→LEFT",
"SPLIT_TOP_BOTTOM": "TOP→BOTTOM",
"TITLE": "3D Stereo Mode"
},
"MOUSE": {
"TITLE": "Mouse fixes",
"EDIT_MODE.MOUSE.NORMAL": "Normal",
"EDIT_MODE.MOUSE.ROTATE90": "Rotated 90°",
"EDIT_MODE.MOUSE.ROTATE180": "Rotated 170°",
"EDIT_MODE.MOUSE.ROTATE270": "Rotated 270°",
"EDIT_MODE.MOUSE.FLIPPED": "Flipped",
"EDIT_MODE.MOUSE.ROTATE90": "Flipped 90°",
"EDIT_MODE.MOUSE.ROTATE180": "Flipped 170°",
"EDIT_MODE.MOUSE.ROTATE270": "Flipped 270°"
}
},
"GRAB": {
"ADJUST_DISTANCE": "Adjust distance",
"ADJUST_SIZE": "Adjust size",
"UNRESTRICTED_MOVEMENT": "Unrestricted movement"
},
"WATCH": {
"ADD_NEW_SET": "Add a new set",
"CLEANUP_MIRRORS": "Remove mirrors that are\nnot currently visible",

View File

@@ -10,7 +10,7 @@ use wlx_common::common::LeftRight;
use wlx_common::windowing::{OverlayWindowState, Positioning};
use crate::backend::task::OverlayTask;
use crate::overlays::anchor::ANCHOR_NAME;
use crate::overlays::anchor::{ANCHOR_NAME, GRAB_HELP_NAME};
use crate::overlays::watch::WATCH_NAME;
use crate::state::{AppSession, AppState};
use crate::subsystem::hid::WheelDelta;
@@ -642,6 +642,20 @@ fn start_grab(
o.activate(app);
}),
)));
if let Some(hand) = pointer.hand().clone() {
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Name(GRAB_HELP_NAME.clone()),
Box::new(move |app, o| {
o.default_state.positioning = Positioning::FollowHand {
hand,
lerp: 0.1,
align_to_hmd: true,
};
o.activate(app);
}),
)));
}
}
fn handle_scale(transform: &mut Affine3A, scroll_y: f32) {
@@ -730,16 +744,26 @@ where
// watch special: when dropped, follow the hand that wasn't grabbing
if let Some(overlay_state) = overlay.config.active_state.as_mut() {
overlay_state.positioning = match overlay_state.positioning {
Positioning::FollowHand { hand, lerp } => match pointer.hand() {
Positioning::FollowHand {
hand,
lerp,
align_to_hmd,
} => match pointer.hand() {
Some(LeftRight::Left) => Positioning::FollowHand {
hand: LeftRight::Right,
lerp,
align_to_hmd,
},
Some(LeftRight::Right) => Positioning::FollowHand {
hand: LeftRight::Left,
lerp,
align_to_hmd,
},
_ => Positioning::FollowHand {
hand,
lerp,
align_to_hmd,
},
_ => Positioning::FollowHand { hand, lerp },
},
x => x,
};
@@ -766,6 +790,12 @@ where
o.deactivate();
}),
)));
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
OverlaySelector::Name(GRAB_HELP_NAME.clone()),
Box::new(|_app, o| {
o.deactivate();
}),
)));
log::debug!("Hand {}: dropped {}", idx, overlay.config.name);
}
}

View File

@@ -40,10 +40,12 @@ impl AttachTo {
Self::HandLeft => Positioning::FollowHand {
hand: LeftRight::Left,
lerp: 1.0,
align_to_hmd: false,
},
Self::HandRight => Positioning::FollowHand {
hand: LeftRight::Right,
lerp: 1.0,
align_to_hmd: false,
},
Self::Stage => Positioning::Static,
Self::Head => Positioning::FollowHead { lerp: 1.0 },

View File

@@ -4,8 +4,8 @@ use wlx_common::windowing::{OverlayWindowState, Positioning};
use crate::gui::panel::GuiPanel;
use crate::state::AppState;
use crate::windowing::Z_ORDER_ANCHOR;
use crate::windowing::window::OverlayWindowConfig;
use crate::windowing::{Z_ORDER_ANCHOR, Z_ORDER_HELP};
pub static ANCHOR_NAME: LazyLock<Arc<str>> = LazyLock::new(|| Arc::from("anchor"));
@@ -31,3 +31,27 @@ pub fn create_anchor(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig>
..OverlayWindowConfig::from_backend(Box::new(panel))
})
}
pub static GRAB_HELP_NAME: LazyLock<Arc<str>> = LazyLock::new(|| Arc::from("grab-help"));
pub fn create_grab_help(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
let mut panel = GuiPanel::new_from_template(app, "gui/grab-help.xml", (), Default::default())?;
panel.update_layout()?;
Ok(OverlayWindowConfig {
name: GRAB_HELP_NAME.clone(),
z_order: Z_ORDER_HELP,
default_state: OverlayWindowState {
interactable: false,
grabbable: false,
transform: Affine3A::from_scale_rotation_translation(
Vec3::ONE * 0.15,
Quat::IDENTITY,
Vec3::ZERO,
),
..OverlayWindowState::default()
},
global: true,
..OverlayWindowConfig::from_backend(Box::new(panel))
})
}

View File

@@ -381,6 +381,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
)?;
set_up_checkbox(&mut panel, "additive_box", cb_assign_additive)?;
set_up_checkbox(&mut panel, "align_box", cb_assign_align)?;
set_up_slider(&mut panel, "lerp_slider", cb_assign_lerp)?;
set_up_slider(&mut panel, "alpha_slider", cb_assign_alpha)?;
set_up_slider(&mut panel, "curve_slider", cb_assign_curve)?;
@@ -427,6 +428,11 @@ fn reset_panel(
.fetch_component_as::<ComponentCheckbox>("additive_box")?;
c.set_checked(&mut common, state.additive);
let c = panel
.parser_state
.fetch_component_as::<ComponentCheckbox>("align_box")?;
c.set_checked(&mut common, state.positioning.get_align().unwrap_or(false));
panel
.state
.pos
@@ -493,6 +499,12 @@ const fn cb_assign_additive(_app: &mut AppState, owc: &mut OverlayWindowConfig,
owc.active_state.as_mut().unwrap().additive = additive;
}
const fn cb_assign_align(_app: &mut AppState, owc: &mut OverlayWindowConfig, align: bool) {
owc.dirty = true;
let active_state = owc.active_state.as_mut().unwrap();
active_state.positioning = active_state.positioning.with_align(align);
}
fn set_up_slider(
panel: &mut EditModeWrapPanel,
id: &str,

View File

@@ -15,6 +15,7 @@ static POS_NAMES: [&str; 6] = ["static", "anchored", "floating", "hmd", "hand_l"
pub struct PosTabState {
pos: Positioning,
has_lerp: bool,
has_align: bool,
}
impl From<Positioning> for PosTabState {
@@ -22,6 +23,7 @@ impl From<Positioning> for PosTabState {
Self {
pos: value,
has_lerp: false,
has_align: false,
}
}
}
@@ -30,6 +32,7 @@ pub fn new_pos_tab_handler(
panel: &mut EditModeWrapPanel,
) -> anyhow::Result<SpriteTabHandler<PosTabState>> {
let interpolation_id = panel.parser_state.get_widget_id("pos_interpolation")?;
let align_to_hmd_id = panel.parser_state.get_widget_id("pos_align_to_hmd")?;
SpriteTabHandler::new(
panel,
@@ -55,6 +58,16 @@ pub fn new_pos_tab_handler(
interpolation_id,
StyleSetRequest::Display(interpolation_disp),
);
let align_to_hmd_disp = if state.has_align {
taffy::Display::Flex
} else {
taffy::Display::None
};
common
.alterables
.set_style(align_to_hmd_id, StyleSetRequest::Display(align_to_hmd_disp));
})),
)
}
@@ -82,32 +95,40 @@ impl SpriteTabKey for PosTabState {
"static" => PosTabState {
pos: Positioning::Static,
has_lerp: false,
has_align: false,
},
"anchored" => PosTabState {
pos: Positioning::Anchored,
has_lerp: false,
has_align: false,
},
"floating" => PosTabState {
pos: Positioning::Floating,
has_lerp: false,
has_align: false,
},
"hmd" => PosTabState {
pos: Positioning::FollowHead { lerp: 1.0 },
has_lerp: true,
has_align: false,
},
"hand_l" => PosTabState {
pos: Positioning::FollowHand {
hand: LeftRight::Left,
lerp: 1.0,
align_to_hmd: false,
},
has_lerp: true,
has_align: true,
},
"hand_r" => PosTabState {
pos: Positioning::FollowHand {
hand: LeftRight::Right,
lerp: 1.0,
align_to_hmd: false,
},
has_lerp: true,
has_align: true,
},
_ => {
panic!("cannot translate to positioning: {key}")

View File

@@ -128,6 +128,7 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option<OverlayWindowConfig> {
LeftRight::Left =>*/ Positioning::FollowHand {
hand: LeftRight::Left,
lerp: 1.0,
align_to_hmd: true,
/*
},
LeftRight::Right => {

View File

@@ -433,6 +433,7 @@ pub fn create_watch(app: &mut AppState) -> anyhow::Result<OverlayWindowConfig> {
let positioning = Positioning::FollowHand {
hand: LeftRight::Left,
lerp: 1.0,
align_to_hmd: false,
};
panel.update_layout()?;

View File

@@ -16,8 +16,13 @@ use crate::{
backend::task::OverlayTask,
config::save_state,
overlays::{
anchor::create_anchor, custom::create_custom, edit::EditWrapperManager,
keyboard::create_keyboard, screen::create_screens, toast::Toast, watch::create_watch,
anchor::{create_anchor, create_grab_help},
custom::create_custom,
edit::EditWrapperManager,
keyboard::create_keyboard,
screen::create_screens,
toast::Toast,
watch::create_watch,
},
state::AppState,
windowing::{
@@ -115,6 +120,9 @@ where
let watch = OverlayWindowData::from_config(create_watch(app)?);
me.watch_id = me.add(watch, app);
let grab_help = OverlayWindowData::from_config(create_grab_help(app)?);
me.add(grab_help, app);
let custom_panels = app.session.config.custom_panels.clone();
for name in custom_panels.into_iter() {
let Some(panel) = create_custom(app, name) else {

View File

@@ -17,7 +17,8 @@ pub enum OverlaySelector {
Name(Arc<str>),
}
pub const Z_ORDER_TOAST: u32 = 70;
pub const Z_ORDER_TOAST: u32 = 71;
pub const Z_ORDER_HELP: u32 = 70;
pub const Z_ORDER_LINES: u32 = 69;
pub const Z_ORDER_WATCH: u32 = 68;
pub const Z_ORDER_ANCHOR: u32 = 67;

View File

@@ -145,12 +145,18 @@ impl OverlayWindowConfig {
.saved_transform
.unwrap_or(self.default_state.transform);
let (parent_transform, lerp) = match state.positioning {
Positioning::FollowHead { lerp } => (app.input_state.hmd, lerp),
Positioning::FollowHand { hand, lerp } => {
(app.input_state.pointers[hand as usize].pose, lerp)
}
Positioning::Anchored => (app.anchor, 1.0),
let (parent_transform, lerp, align_to_hmd) = match state.positioning {
Positioning::FollowHead { lerp } => (app.input_state.hmd, lerp, false),
Positioning::FollowHand {
hand,
lerp,
align_to_hmd,
} => (
app.input_state.pointers[hand as usize].pose,
lerp,
align_to_hmd,
),
Positioning::Anchored => (app.anchor, 1.0, false),
_ => return,
};
@@ -177,6 +183,11 @@ impl OverlayWindowConfig {
)
}
};
if align_to_hmd {
realign(&mut state.transform, &app.input_state.hmd);
}
self.dirty = true;
}
@@ -190,10 +201,12 @@ impl OverlayWindowConfig {
.saved_transform
.unwrap_or(self.default_state.transform);
let parent_transform = match state.positioning {
Positioning::Floating | Positioning::FollowHead { .. } => app.input_state.hmd,
Positioning::FollowHand { hand, .. } => app.input_state.pointers[hand as usize].pose,
Positioning::Anchored => app.anchor,
let (parent_transform, align_to_hmd) = match state.positioning {
Positioning::Floating | Positioning::FollowHead { .. } => (app.input_state.hmd, false),
Positioning::FollowHand {
hand, align_to_hmd, ..
} => (app.input_state.pointers[hand as usize].pose, align_to_hmd),
Positioning::Anchored => (app.anchor, false),
Positioning::Static => return,
};
@@ -203,7 +216,7 @@ impl OverlayWindowConfig {
state.transform = parent_transform * cur_transform;
if state.grabbable && hard_reset {
if align_to_hmd || (state.grabbable && hard_reset) {
realign(&mut state.transform, &app.input_state.hmd);
}
self.dirty = true;