From 27bfe2e3b9bfd8caf8533f0bb105588e975a3165 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 2 Nov 2024 12:00:16 +0300 Subject: [PATCH] session_lock: Change surface to Weak Fix the reference cycle. --- src/wayland/session_lock/lock.rs | 2 +- src/wayland/session_lock/surface.rs | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/wayland/session_lock/lock.rs b/src/wayland/session_lock/lock.rs index a589f8ccd9d9..7867e17e511b 100644 --- a/src/wayland/session_lock/lock.rs +++ b/src/wayland/session_lock/lock.rs @@ -79,7 +79,7 @@ where } let data = ExtLockSurfaceUserData { - surface: surface.clone(), + surface: surface.downgrade(), }; let lock_surface = data_init.init(id, data); diff --git a/src/wayland/session_lock/surface.rs b/src/wayland/session_lock/surface.rs index fc0f78d0b707..fb2c46d5e9cf 100644 --- a/src/wayland/session_lock/surface.rs +++ b/src/wayland/session_lock/surface.rs @@ -7,14 +7,17 @@ use crate::wayland::compositor; use _session_lock::ext_session_lock_surface_v1::{Error, ExtSessionLockSurfaceV1, Request}; use wayland_protocols::ext::session_lock::v1::server::{self as _session_lock, ext_session_lock_surface_v1}; use wayland_server::protocol::wl_surface::WlSurface; -use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource}; +use wayland_server::{Client, DataInit, Dispatch, DisplayHandle, Resource, Weak}; use crate::wayland::session_lock::{SessionLockHandler, SessionLockManagerState}; /// User data for ext-session-lock surfaces. #[derive(Debug)] pub struct ExtLockSurfaceUserData { - pub(crate) surface: WlSurface, + // `LockSurfaceAttributes` stored in the surface `data_map` contains a + // `ExtSessionLockSurfaceV1`. So this reference needs to be weak to avoid a + // cycle. + pub(crate) surface: Weak, } impl Dispatch for SessionLockManagerState @@ -34,15 +37,19 @@ where ) { match request { Request::AckConfigure { serial } => { + let Ok(surface) = data.surface.upgrade() else { + return; + }; + // Find configure for this serial. let serial = Serial::from(serial); - let configure = compositor::with_states(&data.surface, |states| { + let configure = compositor::with_states(&surface, |states| { let surface_data = states.data_map.get::>(); surface_data.unwrap().lock().unwrap().ack_configure(serial) }); match configure { - Some(configure) => state.ack_configure(data.surface.clone(), configure), + Some(configure) => state.ack_configure(surface.clone(), configure), None => lock_surface.post_error( Error::InvalidSerial, format!("wrong configure serial: {}", ::from(serial)),