aboutsummaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-05-03 13:46:33 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-05-03 13:46:33 +0400
commit85680a57dac965973644e9e96159716c0608bb57 (patch)
tree83f1f1c84a1140e194284a7d881aa3b42e1f2a0f /src/layout
parent1a8d6b1f1df80009795ed23e9ce0298fac65d766 (diff)
downloadniri-85680a57dac965973644e9e96159716c0608bb57.tar.gz
niri-85680a57dac965973644e9e96159716c0608bb57.tar.bz2
niri-85680a57dac965973644e9e96159716c0608bb57.zip
Reduce unnecessary damage to borders
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/focus_ring.rs57
1 files changed, 44 insertions, 13 deletions
diff --git a/src/layout/focus_ring.rs b/src/layout/focus_ring.rs
index d52bb08e..38e4a7ab 100644
--- a/src/layout/focus_ring.rs
+++ b/src/layout/focus_ring.rs
@@ -1,3 +1,4 @@
+use std::cell::RefCell;
use std::cmp::{max, min};
use std::iter::zip;
@@ -16,6 +17,7 @@ pub struct FocusRing {
buffers: [SolidColorBuffer; 8],
locations: [Point<i32, Logical>; 8],
sizes: [Size<i32, Logical>; 8],
+ borders: RefCell<Option<[BorderRenderElement; 8]>>,
full_size: Size<i32, Logical>,
is_active: bool,
is_border: bool,
@@ -36,6 +38,7 @@ impl FocusRing {
buffers: Default::default(),
locations: Default::default(),
sizes: Default::default(),
+ borders: Default::default(),
full_size: Default::default(),
is_active: false,
is_border: false,
@@ -179,15 +182,40 @@ impl FocusRing {
};
let shader = BorderRenderElement::shader(renderer);
- let mut push = |buffer, location: Point<i32, Logical>, size: Size<i32, Logical>| {
+ let mut borders = self.borders.borrow_mut();
+
+ // Initialize the border render elements.
+ if let Some(shader) = shader {
+ if let Some(borders) = &mut *borders {
+ for elem in borders {
+ elem.update_shader(shader);
+ }
+ } else {
+ *borders = Some([(); 8].map(|()| BorderRenderElement::empty(shader.clone())));
+ }
+ }
+
+ let mut borders = if let Some(borders) = &mut *borders {
+ let a = Some(borders.iter_mut().map(Some));
+ let b = None;
+ a.into_iter().flatten().chain(b.into_iter().flatten())
+ } else {
+ let a = None;
+ let b = Some([None, None, None, None, None, None, None, None].into_iter());
+ a.into_iter().flatten().chain(b.into_iter().flatten())
+ };
+
+ let mut push = |buffer,
+ border: Option<&mut BorderRenderElement>,
+ location: Point<i32, Logical>,
+ size: Size<i32, Logical>| {
let elem = if let Some(gradient) = gradient {
let gradient_area = match gradient.relative_to {
GradientRelativeTo::Window => full_rect,
GradientRelativeTo::WorkspaceView => view_rect,
};
- shader.cloned().map(|shader| {
- BorderRenderElement::new(
- shader,
+ border.map(|border| {
+ border.update(
scale,
Rectangle::from_loc_and_size(location, size),
gradient_area,
@@ -197,13 +225,12 @@ impl FocusRing {
full_rect,
border_width,
self.radius,
- )
- .into()
+ );
+ border.clone().into()
})
} else if self.radius != CornerRadius::default() {
- shader.cloned().map(|shader| {
- BorderRenderElement::new(
- shader,
+ border.map(|border| {
+ border.update(
scale,
Rectangle::from_loc_and_size(location, size),
full_rect,
@@ -213,8 +240,8 @@ impl FocusRing {
full_rect,
border_width,
self.radius,
- )
- .into()
+ );
+ border.clone().into()
})
} else {
None
@@ -234,12 +261,16 @@ impl FocusRing {
};
if self.is_border {
- for (buf, (loc, size)) in zip(&self.buffers, zip(self.locations, self.sizes)) {
- push(buf, location + loc, size);
+ for ((buf, border), (loc, size)) in zip(
+ zip(&self.buffers, &mut borders),
+ zip(self.locations, self.sizes),
+ ) {
+ push(buf, border, location + loc, size);
}
} else {
push(
&self.buffers[0],
+ borders.next().unwrap(),
location + self.locations[0],
self.sizes[0],
);