From d5bfc6f613e3bdeddb93b1d44468b3d110e35ed5 Mon Sep 17 00:00:00 2001 From: Poly Date: Sun, 16 Jan 2022 21:15:21 +0100 Subject: [PATCH] desktop.space: Fix multioutput rendering --- src/desktop/space/element.rs | 1 + src/desktop/space/mod.rs | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/desktop/space/element.rs b/src/desktop/space/element.rs index ac013c9..d162060 100644 --- a/src/desktop/space/element.rs +++ b/src/desktop/space/element.rs @@ -28,6 +28,7 @@ where /// Returns the bounding box of this element including its position in the space. fn geometry(&self) -> Rectangle; /// Returns the damage of the element since it's last update. + /// It should be relative to the elements coordinates. /// /// If you receive `Some(_)` for `for_values` you may cache that you /// send the damage for this `Space` and `Output` combination once diff --git a/src/desktop/space/mod.rs b/src/desktop/space/mod.rs index 56b1119..ed45ad9 100644 --- a/src/desktop/space/mod.rs +++ b/src/desktop/space/mod.rs @@ -454,7 +454,8 @@ impl Space { /// trait and use `custom_elements` to provide them to this function. `custom_elements are rendered /// after every other element. /// - /// Returns a list of updated regions (or `None` if that list would be empty) in case of success. + /// Returns a list of updated regions relative to the rendered output + /// (or `None` if that list would be empty) in case of success. pub fn render_output( &mut self, renderer: &mut R, @@ -603,6 +604,9 @@ impl Space { clear_color, &damage .iter() + // Map from global space to output space + .map(|geo| Rectangle::from_loc_and_size(geo.loc - output_geo.loc, geo.size)) + // Map from logical to physical .map(|geo| geo.to_f64().to_physical(state.render_scale).to_i32_round()) .collect::>(), )?; @@ -624,16 +628,17 @@ impl Space { { let geo = element.geometry(self.id); if damage.iter().any(|d| d.overlaps(geo)) { - let loc = element.location(self.id) - output_geo.loc; + let loc = element.location(self.id); let damage = damage .iter() .flat_map(|d| d.intersection(geo)) + // Map from output space to surface-relative coordinates .map(|geo| Rectangle::from_loc_and_size(geo.loc - loc, geo.size)) .collect::>(); slog::trace!( self.logger, "Rendering toplevel at {:?} with damage {:#?}", - geo, + Rectangle::from_loc_and_size(geo.loc - output_geo.loc, geo.size), damage ); element.draw( @@ -641,7 +646,7 @@ impl Space { renderer, frame, state.render_scale, - loc, + loc - output_geo.loc, &damage, &self.logger, )?; @@ -676,7 +681,15 @@ impl Space { .collect(); state.old_damage.push_front(new_damage.clone()); - Ok(Some(new_damage)) + Ok(Some( + new_damage + .into_iter() + .map(|mut geo| { + geo.loc -= output_geo.loc; + geo + }) + .collect(), + )) } /// Sends the frame callback to mapped [`Window`]s and [`LayerSurface`]s.