diff options
| author | srdusr <[email protected]> | 2024-12-24 20:44:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2024-12-24 20:44:00 +0200 |
| commit | 3d73ed0f057a555ded67ad58dbe02b36cd4d2d1f (patch) | |
| tree | 71e9bab462b9073444183e2a969ba512cb94559f /crates/wayland/src/winit/render.rs | |
| parent | 331a1a1d3a0d8dfd4c285b755c2e13785c95ee2a (diff) | |
| download | srdwm-3d73ed0f057a555ded67ad58dbe02b36cd4d2d1f.tar.gz srdwm-3d73ed0f057a555ded67ad58dbe02b36cd4d2d1f.zip | |
Accumulate wayland-crate additions: capture rendering, focus/Space sync, VT resume, plumbing
Bundles the remaining wayland-crate changes built up here,
touching both backends (udev and winit) and the shared input/rendering
code:
- udev/capture.rs: off-screen Pixman render of an arbitrary (not
necessarily on-screen) workspace's window content to a PPM file --
what crates/core's capture-request queue drives, for a workspace
switcher's thumbnail previews. wlr-screencopy structurally can't do
this (it can only see what an output is presenting), which is why
this exists as a separate render path rather than reusing it.
- input::focus_window now also raises the window in smithay's own
Space, not just core's stacking order - Space is what actually
renders on top and what pointer hit-testing reads, so any focus path
that skipped this (an IPC "focus" dispatch, concretely) left a
window genuinely focused while still rendering, and receiving
clicks, underneath whatever was already topmost. Both backends'
poll loops now re-sync this after any IPC mutation.
- udev/session.rs's VT-switch resume fix (drains a stale pending page
flip before reasserting CRTCs) already has its own earlier, cleanly
isolated commit - not duplicated here.
- Assorted decoration/cursor/rounded-corners/output-management/
screencopy/XWayland changes and their cross-backend wiring.
Coarser than the repo's usual one-purpose-per-commit convention,
deliberately - see the core-crate sweep commit's own message for why.
Diffstat (limited to 'crates/wayland/src/winit/render.rs')
| -rw-r--r-- | crates/wayland/src/winit/render.rs | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/crates/wayland/src/winit/render.rs b/crates/wayland/src/winit/render.rs index 3ab3354..735ff34 100644 --- a/crates/wayland/src/winit/render.rs +++ b/crates/wayland/src/winit/render.rs @@ -22,8 +22,22 @@ impl WaylandPlatform { let age = self.backend.buffer_age().unwrap_or(0); let (renderer, mut framebuffer) = self.backend.bind().map_err(err)?; - // Locked: the lock surface over an opaque black clear, and nothing - // else - no windows, no decorations, no layer surfaces. + // Locked: srdwm's own native lock UI, or an external locker's + // surface, over an opaque black clear - nothing else, no windows, + // no decorations, no layer surfaces, either way. + if self.state.lock.locked && self.state.lock.native.is_some() { + let name = self.output.name(); + let bg = self.state.native_lock_background(&name).cloned(); + let ui = self.state.native_lock_ui().map(|(buf, s)| (buf.clone(), s)); + let elements = crate::native_lock::native_lock_render_elements(bg.as_ref(), ui.as_ref().map(|(b, s)| (b, *s)), (size.w, size.h), renderer); + self.damage_tracker + .render_output(renderer, &mut framebuffer, age, &elements, [0.0, 0.0, 0.0, 1.0]) + .map_err(err)?; + drop(framebuffer); + self.backend.submit(None).map_err(err)?; + screencopy::fail_pending(std::mem::take(&mut self.state.screencopy_pending)); + return Ok(()); + } if self.state.lock.locked { let lock_surface = self.state.lock_surface_for(&self.output).cloned(); let elements = lock_render_elements(lock_surface.as_ref(), renderer); @@ -58,6 +72,14 @@ impl WaylandPlatform { Err(e) => log::warn!("failed to import context menu buffer: {e}"), } } + // The Snap-Layouts flyout, if open - same topmost placement. + if let (Some(flyout), Some(buffer)) = (self.state.snap_flyout.as_ref(), self.state.snap_flyout_buffer.as_ref()) { + let pos = (flyout.pos.0 as f64, flyout.pos.1 as f64); + match MemoryRenderBufferRenderElement::from_buffer(renderer, pos, buffer, None, None, None, Kind::Unspecified) { + Ok(elem) => custom_elements.push(crate::rounded_corners::WinitElement::Base(crate::elements::OverlayElement::Memory(elem))), + Err(e) => log::warn!("failed to import snap flyout buffer: {e}"), + } + } // Content now renders here too, one window at a time, not through // `render_output`'s own `spaces` argument - see this function's // own call to `damage_tracker.render_output` further down for why, @@ -228,7 +250,7 @@ impl WaylandPlatform { let pos = (geom.x, geom.y + band); let rounded = rounded_corners_enabled.then_some(self.state.rounded_corners_program.as_ref()).flatten().and_then(|program| { let corners = if w.decorated { crate::rounded_corners::RoundedCorners::BOTTOM_ONLY } else { crate::rounded_corners::RoundedCorners::ALL }; - crate::rounded_corners::rounded_content_element(renderer, program, &surface, pos, w.opacity, crate::decoration::CORNER_RADIUS as f32, corners) + crate::rounded_corners::rounded_content_element(renderer, program, &surface, pos, w.opacity, w.corner_radius as f32, corners) }); match rounded { Some(elem) => custom_elements.push(crate::rounded_corners::WinitElement::Rounded(elem)), @@ -257,6 +279,22 @@ impl WaylandPlatform { .map_err(err)?; let damage_rects: Vec<Rectangle<i32, Physical>> = result.damage.cloned().unwrap_or_default(); let has_damage = !damage_rects.is_empty(); + // A native lock is waiting on this output's background - same + // capture hook as `udev/render.rs`'s matching point, exercised + // here too so a native lock can be tested against this nested dev + // session without ever touching the live tty1 one. `self.state. + // lock.locked` is still `false` at this point (`begin_native_lock` + // doesn't flip it until every output has a background - see its + // own doc comment), so the frame just rendered into `framebuffer` + // is the ordinary desktop scene, not a lock scene. + if self.state.native_lock_needs_capture(&self.output.name()) { + let name = self.output.name(); + let blur_radius = self.state.wm.borrow().lock.blur_radius; + match crate::native_lock::capture_and_blur(renderer, &framebuffer, size.into(), blur_radius) { + Ok(blurred) => self.state.capture_output(&name, blurred), + Err(e) => log::warn!("native lock: capture failed for output {name}: {e}"), + } + } drop(framebuffer); // Both the buffer swap and the frame-callback notification are // conditional on real damage now - this used to run |