commit 1b7e8201fc3b5cfc46f0c36fadf232b955fd67fc
parent 986b9e3e483242fbdb6e3d34f9d395a5782d721e
Author: deurzen <m.deurzen@tum.de>
Date: Tue, 16 Mar 2021 03:29:03 +0100
refactors layout handling code
Diffstat:
4 files changed, 125 insertions(+), 86 deletions(-)
diff --git a/src/core/model.rs b/src/core/model.rs
@@ -26,6 +26,7 @@ use crate::zone::LayoutKind;
use crate::zone::Placement;
use crate::zone::PlacementKind;
use crate::zone::PlacementMethod;
+use crate::zone::PlacementRegion;
use crate::zone::ZoneContent;
use crate::zone::ZoneManager;
@@ -340,7 +341,7 @@ impl<'a> Model<'a> {
let (show, hide): (Vec<&Placement>, Vec<&Placement>) = placements
.iter()
- .partition(|&placement| placement.region.is_some());
+ .partition(|&placement| placement.region != PlacementRegion::NoRegion);
for placement in show {
match placement.kind {
@@ -1084,13 +1085,23 @@ impl<'a> Model<'a> {
match placement.kind {
PlacementKind::Client(window) => {
let client = self.client_mut(window).unwrap();
- let region = &placement.region.unwrap();
+ let region = match placement.region {
+ PlacementRegion::FreeRegion => *client.free_region(),
+ PlacementRegion::NewRegion(region) => region,
+ PlacementRegion::NoRegion => return,
+ };
client.set_decoration(placement.decoration);
match placement.method {
- PlacementMethod::Free => client.set_free_region(region),
- PlacementMethod::Tile => client.set_tile_region(region),
+ PlacementMethod::Free => {
+ let id = client.zone();
+ client.set_free_region(®ion);
+
+ let zone = self.zone_manager.zone_mut(id);
+ zone.set_region(region);
+ },
+ PlacementMethod::Tile => client.set_tile_region(®ion),
};
},
_ => panic!("attempting to update non-client placement"),
@@ -2313,7 +2324,7 @@ impl<'a> Model<'a> {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
zone: client.zone(),
- region: Some(region),
+ region: PlacementRegion::NewRegion(region),
decoration: *client.decoration(),
};
@@ -2360,7 +2371,7 @@ impl<'a> Model<'a> {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
zone: client.zone(),
- region: Some(region),
+ region: PlacementRegion::NewRegion(region),
decoration: *client.decoration(),
};
@@ -2423,7 +2434,7 @@ impl<'a> Model<'a> {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
zone: client.zone(),
- region: Some(region),
+ region: PlacementRegion::NewRegion(region),
decoration: *client.decoration(),
};
@@ -2517,7 +2528,7 @@ impl<'a> Model<'a> {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
zone: client.zone(),
- region: Some(region),
+ region: PlacementRegion::NewRegion(region),
decoration: *client.decoration(),
};
@@ -2573,7 +2584,7 @@ impl<'a> Model<'a> {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
zone: client.zone(),
- region: Some(region),
+ region: PlacementRegion::NewRegion(region),
decoration: *client.decoration(),
};
@@ -2678,7 +2689,7 @@ impl<'a> Model<'a> {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
zone: client.zone(),
- region: Some(region),
+ region: PlacementRegion::NewRegion(region),
decoration: *decoration,
};
@@ -3211,7 +3222,7 @@ impl<'a> Model<'a> {
method: PlacementMethod::Free,
kind: PlacementKind::Client(window),
zone: client.zone(),
- region: Some(region),
+ region: PlacementRegion::NewRegion(region),
decoration: *client.decoration(),
};
diff --git a/src/core/util.rs b/src/core/util.rs
@@ -90,7 +90,6 @@ impl Util {
let args: Vec<&str> = cmd.split_whitespace().collect();
if args.len() > 1 {
- println!("args: {:?}", args);
Command::new(args[0])
.args(&args[1..])
.stdout(Stdio::null())
@@ -98,7 +97,6 @@ impl Util {
.spawn()
.ok();
} else {
- println!("args: {:?}", args);
Command::new(args[0])
.stdout(Stdio::null())
.stderr(Stdio::null())
diff --git a/src/core/workspace.rs b/src/core/workspace.rs
@@ -13,6 +13,7 @@ use crate::cycle::Selector;
use crate::zone::Placement;
use crate::zone::PlacementKind;
use crate::zone::PlacementMethod;
+use crate::zone::PlacementRegion;
use crate::zone::ZoneId;
use crate::zone::ZoneManager;
use crate::zone::MAX_GAP_SIZE;
@@ -349,29 +350,29 @@ impl Workspace {
.map(|client| (client.zone(), client))
.unzip();
- let mut placements = zone_manager.arrange(self.root_zone, &to_ignore_ids);
- placements.extend(to_ignore_clients.into_iter().map(|client| {
- let (method, region, decoration) =
- if client.is_fullscreen() && !client.is_in_window() {
- (PlacementMethod::Tile, screen_region, NO_DECORATION)
+ zone_manager
+ .arrange(self.root_zone, &to_ignore_ids)
+ .into_iter()
+ .chain(to_ignore_clients.into_iter().map(|client| {
+ let (method, decoration) = if client.is_fullscreen() && !client.is_in_window() {
+ (PlacementMethod::Tile, NO_DECORATION)
} else {
- (
- PlacementMethod::Free,
- *client.free_region(),
- FREE_DECORATION,
- )
+ (PlacementMethod::Free, FREE_DECORATION)
};
- Placement {
- method,
- kind: PlacementKind::Client(client.window()),
- zone: client.zone(),
- region: Some(region),
- decoration,
- }
- }));
-
- placements
+ Placement {
+ method,
+ kind: PlacementKind::Client(client.window()),
+ zone: client.zone(),
+ region: if method == PlacementMethod::Tile {
+ PlacementRegion::NewRegion(screen_region)
+ } else {
+ PlacementRegion::FreeRegion
+ },
+ decoration,
+ }
+ }))
+ .collect()
} else {
Vec::with_capacity(0)
}
diff --git a/src/core/zone.rs b/src/core/zone.rs
@@ -79,45 +79,21 @@ impl PlacementKind {
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum PlacementRegion {
+ NoRegion,
+ FreeRegion,
+ NewRegion(Region),
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Placement {
pub method: PlacementMethod,
pub kind: PlacementKind,
pub zone: ZoneId,
- pub region: Option<Region>,
+ pub region: PlacementRegion,
pub decoration: Decoration,
}
-impl Placement {
- pub fn inner_region(&self) -> Option<Region> {
- if let Some(region) = self.region {
- if let Some(frame) = self.decoration.frame {
- let extents = frame.extents;
-
- return Some(Region {
- pos: Pos {
- x: extents.left as i32,
- y: extents.top as i32,
- },
- dim: Dim {
- w: region.dim.w - extents.left - extents.right,
- h: region.dim.h - extents.top - extents.bottom,
- },
- });
- } else {
- return Some(Region {
- pos: Pos {
- x: 0,
- y: 0,
- },
- dim: region.dim,
- });
- }
- }
-
- None
- }
-}
-
type LayoutFn = fn(&Region, &LayoutData, Vec<bool>) -> Vec<(Disposition, bool)>;
#[non_exhaustive]
@@ -126,6 +102,7 @@ type LayoutFn = fn(&Region, &LayoutData, Vec<bool>) -> Vec<(Disposition, bool)>;
pub enum LayoutKind {
/// Free layouts
Float = b'F',
+ BorderlessFloat = b'L',
SingleFloat = b'Z',
/// Tiled layouts
@@ -158,6 +135,15 @@ impl LayoutKind {
single: false,
wraps: true,
},
+ LayoutKind::BorderlessFloat => LayoutConfig {
+ method: PlacementMethod::Free,
+ decoration: NO_DECORATION,
+ root_only: true,
+ gap: false,
+ persistent: false,
+ single: false,
+ wraps: true,
+ },
LayoutKind::SingleFloat => LayoutConfig {
method: PlacementMethod::Free,
decoration: FREE_DECORATION,
@@ -294,6 +280,7 @@ impl LayoutKind {
fn default_data(&self) -> LayoutData {
match *self {
LayoutKind::Float => Default::default(),
+ LayoutKind::BorderlessFloat => Default::default(),
LayoutKind::SingleFloat => Default::default(),
LayoutKind::Center => LayoutData {
main_count: 5u32,
@@ -339,6 +326,9 @@ impl LayoutKind {
LayoutKind::Float => {
|_, _, active_map| vec![(Disposition::Unchanged, true); active_map.len()]
},
+ LayoutKind::BorderlessFloat => {
+ |_, _, active_map| vec![(Disposition::Unchanged, true); active_map.len()]
+ },
LayoutKind::SingleFloat => |_, _, active_map| {
active_map
.into_iter()
@@ -1065,7 +1055,11 @@ impl ZoneManager {
method,
kind: PlacementKind::Client(*window),
zone: id,
- region: Some(region),
+ region: if method == PlacementMethod::Free {
+ PlacementRegion::FreeRegion
+ } else {
+ PlacementRegion::NewRegion(region)
+ },
decoration,
}];
},
@@ -1074,7 +1068,12 @@ impl ZoneManager {
method,
kind: PlacementKind::Tab(zones.len()),
zone: id,
- region: Some(region),
+ region: if method == PlacementMethod::Free {
+ PlacementRegion::FreeRegion
+ } else {
+ zone_changes.push((id, ZoneChange::Region(region)));
+ PlacementRegion::NewRegion(region)
+ },
decoration,
}];
@@ -1113,6 +1112,7 @@ impl ZoneManager {
placements.extend(
self.arrange_subzones(id, region, decoration, method, to_ignore),
);
+
placements
},
}
@@ -1124,7 +1124,11 @@ impl ZoneManager {
method,
kind: PlacementKind::Layout,
zone: id,
- region: Some(region),
+ region: if method == PlacementMethod::Free {
+ PlacementRegion::FreeRegion
+ } else {
+ PlacementRegion::NewRegion(region)
+ },
decoration,
}];
@@ -1141,28 +1145,46 @@ impl ZoneManager {
zones.into_iter().zip(application.into_iter()).for_each(
|(id, (disposition, is_visible))| {
- let zone = self.zone_map.get(&id).unwrap();
- let subzones = self.gather_subzones(id, true);
-
- zone_changes.extend(
- subzones
- .into_iter()
- .map(|id| (id, ZoneChange::Visible(true)))
- .collect::<Vec<(ZoneId, ZoneChange)>>(),
- );
-
let (region, decoration) = match disposition {
- Disposition::Unchanged => (zone.region, zone.decoration),
- Disposition::Changed(region, decoration) => {
- zone_changes.push((id, ZoneChange::Region(region)));
- zone_changes.push((id, ZoneChange::Decoration(decoration)));
- zone_changes.push((id, ZoneChange::Method(method)));
-
- (region, decoration)
+ Disposition::Unchanged => {
+ let zone = self.zone_map.get(&id).unwrap();
+ (zone.region, decoration)
},
+ Disposition::Changed(region, decoration) => (region, decoration),
};
- if is_visible {
+ if !is_visible {
+ let subzones = self.gather_subzones(id, true);
+
+ placements.push(Placement {
+ method,
+ kind: PlacementKind::from_zone_content(
+ &self.zone(id).content,
+ ),
+ zone: id,
+ region: PlacementRegion::NoRegion,
+ decoration,
+ });
+
+ zone_changes.extend(
+ subzones
+ .into_iter()
+ .map(|id| {
+ placements.push(Placement {
+ method,
+ kind: PlacementKind::from_zone_content(
+ &self.zone(id).content,
+ ),
+ zone: id,
+ region: PlacementRegion::NoRegion,
+ decoration,
+ });
+
+ (id, ZoneChange::Visible(false))
+ })
+ .collect::<Vec<(ZoneId, ZoneChange)>>(),
+ );
+ } else {
subplacements.push((id, region, decoration));
}
},
@@ -1180,6 +1202,13 @@ impl ZoneManager {
},
};
+ {
+ let zone = self.zone_map.get_mut(&id).unwrap();
+ zone.region = region;
+ zone.decoration = decoration;
+ zone.method = method;
+ }
+
zone_changes.into_iter().for_each(|(id, change)| {
let zone = self.zone_map.get_mut(&id).unwrap();