OverlayContainer to use HopSlotMap

This commit is contained in:
galister
2025-10-03 12:52:29 +09:00
parent a1edc2f0b8
commit 231850cf73
19 changed files with 121 additions and 123 deletions

View File

@@ -7,15 +7,15 @@ use std::{
use crate::{ use crate::{
animation::Animations, animation::Animations,
components::{Component, InitData}, components::{Component, InitData},
drawing::{self, Boundary, has_overflow_clip}, drawing::{self, has_overflow_clip, Boundary},
event::{self, CallbackDataCommon, EventAlterables, EventListenerCollection}, event::{self, CallbackDataCommon, EventAlterables, EventListenerCollection},
globals::WguiGlobals, globals::WguiGlobals,
stack::{self, ScissorBoundary, Transform}, stack::{self, ScissorBoundary},
widget::{self, EventParams, WidgetObj, WidgetState, div::WidgetDiv}, widget::{self, div::WidgetDiv, EventParams, WidgetObj, WidgetState},
}; };
use glam::{Vec2, vec2}; use glam::{vec2, Vec2};
use slotmap::{HopSlotMap, SecondaryMap, new_key_type}; use slotmap::{new_key_type, HopSlotMap, SecondaryMap};
use taffy::{NodeId, TaffyTree, TraversePartialTree}; use taffy::{NodeId, TaffyTree, TraversePartialTree};
new_key_type! { new_key_type! {

View File

@@ -11,7 +11,6 @@ use crate::{
}, },
layout::{Layout, LayoutState, WidgetID}, layout::{Layout, LayoutState, WidgetID},
stack::{ScissorStack, TransformStack}, stack::{ScissorStack, TransformStack},
widget,
}; };
pub mod div; pub mod div;

View File

