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 60d1daa699d6e343889eeb26b0ba4ee463836ebe
parent 2ff313b6dbe6a91375ce0c8879bd04bd81f680f0
Author: deurzen <m.deurzen@tum.de>
Date:   Sat, 13 Mar 2021 16:36:19 +0100

fixes zone stacking order

Diffstat:
Msrc/core/model.rs | 48+++++++++++++++++++++++-------------------------
Msrc/core/workspace.rs | 23+++++++++++++++++++++++
Msrc/core/zone.rs | 94++++++++++++++++++++++++++++++++++++++++++-------------------------------------
3 files changed, 96 insertions(+), 69 deletions(-)

diff --git a/src/core/model.rs b/src/core/model.rs @@ -153,7 +153,7 @@ impl<'a> Model<'a> { id, )); - model.zone_manager.get_zone_mut(id).set_region(region); + model.zone_manager.zone_mut(id).set_region(region); } model.workspaces.activate_for(&Selector::AtIndex(0)); @@ -346,7 +346,8 @@ impl<'a> Model<'a> { // TODO: zone change let region = self.active_screen().placeable_region(); - let placements = workspace.arrange(&mut self.zone_manager, region); + let placements = + workspace.arrange(&mut self.zone_manager, &self.client_map, region); let (show, hide): (Vec<&Placement>, Vec<&Placement>) = placements .iter() @@ -404,24 +405,21 @@ impl<'a> Model<'a> { .collect(); let (regular, fullscreen): (Vec<Window>, Vec<Window>) = - stack.iter().partition(|&window| { - self.client(*window).map_or(false, |client| { + stack.iter().partition(|&&window| { + self.client(window).map_or(false, |client| { !client.is_fullscreen() || client.is_in_window() }) }); - // TODO: zone change - // let (regular, free): (Vec<Window>, Vec<Window>) = - // if workspace.layout_config().method == PlacementMethod::Free { - // (Vec::new(), regular) - // } else { - // regular.iter().partition(|&window| { - // self.client(*window) - // .map_or(false, |client| !client.is_free()) - // }) - // }; - - let (regular, free): (Vec<Window>, Vec<Window>) = (Vec::new(), regular); + let (free, regular): (Vec<Window>, Vec<Window>) = + regular.iter().partition(|&&window| { + self.client(window).map_or(true, |client| { + let id = self.zone_manager.client_id(client.window()); + let zone = self.zone_manager.zone(id); + + zone.method() == PlacementMethod::Free || client.is_free() + }) + }); let above = self.stack.layer_windows(StackLayer::Above); let notification = self.stack.layer_windows(StackLayer::Notification); @@ -1044,7 +1042,7 @@ impl<'a> Model<'a> { } } - let id = self.zone_manager.client_zone(window); + let id = self.zone_manager.client_id(window); self.workspaces.get_mut(workspace).map(|w| { w.remove_zone(id); w.remove_client(window); @@ -1700,7 +1698,7 @@ impl<'a> Model<'a> { if let Some(id) = workspace.active_zone() { let cycle = self.zone_manager.nearest_cycle(id); - let cycle = self.zone_manager.get_zone_mut(cycle); + let cycle = self.zone_manager.zone_mut(cycle); cycle.set_kind(kind); } @@ -2336,7 +2334,7 @@ impl<'a> Model<'a> { let placement = Placement { method: PlacementMethod::Free, kind: PlacementKind::Client(window), - zone: self.zone_manager.client_zone(window), + zone: self.zone_manager.client_id(window), region: Some(region), decoration: *client.decoration(), }; @@ -2383,7 +2381,7 @@ impl<'a> Model<'a> { let placement = Placement { method: PlacementMethod::Free, kind: PlacementKind::Client(window), - zone: self.zone_manager.client_zone(window), + zone: self.zone_manager.client_id(window), region: Some(region), decoration: *client.decoration(), }; @@ -2450,7 +2448,7 @@ impl<'a> Model<'a> { let placement = Placement { method: PlacementMethod::Free, kind: PlacementKind::Client(window), - zone: self.zone_manager.client_zone(window), + zone: self.zone_manager.client_id(window), region: Some(region), decoration: *client.decoration(), }; @@ -2552,7 +2550,7 @@ impl<'a> Model<'a> { let placement = Placement { method: PlacementMethod::Free, kind: PlacementKind::Client(window), - zone: self.zone_manager.client_zone(window), + zone: self.zone_manager.client_id(window), region: Some(region), decoration: *client.decoration(), }; @@ -2611,7 +2609,7 @@ impl<'a> Model<'a> { let placement = Placement { method: PlacementMethod::Free, kind: PlacementKind::Client(window), - zone: self.zone_manager.client_zone(window), + zone: self.zone_manager.client_id(window), region: Some(region), decoration: *client.decoration(), }; @@ -2718,7 +2716,7 @@ impl<'a> Model<'a> { } let window = client.window(); - let id = self.zone_manager.client_zone(window); + let id = self.zone_manager.client_id(window); let placement = Placement { method: PlacementMethod::Free, @@ -3284,7 +3282,7 @@ impl<'a> Model<'a> { let placement = Placement { method: PlacementMethod::Free, kind: PlacementKind::Client(window), - zone: self.zone_manager.client_zone(window), + zone: self.zone_manager.client_id(window), region: Some(region), decoration: *client.decoration(), }; diff --git a/src/core/workspace.rs b/src/core/workspace.rs @@ -7,7 +7,9 @@ use crate::common::Index; use crate::cycle::Cycle; use crate::cycle::InsertPos; use crate::cycle::Selector; +use crate::zone::Decoration; use crate::zone::Placement; +use crate::zone::PlacementKind; use crate::zone::PlacementMethod; use crate::zone::ZoneId; use crate::zone::ZoneManager; @@ -315,11 +317,32 @@ impl Workspace { pub fn arrange( &self, zone_manager: &mut ZoneManager, + client_map: &HashMap<Window, Client>, screen_region: Region, ) -> Vec<Placement> { if !self.clients.is_empty() { + let zone = zone_manager.zone_mut(self.root_zone); + zone.set_region(screen_region); + let mut placements = zone_manager.arrange(self.root_zone); + self.clients.iter().for_each(|&window| { + let client = client_map.get(&window).unwrap(); + + if client.is_fullscreen() { + placements.push(Placement { + method: PlacementMethod::Tile, + kind: PlacementKind::Client(window), + zone: zone_manager.client_id(window), + region: Some(screen_region), + decoration: Decoration { + border: None, + frame: None, + }, + }); + } + }); + placements } else { Vec::with_capacity(0) diff --git a/src/core/zone.rs b/src/core/zone.rs @@ -792,6 +792,7 @@ pub enum ZoneContent { pub struct Zone { id: ZoneId, parent: Option<ZoneId>, + method: PlacementMethod, content: ZoneContent, region: Region, decoration: Decoration, @@ -812,6 +813,7 @@ impl Zone { (id, Self { id, parent, + method: PlacementMethod::Free, content, region, decoration: Decoration { @@ -841,6 +843,10 @@ impl Zone { ) { self.region = region; } + + pub fn method(&self) -> PlacementMethod { + self.method + } } enum ZoneChange { @@ -848,6 +854,7 @@ enum ZoneChange { Active(bool), Region(Region), Decoration(Decoration), + Method(PlacementMethod), } pub struct ZoneManager { @@ -890,14 +897,14 @@ impl ZoneManager { id } - pub fn get_zone( + pub fn zone( &self, id: ZoneId, ) -> &Zone { self.zone_map.get(&id).unwrap() } - pub fn get_zone_mut( + pub fn zone_mut( &mut self, id: ZoneId, ) -> &mut Zone { @@ -911,7 +918,7 @@ impl ZoneManager { self.client_zones.remove(&id); } - pub fn client_zone( + pub fn client_id( &self, client: Window, ) -> ZoneId { @@ -1034,46 +1041,44 @@ impl ZoneManager { decoration, }]; - zone_changes.extend( - self.gather_subzones(id, true) - .iter() - .map(|&id| (id, ZoneChange::Visible(false))) - .collect::<Vec<(ZoneId, ZoneChange)>>(), - ); - let active_element = zones.active_element(); + active_element.iter().for_each(|&&id| { + zone_changes.push((id, ZoneChange::Visible(true))); + + self.gather_subzones(id, true).iter().for_each(|&id| { + zone_changes.push((id, ZoneChange::Visible(true))); + }); + }); + zones .iter() .filter(|&id| Some(id) != active_element) .for_each(|&id| { zone_changes.push((id, ZoneChange::Visible(false))); + + self.gather_subzones(id, true).iter().for_each(|&id| { + zone_changes.push((id, ZoneChange::Visible(false))); + }); }); match active_element { None => placements, Some(&id) => { let subzones = self.gather_subzones(id, true); + let method = PlacementMethod::Tile; - zone_changes.extend( - subzones - .iter() - .map(|&id| (id, ZoneChange::Visible(true))) - .collect::<Vec<(ZoneId, ZoneChange)>>(), - ); + subzones.iter().for_each(|&id| { + zone_changes.push((id, ZoneChange::Visible(true))); + zone_changes.push((id, ZoneChange::Region(region))); + zone_changes.push((id, ZoneChange::Method(method))); + }); - zone_changes.extend( - subzones - .iter() - .map(|&id| (id, ZoneChange::Region(region))) - .collect::<Vec<(ZoneId, ZoneChange)>>(), + placements.extend( + self.arrange_subzones( + id, region, decoration, method, + ), ); - placements.extend(self.arrange_subzones( - id, - region, - decoration, - PlacementMethod::Tile, - )); placements }, } @@ -1098,9 +1103,9 @@ impl ZoneManager { let mut subplacements = Vec::new(); zones.iter().zip(application.iter()).for_each( - |(id, (disposition, is_visible))| { - let zone = self.zone_map.get(id).unwrap(); - let subzones = self.gather_subzones(*id, true); + |(&id, (disposition, is_visible))| { + let zone = self.zone_map.get(&id).unwrap(); + let subzones = self.gather_subzones(id, true); zone_changes.extend( subzones @@ -1115,19 +1120,21 @@ impl ZoneManager { }, Disposition::Changed(region, decoration) => { zone_changes - .push((*id, ZoneChange::Region(*region))); + .push((id, ZoneChange::Region(*region))); zone_changes.push(( - *id, + id, ZoneChange::Decoration(*decoration), )); + zone_changes.push((id, ZoneChange::Method(method))); + (*region, *decoration) }, }; if *is_visible { - subplacements.push((*id, region, decoration)); + subplacements.push((id, region, decoration)); } }, ); @@ -1147,25 +1154,24 @@ impl ZoneManager { zone_changes.iter().for_each(|(id, change)| { let zone = self.zone_map.get_mut(id).unwrap(); - let kind = PlacementKind::from_zone_content(&zone.content); let region = zone.region; let decoration = zone.decoration; match *change { ZoneChange::Visible(is_visible) => { - // placements.push(Placement { - // kind, - // zone: *id, - // region: Some(region), - // decoration, - // }); - zone.is_visible = is_visible; }, - ZoneChange::Active(is_active) => zone.is_active = is_active, - ZoneChange::Region(region) => zone.region = region, + ZoneChange::Active(is_active) => { + zone.is_active = is_active; + }, + ZoneChange::Region(region) => { + zone.region = region; + }, ZoneChange::Decoration(decoration) => { - zone.decoration = decoration + zone.decoration = decoration; + }, + ZoneChange::Method(method) => { + zone.method = method; }, }; });