Make WayVR IPC independent of the built-in Wayland server
- Rename state -> wayland_state - Move WayVR IPC server outside "wayvr" (wayland server) feature - WayVR IPC server is now available without "wayvr" (wayland server) feature - Remove run_compositor_at_start (run wayland server instantly)
This commit is contained in:
@@ -17,7 +17,8 @@ members = [
|
||||
"wlx-overlay-s",
|
||||
"wlx-capture",
|
||||
"dash-frontend",
|
||||
"wayvr-ipc", "wayvrctl",
|
||||
"wayvr-ipc",
|
||||
"wayvrctl",
|
||||
]
|
||||
resolver = "3"
|
||||
|
||||
|
||||
@@ -382,7 +382,7 @@ impl Layout {
|
||||
|
||||
let mut iter = |idx: usize| -> anyhow::Result<bool> {
|
||||
let child_id = self.state.tree.get_child_id(parent_node_id, idx);
|
||||
self.push_event_widget(child_id, event, event_result, alterables, user_data, false)?;
|
||||
self.push_event_widget(child_id, event, event_result, alterables, user_data)?;
|
||||
Ok(!event_result.can_propagate())
|
||||
};
|
||||
|
||||
@@ -403,7 +403,6 @@ impl Layout {
|
||||
event_result: &mut EventResult,
|
||||
alterables: &mut EventAlterables,
|
||||
user_data: &mut (&'a mut U1, &'a mut U2),
|
||||
is_root_node: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
let l = self.state.tree.layout(node_id)?;
|
||||
let Some(widget_id) = self.state.tree.get_node_context(node_id).copied() else {
|
||||
@@ -495,7 +494,6 @@ impl Layout {
|
||||
&mut event_result,
|
||||
&mut alterables,
|
||||
&mut (user1, user2),
|
||||
true,
|
||||
)?;
|
||||
self.process_alterables(alterables)?;
|
||||
Ok(event_result)
|
||||
|
||||
@@ -81,9 +81,11 @@ tracing = "0.1.43"
|
||||
vulkano = { workspace = true }
|
||||
vulkano-shaders = { workspace = true }
|
||||
wgui = { path = "../wgui" }
|
||||
bytes = { version = "1.11.0" }
|
||||
wayvr-ipc = { path = "../wayvr-ipc", default-features = false }
|
||||
|
||||
################################
|
||||
#WayVR-only deps
|
||||
# Wayland Server deps
|
||||
################################
|
||||
khronos-egl = { version = "6.0.0", features = ["static"], optional = true }
|
||||
smithay = { version = "0.7.0", default-features = false, features = [
|
||||
@@ -96,8 +98,6 @@ smithay = { version = "0.7.0", default-features = false, features = [
|
||||
uuid = { version = "1.19.0", features = ["v4", "fast-rng"], optional = true }
|
||||
wayland-client = { workspace = true, optional = true }
|
||||
wayland-egl = { version = "0.32.8", optional = true }
|
||||
bytes = { version = "1.11.0", optional = true }
|
||||
wayvr-ipc = { path = "../wayvr-ipc", default-features = false, optional = true }
|
||||
rust-embed = { workspace = true }
|
||||
signal-hook = "0.3.18"
|
||||
################################
|
||||
@@ -105,6 +105,7 @@ signal-hook = "0.3.18"
|
||||
[build-dependencies]
|
||||
regex = { version = "1.12.2" }
|
||||
|
||||
# TODO: rename "wayvr" feature to "wayland-server"
|
||||
[features]
|
||||
default = ["openvr", "openxr", "osc", "x11", "wayland", "wayvr"]
|
||||
openvr = ["dep:ovr_overlay", "dep:json"]
|
||||
@@ -121,7 +122,5 @@ wayvr = [
|
||||
"dep:uuid",
|
||||
"dep:wayland-client",
|
||||
"dep:wayland-egl",
|
||||
"dep:bytes",
|
||||
"dep:wayvr-ipc",
|
||||
]
|
||||
as-raw-xcb-connection = []
|
||||
|
||||
@@ -303,11 +303,10 @@ pub fn openvr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
|
||||
let _ = sender.send_params(&overlays, &app.input_state.devices);
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
if let Err(e) =
|
||||
crate::overlays::wayvr::tick_events::<OpenVrOverlayData>(&mut app, &mut overlays)
|
||||
crate::ipc::events::tick_events::<OpenVrOverlayData>(&mut app, &mut overlays)
|
||||
{
|
||||
log::error!("WayVR tick_events failed: {e:?}");
|
||||
log::error!("WayVR IPC tick_events failed: {e:?}");
|
||||
}
|
||||
|
||||
log::trace!("Rendering frame");
|
||||
@@ -336,9 +335,7 @@ pub fn openvr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
|
||||
.for_each(|o| o.after_render(universe.clone(), &mut overlay_mgr, &app.gfx));
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
if let Some(wayvr) = &app.wayvr {
|
||||
wayvr.borrow_mut().data.tick_finish()?;
|
||||
}
|
||||
app.wayvr.borrow_mut().data.tick_finish()?;
|
||||
|
||||
// chaperone
|
||||
} // main_loop
|
||||
|
||||
@@ -373,9 +373,9 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
if let Err(e) =
|
||||
crate::overlays::wayvr::tick_events::<OpenXrOverlayData>(&mut app, &mut overlays)
|
||||
crate::ipc::events::tick_events::<OpenXrOverlayData>(&mut app, &mut overlays)
|
||||
{
|
||||
log::error!("WayVR tick_events failed: {e:?}");
|
||||
log::error!("WayVR IPC tick_events failed: {e:?}");
|
||||
}
|
||||
|
||||
// Begin rendering
|
||||
@@ -459,9 +459,7 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
|
||||
// End layer composition
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
if let Some(wayvr) = &app.wayvr {
|
||||
wayvr.borrow_mut().data.tick_finish()?;
|
||||
}
|
||||
app.wayvr.borrow_mut().data.tick_finish()?;
|
||||
|
||||
// Begin layer submit
|
||||
layers.sort_by(|a, b| b.0.total_cmp(&a.0));
|
||||
|
||||
@@ -37,8 +37,9 @@ use wayland_server::Client;
|
||||
use wayland_server::backend::{ClientData, ClientId, DisconnectReason};
|
||||
use wayland_server::protocol::wl_surface::WlSurface;
|
||||
|
||||
use crate::ipc::event_queue::SyncEventQueue;
|
||||
|
||||
use super::WayVRTask;
|
||||
use super::event_queue::SyncEventQueue;
|
||||
|
||||
pub struct Application {
|
||||
pub gles_renderer: GlesRenderer,
|
||||
|
||||
@@ -17,12 +17,13 @@ use smithay::{
|
||||
use wayvr_ipc::packet_server;
|
||||
|
||||
use crate::{
|
||||
backend::wayvr::time::get_millis, gen_id, subsystem::hid::WheelDelta, windowing::OverlayID,
|
||||
backend::wayvr::time::get_millis, gen_id, ipc::event_queue::SyncEventQueue,
|
||||
subsystem::hid::WheelDelta, windowing::OverlayID,
|
||||
};
|
||||
|
||||
use super::{
|
||||
BlitMethod, WayVRSignal, client::WayVRCompositor, comp::send_frames_surface_tree, egl_data,
|
||||
event_queue::SyncEventQueue, process, smithay_wrapper, time, window,
|
||||
process, smithay_wrapper, time, window,
|
||||
};
|
||||
|
||||
fn generate_auth_key() -> String {
|
||||
|
||||
@@ -3,20 +3,16 @@ mod comp;
|
||||
pub mod display;
|
||||
pub mod egl_data;
|
||||
mod egl_ex;
|
||||
pub mod event_queue;
|
||||
mod handle;
|
||||
mod process;
|
||||
pub mod server_ipc;
|
||||
pub mod process;
|
||||
mod smithay_wrapper;
|
||||
mod time;
|
||||
mod window;
|
||||
pub mod window;
|
||||
use anyhow::Context;
|
||||
use comp::Application;
|
||||
use display::{Display, DisplayInitParams, DisplayVec};
|
||||
use event_queue::SyncEventQueue;
|
||||
use process::ProcessVec;
|
||||
use serde::Deserialize;
|
||||
use server_ipc::WayVRServer;
|
||||
use smallvec::SmallVec;
|
||||
use smithay::{
|
||||
backend::{
|
||||
@@ -48,6 +44,7 @@ use wayvr_ipc::{
|
||||
use xkbcommon::xkb;
|
||||
|
||||
use crate::{
|
||||
ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal},
|
||||
state::AppState,
|
||||
subsystem::hid::{MODS_TO_KEYS, WheelDelta},
|
||||
};
|
||||
@@ -87,19 +84,6 @@ pub enum WayVRTask {
|
||||
ProcessTerminationRequest(process::ProcessHandle),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum WayVRSignal {
|
||||
DisplayVisibility(display::DisplayHandle, bool),
|
||||
DisplayWindowLayout(
|
||||
display::DisplayHandle,
|
||||
packet_server::WvrDisplayWindowLayout,
|
||||
),
|
||||
BroadcastStateChanged(packet_server::WvrStateChanged),
|
||||
DropOverlay(crate::windowing::OverlayID),
|
||||
Haptics(super::input::Haptics),
|
||||
CustomTask(crate::backend::task::ModifyPanelTask),
|
||||
}
|
||||
|
||||
pub enum BlitMethod {
|
||||
Dmabuf,
|
||||
Software,
|
||||
@@ -127,20 +111,19 @@ pub struct WayVRState {
|
||||
time_start: u64,
|
||||
pub displays: display::DisplayVec,
|
||||
pub manager: client::WayVRCompositor,
|
||||
wm: Rc<RefCell<window::WindowManager>>,
|
||||
pub wm: Rc<RefCell<window::WindowManager>>,
|
||||
egl_data: Rc<egl_data::EGLData>,
|
||||
pub processes: process::ProcessVec,
|
||||
pub config: Config,
|
||||
dashboard_display: Option<display::DisplayHandle>,
|
||||
pub tasks: SyncEventQueue<WayVRTask>,
|
||||
pub signals: SyncEventQueue<WayVRSignal>,
|
||||
ticks: u64,
|
||||
cur_modifiers: u8,
|
||||
signals: SyncEventQueue<WayVRSignal>,
|
||||
}
|
||||
|
||||
pub struct WayVR {
|
||||
pub state: WayVRState,
|
||||
pub ipc_server: WayVRServer,
|
||||
}
|
||||
|
||||
pub enum MouseIndex {
|
||||
@@ -159,7 +142,7 @@ pub enum TickTask {
|
||||
|
||||
impl WayVR {
|
||||
#[allow(clippy::too_many_lines, clippy::cognitive_complexity)]
|
||||
pub fn new(config: Config) -> anyhow::Result<Self> {
|
||||
pub fn new(config: Config, signals: SyncEventQueue<WayVRSignal>) -> anyhow::Result<Self> {
|
||||
log::info!("Initializing WayVR");
|
||||
let display: wayland_server::Display<Application> = wayland_server::Display::new()?;
|
||||
let dh = display.handle();
|
||||
@@ -264,8 +247,6 @@ impl WayVR {
|
||||
|
||||
let time_start = get_millis();
|
||||
|
||||
let ipc_server = WayVRServer::new()?;
|
||||
|
||||
let state = WayVRState {
|
||||
time_start,
|
||||
manager: client::WayVRCompositor::new(state, display, seat_keyboard, seat_pointer)?,
|
||||
@@ -277,11 +258,11 @@ impl WayVR {
|
||||
dashboard_display: None,
|
||||
ticks: 0,
|
||||
tasks,
|
||||
signals: SyncEventQueue::new(),
|
||||
cur_modifiers: 0,
|
||||
signals,
|
||||
};
|
||||
|
||||
Ok(Self { state, ipc_server })
|
||||
Ok(Self { state })
|
||||
}
|
||||
|
||||
pub fn render_display(&mut self, display: display::DisplayHandle) -> anyhow::Result<bool> {
|
||||
@@ -312,13 +293,14 @@ impl WayVR {
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines, clippy::cognitive_complexity)]
|
||||
pub fn tick_events(&mut self, app: &AppState) -> anyhow::Result<Vec<TickTask>> {
|
||||
pub fn tick_events(&mut self, app: &mut AppState) -> anyhow::Result<Vec<TickTask>> {
|
||||
let mut tasks: Vec<TickTask> = Vec::new();
|
||||
|
||||
self.ipc_server.tick(&mut server_ipc::TickParams {
|
||||
state: &mut self.state,
|
||||
app.ipc_server.tick(&mut ipc_server::TickParams {
|
||||
wayland_state: &mut self.state,
|
||||
input_state: &app.input_state,
|
||||
tasks: &mut tasks,
|
||||
app,
|
||||
signals: &app.wayvr_signals,
|
||||
});
|
||||
|
||||
// Check for redraw events
|
||||
@@ -357,11 +339,11 @@ impl WayVR {
|
||||
}
|
||||
|
||||
for (handle, display) in self.state.displays.iter_mut() {
|
||||
display.tick(&self.state.config, &handle, &mut self.state.signals);
|
||||
display.tick(&self.state.config, &handle, &mut app.wayvr_signals);
|
||||
}
|
||||
|
||||
if !to_remove.is_empty() {
|
||||
self.state.signals.send(WayVRSignal::BroadcastStateChanged(
|
||||
app.wayvr_signals.send(WayVRSignal::BroadcastStateChanged(
|
||||
packet_server::WvrStateChanged::ProcessRemoved,
|
||||
));
|
||||
}
|
||||
@@ -402,7 +384,7 @@ impl WayVR {
|
||||
};
|
||||
|
||||
display.add_window(window_handle, process_handle, &toplevel);
|
||||
self.state.signals.send(WayVRSignal::BroadcastStateChanged(
|
||||
app.wayvr_signals.send(WayVRSignal::BroadcastStateChanged(
|
||||
packet_server::WvrStateChanged::WindowCreated,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::{
|
||||
},
|
||||
config::load_config_with_conf_d,
|
||||
config_io,
|
||||
ipc::{event_queue::SyncEventQueue, signal::WayVRSignal},
|
||||
overlays::wayvr::{WayVRData, executable_exists_in_path},
|
||||
};
|
||||
|
||||
@@ -135,9 +136,6 @@ pub struct WayVRDashboard {
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct WayVRConfig {
|
||||
#[serde(default = "def_true")]
|
||||
pub run_compositor_at_start: bool,
|
||||
|
||||
#[serde(default = "Default::default")]
|
||||
pub catalogs: HashMap<String, WayVRCatalog>,
|
||||
|
||||
@@ -203,7 +201,8 @@ impl WayVRConfig {
|
||||
&self,
|
||||
config: &GeneralConfig,
|
||||
tasks: &mut TaskContainer,
|
||||
) -> anyhow::Result<Option<Rc<RefCell<WayVRData>>>> {
|
||||
signals: SyncEventQueue<WayVRSignal>,
|
||||
) -> anyhow::Result<Rc<RefCell<WayVRData>>> {
|
||||
let primary_count = self
|
||||
.displays
|
||||
.iter()
|
||||
@@ -212,10 +211,6 @@ impl WayVRConfig {
|
||||
|
||||
if primary_count > 1 {
|
||||
anyhow::bail!("Number of primary displays is more than 1")
|
||||
} else if primary_count == 0 {
|
||||
log::warn!(
|
||||
"No primary display specified. External Wayland applications will not be attached."
|
||||
);
|
||||
}
|
||||
|
||||
for (catalog_name, catalog) in &self.catalogs {
|
||||
@@ -231,15 +226,10 @@ impl WayVRConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if self.run_compositor_at_start {
|
||||
// Start Wayland server instantly
|
||||
Ok(Some(Rc::new(RefCell::new(WayVRData::new(
|
||||
Self::get_wayvr_config(config, self)?,
|
||||
)?))))
|
||||
} else {
|
||||
// Lazy-init WayVR later if the user requested
|
||||
Ok(None)
|
||||
}
|
||||
Ok(Rc::new(RefCell::new(WayVRData::new(
|
||||
Self::get_wayvr_config(config, self)?,
|
||||
signals,
|
||||
)?)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
189
wlx-overlay-s/src/ipc/events.rs
Normal file
189
wlx-overlay-s/src/ipc/events.rs
Normal file
@@ -0,0 +1,189 @@
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::ipc::ipc_server;
|
||||
use wayvr_ipc::packet_server;
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
use crate::{
|
||||
backend::wayvr, config_wayvr, overlays::wayvr::OverlayToCreate, overlays::wayvr::WayVRData,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
backend::{
|
||||
self,
|
||||
task::{OverlayTask, TaskType},
|
||||
},
|
||||
ipc::signal::WayVRSignal,
|
||||
overlays::{self},
|
||||
state::AppState,
|
||||
windowing::{OverlaySelector, manager::OverlayWindowManager},
|
||||
};
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn process_tick_tasks(
|
||||
app: &mut AppState,
|
||||
tick_tasks: Vec<backend::wayvr::TickTask>,
|
||||
r_wayvr: &Rc<RefCell<WayVRData>>,
|
||||
) -> anyhow::Result<()> {
|
||||
for tick_task in tick_tasks {
|
||||
match tick_task {
|
||||
backend::wayvr::TickTask::NewExternalProcess(request) => {
|
||||
let config = &app.session.wayvr_config;
|
||||
|
||||
let disp_name = request.env.display_name.map_or_else(
|
||||
|| {
|
||||
config
|
||||
.get_default_display()
|
||||
.map(|(display_name, _)| display_name)
|
||||
},
|
||||
|display_name| {
|
||||
config
|
||||
.get_display(display_name.as_str())
|
||||
.map(|_| display_name)
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(disp_name) = disp_name {
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
|
||||
log::info!("Registering external process with PID {}", request.pid);
|
||||
|
||||
let disp_handle = overlays::wayvr::get_or_create_display_by_name(
|
||||
app, &mut wayvr, &disp_name,
|
||||
)?;
|
||||
|
||||
wayvr
|
||||
.data
|
||||
.state
|
||||
.add_external_process(disp_handle, request.pid);
|
||||
|
||||
wayvr
|
||||
.data
|
||||
.state
|
||||
.manager
|
||||
.add_client(wayvr::client::WayVRClient {
|
||||
client: request.client,
|
||||
display_handle: disp_handle,
|
||||
pid: request.pid,
|
||||
});
|
||||
}
|
||||
}
|
||||
wayvr::TickTask::NewDisplay(cpar, disp_handle) => {
|
||||
log::info!("Creating new display with name \"{}\"", cpar.name);
|
||||
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
|
||||
let unique_name = wayvr.get_unique_display_name(cpar.name);
|
||||
|
||||
let disp_handle = match disp_handle {
|
||||
Some(d) => d,
|
||||
None => wayvr.data.state.create_display(
|
||||
cpar.width,
|
||||
cpar.height,
|
||||
&unique_name,
|
||||
false,
|
||||
)?,
|
||||
};
|
||||
|
||||
wayvr.overlays_to_create.push(OverlayToCreate {
|
||||
disp_handle,
|
||||
conf_display: config_wayvr::WayVRDisplay {
|
||||
attach_to: Some(config_wayvr::AttachTo::from_packet(&cpar.attach_to)),
|
||||
width: cpar.width,
|
||||
height: cpar.height,
|
||||
pos: None,
|
||||
primary: None,
|
||||
rotation: None,
|
||||
scale: cpar.scale,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn tick_events<O>(
|
||||
app: &mut AppState,
|
||||
overlays: &mut OverlayWindowManager<O>,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
O: Default,
|
||||
{
|
||||
#[cfg(feature = "wayvr")]
|
||||
let r_wayvr = app.wayvr.clone();
|
||||
#[cfg(feature = "wayvr")]
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
|
||||
while let Some(signal) = app.wayvr_signals.read() {
|
||||
match signal {
|
||||
#[cfg(feature = "wayvr")]
|
||||
WayVRSignal::DisplayVisibility(display_handle, visible) => {
|
||||
if let Some(overlay_id) = wayvr.display_handle_map.get(&display_handle) {
|
||||
let overlay_id = *overlay_id;
|
||||
wayvr
|
||||
.data
|
||||
.state
|
||||
.set_display_visible(display_handle, visible);
|
||||
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
|
||||
OverlaySelector::Id(overlay_id),
|
||||
Box::new(move |app, o| {
|
||||
if visible == o.is_active() {
|
||||
return;
|
||||
}
|
||||
if visible {
|
||||
o.activate(app);
|
||||
} else {
|
||||
o.deactivate();
|
||||
}
|
||||
}),
|
||||
)));
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "wayvr")]
|
||||
WayVRSignal::DisplayWindowLayout(display_handle, layout) => {
|
||||
wayvr.data.state.set_display_layout(display_handle, layout);
|
||||
}
|
||||
#[cfg(feature = "wayvr")]
|
||||
WayVRSignal::BroadcastStateChanged(packet) => {
|
||||
app.ipc_server
|
||||
.broadcast(packet_server::PacketServer::WvrStateChanged(packet));
|
||||
}
|
||||
#[cfg(feature = "wayvr")]
|
||||
WayVRSignal::Haptics(haptics) => {
|
||||
wayvr.pending_haptics = Some(haptics);
|
||||
}
|
||||
WayVRSignal::DropOverlay(overlay_id) => {
|
||||
app.tasks
|
||||
.enqueue(TaskType::Overlay(OverlayTask::Drop(OverlaySelector::Id(
|
||||
overlay_id,
|
||||
))));
|
||||
}
|
||||
WayVRSignal::CustomTask(custom_task) => {
|
||||
app.tasks
|
||||
.enqueue(TaskType::Overlay(OverlayTask::ModifyPanel(custom_task)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
{
|
||||
let tick_tasks = wayvr.data.tick_events(app)?;
|
||||
process_tick_tasks(app, tick_tasks, &r_wayvr)?;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wayvr"))]
|
||||
{
|
||||
app.ipc_server.tick(&mut ipc_server::TickParams {
|
||||
input_state: &app.input_state,
|
||||
signals: &app.wayvr_signals,
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
overlays::wayvr::create_queued_displays(app, &mut wayvr, overlays)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
use crate::state::AppState;
|
||||
#[cfg(feature = "wayvr")]
|
||||
use crate::backend::wayvr::{self, WayVRState};
|
||||
|
||||
use super::{TickTask, WayVRSignal, display, process, window};
|
||||
use crate::{
|
||||
backend::input::InputState,
|
||||
ipc::{event_queue::SyncEventQueue, signal::WayVRSignal},
|
||||
};
|
||||
use bytes::BufMut;
|
||||
use glam::Vec3A;
|
||||
use interprocess::local_socket::{self, ToNsName, traits::Listener};
|
||||
@@ -71,9 +75,12 @@ fn read_payload(conn: &mut local_socket::Stream, size: u32) -> Option<Payload> {
|
||||
}
|
||||
|
||||
pub struct TickParams<'a> {
|
||||
pub state: &'a mut super::WayVRState,
|
||||
pub tasks: &'a mut Vec<TickTask>,
|
||||
pub app: &'a AppState,
|
||||
#[cfg(feature = "wayvr")]
|
||||
pub wayland_state: &'a mut WayVRState,
|
||||
#[cfg(feature = "wayvr")]
|
||||
pub tasks: &'a mut Vec<wayvr::TickTask>,
|
||||
pub signals: &'a SyncEventQueue<WayVRSignal>,
|
||||
pub input_state: &'a InputState,
|
||||
}
|
||||
|
||||
pub fn gen_args_vec(input: &str) -> Vec<&str> {
|
||||
@@ -149,13 +156,14 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_display_list(
|
||||
&mut self,
|
||||
params: &TickParams,
|
||||
serial: ipc::Serial,
|
||||
) -> anyhow::Result<()> {
|
||||
let list: Vec<packet_server::WvrDisplay> = params
|
||||
.state
|
||||
.wayland_state
|
||||
.displays
|
||||
.vec
|
||||
.iter()
|
||||
@@ -165,7 +173,10 @@ impl Connection {
|
||||
return None;
|
||||
};
|
||||
let display = &cell.obj;
|
||||
Some(display.as_packet(display::DisplayHandle::new(idx as u32, cell.generation)))
|
||||
Some(display.as_packet(wayvr::display::DisplayHandle::new(
|
||||
idx as u32,
|
||||
cell.generation,
|
||||
)))
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -185,8 +196,6 @@ impl Connection {
|
||||
params: &TickParams,
|
||||
serial: ipc::Serial,
|
||||
) -> anyhow::Result<()> {
|
||||
let input_state = ¶ms.app.input_state;
|
||||
|
||||
let to_arr = |vec: &Vec3A| -> [f32; 3] { [vec.x, vec.y, vec.z] };
|
||||
|
||||
send_packet(
|
||||
@@ -194,12 +203,12 @@ impl Connection {
|
||||
&ipc::data_encode(&PacketServer::WlxInputStateResponse(
|
||||
serial,
|
||||
packet_server::WlxInputState {
|
||||
hmd_pos: to_arr(&input_state.hmd.translation),
|
||||
hmd_pos: to_arr(¶ms.input_state.hmd.translation),
|
||||
left: WlxInputStatePointer {
|
||||
pos: to_arr(&input_state.pointers[0].raw_pose.translation),
|
||||
pos: to_arr(¶ms.input_state.pointers[0].raw_pose.translation),
|
||||
},
|
||||
right: WlxInputStatePointer {
|
||||
pos: to_arr(&input_state.pointers[0].raw_pose.translation),
|
||||
pos: to_arr(¶ms.input_state.pointers[0].raw_pose.translation),
|
||||
},
|
||||
},
|
||||
)),
|
||||
@@ -208,22 +217,24 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_display_create(
|
||||
&mut self,
|
||||
params: &mut TickParams,
|
||||
serial: ipc::Serial,
|
||||
packet_params: packet_client::WvrDisplayCreateParams,
|
||||
) -> anyhow::Result<()> {
|
||||
let display_handle = params.state.create_display(
|
||||
let display_handle = params.wayland_state.create_display(
|
||||
packet_params.width,
|
||||
packet_params.height,
|
||||
&packet_params.name,
|
||||
false,
|
||||
)?;
|
||||
|
||||
params
|
||||
.tasks
|
||||
.push(TickTask::NewDisplay(packet_params, Some(display_handle)));
|
||||
params.tasks.push(wayvr::TickTask::NewDisplay(
|
||||
packet_params,
|
||||
Some(display_handle),
|
||||
));
|
||||
|
||||
send_packet(
|
||||
&mut self.conn,
|
||||
@@ -235,6 +246,7 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_display_remove(
|
||||
&mut self,
|
||||
params: &mut TickParams,
|
||||
@@ -242,8 +254,8 @@ impl Connection {
|
||||
handle: packet_server::WvrDisplayHandle,
|
||||
) -> anyhow::Result<()> {
|
||||
let res = params
|
||||
.state
|
||||
.destroy_display(display::DisplayHandle::from_packet(handle))
|
||||
.wayland_state
|
||||
.destroy_display(wayvr::display::DisplayHandle::from_packet(handle))
|
||||
.map_err(|e| format!("{e:?}"));
|
||||
|
||||
send_packet(
|
||||
@@ -253,28 +265,31 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_display_set_visible(
|
||||
params: &mut TickParams,
|
||||
handle: packet_server::WvrDisplayHandle,
|
||||
visible: bool,
|
||||
) {
|
||||
params.state.signals.send(WayVRSignal::DisplayVisibility(
|
||||
display::DisplayHandle::from_packet(handle),
|
||||
params.signals.send(WayVRSignal::DisplayVisibility(
|
||||
wayvr::display::DisplayHandle::from_packet(handle),
|
||||
visible,
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_display_set_window_layout(
|
||||
params: &mut TickParams,
|
||||
handle: packet_server::WvrDisplayHandle,
|
||||
layout: packet_server::WvrDisplayWindowLayout,
|
||||
) {
|
||||
params.state.signals.send(WayVRSignal::DisplayWindowLayout(
|
||||
display::DisplayHandle::from_packet(handle),
|
||||
params.signals.send(WayVRSignal::DisplayWindowLayout(
|
||||
wayvr::display::DisplayHandle::from_packet(handle),
|
||||
layout,
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_display_window_list(
|
||||
&mut self,
|
||||
params: &mut TickParams,
|
||||
@@ -288,10 +303,13 @@ impl Connection {
|
||||
)
|
||||
};
|
||||
|
||||
let Some(display) = params
|
||||
.state
|
||||
.displays
|
||||
.get(&display::DisplayHandle::from_packet(display_handle.clone()))
|
||||
let Some(display) =
|
||||
params
|
||||
.wayland_state
|
||||
.displays
|
||||
.get(&wayvr::display::DisplayHandle::from_packet(
|
||||
display_handle.clone(),
|
||||
))
|
||||
else {
|
||||
return send(None);
|
||||
};
|
||||
@@ -302,14 +320,14 @@ impl Connection {
|
||||
.iter()
|
||||
.filter_map(|disp_win| {
|
||||
params
|
||||
.state
|
||||
.wayland_state
|
||||
.wm
|
||||
.borrow_mut()
|
||||
.windows
|
||||
.get(&disp_win.window_handle)
|
||||
.map(|win| packet_server::WvrWindow {
|
||||
handle: window::WindowHandle::as_packet(&disp_win.window_handle),
|
||||
process_handle: process::ProcessHandle::as_packet(
|
||||
handle: wayvr::window::WindowHandle::as_packet(&disp_win.window_handle),
|
||||
process_handle: wayvr::process::ProcessHandle::as_packet(
|
||||
&disp_win.process_handle,
|
||||
),
|
||||
pos_x: win.pos_x,
|
||||
@@ -324,17 +342,18 @@ impl Connection {
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_window_set_visible(
|
||||
params: &mut TickParams,
|
||||
handle: packet_server::WvrWindowHandle,
|
||||
visible: bool,
|
||||
) {
|
||||
let to_resize = if let Some(window) = params
|
||||
.state
|
||||
.wayland_state
|
||||
.wm
|
||||
.borrow_mut()
|
||||
.windows
|
||||
.get_mut(&window::WindowHandle::from_packet(handle))
|
||||
.get_mut(&wayvr::window::WindowHandle::from_packet(handle))
|
||||
{
|
||||
window.visible = visible;
|
||||
Some(window.display_handle)
|
||||
@@ -343,13 +362,14 @@ impl Connection {
|
||||
};
|
||||
|
||||
if let Some(to_resize) = to_resize
|
||||
&& let Some(display) = params.state.displays.get_mut(&to_resize)
|
||||
&& let Some(display) = params.wayland_state.displays.get_mut(&to_resize)
|
||||
{
|
||||
display.reposition_windows();
|
||||
display.trigger_rerender();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_process_launch(
|
||||
&mut self,
|
||||
params: &mut TickParams,
|
||||
@@ -359,8 +379,8 @@ impl Connection {
|
||||
let args_vec = gen_args_vec(&packet_params.args);
|
||||
let env_vec = gen_env_vec(&packet_params.env);
|
||||
|
||||
let res = params.state.spawn_process(
|
||||
super::display::DisplayHandle::from_packet(packet_params.target_display),
|
||||
let res = params.wayland_state.spawn_process(
|
||||
wayvr::display::DisplayHandle::from_packet(packet_params.target_display),
|
||||
&packet_params.exec,
|
||||
&args_vec,
|
||||
&env_vec,
|
||||
@@ -378,15 +398,16 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_display_get(
|
||||
&mut self,
|
||||
params: &TickParams,
|
||||
serial: ipc::Serial,
|
||||
display_handle: packet_server::WvrDisplayHandle,
|
||||
) -> anyhow::Result<()> {
|
||||
let native_handle = &display::DisplayHandle::from_packet(display_handle);
|
||||
let native_handle = &wayvr::display::DisplayHandle::from_packet(display_handle);
|
||||
let disp = params
|
||||
.state
|
||||
.wayland_state
|
||||
.displays
|
||||
.get(native_handle)
|
||||
.map(|disp| disp.as_packet(*native_handle));
|
||||
@@ -399,13 +420,14 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_process_list(
|
||||
&mut self,
|
||||
params: &TickParams,
|
||||
serial: ipc::Serial,
|
||||
) -> anyhow::Result<()> {
|
||||
let list: Vec<packet_server::WvrProcess> = params
|
||||
.state
|
||||
.wayland_state
|
||||
.processes
|
||||
.vec
|
||||
.iter()
|
||||
@@ -415,7 +437,10 @@ impl Connection {
|
||||
return None;
|
||||
};
|
||||
let process = &cell.obj;
|
||||
Some(process.to_packet(process::ProcessHandle::new(idx as u32, cell.generation)))
|
||||
Some(process.to_packet(wayvr::process::ProcessHandle::new(
|
||||
idx as u32,
|
||||
cell.generation,
|
||||
)))
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -431,12 +456,13 @@ impl Connection {
|
||||
}
|
||||
|
||||
// This request doesn't return anything to the client
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_process_terminate(
|
||||
params: &mut TickParams,
|
||||
process_handle: packet_server::WvrProcessHandle,
|
||||
) {
|
||||
let native_handle = &process::ProcessHandle::from_packet(process_handle);
|
||||
let process = params.state.processes.get_mut(native_handle);
|
||||
let native_handle = &wayvr::process::ProcessHandle::from_packet(process_handle);
|
||||
let process = params.wayland_state.processes.get_mut(native_handle);
|
||||
|
||||
let Some(process) = process else {
|
||||
return;
|
||||
@@ -445,15 +471,16 @@ impl Connection {
|
||||
process.terminate();
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wvr_process_get(
|
||||
&mut self,
|
||||
params: &TickParams,
|
||||
serial: ipc::Serial,
|
||||
process_handle: packet_server::WvrProcessHandle,
|
||||
) -> anyhow::Result<()> {
|
||||
let native_handle = &process::ProcessHandle::from_packet(process_handle);
|
||||
let native_handle = &wayvr::process::ProcessHandle::from_packet(process_handle);
|
||||
let process = params
|
||||
.state
|
||||
.wayland_state
|
||||
.processes
|
||||
.get(native_handle)
|
||||
.map(|process| process.to_packet(*native_handle));
|
||||
@@ -466,17 +493,18 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
fn handle_wlx_haptics(
|
||||
params: &mut TickParams,
|
||||
haptics_params: packet_client::WlxHapticsParams,
|
||||
) {
|
||||
params.state.signals.send(super::WayVRSignal::Haptics(
|
||||
crate::backend::input::Haptics {
|
||||
params
|
||||
.signals
|
||||
.send(WayVRSignal::Haptics(crate::backend::input::Haptics {
|
||||
duration: haptics_params.duration,
|
||||
frequency: haptics_params.frequency,
|
||||
intensity: haptics_params.intensity,
|
||||
},
|
||||
));
|
||||
}));
|
||||
}
|
||||
|
||||
fn handle_wlx_panel(
|
||||
@@ -486,9 +514,8 @@ impl Connection {
|
||||
use crate::backend::task::{ModifyPanelCommand, ModifyPanelTask};
|
||||
|
||||
params
|
||||
.state
|
||||
.signals
|
||||
.send(super::WayVRSignal::CustomTask(ModifyPanelTask {
|
||||
.send(WayVRSignal::CustomTask(ModifyPanelTask {
|
||||
overlay: custom_params.overlay,
|
||||
element: custom_params.element,
|
||||
command: match custom_params.command {
|
||||
@@ -511,6 +538,9 @@ impl Connection {
|
||||
}));
|
||||
}
|
||||
|
||||
// FIXME: we should probably respond an error to the client in case if wayland server feature is disabled
|
||||
// fix this after we're done with the webkit-based wayvr-dashboard
|
||||
#[allow(unused_variables)]
|
||||
fn process_payload(&mut self, params: &mut TickParams, payload: Payload) -> anyhow::Result<()> {
|
||||
let packet: PacketClient = ipc::data_decode(&payload)?;
|
||||
|
||||
@@ -525,42 +555,55 @@ impl Connection {
|
||||
self.handle_wlx_input_state(params, serial)?;
|
||||
}
|
||||
PacketClient::WvrDisplayList(serial) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_display_list(params, serial)?;
|
||||
}
|
||||
PacketClient::WvrDisplayGet(serial, display_handle) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_display_get(params, serial, display_handle)?;
|
||||
}
|
||||
PacketClient::WvrDisplayRemove(serial, display_handle) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_display_remove(params, serial, display_handle)?;
|
||||
}
|
||||
PacketClient::WvrDisplaySetVisible(display_handle, visible) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
Self::handle_wvr_display_set_visible(params, display_handle, visible);
|
||||
}
|
||||
PacketClient::WvrDisplaySetWindowLayout(display_handle, layout) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
Self::handle_wvr_display_set_window_layout(params, display_handle, layout);
|
||||
}
|
||||
PacketClient::WvrDisplayWindowList(serial, display_handle) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_display_window_list(params, serial, display_handle)?;
|
||||
}
|
||||
PacketClient::WvrWindowSetVisible(window_handle, visible) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
Self::handle_wvr_window_set_visible(params, window_handle, visible);
|
||||
}
|
||||
PacketClient::WvrProcessGet(serial, process_handle) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_process_get(params, serial, process_handle)?;
|
||||
}
|
||||
PacketClient::WvrProcessList(serial) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_process_list(params, serial)?;
|
||||
}
|
||||
PacketClient::WvrProcessLaunch(serial, packet_params) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_process_launch(params, serial, packet_params)?;
|
||||
}
|
||||
PacketClient::WvrDisplayCreate(serial, packet_params) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
self.handle_wvr_display_create(params, serial, packet_params)?;
|
||||
}
|
||||
PacketClient::WvrProcessTerminate(process_handle) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
Self::handle_wvr_process_terminate(params, process_handle);
|
||||
}
|
||||
PacketClient::WlxHaptics(haptics_params) => {
|
||||
#[cfg(feature = "wayvr")]
|
||||
Self::handle_wlx_haptics(params, haptics_params);
|
||||
}
|
||||
PacketClient::WlxModifyPanel(custom_params) => {
|
||||
4
wlx-overlay-s/src/ipc/mod.rs
Normal file
4
wlx-overlay-s/src/ipc/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod event_queue;
|
||||
pub mod events;
|
||||
pub mod ipc_server;
|
||||
pub mod signal;
|
||||
19
wlx-overlay-s/src/ipc/signal.rs
Normal file
19
wlx-overlay-s/src/ipc/signal.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
#[cfg(feature = "wayvr")]
|
||||
use crate::backend::wayvr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum WayVRSignal {
|
||||
#[cfg(feature = "wayvr")]
|
||||
DisplayVisibility(wayvr::display::DisplayHandle, bool),
|
||||
#[cfg(feature = "wayvr")]
|
||||
DisplayWindowLayout(
|
||||
wayvr::display::DisplayHandle,
|
||||
wayvr_ipc::packet_server::WvrDisplayWindowLayout,
|
||||
),
|
||||
#[cfg(feature = "wayvr")]
|
||||
BroadcastStateChanged(wayvr_ipc::packet_server::WvrStateChanged),
|
||||
#[cfg(feature = "wayvr")]
|
||||
Haptics(crate::backend::input::Haptics),
|
||||
DropOverlay(crate::windowing::OverlayID),
|
||||
CustomTask(crate::backend::task::ModifyPanelTask),
|
||||
}
|
||||
@@ -22,6 +22,7 @@ mod config;
|
||||
mod config_io;
|
||||
mod graphics;
|
||||
mod gui;
|
||||
mod ipc;
|
||||
mod overlays;
|
||||
mod shaders;
|
||||
mod state;
|
||||
|
||||
@@ -22,13 +22,11 @@ use crate::{
|
||||
backend::{
|
||||
input::{self, HoverResult},
|
||||
task::{OverlayTask, TaskType},
|
||||
wayvr::{
|
||||
self, WayVR, WayVRAction, WayVRDisplayClickAction, display,
|
||||
server_ipc::{gen_args_vec, gen_env_vec},
|
||||
},
|
||||
wayvr::{self, WayVR, WayVRAction, WayVRDisplayClickAction, display},
|
||||
},
|
||||
config_wayvr,
|
||||
graphics::{Vert2Uv, dmabuf::WGfxDmabuf},
|
||||
ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal},
|
||||
state::{self, AppState},
|
||||
subsystem::{hid::WheelDelta, input::KeyboardFocus},
|
||||
windowing::{
|
||||
@@ -63,31 +61,34 @@ impl WayVRContext {
|
||||
}
|
||||
}
|
||||
|
||||
struct OverlayToCreate {
|
||||
pub struct OverlayToCreate {
|
||||
pub conf_display: config_wayvr::WayVRDisplay,
|
||||
pub disp_handle: display::DisplayHandle,
|
||||
}
|
||||
|
||||
pub struct WayVRData {
|
||||
display_handle_map: HashMap<display::DisplayHandle, OverlayID>,
|
||||
overlays_to_create: Vec<OverlayToCreate>,
|
||||
dashboard_executed: bool,
|
||||
pub display_handle_map: HashMap<display::DisplayHandle, OverlayID>,
|
||||
pub overlays_to_create: Vec<OverlayToCreate>,
|
||||
pub dashboard_executed: bool,
|
||||
pub data: WayVR,
|
||||
pending_haptics: Option<input::Haptics>,
|
||||
pub pending_haptics: Option<input::Haptics>,
|
||||
}
|
||||
|
||||
impl WayVRData {
|
||||
pub fn new(config: wayvr::Config) -> anyhow::Result<Self> {
|
||||
pub fn new(
|
||||
config: wayvr::Config,
|
||||
signals: SyncEventQueue<WayVRSignal>,
|
||||
) -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
display_handle_map: HashMap::default(),
|
||||
data: WayVR::new(config)?,
|
||||
data: WayVR::new(config, signals)?,
|
||||
overlays_to_create: Vec::new(),
|
||||
dashboard_executed: false,
|
||||
pending_haptics: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_unique_display_name(&self, mut candidate: String) -> String {
|
||||
pub fn get_unique_display_name(&self, mut candidate: String) -> String {
|
||||
let mut num = 0;
|
||||
|
||||
while !self
|
||||
@@ -179,7 +180,7 @@ impl WayVRBackend {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_or_create_display_by_name(
|
||||
pub fn get_or_create_display_by_name(
|
||||
app: &mut AppState,
|
||||
wayvr: &mut WayVRData,
|
||||
disp_name: &str,
|
||||
@@ -290,12 +291,12 @@ where
|
||||
let args_vec = &conf_dash
|
||||
.args
|
||||
.as_ref()
|
||||
.map_or_else(Vec::new, |args| gen_args_vec(args.as_str()));
|
||||
.map_or_else(Vec::new, |args| ipc_server::gen_args_vec(args.as_str()));
|
||||
|
||||
let env_vec = &conf_dash
|
||||
.env
|
||||
.as_ref()
|
||||
.map_or_else(Vec::new, |env| gen_env_vec(env));
|
||||
.map_or_else(Vec::new, |env| ipc_server::gen_env_vec(env));
|
||||
|
||||
let mut userdata = HashMap::new();
|
||||
userdata.insert(String::from("type"), String::from("dashboard"));
|
||||
@@ -322,9 +323,7 @@ where
|
||||
|
||||
let cur_visibility = !display.visible;
|
||||
|
||||
wayvr
|
||||
.data
|
||||
.ipc_server
|
||||
app.ipc_server
|
||||
.broadcast(PacketServer::WvrStateChanged(if cur_visibility {
|
||||
WvrStateChanged::DashboardShown
|
||||
} else {
|
||||
@@ -379,7 +378,7 @@ fn create_overlay(
|
||||
Ok(overlay)
|
||||
}
|
||||
|
||||
fn create_queued_displays<O>(
|
||||
pub fn create_queued_displays<O>(
|
||||
app: &mut AppState,
|
||||
data: &mut WayVRData,
|
||||
overlays: &mut OverlayWindowManager<O>,
|
||||
@@ -405,152 +404,6 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn tick_events<O>(
|
||||
app: &mut AppState,
|
||||
overlays: &mut OverlayWindowManager<O>,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
O: Default,
|
||||
{
|
||||
let Some(r_wayvr) = app.wayvr.clone() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
|
||||
while let Some(signal) = wayvr.data.state.signals.read() {
|
||||
match signal {
|
||||
wayvr::WayVRSignal::DisplayVisibility(display_handle, visible) => {
|
||||
if let Some(overlay_id) = wayvr.display_handle_map.get(&display_handle) {
|
||||
let overlay_id = *overlay_id;
|
||||
wayvr
|
||||
.data
|
||||
.state
|
||||
.set_display_visible(display_handle, visible);
|
||||
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Modify(
|
||||
OverlaySelector::Id(overlay_id),
|
||||
Box::new(move |app, o| {
|
||||
if visible == o.is_active() {
|
||||
return;
|
||||
}
|
||||
if visible {
|
||||
o.activate(app);
|
||||
} else {
|
||||
o.deactivate();
|
||||
}
|
||||
}),
|
||||
)));
|
||||
}
|
||||
}
|
||||
wayvr::WayVRSignal::DisplayWindowLayout(display_handle, layout) => {
|
||||
wayvr.data.state.set_display_layout(display_handle, layout);
|
||||
}
|
||||
wayvr::WayVRSignal::BroadcastStateChanged(packet) => {
|
||||
wayvr
|
||||
.data
|
||||
.ipc_server
|
||||
.broadcast(packet_server::PacketServer::WvrStateChanged(packet));
|
||||
}
|
||||
wayvr::WayVRSignal::DropOverlay(overlay_id) => {
|
||||
app.tasks
|
||||
.enqueue(TaskType::Overlay(OverlayTask::Drop(OverlaySelector::Id(
|
||||
overlay_id,
|
||||
))));
|
||||
}
|
||||
wayvr::WayVRSignal::Haptics(haptics) => {
|
||||
wayvr.pending_haptics = Some(haptics);
|
||||
}
|
||||
wayvr::WayVRSignal::CustomTask(custom_task) => {
|
||||
app.tasks
|
||||
.enqueue(TaskType::Overlay(OverlayTask::ModifyPanel(custom_task)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let res = wayvr.data.tick_events(app)?;
|
||||
drop(wayvr);
|
||||
|
||||
for result in res {
|
||||
match result {
|
||||
wayvr::TickTask::NewExternalProcess(request) => {
|
||||
let config = &app.session.wayvr_config;
|
||||
|
||||
let disp_name = request.env.display_name.map_or_else(
|
||||
|| {
|
||||
config
|
||||
.get_default_display()
|
||||
.map(|(display_name, _)| display_name)
|
||||
},
|
||||
|display_name| {
|
||||
config
|
||||
.get_display(display_name.as_str())
|
||||
.map(|_| display_name)
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(disp_name) = disp_name {
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
|
||||
log::info!("Registering external process with PID {}", request.pid);
|
||||
|
||||
let disp_handle = get_or_create_display_by_name(app, &mut wayvr, &disp_name)?;
|
||||
|
||||
wayvr
|
||||
.data
|
||||
.state
|
||||
.add_external_process(disp_handle, request.pid);
|
||||
|
||||
wayvr
|
||||
.data
|
||||
.state
|
||||
.manager
|
||||
.add_client(wayvr::client::WayVRClient {
|
||||
client: request.client,
|
||||
display_handle: disp_handle,
|
||||
pid: request.pid,
|
||||
});
|
||||
}
|
||||
}
|
||||
wayvr::TickTask::NewDisplay(cpar, disp_handle) => {
|
||||
log::info!("Creating new display with name \"{}\"", cpar.name);
|
||||
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
|
||||
let unique_name = wayvr.get_unique_display_name(cpar.name);
|
||||
|
||||
let disp_handle = match disp_handle {
|
||||
Some(d) => d,
|
||||
None => wayvr.data.state.create_display(
|
||||
cpar.width,
|
||||
cpar.height,
|
||||
&unique_name,
|
||||
false,
|
||||
)?,
|
||||
};
|
||||
|
||||
wayvr.overlays_to_create.push(OverlayToCreate {
|
||||
disp_handle,
|
||||
conf_display: config_wayvr::WayVRDisplay {
|
||||
attach_to: Some(config_wayvr::AttachTo::from_packet(&cpar.attach_to)),
|
||||
width: cpar.width,
|
||||
height: cpar.height,
|
||||
pos: None,
|
||||
primary: None,
|
||||
rotation: None,
|
||||
scale: cpar.scale,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
create_queued_displays(app, &mut wayvr, overlays)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl WayVRBackend {
|
||||
fn ensure_software_data(
|
||||
&mut self,
|
||||
@@ -805,7 +658,7 @@ pub fn create_wayvr_display_overlay(
|
||||
display_scale: f32,
|
||||
name: &str,
|
||||
) -> anyhow::Result<OverlayWindowConfig> {
|
||||
let wayvr = app.get_wayvr()?;
|
||||
let wayvr = app.wayvr.clone();
|
||||
|
||||
let backend = Box::new(WayVRBackend::new(
|
||||
app,
|
||||
@@ -866,7 +719,7 @@ fn action_app_click<O>(
|
||||
where
|
||||
O: Default,
|
||||
{
|
||||
let wayvr = app.get_wayvr()?;
|
||||
let wayvr = app.wayvr.clone();
|
||||
|
||||
let catalog = app
|
||||
.session
|
||||
@@ -887,12 +740,12 @@ where
|
||||
let args_vec = &app_entry
|
||||
.args
|
||||
.as_ref()
|
||||
.map_or_else(Vec::new, |args| gen_args_vec(args.as_str()));
|
||||
.map_or_else(Vec::new, |args| ipc_server::gen_args_vec(args.as_str()));
|
||||
|
||||
let env_vec = &app_entry
|
||||
.env
|
||||
.as_ref()
|
||||
.map_or_else(Vec::new, |env| gen_env_vec(env));
|
||||
.map_or_else(Vec::new, |env| ipc_server::gen_env_vec(env));
|
||||
|
||||
// Terminate existing process if required
|
||||
if let Some(process_handle) =
|
||||
@@ -930,7 +783,7 @@ pub fn action_display_click<O>(
|
||||
where
|
||||
O: Default,
|
||||
{
|
||||
let wayvr = app.get_wayvr()?;
|
||||
let wayvr = app.wayvr.clone();
|
||||
let mut wayvr = wayvr.borrow_mut();
|
||||
|
||||
let Some(handle) = WayVR::get_display_by_name(&wayvr.data.state.displays, display_name) else {
|
||||
@@ -990,14 +843,7 @@ pub fn wayvr_action<O>(
|
||||
}
|
||||
}
|
||||
WayVRAction::ToggleDashboard => {
|
||||
let wayvr = match app.get_wayvr() {
|
||||
Ok(wayvr) => wayvr,
|
||||
Err(e) => {
|
||||
log::error!("WayVR Error: {e:?}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let wayvr = app.wayvr.clone();
|
||||
let mut wayvr = wayvr.borrow_mut();
|
||||
|
||||
if let Err(e) = toggle_dashboard::<O>(app, overlays, &mut wayvr) {
|
||||
|
||||
@@ -12,11 +12,6 @@ version: 1
|
||||
# "software": Read pixel data to memory via glReadPixels() every time a content has been updated. Minor performance impact on large resolutions
|
||||
blit_method: "dmabuf"
|
||||
|
||||
# Set to true if you want to make Wyland server instantly available.
|
||||
# By default, WayVR starts only when it's needed.
|
||||
# (this option is primarily used for remote starting external processes and development purposes)
|
||||
run_compositor_at_start: false
|
||||
|
||||
# Automatically close overlays with zero window count?
|
||||
auto_hide: true
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ use crate::{
|
||||
config_io::{self, get_config_file_path},
|
||||
graphics::WGfxExtras,
|
||||
gui,
|
||||
ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal},
|
||||
subsystem::{audio::AudioOutput, dbus::DbusConnector, input::HidWrapper},
|
||||
};
|
||||
|
||||
@@ -53,11 +54,16 @@ pub struct AppState {
|
||||
|
||||
pub xr_backend: XrBackend,
|
||||
|
||||
pub ipc_server: ipc_server::WayVRServer,
|
||||
pub wayvr_signals: SyncEventQueue<WayVRSignal>,
|
||||
|
||||
#[cfg(feature = "osc")]
|
||||
pub osc_sender: Option<OscSender>,
|
||||
|
||||
// wayland server
|
||||
// TODO: rename to wayland_server?
|
||||
#[cfg(feature = "wayvr")]
|
||||
pub wayvr: Option<Rc<RefCell<WayVRData>>>, // Dynamically created if requested
|
||||
pub wayvr: Rc<RefCell<WayVRData>>,
|
||||
}
|
||||
|
||||
#[allow(unused_mut)]
|
||||
@@ -71,18 +77,18 @@ impl AppState {
|
||||
let mut tasks = TaskContainer::new();
|
||||
|
||||
let session = AppSession::load();
|
||||
let wayvr_signals = SyncEventQueue::new();
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
let wayvr = session
|
||||
.wayvr_config
|
||||
.post_load(&session.config, &mut tasks)?;
|
||||
let wayvr =
|
||||
session
|
||||
.wayvr_config
|
||||
.post_load(&session.config, &mut tasks, wayvr_signals.clone())?;
|
||||
|
||||
let mut hid_provider = HidWrapper::new();
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
if let Some(wayvr) = wayvr.as_ref() {
|
||||
hid_provider.set_wayvr(wayvr.clone());
|
||||
}
|
||||
hid_provider.set_wayvr(wayvr.clone());
|
||||
|
||||
#[cfg(feature = "osc")]
|
||||
let osc_sender = crate::subsystem::osc::OscSender::new(session.config.osc_out_port).ok();
|
||||
@@ -114,6 +120,8 @@ impl AppState {
|
||||
|
||||
let dbus = DbusConnector::default();
|
||||
|
||||
let ipc_server = ipc_server::WayVRServer::new()?;
|
||||
|
||||
Ok(Self {
|
||||
session,
|
||||
tasks,
|
||||
@@ -135,6 +143,8 @@ impl AppState {
|
||||
)?,
|
||||
dbus,
|
||||
xr_backend,
|
||||
ipc_server,
|
||||
wayvr_signals,
|
||||
|
||||
#[cfg(feature = "osc")]
|
||||
osc_sender,
|
||||
@@ -144,21 +154,6 @@ impl AppState {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
#[allow(dead_code)]
|
||||
pub fn get_wayvr(&mut self) -> anyhow::Result<Rc<RefCell<WayVRData>>> {
|
||||
if let Some(wvr) = &self.wayvr {
|
||||
Ok(wvr.clone())
|
||||
} else {
|
||||
let wayvr = Rc::new(RefCell::new(WayVRData::new(
|
||||
WayVRConfig::get_wayvr_config(&self.session.config, &self.session.wayvr_config)?,
|
||||
)?));
|
||||
self.hid_provider.set_wayvr(wayvr.clone());
|
||||
self.wayvr = Some(wayvr.clone());
|
||||
Ok(wayvr)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_load_bytes(path: &str, fallback_data: &'static [u8]) -> &'static [u8] {
|
||||
if path.is_empty() {
|
||||
return fallback_data;
|
||||
@@ -187,7 +182,7 @@ pub struct AppSession {
|
||||
pub config: GeneralConfig,
|
||||
|
||||
#[cfg(feature = "wayvr")]
|
||||
pub wayvr_config: WayVRConfig,
|
||||
pub wayvr_config: WayVRConfig, // TODO: rename to "wayland_server_config"
|
||||
|
||||
pub toast_topics: IdMap<ToastTopic, ToastDisplayMethod>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user