diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json index 14b8d023..e8091cb7 100644 --- a/dash-frontend/assets/lang/en.json +++ b/dash-frontend/assets/lang/en.json @@ -100,6 +100,7 @@ "SCREEN_RENDER_DOWN_HELP": "Helps with aliasing on high-res screens", "SCROLL_SPEED": "Scroll speed", "SELECT_VARIANT": "Select variant", + "ENABLE_WATCH": "Enable watch", "SETS_ON_WATCH": "Sets on watch", "SKYBOX": "Skybox", "SKYMAP_ALREADY_DOWNLOADED": "This skymap is already downloaded. Select desired action.", diff --git a/dash-frontend/assets/lang/pl.json b/dash-frontend/assets/lang/pl.json index 7e4ceef4..c45a2cdc 100644 --- a/dash-frontend/assets/lang/pl.json +++ b/dash-frontend/assets/lang/pl.json @@ -44,6 +44,7 @@ "USE_SKYBOX_HELP": "Wyświetlaj niebo, jeśli nie ma aplikacji sceny lub passthrough", "USE_PASSTHROUGH_HELP": "Pozwól na passthrough, jeśli runtime XR to obsługuje", "SCREEN_RENDER_DOWN_HELP": "Pomaga redukować aliasing na ekranach o wysokiej rozdzielczości", + "ENABLE_WATCH": "Włącz zegarek", "SETS_ON_WATCH": "Lista zestawów na zegarku", "TROUBLESHOOTING": "Rozwiązywanie problemów", "CLEAR_SAVED_STATE": "Wyczyść zapisany stan", diff --git a/dash-frontend/src/tab/settings/mod.rs b/dash-frontend/src/tab/settings/mod.rs index ab32bdf1..eb66a6dc 100644 --- a/dash-frontend/src/tab/settings/mod.rs +++ b/dash-frontend/src/tab/settings/mod.rs @@ -274,6 +274,7 @@ enum SettingType { PointerLerpFactor, ScreenRenderDown, ScrollSpeed, + EnableWatch, SetsOnWatch, SpaceDragMultiplier, SpaceDragUnlocked, @@ -309,6 +310,7 @@ impl SettingType { Self::KeyboardSoundEnabled => &mut config.keyboard_sound_enabled, Self::UprightScreenFix => &mut config.upright_screen_fix, Self::DoubleCursorFix => &mut config.double_cursor_fix, + Self::EnableWatch => &mut config.enable_watch, Self::SetsOnWatch => &mut config.sets_on_watch, Self::HideGrabHelp => &mut config.hide_grab_help, Self::AllowSliding => &mut config.allow_sliding, @@ -435,6 +437,7 @@ impl SettingType { Self::PointerLerpFactor => Ok("APP_SETTINGS.POINTER_LERP_FACTOR"), Self::ScreenRenderDown => Ok("APP_SETTINGS.SCREEN_RENDER_DOWN"), Self::ScrollSpeed => Ok("APP_SETTINGS.SCROLL_SPEED"), + Self::EnableWatch => Ok("APP_SETTINGS.ENABLE_WATCH"), Self::SetsOnWatch => Ok("APP_SETTINGS.SETS_ON_WATCH"), Self::SpaceDragMultiplier => Ok("APP_SETTINGS.SPACE_DRAG_MULTIPLIER"), Self::SpaceDragUnlocked => Ok("APP_SETTINGS.SPACE_DRAG_UNLOCKED"), diff --git a/dash-frontend/src/tab/settings/tab_look_and_feel.rs b/dash-frontend/src/tab/settings/tab_look_and_feel.rs index 768536db..216e6688 100644 --- a/dash-frontend/src/tab/settings/tab_look_and_feel.rs +++ b/dash-frontend/src/tab/settings/tab_look_and_feel.rs @@ -22,6 +22,7 @@ impl State { options_slider_f32(par.mp, c, SettingType::UiAnimationSpeed, 0.5, 5.0, 0.1)?; // min, max, step options_slider_f32(par.mp, c, SettingType::UiGradientIntensity, 0.0, 1.0, 0.05)?; // min, max, step options_slider_f32(par.mp, c, SettingType::UiRoundMultiplier, 0.1, 5.0, 0.1)?; + options_checkbox(par.mp, c, SettingType::EnableWatch)?; options_checkbox(par.mp, c, SettingType::SetsOnWatch)?; options_checkbox(par.mp, c, SettingType::Clock12h)?; Ok(State {}) diff --git a/wayvr/src/backend/openxr/mod.rs b/wayvr/src/backend/openxr/mod.rs index f6ec7a44..11cc457d 100644 --- a/wayvr/src/backend/openxr/mod.rs +++ b/wayvr/src/backend/openxr/mod.rs @@ -141,7 +141,7 @@ pub fn openxr_run( lines.allocate(&xr_state, &app)?, ]; - let watch_id = overlays.lookup(WATCH_NAME).unwrap(); // want panic + let watch_id = overlays.lookup(WATCH_NAME); let mut input_source = input::OpenXrInputSource::new(&xr_state)?; @@ -345,17 +345,19 @@ pub fn openxr_run( app.hid_provider.inner.commit(); - let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic - let watch_state = watch.config.active_state.as_mut().unwrap(); - let watch_transform = watch_state.transform; - if watch_state.alpha < 0.05 { - //FIXME: Temporary workaround for Monado bug - watch_state.transform = Affine3A::from_scale(Vec3 { - x: 0.001, - y: 0.001, - z: 0.001, - }); - watch_state.alpha = 0.02; // visible but not really. Monado freaks out if no layers are submitted. + let mut watch_transform = Affine3A::IDENTITY; + if let Some(watch) = watch_id.and_then(|id| overlays.mut_by_id(id)) { + let watch_state = watch.config.active_state.as_mut().unwrap(); + watch_transform = watch_state.transform; + if watch_state.alpha < 0.05 { + //FIXME: Temporary workaround for Monado bug + watch_state.transform = Affine3A::from_scale(Vec3 { + x: 0.001, + y: 0.001, + z: 0.001, + }); + watch_state.alpha = 0.02; // visible but not really. Monado freaks out if no layers are submitted. + } } if let Err(e) = @@ -509,8 +511,9 @@ pub fn openxr_run( delete_queue.retain(|(_, frame)| *frame > cur_frame); //FIXME: Temporary workaround for Monado bug - let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic - watch.config.active_state.as_mut().unwrap().transform = watch_transform; + if let Some(watch) = watch_id.and_then(|id| overlays.mut_by_id(id)) { + watch.config.active_state.as_mut().unwrap().transform = watch_transform; + } } // main_loop if let (Some(blocker), Some(monado)) = (blocker, app.monado_state.as_mut()) { diff --git a/wayvr/src/config.rs b/wayvr/src/config.rs index a42526db..c440fd26 100644 --- a/wayvr/src/config.rs +++ b/wayvr/src/config.rs @@ -145,6 +145,7 @@ pub struct AutoSettings { pub keyboard_sound_enabled: bool, pub upright_screen_fix: bool, pub double_cursor_fix: bool, + pub enable_watch: bool, pub sets_on_watch: bool, pub hide_grab_help: bool, pub xr_click_sensitivity: f32, @@ -200,6 +201,7 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> { keyboard_sound_enabled: config.keyboard_sound_enabled, upright_screen_fix: config.upright_screen_fix, double_cursor_fix: config.double_cursor_fix, + 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, diff --git a/wayvr/src/res/config.yaml b/wayvr/src/res/config.yaml index 55747a09..b9fd51af 100644 --- a/wayvr/src/res/config.yaml +++ b/wayvr/src/res/config.yaml @@ -85,6 +85,9 @@ # The settings are here for reference only. # Probably don't include them in your config file. +## The watch will be enabled +#enable_watch: true + ## The bottom of the watch will list sets instead of overlays. #sets_on_watch: false diff --git a/wayvr/src/windowing/manager.rs b/wayvr/src/windowing/manager.rs index 5d8a168c..de14379a 100644 --- a/wayvr/src/windowing/manager.rs +++ b/wayvr/src/windowing/manager.rs @@ -51,7 +51,7 @@ pub struct OverlayWindowManager { /// Usually the same as current_set, except it keeps its value when current_set is hidden. restore_set: usize, anchor_local: Affine3A, - watch_id: OverlayID, + watch_id: Option, keyboard_id: OverlayID, edit_mode: bool, dropped_overlays: VecDeque>, @@ -71,7 +71,7 @@ where sets: vec![OverlayWindowSet::default()], global_set: OverlayWindowSet::default(), anchor_local: Affine3A::from_translation(Vec3::NEG_Z), - watch_id: OverlayID::null(), // set down below + watch_id: None, // set down below keyboard_id: OverlayID::null(), // set down below edit_mode: false, dropped_overlays: VecDeque::with_capacity(8), @@ -127,8 +127,10 @@ where let anchor = OverlayWindowData::from_config(create_anchor(app)?); me.add(anchor, app); - let watch = OverlayWindowData::from_config(create_watch(app)?); - me.watch_id = me.add(watch, app); + if app.session.config.enable_watch { + let watch = OverlayWindowData::from_config(create_watch(app)?); + me.watch_id = Some(me.add(watch, app)); + } let dash_frontend = OverlayWindowData::from_config(create_dash_frontend(app)?); me.add(dash_frontend, app); @@ -149,7 +151,7 @@ where me.restore_layout(app); me.overlays_changed(app)?; - for id in [me.watch_id, me.keyboard_id] { + for id in [me.watch_id, Some(me.keyboard_id)].iter().filter_map(|x| *x) { for ev in [ OverlayEventData::NumSetsChanged(me.sets.len()), OverlayEventData::EditModeChanged(false), @@ -288,6 +290,15 @@ where self.sets_changed(app); } OverlayTask::SettingsChanged => { + if app.session.config.enable_watch != self.watch_id.is_some() { + if let Some(watch_id) = self.watch_id.take() { + self.overlays.remove(watch_id); + } else { + let watch = OverlayWindowData::from_config(create_watch(app)?); + self.watch_id = Some(self.add(watch, app)); + } + } + for o in self.overlays.values_mut() { let _ = o .config @@ -440,7 +451,8 @@ impl OverlayWindowManager { } // global overlays; watch, toast - for oid in &[self.watch_id] { + if let Some(watch_id) = self.watch_id { + for oid in &[watch_id] { let Some(o) = self.get_by_id(*oid) else { break; }; @@ -451,6 +463,7 @@ impl OverlayWindowManager { .config .global_set .insert(o.config.name.clone(), state.clone()); + } } // BackendAttrib @@ -587,16 +600,18 @@ impl OverlayWindowManager { } } } - if changed && let Some(watch) = self.mut_by_id(self.watch_id) { - watch - .config - .active_state - .iter_mut() - .for_each(|f| f.grabbable = enabled); - watch - .config - .backend - .notify(app, OverlayEventData::EditModeChanged(enabled))?; + if let Some(watch_id) = self.watch_id { + if changed && let Some(watch) = self.mut_by_id(watch_id) { + watch + .config + .active_state + .iter_mut() + .for_each(|f| f.grabbable = enabled); + watch + .config + .backend + .notify(app, OverlayEventData::EditModeChanged(enabled))?; + } } Ok(()) } @@ -824,7 +839,7 @@ impl OverlayWindowManager { } self.current_set = new_set; - for id in [self.watch_id, self.keyboard_id] { + for id in [self.watch_id, Some(self.keyboard_id)].iter().filter_map(|x| *x) { let _ = self.mut_by_id(id).context("Missing overlay").and_then(|o| { o.config .backend @@ -877,7 +892,7 @@ impl OverlayWindowManager { } let meta: Rc<[OverlayMeta]> = meta.into(); - for id in [self.watch_id, self.keyboard_id] { + for id in [self.watch_id, Some(self.keyboard_id)].iter().filter_map(|x| *x) { let _ = self.mut_by_id(id).context("Missing overlay").and_then(|o| { o.config .backend @@ -902,7 +917,7 @@ impl OverlayWindowManager { } let vis: Rc<[OverlayID]> = vis.into(); - for id in [self.watch_id, self.keyboard_id] { + for id in [self.watch_id, Some(self.keyboard_id)].iter().filter_map(|x| *x) { let _ = self.mut_by_id(id).context("Missing overlay").and_then(|o| { o.config .backend @@ -915,7 +930,7 @@ impl OverlayWindowManager { fn sets_changed(&mut self, app: &mut AppState) { let len = self.sets.len(); - for id in [self.watch_id, self.keyboard_id] { + for id in [self.watch_id, Some(self.keyboard_id)].iter().filter_map(|x| *x) { if let Some(o) = self.mut_by_id(id) { let _ = o .config @@ -928,11 +943,13 @@ impl OverlayWindowManager { #[allow(clippy::unnecessary_wraps)] pub fn devices_changed(&mut self, app: &mut AppState) -> anyhow::Result<()> { - if let Some(watch) = self.mut_by_id(self.watch_id) { - let _ = watch - .config - .backend - .notify(app, OverlayEventData::DevicesChanged); + if let Some(watch_id) = self.watch_id { + if let Some(watch) = self.mut_by_id(watch_id) { + let _ = watch + .config + .backend + .notify(app, OverlayEventData::DevicesChanged); + } } Ok(()) diff --git a/wlx-common/src/config.rs b/wlx-common/src/config.rs index e673bda9..1770356f 100644 --- a/wlx-common/src/config.rs +++ b/wlx-common/src/config.rs @@ -273,6 +273,9 @@ pub struct GeneralConfig { #[serde(default = "def_false")] pub double_cursor_fix: bool, + #[serde(default = "def_true")] + pub enable_watch: bool, + #[serde(default = "def_false")] pub sets_on_watch: bool,