mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
Add configurable struts
This commit is contained in:
@@ -122,6 +122,18 @@ default-column-width { proportion 0.5; }
|
|||||||
// Set gaps around windows in logical pixels.
|
// Set gaps around windows in logical pixels.
|
||||||
gaps 16
|
gaps 16
|
||||||
|
|
||||||
|
// Struts shrink the area occupied by windows, similarly to layer-shell panels.
|
||||||
|
// You can think of them as a kind of outer gaps. They are set in logical pixels.
|
||||||
|
// Left and right struts will cause the next window to the side to always be visible.
|
||||||
|
// Top and bottom struts will simply add outer gaps in addition to the area occupied by
|
||||||
|
// layer-shell panels and regular gaps.
|
||||||
|
struts {
|
||||||
|
// left 64
|
||||||
|
// right 64
|
||||||
|
// top 64
|
||||||
|
// bottom 64
|
||||||
|
}
|
||||||
|
|
||||||
// You can change the path where screenshots are saved.
|
// You can change the path where screenshots are saved.
|
||||||
// A ~ at the front will be expanded to the home directory.
|
// A ~ at the front will be expanded to the home directory.
|
||||||
// The path is formatted with strftime(3) to give you the screenshot date and time.
|
// The path is formatted with strftime(3) to give you the screenshot date and time.
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ pub struct Config {
|
|||||||
pub default_column_width: Option<DefaultColumnWidth>,
|
pub default_column_width: Option<DefaultColumnWidth>,
|
||||||
#[knuffel(child, unwrap(argument), default = 16)]
|
#[knuffel(child, unwrap(argument), default = 16)]
|
||||||
pub gaps: u16,
|
pub gaps: u16,
|
||||||
|
#[knuffel(child, default)]
|
||||||
|
pub struts: Struts,
|
||||||
#[knuffel(
|
#[knuffel(
|
||||||
child,
|
child,
|
||||||
unwrap(argument),
|
unwrap(argument),
|
||||||
@@ -238,6 +240,18 @@ pub enum PresetWidth {
|
|||||||
#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
|
#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
|
||||||
pub struct DefaultColumnWidth(#[knuffel(children)] pub Vec<PresetWidth>);
|
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)]
|
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
|
||||||
pub struct Binds(#[knuffel(children)] pub Vec<Bind>);
|
pub struct Binds(#[knuffel(children)] pub Vec<Bind>);
|
||||||
|
|
||||||
@@ -594,6 +608,12 @@ mod tests {
|
|||||||
|
|
||||||
gaps 8
|
gaps 8
|
||||||
|
|
||||||
|
struts {
|
||||||
|
left 1
|
||||||
|
right 2
|
||||||
|
top 3
|
||||||
|
}
|
||||||
|
|
||||||
screenshot-path "~/Screenshots/screenshot.png"
|
screenshot-path "~/Screenshots/screenshot.png"
|
||||||
|
|
||||||
binds {
|
binds {
|
||||||
@@ -673,6 +693,12 @@ mod tests {
|
|||||||
],
|
],
|
||||||
default_column_width: Some(DefaultColumnWidth(vec![PresetWidth::Proportion(0.25)])),
|
default_column_width: Some(DefaultColumnWidth(vec![PresetWidth::Proportion(0.25)])),
|
||||||
gaps: 8,
|
gaps: 8,
|
||||||
|
struts: Struts {
|
||||||
|
left: 1,
|
||||||
|
right: 2,
|
||||||
|
top: 3,
|
||||||
|
bottom: 0,
|
||||||
|
},
|
||||||
screenshot_path: Some(String::from("~/Screenshots/screenshot.png")),
|
screenshot_path: Some(String::from("~/Screenshots/screenshot.png")),
|
||||||
binds: Binds(vec![
|
binds: Binds(vec![
|
||||||
Bind {
|
Bind {
|
||||||
|
|||||||
+38
-4
@@ -56,7 +56,7 @@ use smithay::wayland::compositor::{send_surface_state, with_states};
|
|||||||
use smithay::wayland::shell::xdg::SurfaceCachedState;
|
use smithay::wayland::shell::xdg::SurfaceCachedState;
|
||||||
|
|
||||||
use crate::animation::Animation;
|
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)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct OutputId(String);
|
pub struct OutputId(String);
|
||||||
@@ -205,6 +205,8 @@ struct FocusRing {
|
|||||||
struct Options {
|
struct Options {
|
||||||
/// Padding around windows in logical pixels.
|
/// Padding around windows in logical pixels.
|
||||||
gaps: i32,
|
gaps: i32,
|
||||||
|
/// Extra padding around the working area in logical pixels.
|
||||||
|
struts: Struts,
|
||||||
focus_ring: config::FocusRing,
|
focus_ring: config::FocusRing,
|
||||||
/// Column widths that `toggle_width()` switches between.
|
/// Column widths that `toggle_width()` switches between.
|
||||||
preset_widths: Vec<ColumnWidth>,
|
preset_widths: Vec<ColumnWidth>,
|
||||||
@@ -216,6 +218,7 @@ impl Default for Options {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
gaps: 16,
|
gaps: 16,
|
||||||
|
struts: Default::default(),
|
||||||
focus_ring: Default::default(),
|
focus_ring: Default::default(),
|
||||||
preset_widths: vec![
|
preset_widths: vec![
|
||||||
ColumnWidth::Proportion(1. / 3.),
|
ColumnWidth::Proportion(1. / 3.),
|
||||||
@@ -251,6 +254,7 @@ impl Options {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
gaps: config.gaps.into(),
|
gaps: config.gaps.into(),
|
||||||
|
struts: config.struts,
|
||||||
focus_ring: config.focus_ring,
|
focus_ring: config.focus_ring,
|
||||||
preset_widths,
|
preset_widths,
|
||||||
default_width,
|
default_width,
|
||||||
@@ -830,7 +834,7 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
for mon in monitors {
|
for mon in monitors {
|
||||||
if &mon.output == output {
|
if &mon.output == output {
|
||||||
let view_size = output_size(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 {
|
for ws in &mut mon.workspaces {
|
||||||
ws.set_view_size(view_size, working_area);
|
ws.set_view_size(view_size, working_area);
|
||||||
@@ -1886,6 +1890,15 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
ws.update_config(options.clone());
|
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;
|
self.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2064,7 +2077,7 @@ impl Monitor<Window> {
|
|||||||
|
|
||||||
impl<W: LayoutElement> Workspace<W> {
|
impl<W: LayoutElement> Workspace<W> {
|
||||||
fn new(output: Output, options: Rc<Options>) -> Self {
|
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 {
|
Self {
|
||||||
original_output: OutputId::new(&output),
|
original_output: OutputId::new(&output),
|
||||||
view_size: output_size(&output),
|
view_size: output_size(&output),
|
||||||
@@ -2164,7 +2177,7 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
self.output = output;
|
self.output = output;
|
||||||
|
|
||||||
if let Some(output) = &self.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);
|
self.set_view_size(output_size(output), working_area);
|
||||||
|
|
||||||
for win in self.windows() {
|
for win in self.windows() {
|
||||||
@@ -3261,6 +3274,27 @@ pub fn output_size(output: &Output) -> Size<i32, Logical> {
|
|||||||
.to_logical(output_scale)
|
.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(
|
fn compute_new_view_offset(
|
||||||
cur_x: i32,
|
cur_x: i32,
|
||||||
view_width: i32,
|
view_width: i32,
|
||||||
|
|||||||
Reference in New Issue
Block a user