diff --git a/src/backend.rs b/src/backend.rs index bfed7dc2..0a41c053 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -24,6 +24,9 @@ linear_ids!(DrmDeviceIds, DrmDeviceId); pub trait Backend { fn run(self: Rc) -> SpawnedFuture>>; + fn clear(&self) { + // nothing + } #[cfg_attr(not(feature = "it"), allow(dead_code))] fn into_any(self: Rc) -> Rc; diff --git a/src/backends/metal.rs b/src/backends/metal.rs index fb76db20..9d562e35 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -9,7 +9,9 @@ use { Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, TransformMatrix, }, - backends::metal::video::{MetalDrmDeviceData, MetalRenderContext, PendingDrmDevice}, + backends::metal::video::{ + MetalDrmDeviceData, MetalLeaseData, MetalRenderContext, PendingDrmDevice, + }, dbus::{DbusError, SignalHandler}, drm_feedback::DrmFeedback, gfx_api::GfxError, @@ -165,6 +167,53 @@ impl Backend for MetalBackend { }) } + fn clear(&self) { + self.pause_handler.take(); + self.resume_handler.take(); + self.ctx.take(); + self.device_holder.devices.clear(); + for dev in self.device_holder.input_devices.take() { + if let Some(dev) = dev { + dev.inputdev.take(); + dev.events.take(); + dev.cb.take(); + } + } + for (_, dev) in self.device_holder.drm_devices.lock().drain() { + dev.futures.clear(); + for crtc in dev.dev.crtcs.values() { + crtc.connector.take(); + } + dev.dev.handle_events.handle_events.take(); + dev.dev.on_change.clear(); + let clear_lease = |lease: &mut MetalLeaseData| { + lease.connectors.clear(); + lease.crtcs.clear(); + lease.planes.clear(); + }; + for (_, mut lease) in dev.dev.leases.lock().drain() { + clear_lease(&mut lease); + } + for (_, mut lease) in dev.dev.leases_to_break.lock().drain() { + clear_lease(&mut lease); + } + for (_, connector) in dev.connectors.lock().drain() { + { + let d = &mut *connector.display.borrow_mut(); + d.crtcs.clear(); + } + connector.primary_plane.take(); + connector.cursor_plane.take(); + connector.crtc.take(); + connector.on_change.clear(); + connector.present_trigger.clear(); + connector.render_result.take(); + connector.active_framebuffer.take(); + connector.next_framebuffer.take(); + } + } + } + fn into_any(self: Rc) -> Rc { self } diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index 7fc0531a..4e229d1d 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -323,12 +323,12 @@ impl ConnectorDisplayData { linear_ids!(MetalLeaseIds, MetalLeaseId, u64); pub struct MetalLeaseData { - lease: DrmLease, - _lessee: Rc, - connectors: Vec>, - crtcs: Vec>, - planes: Vec>, - revoked: Cell, + pub lease: DrmLease, + pub _lessee: Rc, + pub connectors: Vec>, + pub crtcs: Vec>, + pub planes: Vec>, + pub revoked: Cell, } impl MetalLeaseData { diff --git a/src/main.rs b/src/main.rs index 9047758a..d3b54551 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,8 @@ clippy::uninlined_format_args, clippy::manual_is_ascii_check, clippy::needless_borrow, - clippy::unnecessary_cast + clippy::unnecessary_cast, + clippy::manual_flatten )] #[macro_use] diff --git a/src/state.rs b/src/state.rs index 48cc9e16..628440cb 100644 --- a/src/state.rs +++ b/src/state.rs @@ -722,7 +722,7 @@ impl State { forker.clear(); } self.acceptor.set(None); - self.backend.set(Rc::new(DummyBackend)); + self.backend.set(Rc::new(DummyBackend)).clear(); self.run_toplevel.clear(); self.xwayland.handler.borrow_mut().take(); self.xwayland.queue.clear(); @@ -730,6 +730,7 @@ impl State { self.idle.change.clear(); for (_, drm_dev) in self.drm_devs.lock().drain() { drm_dev.handler.take(); + drm_dev.connectors.clear(); } for (_, connector) in self.connectors.lock().drain() { connector.handler.take(); diff --git a/src/utils/on_change.rs b/src/utils/on_change.rs index feb94408..e0427a7b 100644 --- a/src/utils/on_change.rs +++ b/src/utils/on_change.rs @@ -12,6 +12,11 @@ pub struct OnChange { } impl OnChange { + pub fn clear(&self) { + self.on_change.take(); + self.events.take(); + } + pub fn send_event(&self, event: T) { self.events.push(event); if let Some(cb) = self.on_change.get() { diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index 2a25e45e..82fdef48 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -264,7 +264,15 @@ impl Drop for Wm { if let Some(window) = window.window.take() { window.break_loops(); } + window.children.clear(); + window.parent.take(); + window.stack_link.take(); + window.map_link.take(); } + self.windows_by_surface_id.clear(); + self.windows_by_surface_serial.clear(); + self.focus_window.take(); + self.known_seats.clear(); } }