Add configurable struts

This commit is contained in:
Ivan Molodetskikh
2023-12-21 08:37:30 +04:00
parent 58162ce685
commit 5b1de86d33
3 changed files with 76 additions and 4 deletions
+12
View File
@@ -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.
+26
View File
@@ -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
View File
@@ -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,