Merge remote-tracking branch 'origin/wlvk' into next-dash-interface

[skip ci]
This commit is contained in:
Aleksander
2025-12-25 15:00:12 +01:00
parent ccf72b16c5
commit 99a2dcdd55
12 changed files with 84 additions and 57 deletions

View File

@@ -1,6 +1,6 @@
use std::{collections::HashMap, rc::Rc}; use std::{collections::HashMap, rc::Rc};
use wayvr_ipc::{packet_client::WvrProcessLaunchParams, packet_server::WvrDisplayHandle}; use wayvr_ipc::packet_client::WvrProcessLaunchParams;
use wgui::{ use wgui::{
assets::AssetPath, assets::AssetPath,
components::{button::ComponentButton, checkbox::ComponentCheckbox}, components::{button::ComponentButton, checkbox::ComponentCheckbox},
@@ -246,10 +246,6 @@ impl View {
env, env,
exec: String::from(exec), exec: String::from(exec),
name: desktop_file.name, name: desktop_file.name,
target_display: WvrDisplayHandle {
generation: 12345, // stub
idx: 12345,
},
args, args,
userdata, userdata,
})?; })?;

View File

@@ -26,21 +26,11 @@ pub enum AttachTo {
pub struct WvrProcessLaunchParams { pub struct WvrProcessLaunchParams {
pub name: String, pub name: String,
pub exec: String, pub exec: String,
pub target_display: packet_server::WvrDisplayHandle,
pub env: Vec<String>, pub env: Vec<String>,
pub args: String, pub args: String,
pub userdata: HashMap<String, String>, pub userdata: HashMap<String, String>,
} }
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct WvrDisplayCreateParams {
pub width: u16,
pub height: u16,
pub name: String,
pub scale: Option<f32>,
pub attach_to: AttachTo,
}
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct WlxHapticsParams { pub struct WlxHapticsParams {
pub intensity: f32, pub intensity: f32,

View File

@@ -19,12 +19,6 @@ pub struct Disconnect {
pub reason: String, pub reason: String,
} }
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub struct WvrDisplayHandle {
pub idx: u32,
pub generation: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub struct WvrProcessHandle { pub struct WvrProcessHandle {
pub idx: u32, pub idx: u32,
@@ -37,15 +31,6 @@ pub struct WvrWindowHandle {
pub generation: u64, pub generation: u64,
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WvrDisplay {
pub width: u16,
pub height: u16,
pub name: String,
pub visible: bool,
pub handle: WvrDisplayHandle,
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WvrWindow { pub struct WvrWindow {
pub size_x: u32, pub size_x: u32,
@@ -55,11 +40,6 @@ pub struct WvrWindow {
pub process_handle: WvrProcessHandle, pub process_handle: WvrProcessHandle,
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WvrDisplayList {
pub list: Vec<WvrDisplay>,
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WvrWindowList { pub struct WvrWindowList {
pub list: Vec<WvrWindow>, pub list: Vec<WvrWindow>,
@@ -91,12 +71,6 @@ pub struct StackingOptions {
pub margins_rest: Margins, pub margins_rest: Margins,
} }
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum WvrDisplayWindowLayout {
Tiling,
Stacking(StackingOptions),
}
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum WvrStateChanged { pub enum WvrStateChanged {
ProcessCreated, ProcessCreated,

View File

@@ -105,7 +105,6 @@ pub async fn wvr_process_launch(
exec: String, exec: String,
name: String, name: String,
env: Vec<String>, env: Vec<String>,
target_display: packet_server::WvrDisplayHandle,
args: String, args: String,
userdata: HashMap<String, String>, userdata: HashMap<String, String>,
) { ) {
@@ -118,7 +117,6 @@ pub async fn wvr_process_launch(
env, env,
exec, exec,
name, name,
target_display,
args, args,
userdata, userdata,
}, },

View File

@@ -119,11 +119,10 @@ async fn run_once(state: &mut WayVRClientState, args: Args) -> anyhow::Result<()
exec, exec,
name, name,
env, env,
target_display,
args, args,
} => { } => {
let handle = serde_json::from_str(&target_display).context("Invalid target_display")?; let env = env.split(",").map(|s| s.to_string()).collect::<Vec<_>>();
wvr_process_launch(state, exec, name, env, handle, args, HashMap::new()).await; wvr_process_launch(state, exec, name, env, args, HashMap::new()).await;
} }
Subcommands::Haptics { Subcommands::Haptics {
device, device,
@@ -211,9 +210,10 @@ enum Subcommands {
ProcessLaunch { ProcessLaunch {
exec: String, exec: String,
name: String, name: String,
env: Vec<String>, /// Enviroment variables, separated by comma
/// A display handle JSON returned by DisplayList or DisplayCreate #[arg(default_value = "")]
target_display: String, env: String,
#[arg(default_value = "")]
args: String, args: String,
}, },
/// Trigger haptics on the user's controller /// Trigger haptics on the user's controller

View File

@@ -492,6 +492,7 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr
} }
#[cfg(feature = "openvr")] #[cfg(feature = "openvr")]
TaskType::OpenVR(_) => {} TaskType::OpenVR(_) => {}
#[cfg(feature = "wayvr")]
TaskType::WayVR(_action) => { /* TODO */ } TaskType::WayVR(_action) => { /* TODO */ }
} }
} }

View File

@@ -104,7 +104,7 @@ impl compositor::CompositorHandler for Application {
} }
} }
Some(BufferType::Shm) => { Some(BufferType::Shm) => {
with_buffer_contents(&buffer, |data, size, buf| { let _ = with_buffer_contents(&buffer, |data, size, buf| {
if let Ok(image) = if let Ok(image) =
self.image_importer.import_shm(data, size, buf) self.image_importer.import_shm(data, size, buf)
{ {

View File

@@ -16,10 +16,10 @@ use smithay::{
output::{Mode, Output}, output::{Mode, Output},
reexports::wayland_server::{self, backend::ClientId, protocol::wl_buffer}, reexports::wayland_server::{self, backend::ClientId, protocol::wl_buffer},
wayland::{ wayland::{
compositor::{self, SurfaceData}, compositor::{self, SurfaceData, with_states},
dmabuf::{DmabufFeedbackBuilder, DmabufState}, dmabuf::{DmabufFeedbackBuilder, DmabufState},
selection::data_device::DataDeviceState, selection::data_device::DataDeviceState,
shell::xdg::{ToplevelSurface, XdgShellState}, shell::xdg::{ToplevelSurface, XdgShellState, XdgToplevelSurfaceData},
shm::ShmState, shm::ShmState,
}, },
}; };
@@ -45,6 +45,7 @@ use crate::{
}, },
graphics::WGfxExtras, graphics::WGfxExtras,
ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal}, ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal},
overlays::wayvr::create_wl_window_overlay,
state::AppState, state::AppState,
subsystem::hid::{MODS_TO_KEYS, WheelDelta}, subsystem::hid::{MODS_TO_KEYS, WheelDelta},
windowing::{OverlayID, OverlaySelector}, windowing::{OverlayID, OverlaySelector},
@@ -312,7 +313,34 @@ impl WayVR {
.borrow_mut() .borrow_mut()
.create_window(&toplevel, process_handle); .create_window(&toplevel, process_handle);
//TODO: create overlay let title: Arc<str> = with_states(toplevel.wl_surface(), |states| {
states
.data_map
.get::<XdgToplevelSurfaceData>()
.and_then(|t| t.lock().unwrap().title.clone())
.map(|t| t.into())
.unwrap_or_else(|| format!("P{}", client.pid).into())
});
app.tasks.enqueue(TaskType::Overlay(OverlayTask::Create(
OverlaySelector::Nothing,
Box::new(move |app: &mut AppState| {
Some(
create_wl_window_overlay(
title,
app.xr_backend,
app.wayland_server.as_ref().unwrap().clone(),
window_handle,
)
.inspect_err(|e| {
log::error!("Could not add wayland client overlay: {e:?}")
})
.ok()?,
)
}),
)));
//TODO: populate window_to_overlay
app.wayvr_signals.send(WayVRSignal::BroadcastStateChanged( app.wayvr_signals.send(WayVRSignal::BroadcastStateChanged(
packet_server::WvrStateChanged::WindowCreated, packet_server::WvrStateChanged::WindowCreated,
@@ -346,6 +374,8 @@ impl WayVR {
if let Some(process) = self.state.processes.get_mut(&process_handle) { if let Some(process) = self.state.processes.get_mut(&process_handle) {
process.terminate(); process.terminate();
} }
//TODO: force drop related overlays
} }
} }
} }
@@ -540,9 +570,11 @@ pub struct SurfaceBufWithImage {
} }
impl SurfaceBufWithImage { impl SurfaceBufWithImage {
#[allow(invalid_value)]
fn apply_to_surface(self, surface_data: &SurfaceData) { fn apply_to_surface(self, surface_data: &SurfaceData) {
let container = surface_data.data_map.get_or_insert(|| unsafe { let container = surface_data.data_map.get_or_insert(|| unsafe {
SurfaceBufWithImageContainer { SurfaceBufWithImageContainer {
// safe because we're replacing right after
inner: RefCell::new(MaybeUninit::uninit().assume_init()), inner: RefCell::new(MaybeUninit::uninit().assume_init()),
} }
}); });

View File

@@ -55,7 +55,7 @@ pub struct ScreenBackend {
} }
impl ScreenBackend { impl ScreenBackend {
pub fn new_raw( pub(super) fn new_raw(
name: Arc<str>, name: Arc<str>,
xr_backend: XrBackend, xr_backend: XrBackend,
capture: Box<dyn WlxCapture<WlxCaptureIn, WlxCaptureOut>>, capture: Box<dyn WlxCapture<WlxCaptureIn, WlxCaptureOut>>,

View File

@@ -3,7 +3,10 @@ use smithay::wayland::compositor::with_states;
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
use vulkano::image::view::ImageView; use vulkano::image::view::ImageView;
use wgui::gfx::WGfx; use wgui::gfx::WGfx;
use wlx_common::overlays::{BackendAttrib, BackendAttribValue, StereoMode}; use wlx_common::{
overlays::{BackendAttrib, BackendAttribValue, StereoMode},
windowing::{OverlayWindowState, Positioning},
};
use crate::{ use crate::{
backend::{ backend::{
@@ -15,13 +18,14 @@ use crate::{
ipc::{event_queue::SyncEventQueue, signal::WayVRSignal}, ipc::{event_queue::SyncEventQueue, signal::WayVRSignal},
overlays::screen::capture::ScreenPipeline, overlays::screen::capture::ScreenPipeline,
state::{self, AppState}, state::{self, AppState},
subsystem::hid::WheelDelta, subsystem::{hid::WheelDelta, input::KeyboardFocus},
windowing::{ windowing::{
OverlayID, OverlayID,
backend::{ backend::{
FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender, FrameMeta, OverlayBackend, OverlayEventData, RenderResources, ShouldRender,
ui_transform, ui_transform,
}, },
window::{OverlayCategory, OverlayWindowConfig},
}, },
}; };
@@ -44,6 +48,35 @@ impl WayVRData {
} }
} }
pub fn create_wl_window_overlay(
name: Arc<str>,
xr_backend: XrBackend,
wayvr: Rc<RefCell<WayVRData>>,
window: wayvr::window::WindowHandle,
) -> anyhow::Result<OverlayWindowConfig> {
Ok(OverlayWindowConfig {
name: name.clone(),
default_state: OverlayWindowState {
grabbable: true,
interactable: true,
positioning: Positioning::Floating,
curvature: Some(0.15),
transform: Affine3A::from_scale_rotation_translation(
Vec3::ONE,
Quat::IDENTITY,
vec3(0.0, 0.0, -0.4),
),
..OverlayWindowState::default()
},
keyboard_focus: Some(KeyboardFocus::WayVR),
category: OverlayCategory::WayVR,
show_on_spawn: true,
..OverlayWindowConfig::from_backend(Box::new(WayVRBackend::new(
name, xr_backend, wayvr, window,
)?))
})
}
pub struct WayVRBackend { pub struct WayVRBackend {
name: Arc<str>, name: Arc<str>,
pipeline: Option<ScreenPipeline>, pipeline: Option<ScreenPipeline>,
@@ -59,7 +92,7 @@ pub struct WayVRBackend {
} }
impl WayVRBackend { impl WayVRBackend {
pub fn new( fn new(
name: Arc<str>, name: Arc<str>,
xr_backend: XrBackend, xr_backend: XrBackend,
wayvr: Rc<RefCell<WayVRData>>, wayvr: Rc<RefCell<WayVRData>>,

View File

@@ -532,6 +532,7 @@ impl<T> OverlayWindowManager<T> {
match selector { match selector {
OverlaySelector::Id(id) => Some(*id), OverlaySelector::Id(id) => Some(*id),
OverlaySelector::Name(name) => self.lookup(name), OverlaySelector::Name(name) => self.lookup(name),
_ => None,
} }
} }
@@ -551,6 +552,7 @@ impl<T> OverlayWindowManager<T> {
let id = match selector { let id = match selector {
OverlaySelector::Id(id) => *id, OverlaySelector::Id(id) => *id,
OverlaySelector::Name(name) => self.lookup(name)?, OverlaySelector::Name(name) => self.lookup(name)?,
_ => return None,
}; };
let ret_val = self.overlays.remove(id); let ret_val = self.overlays.remove(id);

View File

@@ -15,6 +15,7 @@ new_key_type! {
pub enum OverlaySelector { pub enum OverlaySelector {
Id(OverlayID), Id(OverlayID),
Name(Arc<str>), Name(Arc<str>),
Nothing,
} }
pub const Z_ORDER_TOAST: u32 = 71; pub const Z_ORDER_TOAST: u32 = 71;