window: cache bbox
This commit is contained in:
parent
d84a66e053
commit
a20fd0c65d
|
@ -4,7 +4,10 @@ use crate::{
|
||||||
desktop::{layer::*, output::*},
|
desktop::{layer::*, output::*},
|
||||||
utils::{Logical, Point, Rectangle},
|
utils::{Logical, Point, Rectangle},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{with_surface_tree_downward, SubsurfaceCachedState, TraversalAction},
|
compositor::{
|
||||||
|
get_parent, is_sync_subsurface, with_surface_tree_downward, SubsurfaceCachedState,
|
||||||
|
TraversalAction,
|
||||||
|
},
|
||||||
output::Output,
|
output::Output,
|
||||||
shell::wlr_layer::Layer as WlrLayer,
|
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>(
|
pub fn render_output<R>(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
cell::Cell,
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
@ -99,6 +100,7 @@ impl Kind {
|
||||||
pub(super) struct WindowInner {
|
pub(super) struct WindowInner {
|
||||||
pub(super) id: usize,
|
pub(super) id: usize,
|
||||||
toplevel: Kind,
|
toplevel: Kind,
|
||||||
|
bbox: Cell<Rectangle<i32, Logical>>,
|
||||||
user_data: UserDataMap,
|
user_data: UserDataMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +137,7 @@ impl Window {
|
||||||
Window(Rc::new(WindowInner {
|
Window(Rc::new(WindowInner {
|
||||||
id,
|
id,
|
||||||
toplevel,
|
toplevel,
|
||||||
|
bbox: Cell::new(Rectangle::from_loc_and_size((0, 0), (0, 0))),
|
||||||
user_data: UserDataMap::new(),
|
user_data: UserDataMap::new(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -153,7 +156,7 @@ impl Window {
|
||||||
// TODO: Cache and document when to trigger updates. If possible let space do it
|
// TODO: Cache and document when to trigger updates. If possible let space do it
|
||||||
pub fn bbox(&self) -> Rectangle<i32, Logical> {
|
pub fn bbox(&self) -> Rectangle<i32, Logical> {
|
||||||
if let Some(surface) = self.0.toplevel.get_surface() {
|
if let Some(surface) = self.0.toplevel.get_surface() {
|
||||||
bbox_from_surface_tree(surface, (0, 0))
|
self.0.bbox.get()
|
||||||
} else {
|
} else {
|
||||||
Rectangle::from_loc_and_size((0, 0), (0, 0))
|
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
|
/// Finds the topmost surface under this point if any and returns it together with the location of this
|
||||||
/// surface.
|
/// surface.
|
||||||
pub fn surface_under<P: Into<Point<f64, Logical>>>(
|
pub fn surface_under<P: Into<Point<f64, Logical>>>(
|
||||||
|
|
Loading…
Reference in New Issue