diff --git a/Cargo.lock b/Cargo.lock index f7ea700..61c95b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6847,6 +6847,17 @@ dependencies = [ "wayland-protocols", ] +[[package]] +name = "wlx-common" +version = "0.1.0" +dependencies = [ + "chrono", + "glam", + "idmap", + "idmap-derive", + "serde", +] + [[package]] name = "wlx-overlay-s" version = "25.4.2" @@ -6902,6 +6913,7 @@ dependencies = [ "wgui", "winit", "wlx-capture", + "wlx-common", "xcb", "xdg 3.0.0", "xkbcommon 0.9.0", diff --git a/Cargo.toml b/Cargo.toml index 9fe825c..fcd4b15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,13 +10,21 @@ inherits = "release" debug = true [workspace] -members = ["uidev", "wgui", "wlx-overlay-s", "wlx-capture", "dash-frontend"] +members = [ + "uidev", + "wgui", + "wlx-common", + "wlx-overlay-s", + "wlx-capture", + "dash-frontend", +] resolver = "3" [workspace.dependencies] anyhow = "1.0.100" glam = "0.30.7" idmap = "0.2.2" +idmap-derive = "0.2.2" log = "0.4.28" regex = "1.11.3" rust-embed = "8.7.2" diff --git a/wlx-common/.editorconfig b/wlx-common/.editorconfig new file mode 100644 index 0000000..f5834b7 --- /dev/null +++ b/wlx-common/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*.rs] +indent_style = tab +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/wlx-common/Cargo.toml b/wlx-common/Cargo.toml new file mode 100644 index 0000000..63f0450 --- /dev/null +++ b/wlx-common/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "wlx-common" +version = "0.1.0" +edition = "2024" + + +[dependencies] +serde = { version = "1.0.228", features = ["derive"] } +glam = { workspace = true } +chrono = "0.4.42" +idmap = { workspace = true, features = ["serde"] } +idmap-derive = { workspace = true } diff --git a/wlx-common/rustfmt.toml b/wlx-common/rustfmt.toml new file mode 100644 index 0000000..bfdeee4 --- /dev/null +++ b/wlx-common/rustfmt.toml @@ -0,0 +1,3 @@ +tab_spaces = 2 +hard_tabs = true +max_width = 120 diff --git a/wlx-common/src/astr_containers.rs b/wlx-common/src/astr_containers.rs new file mode 100644 index 0000000..fef45e9 --- /dev/null +++ b/wlx-common/src/astr_containers.rs @@ -0,0 +1,59 @@ +use std::sync::Arc; + +pub type AStrMap = Vec<(Arc, V)>; + +pub trait AStrMapExt { + fn arc_set(&mut self, key: Arc, value: V) -> bool; + fn arc_get(&self, key: &str) -> Option<&V>; + fn arc_rm(&mut self, key: &str) -> Option; +} + +impl AStrMapExt for AStrMap { + fn arc_set(&mut self, key: Arc, value: V) -> bool { + let index = self.iter().position(|(k, _)| k.as_ref().eq(key.as_ref())); + index.map(|i| self.remove(i).1); + self.push((key, value)); + true + } + + fn arc_get(&self, key: &str) -> Option<&V> { + self + .iter() + .find_map(|(k, v)| if k.as_ref().eq(key) { Some(v) } else { None }) + } + + fn arc_rm(&mut self, key: &str) -> Option { + let index = self.iter().position(|(k, _)| k.as_ref().eq(key)); + index.map(|i| self.remove(i).1) + } +} + +pub type AStrSet = Vec>; + +pub trait AStrSetExt { + fn arc_set(&mut self, value: Arc) -> bool; + fn arc_get(&self, value: &str) -> bool; + fn arc_rm(&mut self, value: &str) -> bool; +} + +impl AStrSetExt for AStrSet { + fn arc_set(&mut self, value: Arc) -> bool { + if self.iter().any(|v| v.as_ref().eq(value.as_ref())) { + return false; + } + self.push(value); + true + } + + fn arc_get(&self, value: &str) -> bool { + self.iter().any(|v| v.as_ref().eq(value)) + } + + fn arc_rm(&mut self, value: &str) -> bool { + let index = self.iter().position(|v| v.as_ref().eq(value)); + index.is_some_and(|i| { + self.remove(i); + true + }) + } +} diff --git a/wlx-common/src/common.rs b/wlx-common/src/common.rs new file mode 100644 index 0000000..4924df4 --- /dev/null +++ b/wlx-common/src/common.rs @@ -0,0 +1,9 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default)] +#[repr(u8)] +pub enum LeftRight { + #[default] + Left, + Right, +} diff --git a/wlx-common/src/config.rs b/wlx-common/src/config.rs new file mode 100644 index 0000000..fb5c87b --- /dev/null +++ b/wlx-common/src/config.rs @@ -0,0 +1,285 @@ +use std::{collections::HashMap, sync::Arc}; + +use chrono::Offset; +use glam::{Affine3A, Quat, Vec3, vec3}; +use idmap::IdMap; +use serde::{Deserialize, Serialize}; + +use crate::{ + astr_containers::{AStrMap, AStrSet}, + common::LeftRight, + overlays::{ToastDisplayMethod, ToastTopic}, + windowing::OverlayWindowState, +}; + +pub type PwTokenMap = AStrMap; + +#[derive(Clone, Serialize, Deserialize)] +pub struct SerializedWindowSet { + pub name: Arc, + pub overlays: HashMap, OverlayWindowState>, +} + +pub const fn def_watch_pos() -> Vec3 { + vec3(-0.03, -0.01, 0.125) +} + +pub const fn def_watch_rot() -> Quat { + Quat::from_xyzw(-0.707_106_6, 0.000_796_361_8, 0.707_106_6, 0.0) +} + +pub const fn def_left() -> LeftRight { + LeftRight::Left +} + +pub const fn def_pw_tokens() -> PwTokenMap { + AStrMap::new() +} + +const fn def_mouse_move_interval_ms() -> u32 { + 10 // 100fps +} + +const fn def_click_freeze_time_ms() -> u32 { + 300 +} + +pub const fn def_true() -> bool { + true +} + +const fn def_false() -> bool { + false +} + +const fn def_one() -> f32 { + 1.0 +} + +pub const fn def_half() -> f32 { + 0.5 +} + +pub const fn def_point7() -> f32 { + 0.7 +} + +pub const fn def_point3() -> f32 { + 0.3 +} + +const fn def_osc_port() -> u16 { + 9000 +} + +const fn def_empty_vec_string() -> Vec { + Vec::new() +} + +const fn def_sets() -> Vec { + Vec::new() +} + +const fn def_zero_u32() -> u32 { + 0 +} + +fn def_timezones() -> Vec { + const EMEA: i32 = -60 * 60; // UTC-1 + const APAC: i32 = 5 * 60 * 60; // UTC+5 + + let offset = chrono::Local::now().offset().fix(); + match offset.local_minus_utc() { + i32::MIN..EMEA => vec!["Europe/Paris".into(), "Asia/Tokyo".into()], + EMEA..APAC => vec!["America/New_York".into(), "Asia/Tokyo".into()], + APAC..=i32::MAX => vec!["Europe/Paris".into(), "America/New_York".into()], + } +} + +const fn def_screens() -> AStrSet { + AStrSet::new() +} + +const fn def_curve_values() -> AStrMap { + AStrMap::new() +} + +const fn def_transforms() -> AStrMap { + AStrMap::new() +} + +fn def_auto() -> Arc { + "auto".into() +} + +fn def_empty() -> Arc { + "".into() +} + +fn def_toast_topics() -> IdMap { + IdMap::new() +} + +fn def_font() -> Arc { + "LiberationSans:style=Bold".into() +} + +const fn def_max_height() -> u16 { + 1440 +} + +#[derive(Deserialize, Serialize)] +pub struct GeneralConfig { + #[serde(default = "def_watch_pos")] + pub watch_pos: Vec3, + + #[serde(default = "def_watch_rot")] + pub watch_rot: Quat, + + #[serde(default = "def_left")] + pub watch_hand: LeftRight, + + #[serde(default = "def_click_freeze_time_ms")] + pub click_freeze_time_ms: u32, + + #[serde(default = "def_false")] + pub invert_scroll_direction_x: bool, + + #[serde(default = "def_false")] + pub invert_scroll_direction_y: bool, + + #[serde(default = "def_one")] + pub scroll_speed: f32, + + #[serde(default = "def_mouse_move_interval_ms")] + pub mouse_move_interval_ms: u32, + + #[serde(default = "def_true")] + pub notifications_enabled: bool, + + #[serde(default = "def_true")] + pub notifications_sound_enabled: bool, + + #[serde(default = "def_toast_topics")] + pub notification_topics: IdMap, + + #[serde(default = "def_empty")] + pub notification_sound: Arc, + + #[serde(default = "def_true")] + pub keyboard_sound_enabled: bool, + + #[serde(default = "def_one")] + pub keyboard_scale: f32, + + #[serde(default = "def_one")] + pub desktop_view_scale: f32, + + #[serde(default = "def_half")] + pub watch_view_angle_min: f32, + + #[serde(default = "def_point7")] + pub watch_view_angle_max: f32, + + #[serde(default = "def_one")] + pub long_press_duration: f32, + + #[serde(default = "def_osc_port")] + pub osc_out_port: u16, + + #[serde(default = "def_false")] + pub upright_screen_fix: bool, + + #[serde(default = "def_false")] + pub double_cursor_fix: bool, + + #[serde(default = "def_screens")] + pub show_screens: AStrSet, + + #[serde(default = "def_curve_values")] + pub curve_values: AStrMap, + + #[serde(default = "def_transforms")] + pub transform_values: AStrMap, + + #[serde(default = "def_auto")] + pub capture_method: Arc, + + #[serde(default = "def_point7")] + pub xr_grab_sensitivity: f32, + + #[serde(default = "def_point7")] + pub xr_click_sensitivity: f32, + + #[serde(default = "def_point7")] + pub xr_alt_click_sensitivity: f32, + + #[serde(default = "def_half")] + pub xr_grab_sensitivity_release: f32, + + #[serde(default = "def_half")] + pub xr_click_sensitivity_release: f32, + + #[serde(default = "def_half")] + pub xr_alt_click_sensitivity_release: f32, + + #[serde(default = "def_true")] + pub allow_sliding: bool, + + #[serde(default = "def_true")] + pub realign_on_showhide: bool, + + #[serde(default = "def_false")] + pub focus_follows_mouse_mode: bool, + + #[serde(default = "def_false")] + pub block_game_input: bool, + + #[serde(default = "def_true")] + pub block_game_input_ignore_watch: bool, + + #[serde(default = "def_font")] + pub primary_font: Arc, + + #[serde(default = "def_one")] + pub space_drag_multiplier: f32, + + #[serde(default = "def_empty")] + pub skybox_texture: Arc, + + #[serde(default = "def_true")] + pub use_skybox: bool, + + #[serde(default = "def_true")] + pub use_passthrough: bool, + + #[serde(default = "def_max_height")] + pub screen_max_height: u16, + + #[serde(default = "def_false")] + pub screen_render_down: bool, + + #[serde(default = "def_point3")] + pub pointer_lerp_factor: f32, + + #[serde(default = "def_false")] + pub space_rotate_unlocked: bool, + + #[serde(default = "def_empty_vec_string")] + pub alt_click_down: Vec, + + #[serde(default = "def_empty_vec_string")] + pub alt_click_up: Vec, + + #[serde(default = "def_timezones")] + pub timezones: Vec, + + #[serde(default = "def_false")] + pub clock_12h: bool, + + #[serde(default = "def_sets")] + pub sets: Vec, + + #[serde(default = "def_zero_u32")] + pub last_set: u32, +} diff --git a/wlx-common/src/lib.rs b/wlx-common/src/lib.rs new file mode 100644 index 0000000..7140f10 --- /dev/null +++ b/wlx-common/src/lib.rs @@ -0,0 +1,5 @@ +pub mod astr_containers; +pub mod common; +pub mod config; +pub mod overlays; +pub mod windowing; diff --git a/wlx-common/src/overlays.rs b/wlx-common/src/overlays.rs new file mode 100644 index 0000000..3663ee4 --- /dev/null +++ b/wlx-common/src/overlays.rs @@ -0,0 +1,17 @@ +use idmap_derive::IntegerId; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, IntegerId, Serialize, Deserialize)] +pub enum ToastTopic { + System, + DesktopNotification, + XSNotification, + IpdChange, +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub enum ToastDisplayMethod { + Hide, + Center, + Watch, +} diff --git a/wlx-common/src/windowing.rs b/wlx-common/src/windowing.rs new file mode 100644 index 0000000..c9d26c2 --- /dev/null +++ b/wlx-common/src/windowing.rs @@ -0,0 +1,60 @@ +use glam::Affine3A; +use serde::{Deserialize, Serialize}; + +use crate::common::LeftRight; + +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)] +pub enum Positioning { + /// Stays in place, recenters relative to HMD + #[default] + Floating, + /// Stays in place, recenters relative to anchor. Follows anchor during anchor grab. + Anchored, + /// Same as anchor but paused due to interaction + AnchoredPaused, + /// Stays in place, no recentering + Static, + /// Following HMD + FollowHead { lerp: f32 }, + /// Normally follows HMD, but paused due to interaction + FollowHeadPaused { lerp: f32 }, + /// Following hand + FollowHand { hand: LeftRight, lerp: f32 }, + /// Normally follows hand, but paused due to interaction + FollowHandPaused { hand: LeftRight, lerp: f32 }, +} + +impl Positioning { + pub const fn moves_with_space(self) -> bool { + matches!(self, Self::Floating | Self::Anchored | Self::Static) + } +} + +// Contains the window state for a given set +#[derive(Clone, Serialize, Deserialize)] +#[serde(default)] +pub struct OverlayWindowState { + pub transform: Affine3A, + pub alpha: f32, + pub grabbable: bool, + pub interactable: bool, + pub positioning: Positioning, + pub curvature: Option, + pub additive: bool, + pub saved_transform: Option, +} + +impl Default for OverlayWindowState { + fn default() -> Self { + Self { + grabbable: false, + interactable: false, + alpha: 1.0, + positioning: Positioning::Floating, + curvature: None, + transform: Affine3A::IDENTITY, + additive: false, + saved_transform: None, + } + } +} diff --git a/wlx-overlay-s/Cargo.toml b/wlx-overlay-s/Cargo.toml index b61966b..cc90799 100644 --- a/wlx-overlay-s/Cargo.toml +++ b/wlx-overlay-s/Cargo.toml @@ -31,7 +31,7 @@ dbus = { version = "0.9.9" } futures = "0.3.31" glam = { workspace = true, features = ["mint", "serde"] } idmap = { workspace = true, features = ["serde"] } -idmap-derive = "0.2.2" +idmap-derive = { workspace = true } input-linux = "0.7.1" json = { version = "0.12.4", optional = true } json5 = "0.4.1" @@ -61,6 +61,7 @@ strum = { version = "0.27.2", features = ["derive"] } sysinfo = { version = "0.37" } thiserror = "2.0" wlx-capture = { path = "../wlx-capture" } +wlx-common = { path = "../wlx-common" } libmonado = { version = "1.3.2", optional = true } winit = { version = "0.30.12", optional = true } xdg = "3.0" diff --git a/wlx-overlay-s/src/backend/input.rs b/wlx-overlay-s/src/backend/input.rs index 404a5a8..4d91557 100644 --- a/wlx-overlay-s/src/backend/input.rs +++ b/wlx-overlay-s/src/backend/input.rs @@ -4,14 +4,15 @@ use std::{collections::VecDeque, time::Instant}; use glam::{Affine3A, Vec2, Vec3A, Vec3Swizzles}; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; +use wlx_common::windowing::{OverlayWindowState, Positioning}; use crate::overlays::anchor::ANCHOR_NAME; use crate::state::{AppSession, AppState}; use crate::subsystem::hid::WheelDelta; use crate::subsystem::input::KeyboardFocus; use crate::windowing::manager::OverlayWindowManager; -use crate::windowing::window::{realign, OverlayWindowData, OverlayWindowState, Positioning}; +use crate::windowing::window::{self, OverlayWindowData, realign}; use crate::windowing::{OverlayID, OverlaySelector}; use super::task::TaskType; @@ -705,7 +706,7 @@ where x => x, }; - overlay_state.save_transform(app); + window::save_transform(overlay_state, app); } // Hide anchor diff --git a/wlx-overlay-s/src/backend/openvr/mod.rs b/wlx-overlay-s/src/backend/openvr/mod.rs index 68c1cd6..8b7e120 100644 --- a/wlx-overlay-s/src/backend/openvr/mod.rs +++ b/wlx-overlay-s/src/backend/openvr/mod.rs @@ -2,37 +2,38 @@ use std::{ collections::VecDeque, ops::Add, sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, + atomic::{AtomicBool, AtomicUsize, Ordering}, }, time::{Duration, Instant}, }; -use anyhow::{anyhow, Result}; +use anyhow::{Result, anyhow}; use ovr_overlay::{ - sys::{ETrackedDeviceProperty, EVRApplicationType, EVREventType}, TrackedDeviceIndex, + sys::{ETrackedDeviceProperty, EVRApplicationType, EVREventType}, }; -use vulkano::{device::physical::PhysicalDevice, Handle, VulkanObject}; +use vulkano::{Handle, VulkanObject, device::physical::PhysicalDevice}; +use wlx_common::overlays::ToastTopic; use crate::{ backend::{ + BackendError, input::interact, openvr::{ helpers::adjust_gain, - input::{set_action_manifest, OpenVrInputSource}, + input::{OpenVrInputSource, set_action_manifest}, lines::LinePool, manifest::{install_manifest, uninstall_manifest}, overlay::OpenVrOverlayData, }, task::{SystemTask, TaskType}, - BackendError, }, config::save_state, - graphics::{init_openvr_graphics, GpuFutures}, + graphics::{GpuFutures, init_openvr_graphics}, overlays::{ - toast::{Toast, ToastTopic}, - watch::{watch_fade, WATCH_NAME}, + toast::Toast, + watch::{WATCH_NAME, watch_fade}, }, state::AppState, subsystem::notifications::NotificationManager, diff --git a/wlx-overlay-s/src/backend/openxr/mod.rs b/wlx-overlay-s/src/backend/openxr/mod.rs index e00ecbc..8360ab4 100644 --- a/wlx-overlay-s/src/backend/openxr/mod.rs +++ b/wlx-overlay-s/src/backend/openxr/mod.rs @@ -2,8 +2,8 @@ use std::{ collections::VecDeque, ops::Add, sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, + atomic::{AtomicBool, AtomicUsize, Ordering}, }, time::{Duration, Instant}, }; @@ -14,19 +14,20 @@ use libmonado::Monado; use openxr as xr; use skybox::create_skybox; use vulkano::{Handle, VulkanObject}; +use wlx_common::overlays::ToastTopic; use crate::{ backend::{ + BackendError, input::interact, openxr::{lines::LinePool, overlay::OpenXrOverlayData}, task::{SystemTask, TaskType}, - BackendError, }, config::save_state, - graphics::{init_openxr_graphics, GpuFutures}, + graphics::{GpuFutures, init_openxr_graphics}, overlays::{ - toast::{Toast, ToastTopic}, - watch::{watch_fade, WATCH_NAME}, + toast::Toast, + watch::{WATCH_NAME, watch_fade}, }, state::AppState, subsystem::notifications::NotificationManager, diff --git a/wlx-overlay-s/src/config.rs b/wlx-overlay-s/src/config.rs index 5afe40d..62d91db 100644 --- a/wlx-overlay-s/src/config.rs +++ b/wlx-overlay-s/src/config.rs @@ -1,360 +1,13 @@ -use std::path::PathBuf; -use std::sync::Arc; - use crate::config_io; -use crate::overlays::toast::{DisplayMethod, ToastTopic}; -use crate::state::LeftRight; -use crate::windowing::set::SerializedWindowSet; -use chrono::Offset; use config::{Config, File}; -use glam::{Affine3A, Quat, Vec3, vec3}; -use idmap::IdMap; +use glam::{Quat, Vec3}; use log::error; use serde::{Deserialize, Serialize}; - -pub type AStrMap = Vec<(Arc, V)>; - -pub trait AStrMapExt { - fn arc_set(&mut self, key: Arc, value: V) -> bool; - fn arc_get(&self, key: &str) -> Option<&V>; - fn arc_rm(&mut self, key: &str) -> Option; -} - -impl AStrMapExt for AStrMap { - fn arc_set(&mut self, key: Arc, value: V) -> bool { - let index = self.iter().position(|(k, _)| k.as_ref().eq(key.as_ref())); - index.map(|i| self.remove(i).1); - self.push((key, value)); - true - } - - fn arc_get(&self, key: &str) -> Option<&V> { - self.iter() - .find_map(|(k, v)| if k.as_ref().eq(key) { Some(v) } else { None }) - } - - fn arc_rm(&mut self, key: &str) -> Option { - let index = self.iter().position(|(k, _)| k.as_ref().eq(key)); - index.map(|i| self.remove(i).1) - } -} - -pub type AStrSet = Vec>; - -pub trait AStrSetExt { - fn arc_set(&mut self, value: Arc) -> bool; - fn arc_get(&self, value: &str) -> bool; - fn arc_rm(&mut self, value: &str) -> bool; -} - -impl AStrSetExt for AStrSet { - fn arc_set(&mut self, value: Arc) -> bool { - if self.iter().any(|v| v.as_ref().eq(value.as_ref())) { - return false; - } - self.push(value); - true - } - - fn arc_get(&self, value: &str) -> bool { - self.iter().any(|v| v.as_ref().eq(value)) - } - - fn arc_rm(&mut self, value: &str) -> bool { - let index = self.iter().position(|v| v.as_ref().eq(value)); - index.is_some_and(|i| { - self.remove(i); - true - }) - } -} - -pub type PwTokenMap = AStrMap; - -pub const fn def_watch_pos() -> Vec3 { - vec3(-0.03, -0.01, 0.125) -} - -pub const fn def_watch_rot() -> Quat { - Quat::from_xyzw(-0.707_106_6, 0.000_796_361_8, 0.707_106_6, 0.0) -} - -pub const fn def_left() -> LeftRight { - LeftRight::Left -} - -pub const fn def_pw_tokens() -> PwTokenMap { - AStrMap::new() -} - -const fn def_mouse_move_interval_ms() -> u32 { - 10 // 100fps -} - -const fn def_click_freeze_time_ms() -> u32 { - 300 -} - -pub const fn def_true() -> bool { - true -} - -const fn def_false() -> bool { - false -} - -const fn def_one() -> f32 { - 1.0 -} - -pub const fn def_half() -> f32 { - 0.5 -} - -pub const fn def_point7() -> f32 { - 0.7 -} - -pub const fn def_point3() -> f32 { - 0.3 -} - -const fn def_osc_port() -> u16 { - 9000 -} - -const fn def_empty_vec_string() -> Vec { - Vec::new() -} - -const fn def_sets() -> Vec { - Vec::new() -} - -const fn def_zero_u32() -> u32 { - 0 -} - -fn def_timezones() -> Vec { - const EMEA: i32 = -60 * 60; // UTC-1 - const APAC: i32 = 5 * 60 * 60; // UTC+5 - - let offset = chrono::Local::now().offset().fix(); - match offset.local_minus_utc() { - i32::MIN..EMEA => vec!["Europe/Paris".into(), "Asia/Tokyo".into()], - EMEA..APAC => vec!["America/New_York".into(), "Asia/Tokyo".into()], - APAC..=i32::MAX => vec!["Europe/Paris".into(), "America/New_York".into()], - } -} - -const fn def_screens() -> AStrSet { - AStrSet::new() -} - -const fn def_curve_values() -> AStrMap { - AStrMap::new() -} - -const fn def_transforms() -> AStrMap { - AStrMap::new() -} - -fn def_auto() -> Arc { - "auto".into() -} - -fn def_empty() -> Arc { - "".into() -} - -fn def_toast_topics() -> IdMap { - IdMap::new() -} - -fn def_font() -> Arc { - "LiberationSans:style=Bold".into() -} - -const fn def_max_height() -> u16 { - 1440 -} - -#[derive(Deserialize, Serialize)] -pub struct GeneralConfig { - #[serde(default = "def_watch_pos")] - pub watch_pos: Vec3, - - #[serde(default = "def_watch_rot")] - pub watch_rot: Quat, - - #[serde(default = "def_left")] - pub watch_hand: LeftRight, - - #[serde(default = "def_click_freeze_time_ms")] - pub click_freeze_time_ms: u32, - - #[serde(default = "def_false")] - pub invert_scroll_direction_x: bool, - - #[serde(default = "def_false")] - pub invert_scroll_direction_y: bool, - - #[serde(default = "def_one")] - pub scroll_speed: f32, - - #[serde(default = "def_mouse_move_interval_ms")] - pub mouse_move_interval_ms: u32, - - #[serde(default = "def_true")] - pub notifications_enabled: bool, - - #[serde(default = "def_true")] - pub notifications_sound_enabled: bool, - - #[serde(default = "def_toast_topics")] - pub notification_topics: IdMap, - - #[serde(default = "def_empty")] - pub notification_sound: Arc, - - #[serde(default = "def_true")] - pub keyboard_sound_enabled: bool, - - #[serde(default = "def_one")] - pub keyboard_scale: f32, - - #[serde(default = "def_one")] - pub desktop_view_scale: f32, - - #[serde(default = "def_half")] - pub watch_view_angle_min: f32, - - #[serde(default = "def_point7")] - pub watch_view_angle_max: f32, - - #[serde(default = "def_one")] - pub long_press_duration: f32, - - #[serde(default = "def_osc_port")] - pub osc_out_port: u16, - - #[serde(default = "def_false")] - pub upright_screen_fix: bool, - - #[serde(default = "def_false")] - pub double_cursor_fix: bool, - - #[serde(default = "def_screens")] - pub show_screens: AStrSet, - - #[serde(default = "def_curve_values")] - pub curve_values: AStrMap, - - #[serde(default = "def_transforms")] - pub transform_values: AStrMap, - - #[serde(default = "def_auto")] - pub capture_method: Arc, - - #[serde(default = "def_point7")] - pub xr_grab_sensitivity: f32, - - #[serde(default = "def_point7")] - pub xr_click_sensitivity: f32, - - #[serde(default = "def_point7")] - pub xr_alt_click_sensitivity: f32, - - #[serde(default = "def_half")] - pub xr_grab_sensitivity_release: f32, - - #[serde(default = "def_half")] - pub xr_click_sensitivity_release: f32, - - #[serde(default = "def_half")] - pub xr_alt_click_sensitivity_release: f32, - - #[serde(default = "def_true")] - pub allow_sliding: bool, - - #[serde(default = "def_true")] - pub realign_on_showhide: bool, - - #[serde(default = "def_false")] - pub focus_follows_mouse_mode: bool, - - #[serde(default = "def_false")] - pub block_game_input: bool, - - #[serde(default = "def_true")] - pub block_game_input_ignore_watch: bool, - - #[serde(default = "def_font")] - pub primary_font: Arc, - - #[serde(default = "def_one")] - pub space_drag_multiplier: f32, - - #[serde(default = "def_empty")] - pub skybox_texture: Arc, - - #[serde(default = "def_true")] - pub use_skybox: bool, - - #[serde(default = "def_true")] - pub use_passthrough: bool, - - #[serde(default = "def_max_height")] - pub screen_max_height: u16, - - #[serde(default = "def_false")] - pub screen_render_down: bool, - - #[serde(default = "def_point3")] - pub pointer_lerp_factor: f32, - - #[serde(default = "def_false")] - pub space_rotate_unlocked: bool, - - #[serde(default = "def_empty_vec_string")] - pub alt_click_down: Vec, - - #[serde(default = "def_empty_vec_string")] - pub alt_click_up: Vec, - - #[serde(default = "def_timezones")] - pub timezones: Vec, - - #[serde(default = "def_false")] - pub clock_12h: bool, - - #[serde(default = "def_sets")] - pub sets: Vec, - - #[serde(default = "def_zero_u32")] - pub last_set: u32, -} - -impl GeneralConfig { - fn sanitize_range(name: &str, val: f32, from: f32, to: f32) { - assert!( - !(!val.is_normal() || val < from || val > to), - "GeneralConfig: {name} needs to be between {from} and {to}" - ); - } - - pub fn load_from_disk() -> Self { - let config = load_general(); - config.post_load(); - config - } - - fn post_load(&self) { - Self::sanitize_range("keyboard_scale", self.keyboard_scale, 0.05, 5.0); - Self::sanitize_range("desktop_view_scale", self.desktop_view_scale, 0.05, 5.0); - Self::sanitize_range("scroll_speed", self.scroll_speed, 0.01, 10.0); - } -} +use std::path::PathBuf; +use wlx_common::{ + common::LeftRight, + config::{GeneralConfig, SerializedWindowSet}, +}; const FALLBACKS: [&str; 2] = [ include_str!("res/keyboard.yaml"), @@ -446,12 +99,10 @@ where } } -pub fn load_general() -> GeneralConfig { +pub fn load_general_config() -> GeneralConfig { load_config_with_conf_d::("config.yaml", config_io::ConfigRoot::Generic) } -// Config that is saved from the settings panel - #[derive(Serialize)] pub struct AutoSettings { pub watch_pos: Vec3, diff --git a/wlx-overlay-s/src/config_wayvr.rs b/wlx-overlay-s/src/config_wayvr.rs index 97e470e..3c226b2 100644 --- a/wlx-overlay-s/src/config_wayvr.rs +++ b/wlx-overlay-s/src/config_wayvr.rs @@ -9,6 +9,7 @@ use std::{ }; use serde::{Deserialize, Serialize}; +use wlx_common::{common::LeftRight, config::GeneralConfig, windowing::Positioning}; use crate::{ backend::{ @@ -17,9 +18,7 @@ use crate::{ }, config::load_config_with_conf_d, config_io, - overlays::wayvr::{executable_exists_in_path, WayVRData}, - state::LeftRight, - windowing::window::Positioning, + overlays::wayvr::{WayVRData, executable_exists_in_path}, }; // Flat version of RelativeTo @@ -180,7 +179,7 @@ impl WayVRConfig { } pub fn get_wayvr_config( - config_general: &crate::config::GeneralConfig, + config_general: &GeneralConfig, config_wayvr: &Self, ) -> anyhow::Result { Ok(wayvr::Config { @@ -199,7 +198,7 @@ impl WayVRConfig { pub fn post_load( &self, - config: &crate::config::GeneralConfig, + config: &GeneralConfig, tasks: &mut TaskContainer, ) -> anyhow::Result>>> { let primary_count = self diff --git a/wlx-overlay-s/src/overlays/anchor.rs b/wlx-overlay-s/src/overlays/anchor.rs index 14300eb..0b4e272 100644 --- a/wlx-overlay-s/src/overlays/anchor.rs +++ b/wlx-overlay-s/src/overlays/anchor.rs @@ -1,10 +1,11 @@ use glam::{Affine3A, Quat, Vec3}; use std::sync::{Arc, LazyLock}; +use wlx_common::windowing::{OverlayWindowState, Positioning}; use crate::gui::panel::GuiPanel; use crate::state::AppState; -use crate::windowing::window::{OverlayWindowConfig, OverlayWindowState, Positioning}; use crate::windowing::Z_ORDER_ANCHOR; +use crate::windowing::window::OverlayWindowConfig; pub static ANCHOR_NAME: LazyLock> = LazyLock::new(|| Arc::from("anchor")); diff --git a/wlx-overlay-s/src/overlays/custom.rs b/wlx-overlay-s/src/overlays/custom.rs index a8cdf58..489ec8f 100644 --- a/wlx-overlay-s/src/overlays/custom.rs +++ b/wlx-overlay-s/src/overlays/custom.rs @@ -1,12 +1,9 @@ use std::sync::Arc; use glam::{Affine3A, Quat, Vec3, vec3}; +use wlx_common::windowing::OverlayWindowState; -use crate::{ - gui::panel::GuiPanel, - state::AppState, - windowing::window::{OverlayWindowConfig, OverlayWindowState}, -}; +use crate::{gui::panel::GuiPanel, state::AppState, windowing::window::OverlayWindowConfig}; const SETTINGS_NAME: &str = "settings"; diff --git a/wlx-overlay-s/src/overlays/edit/pos.rs b/wlx-overlay-s/src/overlays/edit/pos.rs index 6a5d021..a1aca54 100644 --- a/wlx-overlay-s/src/overlays/edit/pos.rs +++ b/wlx-overlay-s/src/overlays/edit/pos.rs @@ -5,11 +5,9 @@ use wgui::{ parser::Fetchable, renderer_vk::text::custom_glyph::CustomGlyphData, widget::sprite::WidgetSprite, }; +use wlx_common::{common::LeftRight, windowing::Positioning}; -use crate::{ - backend::task::OverlayTask, overlays::edit::EditModeWrapPanel, state::LeftRight, - windowing::window::Positioning, -}; +use crate::{backend::task::OverlayTask, overlays::edit::EditModeWrapPanel, windowing::window}; static POS_NAMES: [&str; 6] = ["static", "anchored", "floating", "hmd", "hand_l", "hand_r"]; @@ -98,7 +96,7 @@ impl PositioningHandler { Box::new(move |app, owc| { let state = owc.active_state.as_mut().unwrap(); //want panic state.positioning = pos; - state.save_transform(app); + window::save_transform(state, app); }) } diff --git a/wlx-overlay-s/src/overlays/keyboard/builder.rs b/wlx-overlay-s/src/overlays/keyboard/builder.rs index 0e3bdbc..3c4bdb1 100644 --- a/wlx-overlay-s/src/overlays/keyboard/builder.rs +++ b/wlx-overlay-s/src/overlays/keyboard/builder.rs @@ -17,12 +17,13 @@ use wgui::{ util::WLength, }, }; +use wlx_common::windowing::{OverlayWindowState, Positioning}; use crate::{ gui::panel::GuiPanel, state::AppState, subsystem::hid::{ALT, CTRL, META, SHIFT, SUPER, XkbKeymap}, - windowing::window::{OverlayWindowConfig, OverlayWindowState, Positioning}, + windowing::window::OverlayWindowConfig, }; use super::{ diff --git a/wlx-overlay-s/src/overlays/mirror.rs b/wlx-overlay-s/src/overlays/mirror.rs index 5eef4ac..a821381 100644 --- a/wlx-overlay-s/src/overlays/mirror.rs +++ b/wlx-overlay-s/src/overlays/mirror.rs @@ -5,7 +5,8 @@ use std::{ use futures::{Future, FutureExt}; use glam::{Affine2, Affine3A, Vec3}; -use wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireSelectScreenResult}; +use wlx_capture::pipewire::{PipewireCapture, PipewireSelectScreenResult, pipewire_select_screen}; +use wlx_common::windowing::OverlayWindowState; use crate::{ backend::{ @@ -15,12 +16,12 @@ use crate::{ state::{AppSession, AppState}, subsystem::hid::WheelDelta, windowing::{ - backend::{ - ui_transform, FrameMeta, OverlayBackend, OverlayEventData, RenderResources, - ShouldRender, - }, - window::{OverlayWindowConfig, OverlayWindowState}, OverlaySelector, + backend::{ + FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender, + ui_transform, + }, + window::OverlayWindowConfig, }, }; diff --git a/wlx-overlay-s/src/overlays/screen/capture.rs b/wlx-overlay-s/src/overlays/screen/capture.rs index 5165ca4..ba9e985 100644 --- a/wlx-overlay-s/src/overlays/screen/capture.rs +++ b/wlx-overlay-s/src/overlays/screen/capture.rs @@ -7,25 +7,26 @@ use vulkano::{ command_buffer::CommandBufferUsage, device::Queue, format::Format, - image::{sampler::Filter, view::ImageView, Image}, + image::{Image, sampler::Filter, view::ImageView}, pipeline::graphics::color_blend::AttachmentBlend, }; use wgui::gfx::{ + WGfx, cmd::WGfxClearMode, pass::WGfxPass, pipeline::{WGfxPipeline, WPipelineCreateInfo}, - WGfx, }; use wlx_capture::{ - frame::{self as wlx_frame, DrmFormat, FrameFormat, MouseMeta, Transform, WlxFrame}, WlxCapture, + frame::{self as wlx_frame, DrmFormat, FrameFormat, MouseMeta, Transform, WlxFrame}, }; +use wlx_common::config::GeneralConfig; use crate::{ - config::GeneralConfig, graphics::{ - dmabuf::{fourcc_to_vk, WGfxDmabuf}, - upload_quad_vertices, Vert2Uv, + Vert2Uv, + dmabuf::{WGfxDmabuf, fourcc_to_vk}, + upload_quad_vertices, }, state::AppState, windowing::backend::{FrameMeta, RenderResources}, diff --git a/wlx-overlay-s/src/overlays/screen/mod.rs b/wlx-overlay-s/src/overlays/screen/mod.rs index 1482912..f35002c 100644 --- a/wlx-overlay-s/src/overlays/screen/mod.rs +++ b/wlx-overlay-s/src/overlays/screen/mod.rs @@ -1,15 +1,13 @@ use std::{f32::consts::PI, sync::Arc}; -use glam::{vec3, Affine3A, Quat, Vec3}; +use glam::{Affine3A, Quat, Vec3, vec3}; use wlx_capture::frame::Transform; +use wlx_common::windowing::{OverlayWindowState, Positioning}; use crate::{ state::{AppSession, AppState, ScreenMeta}, subsystem::{hid::XkbKeymap, input::KeyboardFocus}, - windowing::{ - backend::OverlayBackend, - window::{OverlayWindowConfig, OverlayWindowState, Positioning}, - }, + windowing::{backend::OverlayBackend, window::OverlayWindowConfig}, }; pub mod backend; diff --git a/wlx-overlay-s/src/overlays/screen/pw.rs b/wlx-overlay-s/src/overlays/screen/pw.rs index 34a3d0a..c451cba 100644 --- a/wlx-overlay-s/src/overlays/screen/pw.rs +++ b/wlx-overlay-s/src/overlays/screen/pw.rs @@ -6,12 +6,9 @@ use wlx_capture::{ pipewire::{PipewireCapture, PipewireSelectScreenResult}, wayland::WlxOutput, }; +use wlx_common::config::{PwTokenMap, def_pw_tokens}; -use crate::{ - config::{PwTokenMap, def_pw_tokens}, - config_io, - state::AppState, -}; +use crate::{config_io, state::AppState}; use super::{ backend::ScreenBackend, diff --git a/wlx-overlay-s/src/overlays/screen/wl.rs b/wlx-overlay-s/src/overlays/screen/wl.rs index e8ed921..e1e8b56 100644 --- a/wlx-overlay-s/src/overlays/screen/wl.rs +++ b/wlx-overlay-s/src/overlays/screen/wl.rs @@ -5,9 +5,9 @@ use wlx_capture::{ wlr_dmabuf::WlrDmabufCapture, wlr_screencopy::WlrScreencopyCapture, }; +use wlx_common::{astr_containers::AStrMapExt, config::PwTokenMap}; use crate::{ - config::{AStrMapExt, PwTokenMap}, overlays::screen::create_screen_from_backend, state::{AppState, ScreenMeta}, }; diff --git a/wlx-overlay-s/src/overlays/screen/x11.rs b/wlx-overlay-s/src/overlays/screen/x11.rs index 9f34969..48e4257 100644 --- a/wlx-overlay-s/src/overlays/screen/x11.rs +++ b/wlx-overlay-s/src/overlays/screen/x11.rs @@ -35,9 +35,9 @@ impl ScreenBackend { pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result { use glam::vec2; use wlx_capture::{pipewire::PipewireCapture, xshm::xshm_get_monitors}; + use wlx_common::{astr_containers::AStrMapExt, config::PwTokenMap}; use crate::{ - config::{AStrMapExt, PwTokenMap}, overlays::screen::{ create_screen_from_backend, pw::{load_pw_token_config, save_pw_token_config, select_pw_screen}, diff --git a/wlx-overlay-s/src/overlays/toast.rs b/wlx-overlay-s/src/overlays/toast.rs index 048d081..59a880a 100644 --- a/wlx-overlay-s/src/overlays/toast.rs +++ b/wlx-overlay-s/src/overlays/toast.rs @@ -6,8 +6,6 @@ use std::{ }; use glam::{Affine3A, Quat, Vec3, vec3}; -use idmap_derive::IntegerId; -use serde::{Deserialize, Serialize}; use wgui::{ i18n::Translation, parser::parse_color_hex, @@ -22,15 +20,17 @@ use wgui::{ util::WLength, }, }; +use wlx_common::{ + common::LeftRight, + overlays::{ToastDisplayMethod, ToastTopic}, + windowing::{OverlayWindowState, Positioning}, +}; use crate::{ backend::task::TaskType, gui::panel::GuiPanel, - state::{AppState, LeftRight}, - windowing::{ - OverlaySelector, Z_ORDER_TOAST, - window::{OverlayWindowConfig, OverlayWindowState, Positioning}, - }, + state::AppState, + windowing::{OverlaySelector, Z_ORDER_TOAST, window::OverlayWindowConfig}, }; const FONT_SIZE: isize = 16; @@ -38,21 +38,6 @@ const PADDING: (f32, f32) = (25., 7.); const PIXELS_TO_METERS: f32 = 1. / 2000.; static TOAST_NAME: LazyLock> = LazyLock::new(|| "toast".into()); -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub enum DisplayMethod { - Hide, - Center, - Watch, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, IntegerId, Serialize, Deserialize)] -pub enum ToastTopic { - System, - DesktopNotification, - XSNotification, - IpdChange, -} - pub struct Toast { pub title: String, pub body: String, @@ -134,16 +119,16 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option { .toast_topics .get(toast.topic) .copied() - .unwrap_or(DisplayMethod::Hide); + .unwrap_or(ToastDisplayMethod::Hide); let (spawn_point, spawn_rotation, positioning) = match current_method { - DisplayMethod::Hide => return None, - DisplayMethod::Center => ( + ToastDisplayMethod::Hide => return None, + ToastDisplayMethod::Center => ( vec3(0., -0.2, -0.5), Quat::IDENTITY, Positioning::FollowHead { lerp: 0.1 }, ), - DisplayMethod::Watch => { + ToastDisplayMethod::Watch => { let mut watch_pos = app.session.config.watch_pos + vec3(-0.005, -0.05, 0.02); let mut watch_rot = app.session.config.watch_rot; let relative_to = match app.session.config.watch_hand { diff --git a/wlx-overlay-s/src/overlays/watch.rs b/wlx-overlay-s/src/overlays/watch.rs index 1a21b11..812a261 100644 --- a/wlx-overlay-s/src/overlays/watch.rs +++ b/wlx-overlay-s/src/overlays/watch.rs @@ -6,6 +6,7 @@ use wgui::{ event::{CallbackDataCommon, EventAlterables}, parser::Fetchable, }; +use wlx_common::windowing::{OverlayWindowState, Positioning}; use crate::{ gui::{ @@ -14,9 +15,9 @@ use crate::{ }, state::AppState, windowing::{ - backend::OverlayEventData, - window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState, Positioning}, Z_ORDER_WATCH, + backend::OverlayEventData, + window::{OverlayWindowConfig, OverlayWindowData}, }, }; diff --git a/wlx-overlay-s/src/overlays/wayvr.rs b/wlx-overlay-s/src/overlays/wayvr.rs index 1a37d6f..654b225 100644 --- a/wlx-overlay-s/src/overlays/wayvr.rs +++ b/wlx-overlay-s/src/overlays/wayvr.rs @@ -1,42 +1,42 @@ -use glam::{vec3, Affine2, Affine3A, Quat, Vec3}; +use glam::{Affine2, Affine3A, Quat, Vec3, vec3}; use smallvec::smallvec; use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; use vulkano::{ buffer::{BufferUsage, Subbuffer}, command_buffer::CommandBufferUsage, format::Format, - image::{view::ImageView, Image, ImageTiling, SubresourceLayout}, + image::{Image, ImageTiling, SubresourceLayout, view::ImageView}, }; use wayvr_ipc::packet_server::{self, PacketServer, WvrStateChanged}; use wgui::gfx::{ + WGfx, pass::WGfxPass, pipeline::{WGfxPipeline, WPipelineCreateInfo}, - WGfx, }; use wlx_capture::frame::{DmabufFrame, FourCC, FrameFormat, FramePlane}; +use wlx_common::windowing::OverlayWindowState; use crate::{ backend::{ input::{self, HoverResult}, task::TaskType, wayvr::{ - self, display, + self, WayVR, WayVRAction, WayVRDisplayClickAction, display, server_ipc::{gen_args_vec, gen_env_vec}, - WayVR, WayVRAction, WayVRDisplayClickAction, }, }, config_wayvr, - graphics::{dmabuf::WGfxDmabuf, Vert2Uv}, + graphics::{Vert2Uv, dmabuf::WGfxDmabuf}, state::{self, AppState}, subsystem::{hid::WheelDelta, input::KeyboardFocus}, windowing::{ + OverlayID, OverlaySelector, Z_ORDER_DASHBOARD, backend::{ - ui_transform, FrameMeta, OverlayBackend, OverlayEventData, RenderResources, - ShouldRender, + FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender, + ui_transform, }, manager::OverlayWindowManager, - window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState}, - OverlayID, OverlaySelector, Z_ORDER_DASHBOARD, + window::{OverlayWindowConfig, OverlayWindowData}, }, }; diff --git a/wlx-overlay-s/src/state.rs b/wlx-overlay-s/src/state.rs index 11bb93e..cab9e55 100644 --- a/wlx-overlay-s/src/state.rs +++ b/wlx-overlay-s/src/state.rs @@ -1,12 +1,15 @@ use glam::Affine3A; use idmap::IdMap; -use serde::{Deserialize, Serialize}; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use std::sync::Arc; use wgui::{ font_config::WguiFontConfig, gfx::WGfx, globals::WguiGlobals, renderer_vk::context::SharedContext as WSharedContext, }; +use wlx_common::{ + config::GeneralConfig, + overlays::{ToastDisplayMethod, ToastTopic}, +}; #[cfg(feature = "wayvr")] use { @@ -20,11 +23,10 @@ use crate::subsystem::osc::OscSender; use crate::{ backend::{input::InputState, task::TaskContainer}, - config::GeneralConfig, + config::load_general_config, config_io, graphics::WGfxExtras, gui, - overlays::toast::{DisplayMethod, ToastTopic}, subsystem::{audio::AudioOutput, input::HidWrapper}, }; @@ -156,19 +158,19 @@ pub struct AppSession { #[cfg(feature = "wayvr")] pub wayvr_config: WayVRConfig, - pub toast_topics: IdMap, + pub toast_topics: IdMap, } impl AppSession { pub fn load() -> Self { let config_root_path = config_io::ConfigRoot::Generic.ensure_dir(); log::info!("Config root path: {}", config_root_path.display()); - let config = GeneralConfig::load_from_disk(); + let config = load_general_config(); let mut toast_topics = IdMap::new(); - toast_topics.insert(ToastTopic::System, DisplayMethod::Center); - toast_topics.insert(ToastTopic::DesktopNotification, DisplayMethod::Center); - toast_topics.insert(ToastTopic::XSNotification, DisplayMethod::Center); + toast_topics.insert(ToastTopic::System, ToastDisplayMethod::Center); + toast_topics.insert(ToastTopic::DesktopNotification, ToastDisplayMethod::Center); + toast_topics.insert(ToastTopic::XSNotification, ToastDisplayMethod::Center); config.notification_topics.iter().for_each(|(k, v)| { toast_topics.insert(*k, *v); @@ -190,11 +192,3 @@ pub struct ScreenMeta { pub name: Arc, pub native_handle: u32, } - -#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default)] -#[repr(u8)] -pub enum LeftRight { - #[default] - Left, - Right, -} diff --git a/wlx-overlay-s/src/subsystem/notifications/mod.rs b/wlx-overlay-s/src/subsystem/notifications/mod.rs index 1503731..f2c42a1 100644 --- a/wlx-overlay-s/src/subsystem/notifications/mod.rs +++ b/wlx-overlay-s/src/subsystem/notifications/mod.rs @@ -17,11 +17,9 @@ use std::{ }, time::Duration, }; +use wlx_common::overlays::ToastTopic; -use crate::{ - overlays::toast::{Toast, ToastTopic}, - state::AppState, -}; +use crate::{overlays::toast::Toast, state::AppState}; pub struct NotificationManager { rx_toast: mpsc::Receiver, diff --git a/wlx-overlay-s/src/windowing/manager.rs b/wlx-overlay-s/src/windowing/manager.rs index c1158ec..74ceff0 100644 --- a/wlx-overlay-s/src/windowing/manager.rs +++ b/wlx-overlay-s/src/windowing/manager.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use glam::{Affine3A, Vec3, Vec3A}; use slotmap::{HopSlotMap, Key, SecondaryMap}; +use wlx_common::config::SerializedWindowSet; use crate::{ overlays::{ @@ -10,11 +11,8 @@ use crate::{ }, state::AppState, windowing::{ - backend::OverlayEventData, - set::{OverlayWindowSet, SerializedWindowSet}, - snap_upright, + OverlayID, OverlaySelector, backend::OverlayEventData, set::OverlayWindowSet, snap_upright, window::OverlayWindowData, - OverlayID, OverlaySelector, }, }; diff --git a/wlx-overlay-s/src/windowing/set.rs b/wlx-overlay-s/src/windowing/set.rs index 7263aed..05bd642 100644 --- a/wlx-overlay-s/src/windowing/set.rs +++ b/wlx-overlay-s/src/windowing/set.rs @@ -1,18 +1,11 @@ -use std::{collections::HashMap, sync::Arc}; - -use serde::{Deserialize, Serialize}; use slotmap::SecondaryMap; +use std::sync::Arc; +use wlx_common::windowing::OverlayWindowState; -use crate::windowing::{window::OverlayWindowState, OverlayID}; +use crate::windowing::OverlayID; #[derive(Default)] pub struct OverlayWindowSet { pub(super) name: Arc, pub(super) overlays: SecondaryMap, } - -#[derive(Clone, Serialize, Deserialize)] -pub struct SerializedWindowSet { - pub name: Arc, - pub overlays: HashMap, OverlayWindowState>, -} diff --git a/wlx-overlay-s/src/windowing/window.rs b/wlx-overlay-s/src/windowing/window.rs index 4916f16..4f9187a 100644 --- a/wlx-overlay-s/src/windowing/window.rs +++ b/wlx-overlay-s/src/windowing/window.rs @@ -1,9 +1,9 @@ use glam::{Affine3A, Mat3A, Quat, Vec3, Vec3A}; -use serde::{Deserialize, Serialize}; use std::{f32::consts::PI, sync::Arc}; +use wlx_common::windowing::{OverlayWindowState, Positioning}; use crate::{ - state::{AppState, LeftRight}, + state::AppState, subsystem::input::KeyboardFocus, windowing::{ backend::{FrameMeta, OverlayBackend, RenderResources, ShouldRender}, @@ -11,33 +11,6 @@ use crate::{ }, }; -#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)] -pub enum Positioning { - /// Stays in place, recenters relative to HMD - #[default] - Floating, - /// Stays in place, recenters relative to anchor. Follows anchor during anchor grab. - Anchored, - /// Same as anchor but paused due to interaction - AnchoredPaused, - /// Stays in place, no recentering - Static, - /// Following HMD - FollowHead { lerp: f32 }, - /// Normally follows HMD, but paused due to interaction - FollowHeadPaused { lerp: f32 }, - /// Following hand - FollowHand { hand: LeftRight, lerp: f32 }, - /// Normally follows hand, but paused due to interaction - FollowHandPaused { hand: LeftRight, lerp: f32 }, -} - -impl Positioning { - pub const fn moves_with_space(self) -> bool { - matches!(self, Self::Floating | Self::Anchored | Self::Static) - } -} - pub struct OverlayWindowData { pub config: OverlayWindowConfig, pub data: T, @@ -261,53 +234,20 @@ pub fn realign(transform: &mut Affine3A, hmd: &Affine3A) { transform.matrix3 = Mat3A::from_cols(col_x, col_y, col_z).mul_scalar(scale) * rot; } -// Contains the window state for a given set -#[derive(Clone, Serialize, Deserialize)] -#[serde(default)] -pub struct OverlayWindowState { - pub transform: Affine3A, - pub alpha: f32, - pub grabbable: bool, - pub interactable: bool, - pub positioning: Positioning, - pub curvature: Option, - pub additive: bool, - pub saved_transform: Option, -} - -impl Default for OverlayWindowState { - fn default() -> Self { - Self { - grabbable: false, - interactable: false, - alpha: 1.0, - positioning: Positioning::Floating, - curvature: None, - transform: Affine3A::IDENTITY, - additive: false, - saved_transform: None, +pub fn save_transform(state: &mut OverlayWindowState, app: &mut AppState) -> bool { + let parent_transform = match state.positioning { + Positioning::Floating => snap_upright(app.input_state.hmd, Vec3A::Y), + Positioning::FollowHead { .. } | Positioning::FollowHeadPaused { .. } => { + app.input_state.hmd } - } -} - -impl OverlayWindowState { - pub fn save_transform(&mut self, app: &mut AppState) -> bool { - let parent_transform = match self.positioning { - Positioning::Floating => snap_upright(app.input_state.hmd, Vec3A::Y), - Positioning::FollowHead { .. } | Positioning::FollowHeadPaused { .. } => { - app.input_state.hmd - } - Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => { - app.input_state.pointers[hand as usize].pose - } - Positioning::Anchored | Positioning::AnchoredPaused => { - snap_upright(app.anchor, Vec3A::Y) - } - Positioning::Static => return false, - }; - - self.saved_transform = Some(parent_transform.inverse() * self.transform); - - true - } + Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => { + app.input_state.pointers[hand as usize].pose + } + Positioning::Anchored | Positioning::AnchoredPaused => snap_upright(app.anchor, Vec3A::Y), + Positioning::Static => return false, + }; + + state.saved_transform = Some(parent_transform.inverse() * state.transform); + + true }