From f166df4d979162ae09b439c87cdc64f2b0981308 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Wed, 31 Jul 2024 17:34:00 +0200 Subject: Split crates/wayland/src/winit.rs (889 lines) into winit/ Pure reorganization, no behavior change - verified by diffing the function-name and struct-name sets before/after (both identical) plus a full cargo test pass. mod.rs keeps the module doc comment, imports, WaylandPlatform's struct definition, and TARGET_FRAME_TIME, plus mod declarations. The rest splits by concern: - connect.rs: connect(), the ~200-line setup/init function. - run.rs: accept_clients, pump_winit - the small per-poll pair. - render.rs: render_frame, the per-frame render loop (left as one intact ~330-line function, same reasoning as udev's render.rs: its structure is deliberate and already documented inline, not a target for further decomposition in a pure reorganization pass). - capture.rs: capture_offscreen, the screencopy path. - events.rs: handle_winit_event. - platform.rs: `impl Platform for WaylandPlatform`. No tests module existed in the original file, so none was split out. A handful of methods/functions (accept_clients, pump_winit, render_frame, capture_offscreen, handle_winit_event) went from private to pub(super): called across what are now sibling submodules, which Rust's privacy model doesn't let see each other's private items. --- crates/wayland/src/winit/capture.rs | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 crates/wayland/src/winit/capture.rs (limited to 'crates/wayland/src/winit/capture.rs') diff --git a/crates/wayland/src/winit/capture.rs b/crates/wayland/src/winit/capture.rs new file mode 100644 index 0000000..a96cff9 --- /dev/null +++ b/crates/wayland/src/winit/capture.rs @@ -0,0 +1,60 @@ +use super::*; + +impl WaylandPlatform { + + /// Re-renders the current scene into an offscreen GLES renderbuffer and + /// serves the queued screencopy captures from it. See the call site for + /// why capture cannot read the window surface directly. + pub(super) fn capture_offscreen(&mut self, captures: Vec) -> PlatformResult<()> { + use smithay::backend::renderer::{Bind, Offscreen}; + + let size = self.output.current_mode().map(|m| m.size).unwrap_or_default(); + if size.w <= 0 || size.h <= 0 { + return Ok(()); + } + let renderer = self.backend.renderer(); + let mut target: smithay::backend::renderer::gles::GlesRenderbuffer = + renderer.create_buffer(Fourcc::Abgr8888, (size.w, size.h).into()).map_err(err)?; + let mut framebuffer = renderer.bind(&mut target).map_err(err)?; + + // Not full parity with the on-screen render loop above (no border/ + // shadow strips here, same as before this function's content/opacity + // fix) - a real, pre-existing gap in what a screenshot shows on + // this backend, flagged rather than grown further in this pass. + // Content (with each window's own `opacity`, unlike the + // `self.state.space`-based single-alpha call this replaced) and the + // bar/dock now render into the capture, at least: a screenshot used + // to only ever show titlebars for windows that had one, and never + // any layer-shell surface at all. + let hide_top_layers = self.wm.borrow().visible_windows_front_to_back().any(|w| w.fullscreen); + let mut custom_elements: Vec> = Vec::new(); + if !hide_top_layers { + custom_elements.extend(crate::elements::output_layer_elements(renderer, &self.output, (0, 0), |layer| matches!(layer, Layer::Top | Layer::Overlay))); + } + for id in self.wm.borrow().visible_windows_front_to_back().map(|w| w.id).collect::>() { + let Some(w) = self.wm.borrow().window(id).cloned() else { continue }; + if let Some(deco) = self.state.decorations.get(&id) { + if let Ok(elem) = MemoryRenderBufferRenderElement::from_buffer(renderer, (w.geometry.x as f64, w.geometry.y as f64), deco, None, None, None, Kind::Unspecified) { + custom_elements.push(crate::elements::OverlayElement::Memory(elem)); + } + } + if let Some(dwindow) = self.state.id_to_window.get(&id) { + if let Some(surface) = crate::elements::window_wl_surface(dwindow) { + let band = if w.decorated { srdwm_core::TITLEBAR_HEIGHT as i32 } else { 0 }; + custom_elements.extend(crate::elements::surface_content_elements(renderer, &surface, (w.geometry.x, w.geometry.y + band), w.opacity)); + } + } + } + custom_elements.extend(crate::elements::output_layer_elements(renderer, &self.output, (0, 0), |layer| matches!(layer, Layer::Background | Layer::Bottom))); + + // A throwaway damage tracker, so this pass always draws the whole + // scene (age 0) and never perturbs the on-screen tracker's history. + let mut tracker = OutputDamageTracker::from_output(&self.output); + tracker + .render_output(renderer, &mut framebuffer, 0, &custom_elements, [0.05, 0.05, 0.08, 1.0]) + .map_err(err)?; + + screencopy::service_pending(captures, renderer, &framebuffer); + Ok(()) + } +} -- cgit v1.2.3