Remove LayerShell only once iced confirms surface destroyed

Prevents "NO VIEW" messages, and possible flicker to placeholder widget.
This commit is contained in:
Ian Douglas Scott 2025-01-16 14:50:45 -08:00
parent a428659ade
commit e3b65d4772

View file

@ -15,7 +15,7 @@ use cosmic::{
iced::{ iced::{
self, self,
clipboard::mime::AsMimeTypes, clipboard::mime::AsMimeTypes,
event::wayland::{Event as WaylandEvent, OutputEvent}, event::wayland::{Event as WaylandEvent, LayerEvent, OutputEvent},
keyboard::key::{Key, Named}, keyboard::key::{Key, Named},
Size, Subscription, Task, Size, Subscription, Task,
}, },
@ -177,6 +177,7 @@ struct Output {
height: i32, height: i32,
} }
#[derive(Debug)]
struct LayerSurface { struct LayerSurface {
output: wl_output::WlOutput, output: wl_output::WlOutput,
// for transitions, would need windows in more than one workspace? But don't capture all of // for transitions, would need windows in more than one workspace? But don't capture all of
@ -264,7 +265,6 @@ impl App {
.find(|(_id, surface)| &surface.output == output) .find(|(_id, surface)| &surface.output == output)
{ {
let id = *id; let id = *id;
self.layer_surfaces.remove(&id).unwrap();
destroy_layer_surface(id) destroy_layer_surface(id)
} else { } else {
Task::none() Task::none()
@ -303,10 +303,10 @@ impl App {
self.update_capture_filter(); self.update_capture_filter();
self.drag_surface = None; self.drag_surface = None;
Task::batch( Task::batch(
mem::take(&mut self.layer_surfaces) self.layer_surfaces
.into_keys() .keys()
.map(destroy_layer_surface) .copied()
.collect::<Vec<_>>(), .map(destroy_layer_surface),
) )
} }
@ -405,6 +405,11 @@ impl Application for App {
} }
} }
} }
WaylandEvent::Layer(LayerEvent::Done, _surface, id) => {
if self.layer_surfaces.remove(&id).is_none() {
log::error!("removing non-existant layer shell id {}?", id);
}
}
_ => {} _ => {}
}, },
Msg::Wayland(evt) => { Msg::Wayland(evt) => {
@ -640,7 +645,7 @@ impl Application for App {
if let Some(surface) = self.layer_surfaces.get(&id) { if let Some(surface) = self.layer_surfaces.get(&id) {
return view::layer_surface(self, surface); return view::layer_surface(self, surface);
} }
log::info!("NO VIEW"); log::error!("non-existant layer shell id {}?", id);
cosmic::widget::text("workspaces").into() cosmic::widget::text("workspaces").into()
} }