From c3cd0e1680edf7014f25168e4e79a3d98aac0015 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Sat, 10 Feb 2024 14:45:47 +0100 Subject: [PATCH] Fix subsurfaces not receiving position updates This fixes an issue where subsurfaces would always stay at their original location regardless of `wl_subsurface::set_position` calls. This was caused by the subsurface's texture being loaded from cache with its original location. To ensure the subsurface position is correct, the texture's location is now always updated after loading it from the cache. Closes #145. --- src/drawing.rs | 13 ++++++++++--- src/windows/window.rs | 4 ++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/drawing.rs b/src/drawing.rs index 0ce393a..29fc9c7 100644 --- a/src/drawing.rs +++ b/src/drawing.rs @@ -1,5 +1,6 @@ //! Drawing utilities. +use std::cell::Cell; use std::ops::Deref; use std::rc::Rc; @@ -54,7 +55,7 @@ const GESTURE_HANDLE_BLOCKED_RGBA: [u8; 3] = [117, 42, 42]; pub struct Texture { opaque_regions: Vec>, tracker: DamageSnapshot, - location: Point, + location: Cell>, src_rect: Rectangle, dst_size: Size, buffer_size: Size, @@ -118,10 +119,10 @@ impl Texture { Self { opaque_regions, window_scale, - location, texture, tracker: buffer.damage.tracker.snapshot(), buffer_size: buffer.buffer_size, + location: Cell::new(location), buffer: buffer.buffer.clone(), transform: buffer.transform, scale: buffer.scale as f64, @@ -146,6 +147,11 @@ impl Texture { Texture::new(texture, logical_size, scale, opaque) } + /// Move texture to a different location. + pub fn set_location(&self, location: Point) { + self.location.replace(location); + } + /// Target size after rendering. pub fn size(&self) -> Size { self.dst_size @@ -185,7 +191,8 @@ impl Element for RenderTexture { fn geometry(&self, scale: Scale) -> Rectangle { let scale = self.window_scale.map_or(scale.x, |window_scale| window_scale.scale(scale.x)); - Rectangle::from_loc_and_size(self.location, self.dst_size).to_physical_precise_round(scale) + Rectangle::from_loc_and_size(self.location.get(), self.dst_size) + .to_physical_precise_round(scale) } fn damage_since( diff --git a/src/windows/window.rs b/src/windows/window.rs index b3e10e8..a9937f3 100644 --- a/src/windows/window.rs +++ b/src/windows/window.rs @@ -275,7 +275,11 @@ impl Window { // Skip surface if buffer was already imported. if let Some(texture) = &data.texture { + // Ensure texture's location is up to date. + texture.set_location(location); + self.texture_cache.push(texture.clone(), location); + return TraversalAction::DoChildren(location); }