feat(xwayland): xwayland feature

This commit is contained in:
Nova
2023-07-23 09:04:22 -04:00
parent 824b1bdd26
commit eedf5446e8
6 changed files with 34 additions and 20 deletions

View File

@@ -13,8 +13,9 @@ name = "stardust-xr-server"
path = "src/main.rs" path = "src/main.rs"
[features] [features]
default = ["wayland"] default = ["wayland", "xwayland"]
wayland = ["dep:smithay", "dep:xkbcommon"] wayland = ["dep:smithay", "dep:xkbcommon"]
xwayland = ["smithay/xwayland"]
profile_tokio = ["dep:console-subscriber", "tokio/tracing"] profile_tokio = ["dep:console-subscriber", "tokio/tracing"]
profile_app = ["dep:tracing-chrome"] profile_app = ["dep:tracing-chrome"]
@@ -70,13 +71,7 @@ version = "0.16.7"
git = "https://github.com/smithay/smithay.git" # Until we get stereokit to understand OES samplers and external textures git = "https://github.com/smithay/smithay.git" # Until we get stereokit to understand OES samplers and external textures
# path = "../smithay" # path = "../smithay"
default-features = false default-features = false
features = [ features = ["desktop", "backend_drm", "renderer_gl", "wayland_frontend"]
"desktop",
"backend_drm",
"renderer_gl",
"wayland_frontend",
"xwayland",
]
version = "*" version = "*"
optional = true optional = true

View File

