wzrd

An ICCCM & EWMH compliant X11 reparenting, dynamic window manager, written in Rust
git clone git://git.deurzen.net/wzrd
Log | Files | Refs | LICENSE

commit 1b7e8201fc3b5cfc46f0c36fadf232b955fd67fc
parent 986b9e3e483242fbdb6e3d34f9d395a5782d721e
Author: deurzen <m.deurzen@tum.de>
Date:   Tue, 16 Mar 2021 03:29:03 +0100

refactors layout handling code

Diffstat:
Msrc/core/model.rs | 33++++++++++++++++++++++-----------
Msrc/core/util.rs | 2--
Msrc/core/workspace.rs | 41+++++++++++++++++++++--------------------
Msrc/core/zone.rs | 135++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
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(&region); + + let zone = self.zone_manager.zone_mut(id); + zone.set_region(region); + }, + PlacementMethod::Tile => client.set_tile_region(&region), }; }, _ => 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();