feat(wayland): resize
This commit is contained in:
@@ -13,7 +13,12 @@ impl CompositorHandler for WaylandState {
|
|||||||
fn commit(&mut self, surface: &WlSurface) {
|
fn commit(&mut self, surface: &WlSurface) {
|
||||||
compositor::with_states(surface, |data| {
|
compositor::with_states(surface, |data| {
|
||||||
data.data_map.insert_if_missing_threadsafe(|| {
|
data.data_map.insert_if_missing_threadsafe(|| {
|
||||||
CoreSurface::new(&self.display, self.display_handle.clone(), surface)
|
CoreSurface::new(
|
||||||
|
&self.weak_ref.upgrade().unwrap(),
|
||||||
|
&self.display,
|
||||||
|
self.display_handle.clone(),
|
||||||
|
surface,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ impl Dispatch<WlDataSource, (), WaylandState> for WaylandState {
|
|||||||
_data_init: &mut DataInit<'_, WaylandState>,
|
_data_init: &mut DataInit<'_, WaylandState>,
|
||||||
) {
|
) {
|
||||||
match request {
|
match request {
|
||||||
Offer { mime_type: _ } => todo!(),
|
Offer { mime_type: _ } => {}
|
||||||
Destroy => todo!(),
|
Destroy => {}
|
||||||
SetActions { dnd_actions: _ } => todo!(),
|
SetActions { dnd_actions: _ } => {}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,12 +88,12 @@ impl Dispatch<WlDataDevice, (), WaylandState> for WaylandState {
|
|||||||
origin: _,
|
origin: _,
|
||||||
icon: _,
|
icon: _,
|
||||||
serial: _,
|
serial: _,
|
||||||
} => todo!(),
|
} => {}
|
||||||
SetSelection {
|
SetSelection {
|
||||||
source: _,
|
source: _,
|
||||||
serial: _,
|
serial: _,
|
||||||
} => todo!(),
|
} => {}
|
||||||
Release => todo!(),
|
Release => {}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,11 +83,7 @@ impl Wayland {
|
|||||||
let display_handle = display.handle();
|
let display_handle = display.handle();
|
||||||
|
|
||||||
let display = Arc::new(Mutex::new(display));
|
let display = Arc::new(Mutex::new(display));
|
||||||
let state = Arc::new(Mutex::new(WaylandState::new(
|
let state = WaylandState::new(log.clone(), display.clone(), display_handle);
|
||||||
log.clone(),
|
|
||||||
display.clone(),
|
|
||||||
display_handle,
|
|
||||||
)));
|
|
||||||
|
|
||||||
let (global_destroy_queue_in, global_destroy_queue) = mpsc::channel(8);
|
let (global_destroy_queue_in, global_destroy_queue) = mpsc::channel(8);
|
||||||
GLOBAL_DESTROY_QUEUE.set(global_destroy_queue_in).unwrap();
|
GLOBAL_DESTROY_QUEUE.set(global_destroy_queue_in).unwrap();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use lazy_static::lazy_static;
|
|||||||
use nanoid::nanoid;
|
use nanoid::nanoid;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
reexports::wayland_server::protocol::wl_pointer::{Axis, ButtonState},
|
reexports::wayland_server::protocol::wl_pointer::{Axis, ButtonState},
|
||||||
|
utils::Size,
|
||||||
wayland::{compositor::SurfaceData, shell::xdg::XdgToplevelSurfaceData},
|
wayland::{compositor::SurfaceData, shell::xdg::XdgToplevelSurfaceData},
|
||||||
};
|
};
|
||||||
use stardust_xr::{
|
use stardust_xr::{
|
||||||
@@ -97,10 +98,11 @@ impl PanelItem {
|
|||||||
);
|
);
|
||||||
node.add_local_signal("keyboardDeactivate", PanelItem::keyboard_deactivate_flex);
|
node.add_local_signal("keyboardDeactivate", PanelItem::keyboard_deactivate_flex);
|
||||||
node.add_local_signal("keyboardKeyState", PanelItem::keyboard_key_state_flex);
|
node.add_local_signal("keyboardKeyState", PanelItem::keyboard_key_state_flex);
|
||||||
|
node.add_local_signal("resize", PanelItem::resize_flex);
|
||||||
node
|
node
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_node(node: &Node) -> &PanelItem {
|
pub fn from_node(node: &Node) -> &PanelItem {
|
||||||
match &node.item.get().unwrap().specialization {
|
match &node.item.get().unwrap().specialization {
|
||||||
ItemType::Panel(panel_item) => panel_item,
|
ItemType::Panel(panel_item) => panel_item,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@@ -179,29 +181,23 @@ impl PanelItem {
|
|||||||
if let Some(panel_node) = surface_data.data_map.get::<Arc<Node>>() {
|
if let Some(panel_node) = surface_data.data_map.get::<Arc<Node>>() {
|
||||||
let panel_item = PanelItem::from_node(panel_node);
|
let panel_item = PanelItem::from_node(panel_node);
|
||||||
|
|
||||||
core_surface.with_data(|core_surface_data| {
|
// core_surface.with_data(|core_surface_data| {
|
||||||
if core_surface_data.resized {
|
// panel_item.resize();
|
||||||
panel_item.resize(core_surface);
|
// });
|
||||||
core_surface_data.resized = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
panel_item.set_cursor();
|
panel_item.set_cursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&self, core_surface: &CoreSurface) {
|
pub fn resize(&self) {
|
||||||
core_surface.with_data(|data| {
|
self.core_surface.upgrade().unwrap().with_data(|data| {
|
||||||
if data.resized {
|
let _ = self.node.upgrade().unwrap().send_remote_signal(
|
||||||
let _ = self.node.upgrade().unwrap().send_remote_signal(
|
"resize",
|
||||||
"resize",
|
&flexbuffer_from_vector_arguments(|vec| {
|
||||||
&flexbuffer_from_vector_arguments(|vec| {
|
vec.push(data.size.x);
|
||||||
vec.push(data.size.x);
|
vec.push(data.size.y);
|
||||||
vec.push(data.size.y);
|
}),
|
||||||
}),
|
);
|
||||||
);
|
|
||||||
data.resized = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,6 +457,41 @@ impl PanelItem {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resize_flex(node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||||
|
if let ItemType::Panel(panel_item) = &node.item.get().unwrap().specialization {
|
||||||
|
if let Some(core_surface) = panel_item.core_surface.upgrade() {
|
||||||
|
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?;
|
||||||
|
let w = flex_vec.index(0)?.get_u64()? as u32;
|
||||||
|
let h = flex_vec.index(1)?.get_u64()? as u32;
|
||||||
|
|
||||||
|
let toplevel_surface = core_surface
|
||||||
|
.wayland_state()
|
||||||
|
.lock()
|
||||||
|
.xdg_shell_state
|
||||||
|
.toplevel_surfaces(|surfaces| {
|
||||||
|
surfaces
|
||||||
|
.iter()
|
||||||
|
.find(|surf| surf.wl_surface().clone() == core_surface.wl_surface())
|
||||||
|
.map(|surf| surf.clone())
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(toplevel_surface) = toplevel_surface {
|
||||||
|
let mut size_set = false;
|
||||||
|
toplevel_surface.with_pending_state(|state| {
|
||||||
|
state.size = Some(Size::default());
|
||||||
|
state.size.as_mut().unwrap().w = w as i32;
|
||||||
|
state.size.as_mut().unwrap().h = h as i32;
|
||||||
|
size_set = true;
|
||||||
|
});
|
||||||
|
if size_set {
|
||||||
|
toplevel_surface.send_configure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl ItemSpecialization for PanelItem {
|
impl ItemSpecialization for PanelItem {
|
||||||
fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder) {
|
fn serialize_start_data(&self, vec: &mut flexbuffers::VectorBuilder) {
|
||||||
|
|||||||
@@ -213,7 +213,12 @@ impl Dispatch<WlPointer, SeatData, WaylandState> for SeatDelegate {
|
|||||||
if let Some(surface) = surface.as_ref() {
|
if let Some(surface) = surface.as_ref() {
|
||||||
compositor::with_states(surface, |data| {
|
compositor::with_states(surface, |data| {
|
||||||
data.data_map.insert_if_missing_threadsafe(|| {
|
data.data_map.insert_if_missing_threadsafe(|| {
|
||||||
CoreSurface::new(&state.display, dh.clone(), surface)
|
CoreSurface::new(
|
||||||
|
&state.weak_ref.upgrade().unwrap(),
|
||||||
|
&state.display,
|
||||||
|
dh.clone(),
|
||||||
|
surface,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
if !data.data_map.insert_if_missing_threadsafe(|| {
|
if !data.data_map.insert_if_missing_threadsafe(|| {
|
||||||
Arc::new(Mutex::new(Cursor {
|
Arc::new(Mutex::new(Cursor {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use smithay::{
|
|||||||
shm::{ShmHandler, ShmState},
|
shm::{ShmHandler, ShmState},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
pub struct ClientState;
|
pub struct ClientState;
|
||||||
impl ClientData for ClientState {
|
impl ClientData for ClientState {
|
||||||
@@ -42,6 +42,7 @@ impl ClientData for ClientState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct WaylandState {
|
pub struct WaylandState {
|
||||||
|
pub weak_ref: Weak<Mutex<WaylandState>>,
|
||||||
pub display: Arc<Mutex<Display<WaylandState>>>,
|
pub display: Arc<Mutex<Display<WaylandState>>>,
|
||||||
pub display_handle: DisplayHandle,
|
pub display_handle: DisplayHandle,
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ impl WaylandState {
|
|||||||
log: Logger,
|
log: Logger,
|
||||||
display: Arc<Mutex<Display<WaylandState>>>,
|
display: Arc<Mutex<Display<WaylandState>>>,
|
||||||
display_handle: DisplayHandle,
|
display_handle: DisplayHandle,
|
||||||
) -> Self {
|
) -> Arc<Mutex<Self>> {
|
||||||
let compositor_state = CompositorState::new::<Self, _>(&display_handle, log.clone());
|
let compositor_state = CompositorState::new::<Self, _>(&display_handle, log.clone());
|
||||||
let xdg_shell_state = XdgShellState::new::<Self, _>(&display_handle, log.clone());
|
let xdg_shell_state = XdgShellState::new::<Self, _>(&display_handle, log.clone());
|
||||||
let xdg_decoration_state = XdgDecorationState::new::<Self, _>(&display_handle, log.clone());
|
let xdg_decoration_state = XdgDecorationState::new::<Self, _>(&display_handle, log.clone());
|
||||||
@@ -84,19 +85,22 @@ impl WaylandState {
|
|||||||
|
|
||||||
println!("Init Wayland compositor");
|
println!("Init Wayland compositor");
|
||||||
|
|
||||||
WaylandState {
|
Arc::new_cyclic(|weak| {
|
||||||
display,
|
Mutex::new(WaylandState {
|
||||||
display_handle,
|
weak_ref: weak.clone(),
|
||||||
|
display,
|
||||||
|
display_handle,
|
||||||
|
|
||||||
compositor_state,
|
compositor_state,
|
||||||
xdg_shell_state,
|
xdg_shell_state,
|
||||||
xdg_decoration_state,
|
xdg_decoration_state,
|
||||||
kde_decoration_state,
|
kde_decoration_state,
|
||||||
shm_state,
|
shm_state,
|
||||||
output_manager_state,
|
output_manager_state,
|
||||||
output,
|
output,
|
||||||
seats: FxHashMap::default(),
|
seats: FxHashMap::default(),
|
||||||
}
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_client(&mut self, client: ClientId, dh: &DisplayHandle) {
|
pub fn new_client(&mut self, client: ClientId, dh: &DisplayHandle) {
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ pub struct CoreSurfaceData {
|
|||||||
sk_tex: Option<SendWrapper<SKTexture>>,
|
sk_tex: Option<SendWrapper<SKTexture>>,
|
||||||
sk_mat: Option<Arc<SendWrapper<Material>>>,
|
sk_mat: Option<Arc<SendWrapper<Material>>>,
|
||||||
pub size: Vector2<u32>,
|
pub size: Vector2<u32>,
|
||||||
pub resized: bool,
|
|
||||||
}
|
}
|
||||||
impl CoreSurfaceData {
|
impl CoreSurfaceData {
|
||||||
fn new(sk: &StereoKit) -> Self {
|
fn new(sk: &StereoKit) -> Self {
|
||||||
@@ -53,7 +52,6 @@ impl CoreSurfaceData {
|
|||||||
sk_tex: Some(sk_tex),
|
sk_tex: Some(sk_tex),
|
||||||
sk_mat: Some(sk_mat),
|
sk_mat: Some(sk_mat),
|
||||||
size: Vector2::from([0, 0]),
|
size: Vector2::from([0, 0]),
|
||||||
resized: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn update_tex(&mut self, data: &RendererSurfaceStateUserData, renderer: &Gles2Renderer) {
|
fn update_tex(&mut self, data: &RendererSurfaceStateUserData, renderer: &Gles2Renderer) {
|
||||||
@@ -92,6 +90,7 @@ impl Drop for CoreSurfaceData {
|
|||||||
|
|
||||||
pub struct CoreSurface {
|
pub struct CoreSurface {
|
||||||
display: Weak<Mutex<Display<WaylandState>>>,
|
display: Weak<Mutex<Display<WaylandState>>>,
|
||||||
|
pub state: Weak<Mutex<WaylandState>>,
|
||||||
pub dh: DisplayHandle,
|
pub dh: DisplayHandle,
|
||||||
pub surface_id: ObjectId,
|
pub surface_id: ObjectId,
|
||||||
pub mapped_data: Mutex<Option<CoreSurfaceData>>,
|
pub mapped_data: Mutex<Option<CoreSurfaceData>>,
|
||||||
@@ -100,12 +99,14 @@ pub struct CoreSurface {
|
|||||||
|
|
||||||
impl CoreSurface {
|
impl CoreSurface {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
state: &Arc<Mutex<WaylandState>>,
|
||||||
display: &Arc<Mutex<Display<WaylandState>>>,
|
display: &Arc<Mutex<Display<WaylandState>>>,
|
||||||
dh: DisplayHandle,
|
dh: DisplayHandle,
|
||||||
surface: &WlSurface,
|
surface: &WlSurface,
|
||||||
) -> Arc<Self> {
|
) -> Arc<Self> {
|
||||||
CORE_SURFACES.add(CoreSurface {
|
CORE_SURFACES.add(CoreSurface {
|
||||||
display: Arc::downgrade(display),
|
display: Arc::downgrade(display),
|
||||||
|
state: Arc::downgrade(state),
|
||||||
dh,
|
dh,
|
||||||
surface_id: surface.id(),
|
surface_id: surface.id(),
|
||||||
mapped_data: Mutex::new(None),
|
mapped_data: Mutex::new(None),
|
||||||
@@ -181,6 +182,10 @@ impl CoreSurface {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wayland_state(&self) -> Arc<Mutex<WaylandState>> {
|
||||||
|
self.state.upgrade().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn wl_surface(&self) -> WlSurface {
|
pub fn wl_surface(&self) -> WlSurface {
|
||||||
WlSurface::from_id(&self.dh, self.surface_id.clone()).unwrap()
|
WlSurface::from_id(&self.dh, self.surface_id.clone()).unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
use super::state::WaylandState;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::nodes::Node;
|
||||||
|
|
||||||
|
use super::{panel_item::PanelItem, state::WaylandState, surface::CoreSurface};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
delegate_xdg_shell,
|
delegate_xdg_shell,
|
||||||
reexports::{
|
reexports::{
|
||||||
@@ -6,11 +10,15 @@ use smithay::{
|
|||||||
decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode,
|
decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode,
|
||||||
shell::server::xdg_toplevel::State,
|
shell::server::xdg_toplevel::State,
|
||||||
},
|
},
|
||||||
wayland_server::protocol::wl_seat::WlSeat,
|
wayland_server::protocol::{wl_seat::WlSeat, wl_surface::WlSurface},
|
||||||
},
|
},
|
||||||
utils::Serial,
|
utils::Serial,
|
||||||
wayland::shell::xdg::{
|
wayland::{
|
||||||
PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState,
|
compositor,
|
||||||
|
shell::xdg::{
|
||||||
|
Configure, PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler,
|
||||||
|
XdgShellState,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,9 +37,33 @@ impl XdgShellHandler for WaylandState {
|
|||||||
});
|
});
|
||||||
surface.send_configure();
|
surface.send_configure();
|
||||||
}
|
}
|
||||||
|
fn ack_configure(&mut self, surface: WlSurface, configure: Configure) {
|
||||||
|
match configure {
|
||||||
|
Configure::Toplevel(config) => {
|
||||||
|
if let Some(size) = config.state.size {
|
||||||
|
compositor::with_states(&surface, |data| {
|
||||||
|
if let Some(panel_node) = data.data_map.get::<Arc<Node>>() {
|
||||||
|
if let Some(core_surface) = data.data_map.get::<Arc<CoreSurface>>() {
|
||||||
|
let panel_item = PanelItem::from_node(panel_node);
|
||||||
|
if core_surface
|
||||||
|
.with_data(|data| {
|
||||||
|
data.size.x = size.w as u32;
|
||||||
|
data.size.y = size.h as u32;
|
||||||
|
})
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
panel_item.resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Configure::Popup(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn new_popup(&mut self, _surface: PopupSurface, _positioner: PositionerState) {}
|
fn new_popup(&mut self, _surface: PopupSurface, _positioner: PositionerState) {}
|
||||||
|
|
||||||
fn grab(&mut self, _surface: PopupSurface, _seat: WlSeat, _serial: Serial) {}
|
fn grab(&mut self, _surface: PopupSurface, _seat: WlSeat, _serial: Serial) {}
|
||||||
}
|
}
|
||||||
delegate_xdg_shell!(WaylandState);
|
delegate_xdg_shell!(WaylandState);
|
||||||
|
|||||||
Reference in New Issue
Block a user