refactor(wayland): weak references to objects in roles

This commit is contained in:
Nova
2025-09-06 15:19:37 -07:00
parent 053d468035
commit 4641f4f724
2 changed files with 38 additions and 8 deletions

View File

@@ -101,7 +101,7 @@ impl XdgSurface for Surface {
} }
if role if role
.set(XdgSurfaceRole::Toplevel(toplevel.clone())) .set(XdgSurfaceRole::Toplevel(Arc::downgrade(&toplevel)))
.is_err() .is_err()
{ {
return client return client
@@ -140,6 +140,9 @@ impl XdgSurface for Surface {
let Some(XdgSurfaceRole::Toplevel(toplevel)) = role.get() else { let Some(XdgSurfaceRole::Toplevel(toplevel)) = role.get() else {
return true; return true;
}; };
let Some(toplevel) = toplevel.upgrade() else {
return true;
};
// Only proceed if configured and has valid buffer // Only proceed if configured and has valid buffer
let has_valid_buffer = state let has_valid_buffer = state
@@ -184,10 +187,34 @@ impl XdgSurface for Surface {
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) => {
let toplevel_lock = toplevel.mapped.lock(); if let Some(toplevel) = toplevel.upgrade() {
toplevel_lock.as_ref().unwrap()._panel_item.clone() let toplevel_lock = toplevel.mapped.lock();
toplevel_lock.as_ref().unwrap()._panel_item.clone()
} else {
return client
.protocol_error(
sender_id,
popup_id,
3, // INVALID_POPUP_PARENT
"Parent surface does not have an XDG role".to_string(),
)
.await;
}
}
XdgSurfaceRole::Popup(popup) => {
if let Some(popup) = popup.upgrade() {
popup.panel_item.upgrade().unwrap()
} else {
return client
.protocol_error(
sender_id,
popup_id,
3, // INVALID_POPUP_PARENT
"Parent surface does not have an XDG role".to_string(),
)
.await;
}
} }
XdgSurfaceRole::Popup(popup) => popup.panel_item.upgrade().unwrap(),
}, },
_ => { _ => {
return client return client
@@ -247,7 +274,10 @@ impl XdgSurface for Surface {
.await; .await;
} }
if role.set(XdgSurfaceRole::Popup(popup.clone())).is_err() { if role
.set(XdgSurfaceRole::Popup(Arc::downgrade(&popup)))
.is_err()
{
return client return client
.protocol_error( .protocol_error(
sender_id, sender_id,

View File

@@ -2,7 +2,7 @@ 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::xdg::surface::Surface;
use std::sync::Arc; use std::sync::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},
@@ -11,8 +11,8 @@ use waynest::{
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum XdgSurfaceRole { pub enum XdgSurfaceRole {
Toplevel(Arc<Toplevel>), Toplevel(Weak<Toplevel>),
Popup(Arc<Popup>), Popup(Weak<Popup>),
} }
#[derive(Debug, Dispatcher, Default)] #[derive(Debug, Dispatcher, Default)]