@@ -214,6 +214,7 @@ fn main() {
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
{ {
startup_command.env("WAYLAND_DISPLAY", &wayland.as_ref().unwrap().socket_name); startup_command.env("WAYLAND_DISPLAY", &wayland.as_ref().unwrap().socket_name);
#[cfg(feature = "xwayland")]
startup_command.env( startup_command.env(
"DISPLAY", "DISPLAY",
format!(":{}", wayland.as_ref().unwrap().xwayland_state.display), format!(":{}", wayland.as_ref().unwrap().xwayland_state.display),

View File

@@ -1,8 +1,6 @@
use crate::{ #[cfg(feature = "xwayland")]
core::client::Client, use crate::wayland::xwayland::DISPLAY;
wayland::{xwayland::DISPLAY, WAYLAND_DISPLAY}, use crate::{core::client::Client, wayland::WAYLAND_DISPLAY, STARDUST_INSTANCE};
STARDUST_INSTANCE,
};
use super::{ use super::{
items::{ItemAcceptor, TypeInfo}, items::{ItemAcceptor, TypeInfo},
@@ -139,6 +137,7 @@ pub fn get_connection_environment_flex(
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
{ {
var_env_insert!(env, WAYLAND_DISPLAY); var_env_insert!(env, WAYLAND_DISPLAY);
#[cfg(feature = "xwayland")]
var_env_insert!(env, DISPLAY); var_env_insert!(env, DISPLAY);
env.insert("GDK_BACKEND".to_string(), "wayland".to_string()); env.insert("GDK_BACKEND".to_string(), "wayland".to_string());
env.insert("QT_QPA_PLATFORM".to_string(), "wayland".to_string()); env.insert("QT_QPA_PLATFORM".to_string(), "wayland".to_string());

View File

@@ -2,11 +2,12 @@ use crate::wayland::surface::CoreSurface;
use super::state::{ClientState, WaylandState}; use super::state::{ClientState, WaylandState};
use portable_atomic::{AtomicU32, Ordering}; use portable_atomic::{AtomicU32, Ordering};
#[cfg(feature = "xwayland")]
use smithay::xwayland::XWaylandClientData;
use smithay::{ use smithay::{
delegate_compositor, delegate_compositor,
reexports::wayland_server::{protocol::wl_surface::WlSurface, Client}, reexports::wayland_server::{protocol::wl_surface::WlSurface, Client},
wayland::compositor::{self, CompositorClientState, CompositorHandler, CompositorState}, wayland::compositor::{self, CompositorClientState, CompositorHandler, CompositorState},
xwayland::XWaylandClientData,
}; };
use std::sync::Arc; use std::sync::Arc;
use tracing::debug; use tracing::debug;
@@ -41,9 +42,11 @@ impl CompositorHandler for WaylandState {
fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
if let Some(client_state) = client.get_data::<ClientState>() { if let Some(client_state) = client.get_data::<ClientState>() {
&client_state.compositor_state &client_state.compositor_state
} else if let Some(xwayland_client_data) = client.get_data::<XWaylandClientData>() {
&xwayland_client_data.compositor_state
} else { } else {
#[cfg(feature = "xwayland")]
if let Some(xwayland_client_data) = client.get_data::<XWaylandClientData>() {
return &xwayland_client_data.compositor_state;
}
unimplemented!() unimplemented!()
} }
} }

View File

@@ -8,9 +8,9 @@ mod state;
mod surface; mod surface;
// mod xdg_activation; // mod xdg_activation;
mod xdg_shell; mod xdg_shell;
#[cfg(feature = "xwayland")]
pub mod xwayland; pub mod xwayland;
use self::xwayland::XWaylandState;
use self::{state::WaylandState, surface::CORE_SURFACES}; use self::{state::WaylandState, surface::CORE_SURFACES};
use crate::{core::task, wayland::state::ClientState}; use crate::{core::task, wayland::state::ClientState};
use color_eyre::eyre::{ensure, Result}; use color_eyre::eyre::{ensure, Result};
@@ -70,7 +70,8 @@ pub struct Wayland {
renderer: GlesRenderer, renderer: GlesRenderer,
dmabuf_rx: UnboundedReceiver<Dmabuf>, dmabuf_rx: UnboundedReceiver<Dmabuf>,
wayland_state: Arc<Mutex<WaylandState>>, wayland_state: Arc<Mutex<WaylandState>>,
pub xwayland_state: XWaylandState, #[cfg(feature = "xwayland")]
pub xwayland_state: xwayland::XWaylandState,
} }
impl Wayland { impl Wayland {
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {
@@ -88,7 +89,8 @@ impl Wayland {
let (dmabuf_tx, dmabuf_rx) = mpsc::unbounded_channel(); let (dmabuf_tx, dmabuf_rx) = mpsc::unbounded_channel();
let display = Arc::new(Mutex::new(display)); let display = Arc::new(Mutex::new(display));
let xwayland_state = XWaylandState::create(display.clone(), &display_handle).unwrap(); #[cfg(feature = "xwayland")]
let xwayland_state = xwayland::XWaylandState::create(display.clone(), &display_handle).unwrap();
let wayland_state = let wayland_state =
WaylandState::new(display.clone(), display_handle, &renderer, dmabuf_tx); WaylandState::new(display.clone(), display_handle, &renderer, dmabuf_tx);
@@ -116,6 +118,7 @@ impl Wayland {
renderer, renderer,
dmabuf_rx, dmabuf_rx,
wayland_state, wayland_state,
#[cfg(feature = "xwayland")]
xwayland_state, xwayland_state,
}) })
} }

View File

@@ -40,8 +40,11 @@ use smithay::{
backend::Credentials, protocol::wl_surface::WlSurface, Resource, Weak as WlWeak, backend::Credentials, protocol::wl_surface::WlSurface, Resource, Weak as WlWeak,
}, },
}, },
utils::Rectangle,
wayland::compositor, wayland::compositor,
};
#[cfg(feature = "xwayland")]
use smithay::{
utils::Rectangle,
xwayland::{xwm::X11SurfaceError, X11Surface}, xwayland::{xwm::X11SurfaceError, X11Surface},
}; };
use stardust_xr::schemas::flex::{deserialize, serialize}; use stardust_xr::schemas::flex::{deserialize, serialize};
@@ -331,11 +334,14 @@ impl WaylandBackend {
*self.cursor.lock() = surface.map(|surf| surf.downgrade()); *self.cursor.lock() = surface.map(|surf| surf.downgrade());
} }
} }
#[cfg(feature = "xwayland")]
#[derive(Debug)] #[derive(Debug)]
pub struct X11Backend { pub struct X11Backend {
pub toplevel_parent: Option<X11Surface>, pub toplevel_parent: Option<X11Surface>,
pub toplevel: X11Surface, pub toplevel: X11Surface,
} }
#[cfg(feature = "xwayland")]
impl X11Backend { impl X11Backend {
fn configure_toplevel( fn configure_toplevel(
&self, &self,
@@ -377,6 +383,7 @@ impl X11Backend {
#[derive(Debug)] #[derive(Debug)]
pub enum Backend { pub enum Backend {
Wayland(WaylandBackend), Wayland(WaylandBackend),
#[cfg(feature = "xwayland")]
X11(X11Backend), X11(X11Backend),
} }
@@ -475,6 +482,7 @@ impl PanelItem {
fn toplevel_wl_surface(&self) -> Option<WlSurface> { fn toplevel_wl_surface(&self) -> Option<WlSurface> {
match &self.backend { match &self.backend {
Backend::Wayland(w) => w.toplevel_wl_surface(), Backend::Wayland(w) => w.toplevel_wl_surface(),
#[cfg(feature = "xwayland")]
Backend::X11(x) => x.toplevel.wl_surface(), Backend::X11(x) => x.toplevel.wl_surface(),
} }
} }
@@ -491,6 +499,7 @@ impl PanelItem {
fn wl_surface_from_id(&self, id: &SurfaceID) -> Option<WlSurface> { fn wl_surface_from_id(&self, id: &SurfaceID) -> Option<WlSurface> {
match &self.backend { match &self.backend {
Backend::Wayland(w) => w.wl_surface_from_id(id), Backend::Wayland(w) => w.wl_surface_from_id(id),
#[cfg(feature = "xwayland")]
Backend::X11(x) => x.wl_surface_from_id(id), Backend::X11(x) => x.wl_surface_from_id(id),
} }
} }
@@ -631,6 +640,7 @@ impl PanelItem {
keymap, keymap,
match &panel_item.backend { match &panel_item.backend {
Backend::Wayland(w) => w.input_surfaces(), Backend::Wayland(w) => w.input_surfaces(),
#[cfg(feature = "xwayland")]
Backend::X11(_) => panel_item Backend::X11(_) => panel_item
.toplevel_wl_surface() .toplevel_wl_surface()
.map(|s| vec![s]) .map(|s| vec![s])
@@ -671,6 +681,7 @@ impl PanelItem {
match &panel_item.backend { match &panel_item.backend {
Backend::Wayland(w) => w.configure_toplevel(info.size, info.states, info.bounds), Backend::Wayland(w) => w.configure_toplevel(info.size, info.states, info.bounds),
#[cfg(feature = "xwayland")]
Backend::X11(x) => x.configure_toplevel(info.size, info.states)?, Backend::X11(x) => x.configure_toplevel(info.size, info.states)?,
} }
Ok(()) Ok(())
@@ -706,6 +717,7 @@ impl PanelItem {
let Some(node) = self.node.upgrade() else { return }; let Some(node) = self.node.upgrade() else { return };
let Ok(data) = (match &self.backend { let Ok(data) = (match &self.backend {
Backend::Wayland(w) => w.serialize_toplevel(), Backend::Wayland(w) => w.serialize_toplevel(),
#[cfg(feature = "xwayland")]
Backend::X11(x) => x.serialize_toplevel(), Backend::X11(x) => x.serialize_toplevel(),
}) else {return}; }) else {return};
let _ = node.send_remote_signal("commit_toplevel", &data); let _ = node.send_remote_signal("commit_toplevel", &data);
@@ -755,6 +767,7 @@ impl ItemSpecialization for PanelItem {
)) ))
.ok() .ok()
} }
#[cfg(feature = "xwayland")]
Backend::X11(x) => { Backend::X11(x) => {
let size = ( let size = (
x.toplevel.geometry().size.w as u32, x.toplevel.geometry().size.w as u32,