srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/rounded_corners_pixman.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2024-12-24 20:44:00 +0200
committersrdusr <[email protected]>2024-12-24 20:44:00 +0200
commit3d73ed0f057a555ded67ad58dbe02b36cd4d2d1f (patch)
tree71e9bab462b9073444183e2a969ba512cb94559f /crates/wayland/src/rounded_corners_pixman.rs
parent331a1a1d3a0d8dfd4c285b755c2e13785c95ee2a (diff)
downloadsrdwm-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/rounded_corners_pixman.rs')
-rw-r--r--crates/wayland/src/rounded_corners_pixman.rs16
1 files changed, 16 insertions, 0 deletions
diff --git a/crates/wayland/src/rounded_corners_pixman.rs b/crates/wayland/src/rounded_corners_pixman.rs
index 1aaa5bc..1879b9e 100644
--- a/crates/wayland/src/rounded_corners_pixman.rs
+++ b/crates/wayland/src/rounded_corners_pixman.rs
@@ -49,6 +49,7 @@ use smithay::backend::renderer::utils::{with_renderer_surface_state, RendererSur
use smithay::reexports::wayland_server::protocol::wl_shm;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::Transform;
+use smithay::wayland::compositor::get_children;
use smithay::wayland::shm::{with_buffer_contents, BufferData};
/// Builds a rounded-corner-masked copy of `surface`'s own committed content,
@@ -57,6 +58,21 @@ use smithay::wayland::shm::{with_buffer_contents, BufferData};
/// in the same logical-pixel units as `decoration::CORNER_RADIUS`; scaled
/// up to buffer pixels internally using the surface's own buffer scale.
pub(crate) fn masked_content_buffer(surface: &WlSurface, radius: f32, corners: RoundedCorners) -> Option<MemoryRenderBuffer> {
+ // The module doc comment above has always claimed "only a window's main
+ // surface (no subsurfaces)... falls back to None" - but nothing here
+ // actually checked that; this function read `surface`'s own buffer
+ // unconditionally regardless of whether it had children. A window whose
+ // real content is painted into a subsurface (a common GTK4/WebRender
+ // pattern - confirmed live: Firefox does this) has its own root
+ // surface holding only a blank/background buffer, so masking succeeded
+ // and produced a buffer, just the wrong one - the actual page content
+ // in the child subsurface was never read at all, and the window
+ // rendered as blank with rounded corners on instead of falling back to
+ // the unmasked path (`surface_content_elements`), which does walk the
+ // full surface tree and shows real content correctly.
+ if !get_children(surface).is_empty() {
+ return None;
+ }
let (buffer, scale, transform) = with_renderer_surface_state(surface, |state: &mut RendererSurfaceState| {
let buffer = state.buffer()?.clone();
Some((buffer, state.buffer_scale(), state.buffer_transform()))