diff options
Diffstat (limited to 'crates/wayland/src/udev')
| -rw-r--r-- | crates/wayland/src/udev/capture.rs | 5 | ||||
| -rw-r--r-- | crates/wayland/src/udev/platform.rs | 1 | ||||
| -rw-r--r-- | crates/wayland/src/udev/render.rs | 13 |
3 files changed, 19 insertions, 0 deletions
diff --git a/crates/wayland/src/udev/capture.rs b/crates/wayland/src/udev/capture.rs index a64a73c..287c003 100644 --- a/crates/wayland/src/udev/capture.rs +++ b/crates/wayland/src/udev/capture.rs @@ -69,6 +69,11 @@ impl CompState { let Some(udev) = self.udev.as_mut() else { return Err("no udev backend".to_string()) }; let mut elements: Vec<crate::elements::OverlayElement<PixmanRenderer>> = Vec::new(); for id in ids { + // Matches the render loops: a capture must not show a frame the + // screen does not (see `window_has_content`). + if !Self::has_content(&self.windows_shown_once, &self.id_to_window, id) { + continue; + } let Some(w) = self.id_to_window.get(&id) else { continue }; let Some(surface) = crate::input::dwindow_wl_surface(w) else { continue }; let Some(geom) = self.wm.borrow().window(id).map(|w| w.geometry) else { continue }; diff --git a/crates/wayland/src/udev/platform.rs b/crates/wayland/src/udev/platform.rs index 8dad7c3..86307dc 100644 --- a/crates/wayland/src/udev/platform.rs +++ b/crates/wayland/src/udev/platform.rs @@ -256,6 +256,7 @@ impl UdevPlatform { dead_layer_surfaces: HashSet::new(), hidden_layer_surfaces: HashMap::new(), layer_surfaces_shown_once: HashSet::new(), + windows_shown_once: HashSet::new(), decorations: HashMap::new(), border_top_decorations: HashMap::new(), border_bottom_decorations: HashMap::new(), diff --git a/crates/wayland/src/udev/render.rs b/crates/wayland/src/udev/render.rs index 9992b2c..c2899ae 100644 --- a/crates/wayland/src/udev/render.rs +++ b/crates/wayland/src/udev/render.rs @@ -303,6 +303,14 @@ impl CompState { let mut elements: Vec<crate::elements::OverlayElement<smithay::backend::renderer::gles::GlesRenderer>> = crate::cursor::render_elements(&cursor_status, &cursor_buffers, &mut gpu.renderer, udev.pointer_pos, origin, udev.heads[index].size); for &id in &ids { + // Nothing is drawn for a window that has never committed a + // buffer - otherwise its border, titlebar and shadow + // stand around empty desktop until the client paints, + // then jump when the placeholder size is replaced. See + // `window_has_content`. + if !Self::has_content(&self.windows_shown_once, &self.id_to_window, id) { + continue; + } let Some(w) = self.wm.borrow().window(id).cloned() else { continue }; let Some(dwindow) = self.id_to_window.get(&id) else { continue }; let Some(surface) = crate::elements::window_wl_surface(dwindow) else { continue }; @@ -541,6 +549,11 @@ impl CompState { // window is stacked in front. let mut occluders: Vec<srdwm_core::Rect> = Vec::with_capacity(ids.len()); for &id in &ids { + // See the GPU loop above: a window with no buffer yet has + // nothing for a frame to go around. + if !Self::has_content(&self.windows_shown_once, &self.id_to_window, id) { + continue; + } let Some(w) = self.wm.borrow().window(id).cloned() else { continue }; // `w.geometry` is the animation's *target*, not // necessarily where the window is actually drawn this |