feat(wayland): resize

This commit is contained in:
Nova
2022-09-20 19:01:09 -04:00
parent a832232cbf
commit 56afecca74
8 changed files with 131 additions and 53 deletions

View File

@@ -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,
)
}) })
}); });
} }

View File

@@ -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!(),
} }
} }

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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()
} }

View File

@@ -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);