window: cache bbox

This commit is contained in:
Victor Brekenfeld 2021-12-17 12:59:11 +01:00
parent d84a66e053
commit a20fd0c65d
2 changed files with 33 additions and 2 deletions

View File

@ -4,7 +4,10 @@ use crate::{
desktop::{layer::*, output::*},
utils::{Logical, Point, Rectangle},
wayland::{
compositor::{with_surface_tree_downward, SubsurfaceCachedState, TraversalAction},
compositor::{
get_parent, is_sync_subsurface, with_surface_tree_downward, SubsurfaceCachedState,
TraversalAction,
},
output::Output,
shell::wlr_layer::Layer as WlrLayer,
},
@ -396,6 +399,21 @@ impl Space {
}
}
/// Automatically calls `Window::refresh` for the window that belongs to the given surface,
/// if managed by this space.
pub fn commit(&mut self, surface: &WlSurface) {
if is_sync_subsurface(surface) {
return;
}
let mut root = surface.clone();
while let Some(parent) = get_parent(&root) {
root = parent;
}
if let Some(window) = self.windows().find(|w| w.toplevel().get_surface() == Some(&root)) {
window.refresh();
}
}
pub fn render_output<R>(
&mut self,
renderer: &mut R,

View File

@ -9,6 +9,7 @@ use crate::{
},
};
use std::{
cell::Cell,
collections::HashSet,
hash::{Hash, Hasher},
rc::Rc,
@ -99,6 +100,7 @@ impl Kind {
pub(super) struct WindowInner {
pub(super) id: usize,
toplevel: Kind,
bbox: Cell<Rectangle<i32, Logical>>,
user_data: UserDataMap,
}
@ -135,6 +137,7 @@ impl Window {
Window(Rc::new(WindowInner {
id,
toplevel,
bbox: Cell::new(Rectangle::from_loc_and_size((0, 0), (0, 0))),
user_data: UserDataMap::new(),
}))
}
@ -153,7 +156,7 @@ impl Window {
// TODO: Cache and document when to trigger updates. If possible let space do it
pub fn bbox(&self) -> Rectangle<i32, Logical> {
if let Some(surface) = self.0.toplevel.get_surface() {
bbox_from_surface_tree(surface, (0, 0))
self.0.bbox.get()
} else {
Rectangle::from_loc_and_size((0, 0), (0, 0))
}
@ -219,6 +222,16 @@ impl Window {
}
}
/// Updates internal values
///
/// Needs to be called whenever the toplevel surface or any unsynchronized subsurfaces of this window are updated
/// to correctly update the bounding box of this window.
pub fn refresh(&self) {
if let Some(surface) = self.0.toplevel.get_surface() {
self.0.bbox.set(bbox_from_surface_tree(surface, (0, 0)));
}
}
/// Finds the topmost surface under this point if any and returns it together with the location of this
/// surface.
pub fn surface_under<P: Into<Point<f64, Logical>>>(