@@ -4,17 +4,16 @@ use std::sync::{Arc, LazyLock};
use openxr as xr; use openxr as xr;
use glam::{Affine3A, Vec3, Vec3A}; use glam::{Affine3A, Vec3, Vec3A};
use idmap::IdMap; use slotmap::HopSlotMap;
use serde::Deserialize;
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
config::AStrSetExt, config::AStrSetExt,
overlays::{ overlays::{
anchor::create_anchor, anchor::create_anchor,
keyboard::{KEYBOARD_NAME, builder::create_keyboard}, keyboard::{builder::create_keyboard, KEYBOARD_NAME},
screen::create_screens, screen::create_screens,
watch::{WATCH_NAME, create_watch}, watch::{create_watch, WATCH_NAME},
}, },
state::AppState, state::AppState,
}; };
@@ -40,7 +39,7 @@ pub struct OverlayContainer<T>
where where
T: Default, T: Default,
{ {
overlays: IdMap<usize, OverlayData<T>>, overlays: HopSlotMap<OverlayID, OverlayData<T>>,
} }
impl<T> OverlayContainer<T> impl<T> OverlayContainer<T>
@@ -48,7 +47,7 @@ where
T: Default, T: Default,
{ {
pub fn new(app: &mut AppState, headless: bool) -> anyhow::Result<Self> { pub fn new(app: &mut AppState, headless: bool) -> anyhow::Result<Self> {
let mut overlays = IdMap::new(); let mut overlays = HopSlotMap::with_key();
let mut show_screens = app.session.config.show_screens.clone(); let mut show_screens = app.session.config.show_screens.clone();
let mut maybe_keymap = None; let mut maybe_keymap = None;
@@ -66,13 +65,10 @@ where
if show_screens.arc_get(state.name.as_ref()) { if show_screens.arc_get(state.name.as_ref()) {
state.show_hide = true; state.show_hide = true;
} }
overlays.insert( overlays.insert(OverlayData::<T> {
state.id.0,
OverlayData::<T> {
state, state,
..OverlayData::from_backend(backend) ..OverlayData::from_backend(backend)
}, });
);
app.screens.push(meta); app.screens.push(meta);
} }
@@ -83,16 +79,16 @@ where
} }
let anchor = create_anchor(app)?; let anchor = create_anchor(app)?;
overlays.insert(anchor.state.id.0, anchor); overlays.insert(anchor);
let mut watch = create_watch::<T>(app)?; let mut watch = create_watch::<T>(app)?;
watch.state.want_visible = true; watch.state.want_visible = true;
overlays.insert(watch.state.id.0, watch); overlays.insert(watch);
let mut keyboard = create_keyboard(app, maybe_keymap)?; let mut keyboard = create_keyboard(app, maybe_keymap)?;
keyboard.state.show_hide = show_screens.arc_get(KEYBOARD_NAME); keyboard.state.show_hide = show_screens.arc_get(KEYBOARD_NAME);
keyboard.state.want_visible = false; keyboard.state.want_visible = false;
overlays.insert(keyboard.state.id.0, keyboard); overlays.insert(keyboard);
Ok(Self { overlays }) Ok(Self { overlays })
} }
@@ -106,24 +102,19 @@ where
pub fn remove_by_selector(&mut self, selector: &OverlaySelector) -> Option<OverlayData<T>> { pub fn remove_by_selector(&mut self, selector: &OverlaySelector) -> Option<OverlayData<T>> {
match selector { match selector {
OverlaySelector::Id(id) => self.overlays.remove(id.0), OverlaySelector::Id(id) => self.overlays.remove(*id),
OverlaySelector::Name(name) => { OverlaySelector::Name(name) => {
let id = self self.lookup(name).and_then(|id| self.overlays.remove(id))
.overlays
.iter()
.find(|(_, o)| *o.state.name == **name)
.map(|(id, _)| *id);
id.and_then(|id| self.overlays.remove(id))
} }
} }
} }
pub fn get_by_id(&mut self, id: OverlayID) -> Option<&OverlayData<T>> { pub fn get_by_id(&mut self, id: OverlayID) -> Option<&OverlayData<T>> {
self.overlays.get(id.0) self.overlays.get(id)
} }
pub fn mut_by_id(&mut self, id: OverlayID) -> Option<&mut OverlayData<T>> { pub fn mut_by_id(&mut self, id: OverlayID) -> Option<&mut OverlayData<T>> {
self.overlays.get_mut(id.0) self.overlays.get_mut(id)
} }
pub fn get_by_name<'a>(&'a mut self, name: &str) -> Option<&'a OverlayData<T>> { pub fn get_by_name<'a>(&'a mut self, name: &str) -> Option<&'a OverlayData<T>> {
@@ -134,16 +125,31 @@ where
self.overlays.values_mut().find(|o| *o.state.name == *name) self.overlays.values_mut().find(|o| *o.state.name == *name)
} }
pub fn iter(&self) -> impl Iterator<Item = &'_ OverlayData<T>> { pub fn iter(&self) -> impl Iterator<Item = (OverlayID, &'_ OverlayData<T>)> {
self.overlays.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (OverlayID, &'_ mut OverlayData<T>)> {
self.overlays.iter_mut()
}
pub fn values(&self) -> impl Iterator<Item = &'_ OverlayData<T>> {
self.overlays.values() self.overlays.values()
} }
pub fn iter_mut(&mut self) -> impl Iterator<Item = &'_ mut OverlayData<T>> { pub fn values_mut(&mut self) -> impl Iterator<Item = &'_ mut OverlayData<T>> {
self.overlays.values_mut() self.overlays.values_mut()
} }
pub fn add(&mut self, overlay: OverlayData<T>) { pub fn lookup(&self, name: &str) -> Option<OverlayID> {
self.overlays.insert(overlay.state.id.0, overlay); self.overlays
.iter()
.find(|(_, v)| v.state.name.as_ref() == name)
.map(|(k, _)| k)
}
pub fn add(&mut self, overlay: OverlayData<T>) -> OverlayID {
self.overlays.insert(overlay)
} }
pub fn show_hide(&mut self, app: &mut AppState) { pub fn show_hide(&mut self, app: &mut AppState) {
@@ -177,8 +183,7 @@ where
} }
} }
#[derive(Clone, Deserialize, Debug)] #[derive(Clone, Debug)]
#[serde(untagged)]
pub enum OverlaySelector { pub enum OverlaySelector {
Id(OverlayID), Id(OverlayID),
Name(Arc<str>), Name(Arc<str>),

View File

@@ -4,7 +4,7 @@ use std::{collections::VecDeque, time::Instant};
use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles}; use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
use smallvec::{SmallVec, smallvec}; use smallvec::{smallvec, SmallVec};
use crate::backend::common::OverlaySelector; use crate::backend::common::OverlaySelector;
use crate::backend::overlay::Positioning; use crate::backend::overlay::Positioning;
@@ -323,7 +323,7 @@ where
if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) { if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) {
Pointer::handle_grabbed(idx, grabbed, app); Pointer::handle_grabbed(idx, grabbed, app);
} else { } else {
log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id.0); log::warn!("Grabbed overlay {:?} does not exist", grab_data.grabbed_id);
pointer.interaction.grabbed = None; pointer.interaction.grabbed = None;
} }
return (0.1, None); return (0.1, None);
@@ -364,7 +364,7 @@ where
pointer = &mut app.input_state.pointers[idx]; pointer = &mut app.input_state.pointers[idx];
} }
let Some(hovered) = overlays.mut_by_id(hit.overlay) else { let Some(hovered) = overlays.mut_by_id(hit.overlay) else {
log::warn!("Hit overlay {} does not exist", hit.overlay.0); log::warn!("Hit overlay {:?} does not exist", hit.overlay);
return (0.0, None); // no hit return (0.0, None); // no hit
}; };
@@ -385,7 +385,7 @@ where
if pointer.now.grab && !pointer.before.grab && hovered.state.grabbable { if pointer.now.grab && !pointer.before.grab && hovered.state.grabbable {
update_focus(&mut app.hid_provider.keyboard_focus, &hovered.state); update_focus(&mut app.hid_provider.keyboard_focus, &hovered.state);
pointer.start_grab(hovered, &mut app.tasks); pointer.start_grab(hit.overlay, hovered, &mut app.tasks);
return ( return (
hit.dist, hit.dist,
Some(Haptics { Some(Haptics {
@@ -454,13 +454,13 @@ impl Pointer {
{ {
let mut hits: SmallVec<[RayHit; 8]> = smallvec!(); let mut hits: SmallVec<[RayHit; 8]> = smallvec!();
for overlay in overlays.iter() { for (id, overlay) in overlays.iter() {
if !overlay.state.want_visible || !overlay.state.interactable { if !overlay.state.want_visible || !overlay.state.interactable {
continue; continue;
} }
if let Some(hit) = self.ray_test( if let Some(hit) = self.ray_test(
overlay.state.id, id,
&overlay.state.transform, &overlay.state.transform,
overlay.state.curvature.as_ref(), overlay.state.curvature.as_ref(),
) { ) {
@@ -502,8 +502,12 @@ impl Pointer {
None None
} }
fn start_grab<O>(&mut self, overlay: &mut OverlayData<O>, tasks: &mut TaskContainer) fn start_grab<O>(
where &mut self,
id: OverlayID,
overlay: &mut OverlayData<O>,
tasks: &mut TaskContainer,
) where
O: Default, O: Default,
{ {
let offset = self let offset = self
@@ -513,7 +517,7 @@ impl Pointer {
self.interaction.grabbed = Some(GrabData { self.interaction.grabbed = Some(GrabData {
offset, offset,
grabbed_id: overlay.state.id, grabbed_id: id,
old_curvature: overlay.state.curvature, old_curvature: overlay.state.curvature,
grab_all: matches!(self.interaction.mode, PointerMode::Right), grab_all: matches!(self.interaction.mode, PointerMode::Right),
}); });
@@ -570,7 +574,7 @@ impl Pointer {
overlay.state.realign(&app.input_state.hmd); overlay.state.realign(&app.input_state.hmd);
overlay.state.dirty = true; overlay.state.dirty = true;
} else { } else {
log::error!("Grabbed overlay {} does not exist", overlay.state.id.0); log::error!("Grabbed overlay does not exist");
pointer.interaction.grabbed = None; pointer.interaction.grabbed = None;
} }
} else { } else {

View File

@@ -2,18 +2,18 @@ use std::{
collections::VecDeque, collections::VecDeque,
ops::Add, ops::Add,
sync::{ sync::{
Arc,
atomic::{AtomicBool, AtomicUsize, Ordering}, atomic::{AtomicBool, AtomicUsize, Ordering},
Arc,
}, },
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use anyhow::{Result, anyhow}; use anyhow::{anyhow, Result};
use ovr_overlay::{ use ovr_overlay::{
TrackedDeviceIndex,
sys::{ETrackedDeviceProperty, EVRApplicationType, EVREventType}, sys::{ETrackedDeviceProperty, EVRApplicationType, EVREventType},
TrackedDeviceIndex,
}; };
use vulkano::{Handle, VulkanObject, device::physical::PhysicalDevice}; use vulkano::{device::physical::PhysicalDevice, Handle, VulkanObject};
use crate::{ use crate::{
backend::{ backend::{
@@ -21,7 +21,7 @@ use crate::{
input::interact, input::interact,
openvr::{ openvr::{
helpers::adjust_gain, helpers::adjust_gain,
input::{OpenVrInputSource, set_action_manifest}, input::{set_action_manifest, OpenVrInputSource},
lines::LinePool, lines::LinePool,
manifest::{install_manifest, uninstall_manifest}, manifest::{install_manifest, uninstall_manifest},
overlay::OpenVrOverlayData, overlay::OpenVrOverlayData,
@@ -29,10 +29,10 @@ use crate::{
overlay::{OverlayData, ShouldRender}, overlay::{OverlayData, ShouldRender},
task::{SystemTask, TaskType}, task::{SystemTask, TaskType},
}, },
graphics::{CommandBuffers, init_openvr_graphics}, graphics::{init_openvr_graphics, CommandBuffers},
overlays::{ overlays::{
toast::{Toast, ToastTopic}, toast::{Toast, ToastTopic},
watch::{WATCH_NAME, watch_fade}, watch::{watch_fade, WATCH_NAME},
}, },
state::AppState, state::AppState,
subsystem::notifications::NotificationManager, subsystem::notifications::NotificationManager,
@@ -289,7 +289,7 @@ pub fn openvr_run(
} }
overlays overlays
.iter_mut() .values_mut()
.for_each(|o| o.state.auto_movement(&mut state)); .for_each(|o| o.state.auto_movement(&mut state));
watch_fade(&mut state, overlays.mut_by_id(watch_id).unwrap()); // want panic watch_fade(&mut state, overlays.mut_by_id(watch_id).unwrap()); // want panic
@@ -314,7 +314,7 @@ pub fn openvr_run(
lines.update(universe.clone(), &mut overlay_mgr, &mut state)?; lines.update(universe.clone(), &mut overlay_mgr, &mut state)?;
for o in overlays.iter_mut() { for o in overlays.values_mut() {
o.after_input(&mut overlay_mgr, &mut state)?; o.after_input(&mut overlay_mgr, &mut state)?;
} }
@@ -332,7 +332,7 @@ pub fn openvr_run(
log::trace!("Rendering frame"); log::trace!("Rendering frame");
for o in overlays.iter_mut() { for o in overlays.values_mut() {
if o.state.want_visible { if o.state.want_visible {
let ShouldRender::Should = o.should_render(&mut state)? else { let ShouldRender::Should = o.should_render(&mut state)? else {
continue; continue;
@@ -359,7 +359,7 @@ pub fn openvr_run(
} }
overlays overlays
.iter_mut() .values_mut()
.for_each(|o| o.after_render(universe.clone(), &mut overlay_mgr, &state.gfx)); .for_each(|o| o.after_render(universe.clone(), &mut overlay_mgr, &state.gfx));
#[cfg(feature = "wayvr")] #[cfg(feature = "wayvr")]

View File

@@ -68,7 +68,7 @@ impl PlayspaceMover {
overlay_transform.translation = offset; overlay_transform.translation = offset;
space_transform.translation = offset; space_transform.translation = offset;
overlays.iter_mut().for_each(|overlay| { overlays.values_mut().for_each(|overlay| {
if overlay.state.grabbable { if overlay.state.grabbable {
overlay.state.dirty = true; overlay.state.dirty = true;
overlay.state.transform.translation = overlay.state.transform.translation =
@@ -125,7 +125,7 @@ impl PlayspaceMover {
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0; let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
overlays.iter_mut().for_each(|overlay| { overlays.values_mut().for_each(|overlay| {
if overlay.state.grabbable { if overlay.state.grabbable {
overlay.state.dirty = true; overlay.state.dirty = true;
overlay.state.transform.translation += overlay_offset; overlay.state.transform.translation += overlay_offset;

View File

@@ -2,8 +2,8 @@ use std::{
collections::VecDeque, collections::VecDeque,
ops::Add, ops::Add,
sync::{ sync::{
Arc,
atomic::{AtomicBool, AtomicUsize, Ordering}, atomic::{AtomicBool, AtomicUsize, Ordering},
Arc,
}, },
time::{Duration, Instant}, time::{Duration, Instant},
}; };
@@ -23,10 +23,10 @@ use crate::{
overlay::{OverlayData, ShouldRender}, overlay::{OverlayData, ShouldRender},
task::{SystemTask, TaskType}, task::{SystemTask, TaskType},
}, },
graphics::{CommandBuffers, init_openxr_graphics}, graphics::{init_openxr_graphics, CommandBuffers},
overlays::{ overlays::{
toast::{Toast, ToastTopic}, toast::{Toast, ToastTopic},
watch::{WATCH_NAME, watch_fade}, watch::{watch_fade, WATCH_NAME},
}, },
state::AppState, state::AppState,
subsystem::notifications::NotificationManager, subsystem::notifications::NotificationManager,
@@ -155,7 +155,7 @@ pub fn openxr_run(
lines.allocate(&xr_state, app.gfx.clone())?, lines.allocate(&xr_state, app.gfx.clone())?,
]; ];
let watch_id = overlays.get_by_name(WATCH_NAME).unwrap().state.id; // want panic let watch_id = overlays.lookup(WATCH_NAME).unwrap(); // want panic
let mut input_source = input::OpenXrInputSource::new(&xr_state)?; let mut input_source = input::OpenXrInputSource::new(&xr_state)?;
@@ -311,7 +311,7 @@ pub fn openxr_run(
); );
} }
for o in overlays.iter_mut() { for o in overlays.values_mut() {
o.after_input(&mut app)?; o.after_input(&mut app)?;
} }
@@ -335,7 +335,7 @@ pub fn openxr_run(
} }
overlays overlays
.iter_mut() .values_mut()
.for_each(|o| o.state.auto_movement(&mut app)); .for_each(|o| o.state.auto_movement(&mut app));
let lengths_haptics = interact(&mut overlays, &mut app); let lengths_haptics = interact(&mut overlays, &mut app);
@@ -379,7 +379,7 @@ pub fn openxr_run(
skybox.render(&xr_state, &app, &mut buffers)?; skybox.render(&xr_state, &app, &mut buffers)?;
} }
for o in overlays.iter_mut() { for o in overlays.values_mut() {
o.data.cur_visible = false; o.data.cur_visible = false;
if !o.state.want_visible { if !o.state.want_visible {
continue; continue;
@@ -431,7 +431,7 @@ pub fn openxr_run(
} }
} }
for o in overlays.iter_mut() { for o in overlays.values_mut() {
if !o.data.cur_visible { if !o.data.cur_visible {
continue; continue;
} }

View File

@@ -128,7 +128,7 @@ impl PlayspaceMover {
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0; let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
overlays.iter_mut().for_each(|overlay| { overlays.values_mut().for_each(|overlay| {
if overlay.state.grabbable { if overlay.state.grabbable {
overlay.state.dirty = true; overlay.state.dirty = true;
overlay.state.transform.translation += overlay_offset; overlay.state.transform.translation += overlay_offset;

View File

@@ -1,13 +1,10 @@
use std::{ use std::{
f32::consts::PI, f32::consts::PI,
sync::{ sync::{atomic::AtomicUsize, Arc},
Arc,
atomic::{AtomicUsize, Ordering},
},
}; };
use glam::{Affine2, Affine3A, Mat3A, Quat, Vec2, Vec3, Vec3A}; use glam::{Affine2, Affine3A, Mat3A, Quat, Vec2, Vec3, Vec3A};
use serde::Deserialize; use slotmap::new_key_type;
use vulkano::{format::Format, image::view::ImageView}; use vulkano::{format::Format, image::view::ImageView};
use crate::{ use crate::{
@@ -21,8 +18,9 @@ use super::{
static OVERLAY_AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0); static OVERLAY_AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Default)] new_key_type! {
pub struct OverlayID(pub usize); pub struct OverlayID;
}
pub const Z_ORDER_TOAST: u32 = 70; pub const Z_ORDER_TOAST: u32 = 70;
pub const Z_ORDER_LINES: u32 = 69; pub const Z_ORDER_LINES: u32 = 69;
@@ -32,7 +30,6 @@ pub const Z_ORDER_DEFAULT: u32 = 0;
pub const Z_ORDER_DASHBOARD: u32 = Z_ORDER_DEFAULT; pub const Z_ORDER_DASHBOARD: u32 = Z_ORDER_DEFAULT;
pub struct OverlayState { pub struct OverlayState {
pub id: OverlayID,
pub name: Arc<str>, pub name: Arc<str>,
pub want_visible: bool, pub want_visible: bool,
pub show_hide: bool, pub show_hide: bool,
@@ -56,7 +53,6 @@ pub struct OverlayState {
impl Default for OverlayState { impl Default for OverlayState {
fn default() -> Self { fn default() -> Self {
Self { Self {
id: OverlayID(OVERLAY_AUTO_INCREMENT.fetch_add(1, Ordering::Relaxed)),
name: Arc::from(""), name: Arc::from(""),
want_visible: false, want_visible: false,
show_hide: false, show_hide: false,

View File

@@ -10,7 +10,7 @@ use wgui::{
}; };
use crate::{ use crate::{
backend::{common::OverlaySelector, overlay::OverlayID, task::TaskType, wayvr::WayVRAction}, backend::{common::OverlaySelector, task::TaskType, wayvr::WayVRAction},
config::{save_layout, AStrSetExt}, config::{save_layout, AStrSetExt},
state::AppState, state::AppState,
}; };
@@ -51,10 +51,7 @@ pub(super) fn setup_custom_button<S>(
continue; continue;
}; };
let selector = selector.parse::<usize>().map_or_else( let selector = OverlaySelector::Name(selector.into());
|_| OverlaySelector::Name(selector.into()),
|id| OverlaySelector::Id(OverlayID(id)),
);
Box::new(move |_common, _data, app, _| { Box::new(move |_common, _data, app, _| {
app.tasks.enqueue(TaskType::Overlay( app.tasks.enqueue(TaskType::Overlay(

View File

@@ -90,7 +90,7 @@ where
for row in 0..layout.key_sizes.len() { for row in 0..layout.key_sizes.len() {
let (div, _) = panel.layout.add_child( let (div, _) = panel.layout.add_child(
background, background.id,
WidgetDiv::create(), WidgetDiv::create(),
taffy::Style { taffy::Style {
flex_direction: taffy::FlexDirection::Row, flex_direction: taffy::FlexDirection::Row,
@@ -111,7 +111,7 @@ where
let Some(key) = layout.get_key_data(keymap.as_ref(), has_altgr, col, row) else { let Some(key) = layout.get_key_data(keymap.as_ref(), has_altgr, col, row) else {
let _ = panel.layout.add_child( let _ = panel.layout.add_child(
div, div.id,
WidgetDiv::create(), WidgetDiv::create(),
taffy::Style { taffy::Style {
size: taffy_size, size: taffy_size,
@@ -169,7 +169,7 @@ where
&template_key, &template_key,
&mut panel.layout, &mut panel.layout,
&mut panel.listeners, &mut panel.listeners,
div, div.id,
params, params,
)?; )?;
@@ -327,7 +327,7 @@ fn on_enter_anim(
Box::new(move |common, data| { Box::new(move |common, data| {
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap(); let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
set_anim_color(&key_state, rect, data.pos); set_anim_color(&key_state, rect, data.pos);
data.data.transform = get_anim_transform(data.pos, data.widget_size); data.data.transform = get_anim_transform(data.pos, data.widget_boundary.size);
common.alterables.mark_redraw(); common.alterables.mark_redraw();
}), }),
)); ));
@@ -345,7 +345,7 @@ fn on_leave_anim(
Box::new(move |common, data| { Box::new(move |common, data| {
let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap(); let rect = data.obj.get_as_mut::<WidgetRectangle>().unwrap();
set_anim_color(&key_state, rect, 1.0 - data.pos); set_anim_color(&key_state, rect, 1.0 - data.pos);
data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_size); data.data.transform = get_anim_transform(1.0 - data.pos, data.widget_boundary.size);
common.alterables.mark_redraw(); common.alterables.mark_redraw();
}), }),
)); ));

View File

@@ -1,9 +1,9 @@
use glam::vec2; use glam::vec2;
use wlx_capture::{ use wlx_capture::{
WlxCapture,
wayland::{WlxClient, WlxOutput}, wayland::{WlxClient, WlxOutput},
wlr_dmabuf::WlrDmabufCapture, wlr_dmabuf::WlrDmabufCapture,
wlr_screencopy::WlrScreencopyCapture, wlr_screencopy::WlrScreencopyCapture,
WlxCapture,
}; };
use crate::{ use crate::{
@@ -13,10 +13,10 @@ use crate::{
}; };
use super::{ use super::{
ScreenCreateData,
backend::ScreenBackend, backend::ScreenBackend,
capture::{MainThreadWlxCapture, new_wlx_capture}, capture::{new_wlx_capture, MainThreadWlxCapture},
pw::{load_pw_token_config, save_pw_token_config}, pw::{load_pw_token_config, save_pw_token_config},
ScreenCreateData,
}; };
impl ScreenBackend { impl ScreenBackend {
@@ -134,7 +134,6 @@ pub fn create_screens_wayland(wl: &mut WlxClient, app: &mut AppState) -> ScreenC
let meta = ScreenMeta { let meta = ScreenMeta {
name: wl.outputs[id].name.clone(), name: wl.outputs[id].name.clone(),
id: state.id,
native_handle: *id, native_handle: *id,
}; };

View File

@@ -2,9 +2,9 @@ use std::sync::Arc;
use glam::vec2; use glam::vec2;
use wlx_capture::{ use wlx_capture::{
WlxCapture,
frame::Transform, frame::Transform,
xshm::{XshmCapture, XshmScreen}, xshm::{XshmCapture, XshmScreen},
WlxCapture,
}; };
use crate::{ use crate::{
@@ -13,9 +13,9 @@ use crate::{
}; };
use super::{ use super::{
ScreenCreateData,
backend::ScreenBackend, backend::ScreenBackend,
capture::{MainThreadWlxCapture, new_wlx_capture}, capture::{new_wlx_capture, MainThreadWlxCapture},
ScreenCreateData,
}; };
#[cfg(feature = "pipewire")] #[cfg(feature = "pipewire")]
@@ -112,7 +112,6 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
let meta = ScreenMeta { let meta = ScreenMeta {
name: m.name.clone(), name: m.name.clone(),
id: state.id,
native_handle: 0, native_handle: 0,
}; };
@@ -194,7 +193,6 @@ pub fn create_screens_xshm(app: &mut AppState) -> anyhow::Result<ScreenCreateDat
let meta = ScreenMeta { let meta = ScreenMeta {
name: s.name.clone(), name: s.name.clone(),
id: state.id,
native_handle: 0, native_handle: 0,
}; };

View File

@@ -5,7 +5,7 @@ use std::{
time::Instant, time::Instant,
}; };
use glam::{Quat, vec3a}; use glam::{vec3a, Quat};
use idmap_derive::IntegerId; use idmap_derive::IntegerId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use wgui::{ use wgui::{
@@ -110,7 +110,7 @@ impl Toast {
// frame, only the first one gets created // frame, only the first one gets created
app.tasks.enqueue_at( app.tasks.enqueue_at(
TaskType::CreateOverlay( TaskType::CreateOverlay(
selector, selector.clone(),
Box::new(move |app| { Box::new(move |app| {
let mut maybe_toast = new_toast(self, app); let mut maybe_toast = new_toast(self, app);
if let Some((state, _)) = maybe_toast.as_mut() { if let Some((state, _)) = maybe_toast.as_mut() {
@@ -118,7 +118,7 @@ impl Toast {
app.tasks.enqueue_at( app.tasks.enqueue_at(
// at timeout, drop the overlay by ID instead // at timeout, drop the overlay by ID instead
// in order to avoid dropping any newer toasts // in order to avoid dropping any newer toasts
TaskType::DropOverlay(OverlaySelector::Id(state.id)), TaskType::DropOverlay(selector),
destroy_at, destroy_at,
); );
} }
@@ -193,7 +193,7 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option<(OverlayState, Box<dyn
.ok()?; .ok()?;
let _ = panel.layout.add_child( let _ = panel.layout.add_child(
rect, rect.id,
WidgetLabel::create( WidgetLabel::create(
&mut globals.get(), &mut globals.get(),
WidgetLabelParams { WidgetLabelParams {
@@ -215,7 +215,7 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option<(OverlayState, Box<dyn
); );
let _ = panel.layout.add_child( let _ = panel.layout.add_child(
rect, rect.id,
WidgetLabel::create( WidgetLabel::create(
&mut globals.get(), &mut globals.get(),
WidgetLabelParams { WidgetLabelParams {

View File

@@ -58,7 +58,7 @@ fn new_tooltip(
.ok()?; .ok()?;
let _ = panel.layout.add_child( let _ = panel.layout.add_child(
rect, rect.id,
TextLabel::create( TextLabel::create(
&mut i18n, &mut i18n,
TextParams { TextParams {

View File

@@ -1,10 +1,10 @@
use std::{collections::HashMap, rc::Rc, time::Duration}; use std::{collections::HashMap, rc::Rc, sync::Arc, time::Duration};
use glam::Vec3A; use glam::Vec3A;
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::{ use crate::{
backend::overlay::{OverlayData, OverlayID, OverlayState, Positioning, Z_ORDER_WATCH}, backend::overlay::{OverlayData, OverlayState, Positioning, Z_ORDER_WATCH},
gui::{panel::GuiPanel, timer::GuiTimer}, gui::{panel::GuiPanel, timer::GuiTimer},
state::AppState, state::AppState,
}; };
@@ -21,8 +21,8 @@ where
let screens = app let screens = app
.screens .screens
.iter() .iter()
.map(|s| s.id) .map(|s| s.name.clone())
.collect::<SmallVec<[OverlayID; 8]>>(); .collect::<SmallVec<[Arc<str>; 8]>>();
let state = WatchState {}; let state = WatchState {};
let mut panel = GuiPanel::new_from_template( let mut panel = GuiPanel::new_from_template(
@@ -38,7 +38,7 @@ where
for (idx, handle) in screens.iter().enumerate() { for (idx, handle) in screens.iter().enumerate() {
let mut params: HashMap<Rc<str>, Rc<str>> = HashMap::new(); let mut params: HashMap<Rc<str>, Rc<str>> = HashMap::new();
params.insert("display".into(), (idx + 1).to_string().into()); params.insert("display".into(), (idx + 1).to_string().into());
params.insert("handle".into(), handle.0.to_string().into()); params.insert("handle".into(), handle.as_ref().into());
parser_state.instantiate_template( parser_state.instantiate_template(
doc_params, "Set", layout, listeners, widget, params, doc_params, "Set", layout, listeners, widget, params,
)?; )?;

View File

@@ -101,6 +101,12 @@ impl WayVRData {
candidate candidate
} }
fn set_overlay_display_handle(&mut self, id: OverlayID, disp_handle: display::DisplayHandle) {
self.display_handle_map.insert(disp_handle, id);
let display = self.data.state.displays.get_mut(&disp_handle).unwrap(); // Never fails
display.overlay_id = Some(id);
}
} }
struct ImageData { struct ImageData {
@@ -241,7 +247,6 @@ where
let mut overlay = create_overlay::<O>( let mut overlay = create_overlay::<O>(
app, app,
wayvr,
DASHBOARD_DISPLAY_NAME, DASHBOARD_DISPLAY_NAME,
OverlayToCreate { OverlayToCreate {
disp_handle, disp_handle,
@@ -264,7 +269,8 @@ where
overlay.state.z_order = Z_ORDER_DASHBOARD; overlay.state.z_order = Z_ORDER_DASHBOARD;
overlay.state.reset(app, true); overlay.state.reset(app, true);
overlays.add(overlay); let overlay_id = overlays.add(overlay);
wayvr.set_overlay_display_handle(overlay_id, disp_handle);
let args_vec = &conf_dash let args_vec = &conf_dash
.args .args
@@ -326,7 +332,6 @@ where
fn create_overlay<O>( fn create_overlay<O>(
app: &mut AppState, app: &mut AppState,
data: &mut WayVRData,
name: &str, name: &str,
cell: OverlayToCreate, cell: OverlayToCreate,
) -> anyhow::Result<OverlayData<O>> ) -> anyhow::Result<OverlayData<O>>
@@ -345,9 +350,6 @@ where
name, name,
)?; )?;
data.display_handle_map
.insert(disp_handle, overlay.state.id);
if let Some(attach_to) = &conf_display.attach_to { if let Some(attach_to) = &conf_display.attach_to {
overlay.state.positioning = attach_to.get_positioning(); overlay.state.positioning = attach_to.get_positioning();
} }
@@ -361,9 +363,6 @@ where
overlay.state.spawn_point = Vec3A::from_slice(pos); overlay.state.spawn_point = Vec3A::from_slice(pos);
} }
let display = data.data.state.displays.get_mut(&disp_handle).unwrap(); // Never fails
display.overlay_id = Some(overlay.state.id);
Ok(overlay) Ok(overlay)
} }
@@ -384,8 +383,10 @@ where
let name = disp.name.clone(); let name = disp.name.clone();
let overlay = create_overlay::<O>(app, data, name.as_str(), cell)?; let disp_handle = cell.disp_handle;
overlays.add(overlay); // Insert freshly created WayVR overlay into wlx stack let overlay = create_overlay::<O>(app, name.as_str(), cell)?;
let overlay_id = overlays.add(overlay); // Insert freshly created WayVR overlay into wlx stack
data.set_overlay_display_handle(overlay_id, disp_handle);
} }
Ok(()) Ok(())

View File

@@ -1,7 +1,7 @@
use glam::Affine3A; use glam::Affine3A;
use idmap::IdMap; use idmap::IdMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use smallvec::{SmallVec, smallvec}; use smallvec::{smallvec, SmallVec};
use std::sync::Arc; use std::sync::Arc;
use wgui::{ use wgui::{
gfx::WGfx, globals::WguiGlobals, renderer_vk::context::SharedContext as WSharedContext, gfx::WGfx, globals::WguiGlobals, renderer_vk::context::SharedContext as WSharedContext,
@@ -18,7 +18,7 @@ use {
use crate::subsystem::osc::OscSender; use crate::subsystem::osc::OscSender;
use crate::{ use crate::{
backend::{input::InputState, overlay::OverlayID, task::TaskContainer}, backend::{input::InputState, task::TaskContainer},
config::GeneralConfig, config::GeneralConfig,
config_io, config_io,
graphics::WGfxExtras, graphics::WGfxExtras,
@@ -184,7 +184,6 @@ impl AppSession {
pub struct ScreenMeta { pub struct ScreenMeta {
pub name: Arc<str>, pub name: Arc<str>,
pub id: OverlayID,
pub native_handle: u32, pub native_handle: u32,
} }

View File

@@ -68,7 +68,7 @@ impl OscSender {
let mut has_keyboard = false; let mut has_keyboard = false;
let mut has_wrist = false; let mut has_wrist = false;
for o in overlays.iter() { for o in overlays.values() {
if !o.state.want_visible { if !o.state.want_visible {
continue; continue;
} }