refactor(wayland): strong reference to all "parent" types
This commit is contained in:
@@ -34,7 +34,7 @@ impl XdgBackend {
|
|||||||
|
|
||||||
fn surface_from_id(&self, id: SurfaceId) -> Option<Arc<Surface>> {
|
fn surface_from_id(&self, id: SurfaceId) -> Option<Arc<Surface>> {
|
||||||
match id {
|
match id {
|
||||||
SurfaceId::Toplevel(_) => Some(self.toplevel().wl_surface()),
|
SurfaceId::Toplevel(_) => Some(self.toplevel().wl_surface().clone()),
|
||||||
SurfaceId::Child(_) => None,
|
SurfaceId::Child(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,24 +222,24 @@ impl Backend for XdgBackend {
|
|||||||
position.x,
|
position.x,
|
||||||
position.y
|
position.y
|
||||||
);
|
);
|
||||||
let surface = self.toplevel().wl_surface();
|
let toplevel = self.toplevel();
|
||||||
let _ = surface.message_sink.send(Message::Seat(
|
let _ = toplevel.wl_surface().message_sink.send(Message::Seat(
|
||||||
crate::wayland::core::seat::SeatMessage::TouchMove { id, position },
|
crate::wayland::core::seat::SeatMessage::TouchMove { id, position },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn touch_up(&self, id: u32) {
|
fn touch_up(&self, id: u32) {
|
||||||
tracing::debug!("Backend: Touch up {}", id);
|
tracing::debug!("Backend: Touch up {}", id);
|
||||||
let surface = self.toplevel().wl_surface();
|
let toplevel = self.toplevel();
|
||||||
let _ = surface.message_sink.send(Message::Seat(
|
let _ = toplevel.wl_surface().message_sink.send(Message::Seat(
|
||||||
crate::wayland::core::seat::SeatMessage::TouchUp { id },
|
crate::wayland::core::seat::SeatMessage::TouchUp { id },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_input(&self) {
|
fn reset_input(&self) {
|
||||||
tracing::debug!("Backend: Reset input");
|
tracing::debug!("Backend: Reset input");
|
||||||
let surface = self.toplevel().wl_surface();
|
let toplevel = self.toplevel();
|
||||||
let _ = surface.message_sink.send(Message::Seat(
|
let _ = toplevel.wl_surface().message_sink.send(Message::Seat(
|
||||||
crate::wayland::core::seat::SeatMessage::Reset,
|
crate::wayland::core::seat::SeatMessage::Reset,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub struct Popup {
|
|||||||
id: ObjectId,
|
id: ObjectId,
|
||||||
version: u32,
|
version: u32,
|
||||||
parent: Arc<Surface>,
|
parent: Arc<Surface>,
|
||||||
surface: Weak<Surface>,
|
surface: Arc<Surface>,
|
||||||
pub panel_item: Weak<PanelItem<XdgBackend>>,
|
pub panel_item: Weak<PanelItem<XdgBackend>>,
|
||||||
positioner_data: Mutex<PositionerData>,
|
positioner_data: Mutex<PositionerData>,
|
||||||
geometry: DoubleBuffer<Geometry>,
|
geometry: DoubleBuffer<Geometry>,
|
||||||
@@ -32,11 +32,11 @@ impl Popup {
|
|||||||
version: u32,
|
version: u32,
|
||||||
parent: Arc<Surface>,
|
parent: Arc<Surface>,
|
||||||
panel_item: &Arc<PanelItem<XdgBackend>>,
|
panel_item: &Arc<PanelItem<XdgBackend>>,
|
||||||
xdg_surface: &Arc<Surface>,
|
surface: Arc<Surface>,
|
||||||
positioner: &Positioner,
|
positioner: &Positioner,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let _ = xdg_surface
|
let _ = surface
|
||||||
.wl_surface()
|
.wl_surface
|
||||||
.surface_id
|
.surface_id
|
||||||
.set(SurfaceId::Child(rand::thread_rng().gen_range(0..u64::MAX)));
|
.set(SurfaceId::Child(rand::thread_rng().gen_range(0..u64::MAX)));
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ impl Popup {
|
|||||||
id,
|
id,
|
||||||
version,
|
version,
|
||||||
parent,
|
parent,
|
||||||
surface: Arc::downgrade(xdg_surface),
|
surface,
|
||||||
panel_item: Arc::downgrade(panel_item),
|
panel_item: Arc::downgrade(panel_item),
|
||||||
positioner_data: Mutex::new(positioner_data),
|
positioner_data: Mutex::new(positioner_data),
|
||||||
geometry: DoubleBuffer::new(positioner_data.infinite_geometry()),
|
geometry: DoubleBuffer::new(positioner_data.infinite_geometry()),
|
||||||
@@ -89,7 +89,7 @@ impl XdgPopup for Popup {
|
|||||||
geometry.size.y as i32,
|
geometry.size.y as i32,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
self.surface.upgrade().unwrap().reconfigure(client).await?;
|
self.surface.reconfigure(client).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::wayland::{
|
|||||||
display::Display,
|
display::Display,
|
||||||
xdg::{toplevel::Toplevel, wm_base::XdgSurfaceRole},
|
xdg::{toplevel::Toplevel, wm_base::XdgSurfaceRole},
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, OnceLock, Weak};
|
use std::sync::{Arc, OnceLock};
|
||||||
pub use waynest::server::protocol::stable::xdg_shell::xdg_surface::*;
|
pub use waynest::server::protocol::stable::xdg_shell::xdg_surface::*;
|
||||||
use waynest::{
|
use waynest::{
|
||||||
server::{Client, Dispatcher, Result},
|
server::{Client, Dispatcher, Result},
|
||||||
@@ -16,7 +16,7 @@ use waynest::{
|
|||||||
pub struct Surface {
|
pub struct Surface {
|
||||||
id: ObjectId,
|
id: ObjectId,
|
||||||
version: u32,
|
version: u32,
|
||||||
wl_surface: Weak<crate::wayland::core::surface::Surface>,
|
pub wl_surface: Arc<crate::wayland::core::surface::Surface>,
|
||||||
configured: Arc<std::sync::atomic::AtomicBool>,
|
configured: Arc<std::sync::atomic::AtomicBool>,
|
||||||
}
|
}
|
||||||
impl Surface {
|
impl Surface {
|
||||||
@@ -28,18 +28,11 @@ impl Surface {
|
|||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
version,
|
version,
|
||||||
wl_surface: Arc::downgrade(&wl_surface),
|
wl_surface,
|
||||||
configured: Arc::new(std::sync::atomic::AtomicBool::new(false)),
|
configured: Arc::new(std::sync::atomic::AtomicBool::new(false)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wl_surface(&self) -> Arc<crate::wayland::core::surface::Surface> {
|
|
||||||
// We can safely unwrap as the surface must exist for the lifetime of the xdg_surface
|
|
||||||
self.wl_surface
|
|
||||||
.upgrade()
|
|
||||||
.expect("Surface was dropped before xdg_surface")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn reconfigure(&self, client: &mut Client) -> Result<()> {
|
pub async fn reconfigure(&self, client: &mut Client) -> Result<()> {
|
||||||
let serial = client.next_event_serial();
|
let serial = client.next_event_serial();
|
||||||
self.configure(client, self.id, serial).await
|
self.configure(client, self.id, serial).await
|
||||||
@@ -59,33 +52,17 @@ impl XdgSurface for Surface {
|
|||||||
sender_id: ObjectId,
|
sender_id: ObjectId,
|
||||||
toplevel_id: ObjectId,
|
toplevel_id: ObjectId,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let surface = self.wl_surface();
|
|
||||||
let toplevel = client.insert(
|
let toplevel = client.insert(
|
||||||
toplevel_id,
|
toplevel_id,
|
||||||
Toplevel::new(
|
Toplevel::new(
|
||||||
toplevel_id,
|
toplevel_id,
|
||||||
surface.clone(),
|
self.wl_surface.clone(),
|
||||||
client.get::<Self>(sender_id).unwrap(),
|
client.get::<Self>(sender_id).unwrap(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// Set up the XDG role if not already done
|
|
||||||
if surface.role.get().is_none() {
|
|
||||||
let xdg_role = SurfaceRole::Xdg(OnceLock::new());
|
|
||||||
|
|
||||||
if surface.role.set(xdg_role).is_err() {
|
|
||||||
return client
|
|
||||||
.protocol_error(
|
|
||||||
sender_id,
|
|
||||||
toplevel_id,
|
|
||||||
1, // XDG_WM_BASE_ERROR_ROLE
|
|
||||||
"Failed to set surface role (race condition)".to_string(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the surface already has an XDG role
|
// Check if the surface already has an XDG role
|
||||||
let surface_role = surface.role.get().unwrap();
|
let surface_role = self.wl_surface.role.get().unwrap();
|
||||||
|
|
||||||
// Now check if this is an XDG surface and set the sub-role
|
// Now check if this is an XDG surface and set the sub-role
|
||||||
if let SurfaceRole::Xdg(role) = surface_role {
|
if let SurfaceRole::Xdg(role) = surface_role {
|
||||||
@@ -128,7 +105,7 @@ impl XdgSurface for Surface {
|
|||||||
|
|
||||||
let pid = client.get::<Display>(ObjectId::DISPLAY).unwrap().pid;
|
let pid = client.get::<Display>(ObjectId::DISPLAY).unwrap().pid;
|
||||||
let configured = self.configured.clone();
|
let configured = self.configured.clone();
|
||||||
surface.add_commit_handler(move |surface, state| {
|
self.wl_surface.add_commit_handler(move |surface, state| {
|
||||||
let Some(role_ref) = surface.role.get() else {
|
let Some(role_ref) = surface.role.get() else {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -184,7 +161,7 @@ impl XdgSurface for Surface {
|
|||||||
.await;
|
.await;
|
||||||
};
|
};
|
||||||
let parent = client.get::<Surface>(parent).unwrap();
|
let parent = client.get::<Surface>(parent).unwrap();
|
||||||
let panel_item = match parent.wl_surface().role.get().unwrap() {
|
let panel_item = match parent.wl_surface.role.get().unwrap() {
|
||||||
SurfaceRole::Xdg(role) => match role.get().unwrap() {
|
SurfaceRole::Xdg(role) => match role.get().unwrap() {
|
||||||
XdgSurfaceRole::Toplevel(toplevel) => {
|
XdgSurfaceRole::Toplevel(toplevel) => {
|
||||||
if let Some(toplevel) = toplevel.upgrade() {
|
if let Some(toplevel) = toplevel.upgrade() {
|
||||||
@@ -238,17 +215,16 @@ impl XdgSurface for Surface {
|
|||||||
self.version,
|
self.version,
|
||||||
parent,
|
parent,
|
||||||
&panel_item,
|
&panel_item,
|
||||||
&surface,
|
surface,
|
||||||
&positioner,
|
&positioner,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set up the XDG role if not already done
|
// Set up the XDG role if not already done
|
||||||
let wl_surface = self.wl_surface();
|
if self.wl_surface.role.get().is_none() {
|
||||||
if wl_surface.role.get().is_none() {
|
|
||||||
let xdg_role = SurfaceRole::Xdg(OnceLock::new());
|
let xdg_role = SurfaceRole::Xdg(OnceLock::new());
|
||||||
|
|
||||||
if wl_surface.role.set(xdg_role).is_err() {
|
if self.wl_surface.role.set(xdg_role).is_err() {
|
||||||
return client
|
return client
|
||||||
.protocol_error(
|
.protocol_error(
|
||||||
sender_id,
|
sender_id,
|
||||||
@@ -261,7 +237,7 @@ impl XdgSurface for Surface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now check if this is an XDG surface and set the sub-role
|
// Now check if this is an XDG surface and set the sub-role
|
||||||
match wl_surface.role.get().unwrap() {
|
match self.wl_surface.role.get().unwrap() {
|
||||||
SurfaceRole::Xdg(role) => {
|
SurfaceRole::Xdg(role) => {
|
||||||
if role.get().is_some() {
|
if role.get().is_some() {
|
||||||
return client
|
return client
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use crate::{
|
|||||||
use mint::Vector2;
|
use mint::Vector2;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Weak;
|
|
||||||
pub use waynest::server::protocol::stable::xdg_shell::xdg_toplevel::*;
|
pub use waynest::server::protocol::stable::xdg_shell::xdg_toplevel::*;
|
||||||
use waynest::{
|
use waynest::{
|
||||||
server::{Client, Dispatcher, Result},
|
server::{Client, Dispatcher, Result},
|
||||||
@@ -58,8 +57,7 @@ impl Default for ToplevelData {
|
|||||||
#[derive(Debug, Dispatcher)]
|
#[derive(Debug, Dispatcher)]
|
||||||
pub struct Toplevel {
|
pub struct Toplevel {
|
||||||
pub id: ObjectId,
|
pub id: ObjectId,
|
||||||
wl_surface: Weak<Surface>,
|
xdg_surface: Arc<super::surface::Surface>,
|
||||||
xdg_surface: Weak<super::surface::Surface>,
|
|
||||||
pub mapped: Mutex<Option<MappedInner>>,
|
pub mapped: Mutex<Option<MappedInner>>,
|
||||||
data: Mutex<ToplevelData>,
|
data: Mutex<ToplevelData>,
|
||||||
}
|
}
|
||||||
@@ -73,18 +71,14 @@ impl Toplevel {
|
|||||||
|
|
||||||
Toplevel {
|
Toplevel {
|
||||||
id: object_id,
|
id: object_id,
|
||||||
wl_surface: Arc::downgrade(&wl_surface),
|
xdg_surface,
|
||||||
xdg_surface: Arc::downgrade(&xdg_surface),
|
|
||||||
mapped: Mutex::new(None),
|
mapped: Mutex::new(None),
|
||||||
data: Mutex::new(ToplevelData::default()),
|
data: Mutex::new(ToplevelData::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wl_surface(&self) -> Arc<Surface> {
|
pub fn wl_surface(&self) -> &Arc<Surface> {
|
||||||
// We can safely unwrap as the surface must exist for the lifetime of the toplevel
|
&self.xdg_surface.wl_surface
|
||||||
self.wl_surface
|
|
||||||
.upgrade()
|
|
||||||
.expect("Surface was dropped before toplevel")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn title(&self) -> Option<String> {
|
pub fn title(&self) -> Option<String> {
|
||||||
@@ -153,9 +147,7 @@ impl Toplevel {
|
|||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if let Some(xdg_surface) = self.xdg_surface.upgrade() {
|
self.xdg_surface.reconfigure(client).await?;
|
||||||
xdg_surface.reconfigure(client).await?;
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,7 +261,8 @@ impl XdgToplevel for Toplevel {
|
|||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.wl_surface().pending_state().pending.min_size = if width == 0 && height == 0 {
|
self.xdg_surface.wl_surface.pending_state().pending.min_size = if width == 0 && height == 0
|
||||||
|
{
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some([width as u32, height as u32].into())
|
Some([width as u32, height as u32].into())
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use super::popup::Popup;
|
use super::popup::Popup;
|
||||||
use super::positioner::Positioner;
|
use super::positioner::Positioner;
|
||||||
use super::toplevel::Toplevel;
|
use super::toplevel::Toplevel;
|
||||||
use crate::wayland::xdg::surface::Surface;
|
use crate::wayland::{core::surface::SurfaceRole, xdg::surface::Surface};
|
||||||
use std::sync::Weak;
|
use std::sync::{OnceLock, Weak};
|
||||||
pub use waynest::server::protocol::stable::xdg_shell::xdg_wm_base::*;
|
pub use waynest::server::protocol::stable::xdg_shell::xdg_wm_base::*;
|
||||||
use waynest::{
|
use waynest::{
|
||||||
server::{Client, Dispatcher, Result},
|
server::{Client, Dispatcher, Result},
|
||||||
@@ -46,6 +46,7 @@ impl XdgWmBase for WmBase {
|
|||||||
.ok_or(waynest::server::Error::Custom(
|
.ok_or(waynest::server::Error::Custom(
|
||||||
"can't get wayland surface id".to_string(),
|
"can't get wayland surface id".to_string(),
|
||||||
))?;
|
))?;
|
||||||
|
let _ = wl_surface.role.set(SurfaceRole::Xdg(OnceLock::new()));
|
||||||
let xdg_surface = Surface::new(xdg_surface_id, self.version, wl_surface);
|
let xdg_surface = Surface::new(xdg_surface_id, self.version, wl_surface);
|
||||||
client.insert(xdg_surface_id, xdg_surface);
|
client.insert(xdg_surface_id, xdg_surface);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user