commit c6e735be3825c516c1fcd80844c3bf3dc31597e9
parent 1b7e8201fc3b5cfc46f0c36fadf232b955fd67fc
Author: deurzen <m.deurzen@tum.de>
Date: Tue, 16 Mar 2021 13:12:41 +0100
fixes decoration and stacking order issue
Diffstat:
3 files changed, 183 insertions(+), 79 deletions(-)
diff --git a/src/core/main.rs b/src/core/main.rs
@@ -187,8 +187,10 @@ fn init_bindings() -> (MouseBindings, KeyBindings) {
"1-m" => do_internal!(set_layout, LayoutKind::Monocle),
"1-t" => do_internal!(set_layout, LayoutKind::Stack),
"1-g" => do_internal!(set_layout, LayoutKind::Center),
- "1-z" => do_internal!(set_layout, LayoutKind::SingleFloat),
"1-S-f" => do_internal!(set_layout, LayoutKind::Float),
+ "1-S-l" => do_internal!(set_layout, LayoutKind::BLFloat),
+ "1-z" => do_internal!(set_layout, LayoutKind::SingleFloat),
+ "1-S-z" => do_internal!(set_layout, LayoutKind::BLSingleFloat),
"1-C-S-f" => do_internal!(apply_float_retain_region),
"1-S-t" => do_internal!(set_layout, LayoutKind::SStack),
"1-C-S-p" => do_internal!(set_layout, LayoutKind::Paper),
diff --git a/src/core/model.rs b/src/core/model.rs
@@ -404,10 +404,7 @@ impl<'a> Model<'a> {
let (free, regular): (Vec<Window>, Vec<Window>) =
regular.into_iter().partition(|&window| {
self.client(window).map_or(true, |client| {
- let id = client.zone();
- let zone = self.zone_manager.zone(id);
-
- zone.method() == PlacementMethod::Free || client.is_free()
+ self.is_free(client)
})
});
@@ -1100,8 +1097,15 @@ impl<'a> Model<'a> {
let zone = self.zone_manager.zone_mut(id);
zone.set_region(region);
+ zone.set_method(placement.method);
+ },
+ PlacementMethod::Tile => {
+ let id = client.zone();
+ client.set_tile_region(®ion);
+
+ let zone = self.zone_manager.zone_mut(id);
+ zone.set_method(placement.method);
},
- PlacementMethod::Tile => client.set_tile_region(®ion),
};
},
_ => panic!("attempting to update non-client placement"),
diff --git a/src/core/zone.rs b/src/core/zone.rs
@@ -48,7 +48,7 @@ fn next_id() -> ZoneId {
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Disposition {
- Unchanged,
+ Unchanged(Decoration),
Changed(Region, Decoration),
}
@@ -97,13 +97,66 @@ pub struct Placement {
type LayoutFn = fn(&Region, &LayoutData, Vec<bool>) -> Vec<(Disposition, bool)>;
#[non_exhaustive]
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub struct LayoutConfig {
+ pub method: PlacementMethod,
+ pub decoration: Decoration,
+ pub root_only: bool,
+ pub margin: bool,
+ pub gap: bool,
+ pub persistent: bool,
+ pub single: bool,
+ pub wraps: bool,
+}
+
+impl Default for LayoutConfig {
+ fn default() -> Self {
+ Self {
+ method: PlacementMethod::Free,
+ decoration: Default::default(),
+ root_only: true,
+ margin: false,
+ gap: false,
+ persistent: false,
+ single: false,
+ wraps: true,
+ }
+ }
+}
+
+#[non_exhaustive]
+#[derive(Debug, PartialEq, Clone, Copy)]
+pub struct LayoutData {
+ /// Generic layout data
+ pub margin: Padding,
+ pub gap_size: u32,
+
+ /// Tiled layout data
+ pub main_count: u32,
+ pub main_factor: f32,
+}
+
+impl Default for LayoutData {
+ fn default() -> Self {
+ Self {
+ margin: Default::default(),
+ gap_size: 0u32,
+
+ main_count: 1u32,
+ main_factor: 0.50f32,
+ }
+ }
+}
+
+#[non_exhaustive]
#[repr(u8)]
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, EnumIter, EnumCount, ToString)]
pub enum LayoutKind {
/// Free layouts
Float = b'F',
- BorderlessFloat = b'L',
+ BLFloat = b'L',
SingleFloat = b'Z',
+ BLSingleFloat = b'Y',
/// Tiled layouts
Center = b';',
@@ -130,15 +183,17 @@ impl LayoutKind {
method: PlacementMethod::Free,
decoration: FREE_DECORATION,
root_only: true,
+ margin: false,
gap: false,
persistent: false,
single: false,
wraps: true,
},
- LayoutKind::BorderlessFloat => LayoutConfig {
+ LayoutKind::BLFloat => LayoutConfig {
method: PlacementMethod::Free,
decoration: NO_DECORATION,
root_only: true,
+ margin: false,
gap: false,
persistent: false,
single: false,
@@ -148,6 +203,17 @@ impl LayoutKind {
method: PlacementMethod::Free,
decoration: FREE_DECORATION,
root_only: true,
+ margin: false,
+ gap: false,
+ persistent: true,
+ single: true,
+ wraps: true,
+ },
+ LayoutKind::BLSingleFloat => LayoutConfig {
+ method: PlacementMethod::Free,
+ decoration: NO_DECORATION,
+ root_only: true,
+ margin: false,
gap: false,
persistent: true,
single: true,
@@ -157,6 +223,7 @@ impl LayoutKind {
method: PlacementMethod::Tile,
decoration: NO_DECORATION,
root_only: false,
+ margin: true,
gap: true,
persistent: false,
single: false,
@@ -166,6 +233,7 @@ impl LayoutKind {
method: PlacementMethod::Tile,
decoration: NO_DECORATION,
root_only: false,
+ margin: true,
gap: true,
persistent: false,
single: false,
@@ -186,12 +254,13 @@ impl LayoutKind {
border: None,
},
root_only: false,
+ margin: true,
gap: true,
persistent: true,
single: false,
wraps: false,
},
- LayoutKind::SStack => LayoutConfig {
+ LayoutKind::Stack => LayoutConfig {
method: PlacementMethod::Tile,
decoration: Decoration {
frame: Some(Frame {
@@ -206,12 +275,13 @@ impl LayoutKind {
border: None,
},
root_only: false,
- gap: false,
+ margin: true,
+ gap: true,
persistent: false,
single: false,
wraps: true,
},
- LayoutKind::Stack => LayoutConfig {
+ LayoutKind::SStack => LayoutConfig {
method: PlacementMethod::Tile,
decoration: Decoration {
frame: Some(Frame {
@@ -226,7 +296,8 @@ impl LayoutKind {
border: None,
},
root_only: false,
- gap: true,
+ margin: true,
+ gap: false,
persistent: false,
single: false,
wraps: true,
@@ -246,6 +317,7 @@ impl LayoutKind {
border: None,
},
root_only: false,
+ margin: true,
gap: true,
persistent: false,
single: false,
@@ -266,6 +338,7 @@ impl LayoutKind {
border: None,
},
root_only: false,
+ margin: true,
gap: true,
persistent: false,
single: false,
@@ -280,8 +353,9 @@ impl LayoutKind {
fn default_data(&self) -> LayoutData {
match *self {
LayoutKind::Float => Default::default(),
- LayoutKind::BorderlessFloat => Default::default(),
+ LayoutKind::BLFloat => Default::default(),
LayoutKind::SingleFloat => Default::default(),
+ LayoutKind::BLSingleFloat => Default::default(),
LayoutKind::Center => LayoutData {
main_count: 5u32,
main_factor: 0.40f32,
@@ -323,16 +397,26 @@ impl LayoutKind {
fn func(&self) -> LayoutFn {
match *self {
- LayoutKind::Float => {
- |_, _, active_map| vec![(Disposition::Unchanged, true); active_map.len()]
+ LayoutKind::Float => |_, _, active_map| {
+ let config = &LayoutKind::Float.config();
+ vec![(Disposition::Unchanged(config.decoration), true); active_map.len()]
},
- LayoutKind::BorderlessFloat => {
- |_, _, active_map| vec![(Disposition::Unchanged, true); active_map.len()]
+ LayoutKind::BLFloat => |_, _, active_map| {
+ let config = &LayoutKind::BLFloat.config();
+ vec![(Disposition::Unchanged(config.decoration), true); active_map.len()]
},
LayoutKind::SingleFloat => |_, _, active_map| {
+ let config = &LayoutKind::SingleFloat.config();
active_map
.into_iter()
- .map(|b| (Disposition::Unchanged, b))
+ .map(|b| (Disposition::Unchanged(config.decoration), b))
+ .collect()
+ },
+ LayoutKind::BLSingleFloat => |_, _, active_map| {
+ let config = &LayoutKind::BLSingleFloat.config();
+ active_map
+ .into_iter()
+ .map(|b| (Disposition::Unchanged(config.decoration), b))
.collect()
},
LayoutKind::Stack => |region, data, active_map| {
@@ -389,6 +473,63 @@ impl LayoutKind {
})
.collect()
},
+ LayoutKind::SStack => |region, data, active_map| {
+ let mut region = region.clone();
+ Layout::adjust_for_gap_size(&mut region, data.gap_size, &MIN_ZONE_DIM);
+
+ let (pos, dim) = region.values();
+ let n = active_map.len();
+
+ if n == 1 {
+ return vec![(Disposition::Changed(region, NO_DECORATION), true)];
+ }
+
+ let (n_main, n_stack) = Self::stack_split(n, data.main_count);
+ let h_stack = if n_stack > 0 { dim.h / n_stack } else { 0 };
+ let h_main = if n_main > 0 { dim.h / n_main } else { 0 };
+
+ let div = if data.main_count > 0 {
+ (dim.w as f32 * data.main_factor) as i32
+ } else {
+ 0
+ };
+
+ let config = &LayoutKind::Stack.config();
+ active_map
+ .into_iter()
+ .enumerate()
+ .map(|(i, _)| {
+ let i = i as u32;
+
+ if i < data.main_count {
+ let w = if n_stack == 0 { dim.w } else { div as u32 };
+
+ (
+ Disposition::Changed(
+ Region::new(pos.x, pos.y + (i * h_main) as i32, w, h_main),
+ config.decoration,
+ ),
+ true,
+ )
+ } else {
+ let sn = (i - data.main_count) as i32;
+
+ (
+ Disposition::Changed(
+ Region::new(
+ pos.x + div,
+ pos.y + sn * h_stack as i32,
+ dim.w - div as u32,
+ h_stack,
+ ),
+ config.decoration,
+ ),
+ true,
+ )
+ }
+ })
+ .collect()
+ },
LayoutKind::Monocle => |region, _, active_map| {
let config = &LayoutKind::Monocle.config();
let (pos, dim) = region.values();
@@ -497,56 +638,6 @@ impl LayoutKind {
}
}
-#[non_exhaustive]
-#[derive(Debug, PartialEq, Clone, Copy)]
-pub struct LayoutConfig {
- pub method: PlacementMethod,
- pub decoration: Decoration,
- pub root_only: bool,
- pub gap: bool,
- pub persistent: bool,
- pub single: bool,
- pub wraps: bool,
-}
-
-impl Default for LayoutConfig {
- fn default() -> Self {
- Self {
- method: PlacementMethod::Free,
- decoration: Default::default(),
- root_only: true,
- gap: false,
- persistent: false,
- single: false,
- wraps: true,
- }
- }
-}
-
-#[non_exhaustive]
-#[derive(Debug, PartialEq, Clone, Copy)]
-pub struct LayoutData {
- /// Generic layout data
- pub margin: Padding,
- pub gap_size: u32,
-
- /// Tiled layout data
- pub main_count: u32,
- pub main_factor: f32,
-}
-
-impl Default for LayoutData {
- fn default() -> Self {
- Self {
- margin: Default::default(),
- gap_size: 0u32,
-
- main_count: 1u32,
- main_factor: 0.50f32,
- }
- }
-}
-
pub struct Layout {
kind: LayoutKind,
prev_kind: LayoutKind,
@@ -676,7 +767,7 @@ impl Apply for Layout {
let config = self.kind.config();
let data = self.get_data();
- let region = if config.gap {
+ let region = if config.margin {
Self::adjust_for_margin(region, &data.margin)
} else {
region
@@ -687,11 +778,13 @@ impl Apply for Layout {
(self.kind.func())(®ion, &data, active_map)
.into_iter()
.map(|(mut disposition, is_visible)| {
- match disposition {
- Disposition::Unchanged => {},
- Disposition::Changed(ref mut region, _) => {
- Self::adjust_for_gap_size(region, data.gap_size, &MIN_ZONE_DIM);
- },
+ if config.gap {
+ match disposition {
+ Disposition::Unchanged(_) => {},
+ Disposition::Changed(ref mut region, _) => {
+ Self::adjust_for_gap_size(region, data.gap_size, &MIN_ZONE_DIM);
+ },
+ }
}
(disposition, is_visible)
@@ -779,6 +872,13 @@ impl Zone {
self.region = region;
}
+ pub fn set_method(
+ &mut self,
+ method: PlacementMethod,
+ ) {
+ self.method = method;
+ }
+
pub fn default_data(&self) -> Option<LayoutData> {
match &self.content {
ZoneContent::Layout(layout, _) => Some(layout.get_default_data()),
@@ -1146,7 +1246,7 @@ impl ZoneManager {
zones.into_iter().zip(application.into_iter()).for_each(
|(id, (disposition, is_visible))| {
let (region, decoration) = match disposition {
- Disposition::Unchanged => {
+ Disposition::Unchanged(decoration) => {
let zone = self.zone_map.get(&id).unwrap();
(zone.region, decoration)
},
@@ -1158,9 +1258,7 @@ impl ZoneManager {
placements.push(Placement {
method,
- kind: PlacementKind::from_zone_content(
- &self.zone(id).content,
- ),
+ kind: PlacementKind::from_zone_content(&self.zone(id).content),
zone: id,
region: PlacementRegion::NoRegion,
decoration,