From 9fd8dd9cec44d99bd7c4e7be5ccb40ae6e04862e Mon Sep 17 00:00:00 2001 From: Victor Brekenfeld Date: Sun, 7 Jun 2020 23:11:27 +0200 Subject: [PATCH] anvil: allow draw_windows to take optional output coordinates --- anvil/src/glium_drawer.rs | 10 +++++++++- anvil/src/udev.rs | 7 ++++++- anvil/src/window_map.rs | 4 ++-- anvil/src/winit.rs | 2 +- src/utils/rectangle.rs | 16 ++++++++++++++++ 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/anvil/src/glium_drawer.rs b/anvil/src/glium_drawer.rs index 49b7301..273502c 100644 --- a/anvil/src/glium_drawer.rs +++ b/anvil/src/glium_drawer.rs @@ -26,6 +26,7 @@ use smithay::{ calloop::LoopHandle, wayland_server::protocol::{wl_buffer, wl_surface}, }, + utils::Rectangle, wayland::{ compositor::{roles::Role, SubsurfaceRole, TraversalAction}, data_device::DnDIconRole, @@ -403,12 +404,19 @@ impl GliumDrawer { &self, frame: &mut Frame, window_map: &MyWindowMap, + output_rect: Option, compositor_token: MyCompositorToken, ) { // redraw the frame, in a simple but inneficient way { let screen_dimensions = self.borrow().get_framebuffer_dimensions(); - window_map.with_windows_from_bottom_to_top(|toplevel_surface, initial_place| { + window_map.with_windows_from_bottom_to_top(|toplevel_surface, initial_place, bounding_box| { + // skip windows that do not overlap with a given output + if let Some(output) = output_rect { + if !output.overlaps(bounding_box) { + return; + } + } if let Some(wl_surface) = toplevel_surface.get_surface() { // this surface is a root of a subsurface tree that needs to be drawn self.draw_surface_tree( diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index dad9b04..01007a5 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -601,7 +601,12 @@ impl DrmRenderer { let mut frame = drawer.draw(); frame.clear(None, Some((0.8, 0.8, 0.9, 1.0)), false, Some(1.0), None); // draw the surfaces - drawer.draw_windows(&mut frame, &*self.window_map.borrow(), self.compositor_token); + drawer.draw_windows( + &mut frame, + &*self.window_map.borrow(), + None, + self.compositor_token, + ); let (x, y) = *self.pointer_location.borrow(); // draw the dnd icon if applicable { diff --git a/anvil/src/window_map.rs b/anvil/src/window_map.rs index fdfdc19..9eeec69 100644 --- a/anvil/src/window_map.rs +++ b/anvil/src/window_map.rs @@ -248,10 +248,10 @@ where pub fn with_windows_from_bottom_to_top(&self, mut f: Func) where - Func: FnMut(&Kind, (i32, i32)), + Func: FnMut(&Kind, (i32, i32), &Rectangle), { for w in self.windows.iter().rev() { - f(&w.toplevel, w.location) + f(&w.toplevel, w.location, &w.bbox) } } diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index bd2d549..0e0f221 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -103,7 +103,7 @@ pub fn run_winit( frame.clear(None, Some((0.8, 0.8, 0.9, 1.0)), false, Some(1.0), None); // draw the windows - drawer.draw_windows(&mut frame, &*state.window_map.borrow(), state.ctoken); + drawer.draw_windows(&mut frame, &*state.window_map.borrow(), None, state.ctoken); let (x, y) = *state.pointer_location.borrow(); // draw the dnd icon if any diff --git a/src/utils/rectangle.rs b/src/utils/rectangle.rs index 5cd8357..575c565 100644 --- a/src/utils/rectangle.rs +++ b/src/utils/rectangle.rs @@ -17,4 +17,20 @@ impl Rectangle { let (x, y) = point; (x >= self.x) && (x < self.x + self.width) && (y >= self.y) && (y < self.y + self.height) } + + /// Checks whether a given rectangle overlaps with this one + pub fn overlaps(&self, other: &Rectangle) -> bool { + // if the rectangle is not outside of the other + // they must overlap + !( + // self is left of other + self.x + self.width < other.x + // self is right of other + || self.x > other.x + other.width + // self is above of other + || self.y + self.height < other.y + // self is below of other + || self.y > other.y + other.height + ) + } }