aboutsummaryrefslogtreecommitdiff
path: root/src/layout.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-09-26 13:09:33 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-09-26 13:45:03 +0400
commita62e1cbef6028cb9de945252fbd1b1e9723e4bde (patch)
tree4ac29ec178dc4af72d45ac55f485c982e0f23ec8 /src/layout.rs
parent906ee36a934154221f1b8ef6d919f80e9ac950fb (diff)
downloadniri-a62e1cbef6028cb9de945252fbd1b1e9723e4bde.tar.gz
niri-a62e1cbef6028cb9de945252fbd1b1e9723e4bde.tar.bz2
niri-a62e1cbef6028cb9de945252fbd1b1e9723e4bde.zip
Make focus ring configurable
Diffstat (limited to 'src/layout.rs')
-rw-r--r--src/layout.rs121
1 files changed, 96 insertions, 25 deletions
diff --git a/src/layout.rs b/src/layout.rs
index 76afaf0e..4a82396d 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -53,11 +53,9 @@ use smithay::wayland::dmabuf::DmabufFeedback;
use smithay::wayland::shell::xdg::SurfaceCachedState;
use crate::animation::Animation;
+use crate::config::{Color, Config};
const PADDING: i32 = 16;
-const FOCUS_RING_PADDING: i32 = 4;
-const FOCUS_RING_ACTIVE_COLOR: [f32; 4] = [0.5, 0.8, 1.0, 1.0];
-const FOCUS_RING_INACTIVE_COLOR: [f32; 4] = [0.3, 0.3, 0.3, 1.0];
const WIDTH_PROPORTIONS: [ColumnWidth; 3] = [
ColumnWidth::Proportion(1. / 3.),
ColumnWidth::Proportion(0.5),
@@ -151,8 +149,8 @@ pub struct Workspace<W: LayoutElement> {
/// Index of the currently active column, if any.
active_column_idx: usize,
- /// The solid color buffer for the focus ring.
- focus_ring: SolidColorBuffer,
+ /// Focus ring buffer and parameters.
+ focus_ring: FocusRing,
/// Offset of the view computed from the active column.
view_offset: i32,
@@ -171,6 +169,15 @@ pub struct Workspace<W: LayoutElement> {
activate_prev_column_on_removal: bool,
}
+#[derive(Debug)]
+struct FocusRing {
+ buffer: SolidColorBuffer,
+ is_off: bool,
+ width: i32,
+ active_color: Color,
+ inactive_color: Color,
+}
+
/// Width of a column.
#[derive(Debug, Clone, Copy)]
enum ColumnWidth {
@@ -267,6 +274,52 @@ impl LayoutElement for Window {
}
}
+impl FocusRing {
+ fn resize(&mut self, size: Size<i32, Logical>) {
+ let size = size + Size::from((self.width * 2, self.width * 2));
+ self.buffer.resize(size);
+ }
+
+ fn set_active(&mut self, is_active: bool) {
+ self.buffer.set_color(if is_active {
+ self.active_color.into()
+ } else {
+ self.inactive_color.into()
+ });
+ }
+
+ fn render(
+ &self,
+ loc: Point<i32, Logical>,
+ scale: Scale<f64>,
+ ) -> Option<SolidColorRenderElement> {
+ if self.is_off {
+ return None;
+ }
+
+ let offset = Point::from((self.width, self.width));
+ Some(SolidColorRenderElement::from_buffer(
+ &self.buffer,
+ (loc - offset).to_physical_precise_round(scale),
+ scale,
+ 1.,
+ Kind::Unspecified,
+ ))
+ }
+}
+
+impl Default for FocusRing {
+ fn default() -> Self {
+ Self {
+ buffer: SolidColorBuffer::new((0, 0), [0., 0., 0., 0.]),
+ is_off: true,
+ width: 0,
+ active_color: Color::default(),
+ inactive_color: Color::default(),
+ }
+ }
+}
+
impl ColumnWidth {
fn resolve(self, view_width: i32) -> i32 {
match self {
@@ -873,6 +926,21 @@ impl<W: LayoutElement> MonitorSet<W> {
}
}
+ pub fn update_config(&mut self, config: &Config) {
+ match self {
+ MonitorSet::Normal { monitors, .. } => {
+ for mon in monitors {
+ mon.update_config(config);
+ }
+ }
+ MonitorSet::NoOutputs(workspaces) => {
+ for ws in workspaces {
+ ws.update_config(config);
+ }
+ }
+ }
+ }
+
pub fn toggle_width(&mut self) {
let Some(monitor) = self.active_monitor() else {
return;
@@ -1235,6 +1303,12 @@ impl<W: LayoutElement> Monitor<W> {
}
}
+ pub fn update_config(&mut self, config: &Config) {
+ for ws in &mut self.workspaces {
+ ws.update_config(config);
+ }
+ }
+
fn toggle_width(&mut self) {
self.active_workspace().toggle_width();
}
@@ -1319,7 +1393,7 @@ impl<W: LayoutElement> Workspace<W> {
output: Some(output),
columns: vec![],
active_column_idx: 0,
- focus_ring: SolidColorBuffer::new((0, 0), FOCUS_RING_ACTIVE_COLOR),
+ focus_ring: FocusRing::default(),
view_offset: 0,
view_offset_anim: None,
activate_prev_column_on_removal: false,
@@ -1333,7 +1407,7 @@ impl<W: LayoutElement> Workspace<W> {
view_size: Size::from((1280, 720)),
columns: vec![],
active_column_idx: 0,
- focus_ring: SolidColorBuffer::new((0, 0), FOCUS_RING_ACTIVE_COLOR),
+ focus_ring: FocusRing::default(),
view_offset: 0,
view_offset_anim: None,
activate_prev_column_on_removal: false,
@@ -1357,17 +1431,20 @@ impl<W: LayoutElement> Workspace<W> {
let col = &self.columns[self.active_column_idx];
let active_win = &col.windows[col.active_window_idx];
let geom = active_win.geometry();
- self.focus_ring
- .resize(geom.size + Size::from((FOCUS_RING_PADDING * 2, FOCUS_RING_PADDING * 2)));
-
- self.focus_ring.set_color(if is_active {
- FOCUS_RING_ACTIVE_COLOR
- } else {
- FOCUS_RING_INACTIVE_COLOR
- });
+ self.focus_ring.resize(geom.size);
+ self.focus_ring.set_active(is_active);
}
}
+ pub fn update_config(&mut self, config: &Config) {
+ let c = &config.focus_ring;
+ self.focus_ring.is_off = c.off;
+ self.focus_ring.width = c.width.into();
+ self.focus_ring.active_color = c.active_color;
+ self.focus_ring.inactive_color = c.inactive_color;
+ // The focus ring buffer will be updated in a subsequent update_animations call.
+ }
+
fn windows(&self) -> impl Iterator<Item = &W> + '_ {
self.columns.iter().flat_map(|col| col.windows.iter())
}
@@ -1917,16 +1994,10 @@ impl Workspace<Window> {
));
// Draw the focus ring.
- rv.push(
- SolidColorRenderElement::from_buffer(
- &self.focus_ring,
- (win_pos + geom.loc - Point::from((FOCUS_RING_PADDING, FOCUS_RING_PADDING)))
- .to_physical_precise_round(output_scale),
- output_scale,
- 1.,
- Kind::Unspecified,
- )
- .into(),
+ rv.extend(
+ self.focus_ring
+ .render(win_pos + geom.loc, output_scale)
+ .map(Into::into),
);
let mut x = PADDING;