aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-12-21 08:37:30 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-12-21 08:37:30 +0400
commit5b1de86d336f7d617f98048fe4318061320d6a29 (patch)
treeb5d7fe08adc23c0715569a07581f34493d8086f6 /src
parent58162ce685c487597cc097fe878650a17415a63b (diff)
downloadniri-5b1de86d336f7d617f98048fe4318061320d6a29.tar.gz
niri-5b1de86d336f7d617f98048fe4318061320d6a29.tar.bz2
niri-5b1de86d336f7d617f98048fe4318061320d6a29.zip
Add configurable struts
Diffstat (limited to 'src')
-rw-r--r--src/config.rs26
-rw-r--r--src/layout.rs42
2 files changed, 64 insertions, 4 deletions
diff --git a/src/config.rs b/src/config.rs
index b5428429..b5e98adf 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -28,6 +28,8 @@ pub struct Config {
pub default_column_width: Option<DefaultColumnWidth>,
#[knuffel(child, unwrap(argument), default = 16)]
pub gaps: u16,
+ #[knuffel(child, default)]
+ pub struts: Struts,
#[knuffel(
child,
unwrap(argument),
@@ -238,6 +240,18 @@ pub enum PresetWidth {
#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
pub struct DefaultColumnWidth(#[knuffel(children)] pub Vec<PresetWidth>);
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq, Eq)]
+pub struct Struts {
+ #[knuffel(child, unwrap(argument), default)]
+ pub left: u16,
+ #[knuffel(child, unwrap(argument), default)]
+ pub right: u16,
+ #[knuffel(child, unwrap(argument), default)]
+ pub top: u16,
+ #[knuffel(child, unwrap(argument), default)]
+ pub bottom: u16,
+}
+
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
pub struct Binds(#[knuffel(children)] pub Vec<Bind>);
@@ -594,6 +608,12 @@ mod tests {
gaps 8
+ struts {
+ left 1
+ right 2
+ top 3
+ }
+
screenshot-path "~/Screenshots/screenshot.png"
binds {
@@ -673,6 +693,12 @@ mod tests {
],
default_column_width: Some(DefaultColumnWidth(vec![PresetWidth::Proportion(0.25)])),
gaps: 8,
+ struts: Struts {
+ left: 1,
+ right: 2,
+ top: 3,
+ bottom: 0,
+ },
screenshot_path: Some(String::from("~/Screenshots/screenshot.png")),
binds: Binds(vec![
Bind {
diff --git a/src/layout.rs b/src/layout.rs
index b53529f5..bf012311 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -56,7 +56,7 @@ use smithay::wayland::compositor::{send_surface_state, with_states};
use smithay::wayland::shell::xdg::SurfaceCachedState;
use crate::animation::Animation;
-use crate::config::{self, Color, Config, PresetWidth, SizeChange};
+use crate::config::{self, Color, Config, PresetWidth, SizeChange, Struts};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OutputId(String);
@@ -205,6 +205,8 @@ struct FocusRing {
struct Options {
/// Padding around windows in logical pixels.
gaps: i32,
+ /// Extra padding around the working area in logical pixels.
+ struts: Struts,
focus_ring: config::FocusRing,
/// Column widths that `toggle_width()` switches between.
preset_widths: Vec<ColumnWidth>,
@@ -216,6 +218,7 @@ impl Default for Options {
fn default() -> Self {
Self {
gaps: 16,
+ struts: Default::default(),
focus_ring: Default::default(),
preset_widths: vec![
ColumnWidth::Proportion(1. / 3.),
@@ -251,6 +254,7 @@ impl Options {
Self {
gaps: config.gaps.into(),
+ struts: config.struts,
focus_ring: config.focus_ring,
preset_widths,
default_width,
@@ -830,7 +834,7 @@ impl<W: LayoutElement> Layout<W> {
for mon in monitors {
if &mon.output == output {
let view_size = output_size(output);
- let working_area = layer_map_for_output(output).non_exclusive_zone();
+ let working_area = compute_working_area(output, self.options.struts);
for ws in &mut mon.workspaces {
ws.set_view_size(view_size, working_area);
@@ -1886,6 +1890,15 @@ impl<W: LayoutElement> Monitor<W> {
ws.update_config(options.clone());
}
+ if self.options.struts != options.struts {
+ let view_size = output_size(&self.output);
+ let working_area = compute_working_area(&self.output, options.struts);
+
+ for ws in &mut self.workspaces {
+ ws.set_view_size(view_size, working_area);
+ }
+ }
+
self.options = options;
}
@@ -2064,7 +2077,7 @@ impl Monitor<Window> {
impl<W: LayoutElement> Workspace<W> {
fn new(output: Output, options: Rc<Options>) -> Self {
- let working_area = layer_map_for_output(&output).non_exclusive_zone();
+ let working_area = compute_working_area(&output, options.struts);
Self {
original_output: OutputId::new(&output),
view_size: output_size(&output),
@@ -2164,7 +2177,7 @@ impl<W: LayoutElement> Workspace<W> {
self.output = output;
if let Some(output) = &self.output {
- let working_area = layer_map_for_output(output).non_exclusive_zone();
+ let working_area = compute_working_area(output, self.options.struts);
self.set_view_size(output_size(output), working_area);
for win in self.windows() {
@@ -3261,6 +3274,27 @@ pub fn output_size(output: &Output) -> Size<i32, Logical> {
.to_logical(output_scale)
}
+fn compute_working_area(output: &Output, struts: Struts) -> Rectangle<i32, Logical> {
+ // Start with the layer-shell non-exclusive zone.
+ let mut working_area = layer_map_for_output(output).non_exclusive_zone();
+
+ // Add struts.
+ let w = working_area.size.w;
+ let h = working_area.size.h;
+
+ working_area.size.w = w
+ .saturating_sub(struts.left.into())
+ .saturating_sub(struts.right.into());
+ working_area.loc.x += struts.left as i32;
+
+ working_area.size.h = h
+ .saturating_sub(struts.top.into())
+ .saturating_sub(struts.bottom.into());
+ working_area.loc.y += struts.top as i32;
+
+ working_area
+}
+
fn compute_new_view_offset(
cur_x: i32,
view_width: i32,