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 336efce7af5f2193a74d36d88e8c4249a3ca48ed
parent 754009d630cdfe78d466837556098b4192953a8e
Author: deurzen <m.deurzen@tum.de>
Date:   Fri, 12 Mar 2021 13:28:06 +0100

updates PlacementMethod specification

Diffstat:
Msrc/core/model.rs | 90++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/core/workspace.rs | 11++++-------
Msrc/core/zone.rs | 117+++++++++++++++++++++++++++++++++++++++++++------------------------------------
3 files changed, 104 insertions(+), 114 deletions(-)

diff --git a/src/core/model.rs b/src/core/model.rs @@ -27,7 +27,7 @@ use crate::workspace::Workspace; use crate::zone::Decoration; use crate::zone::Frame; use crate::zone::Layout; -use crate::zone::LayoutMethod; +use crate::zone::PlacementMethod; use crate::zone::Placement; use crate::zone::PlacementKind; use crate::zone::ZoneContent; @@ -350,7 +350,7 @@ impl<'a> Model<'a> { // TODO: zone change let region = self.active_screen().placeable_region(); - let (method, placements) = + let placements = workspace.arrange(&mut self.zone_manager, region); let (show, hide): (Vec<&Placement>, Vec<&Placement>) = placements .iter() @@ -361,13 +361,8 @@ impl<'a> Model<'a> { PlacementKind::Client(window) => { let frame = self.frame(window).unwrap(); - // TODO: zone change - self.update_client_placement( - &placement, - LayoutMethod::Tile, - ); - // TODO: zone change - self.place_client(window, LayoutMethod::Tile); + self.update_client_placement(&placement); + self.place_client(window, placement.method); self.map_client(frame); }, PlacementKind::Tab(size) => {}, @@ -421,7 +416,7 @@ impl<'a> Model<'a> { // TODO: zone change // let (regular, free): (Vec<Window>, Vec<Window>) = - // if workspace.layout_config().method == LayoutMethod::Free { + // if workspace.layout_config().method == PlacementMethod::Free { // (Vec::new(), regular) // } else { // regular.iter().partition(|&window| { @@ -819,8 +814,8 @@ impl<'a> Model<'a> { .new_zone(parent_zone, ZoneContent::Client(window)); let current_workspace = self.workspaces.get_mut(workspace).unwrap(); - current_workspace.add_zone(id, &InsertPos::AfterActive); current_workspace.add_client(window, &InsertPos::Back); + current_workspace.add_zone(id, &InsertPos::AfterActive); } if let Some(parent) = parent { @@ -981,10 +976,10 @@ impl<'a> Model<'a> { fn is_applyable( client: &Client, // TODO: zone change - // method: LayoutMethod, + // method: PlacementMethod, ) -> bool { // TODO: zone change - // method == LayoutMethod::Free + // method == PlacementMethod::Free !client.is_floating() && !client.is_disowned() && client.is_managed() } @@ -1003,7 +998,7 @@ impl<'a> Model<'a> { // .unwrap() // .layout_config() // .method - // == LayoutMethod::Free) + // == PlacementMethod::Free) } fn is_focusable( @@ -1097,7 +1092,6 @@ impl<'a> Model<'a> { fn update_client_placement( &mut self, placement: &Placement, - method: LayoutMethod, ) { match placement.kind { PlacementKind::Client(window) => { @@ -1108,9 +1102,9 @@ impl<'a> Model<'a> { placement.decoration.frame.map(|f| f.extents), ); - match method { - LayoutMethod::Free => client.set_free_region(region), - LayoutMethod::Tile => client.set_tile_region(region), + match placement.method { + PlacementMethod::Free => client.set_free_region(region), + PlacementMethod::Tile => client.set_tile_region(region), }; }, _ => panic!("attempting to update non-client placement"), @@ -1120,7 +1114,7 @@ impl<'a> Model<'a> { fn place_client( &self, window: Window, - method: LayoutMethod, + method: PlacementMethod, ) { let client = self.client(window).unwrap(); @@ -1131,8 +1125,8 @@ impl<'a> Model<'a> { // TODO: zone change self.conn.place_window(frame, match method { - LayoutMethod::Free => &client.free_region(), - LayoutMethod::Tile => &client.tile_region(), + PlacementMethod::Free => &client.free_region(), + PlacementMethod::Tile => &client.tile_region(), }); self.refresh_client(window); @@ -2328,6 +2322,7 @@ impl<'a> Model<'a> { }; let placement = Placement { + method: PlacementMethod::Free, kind: PlacementKind::Client(window), zone: id, region: Some(region), @@ -2336,9 +2331,9 @@ impl<'a> Model<'a> { }; // TODO: zone change - self.update_client_placement(&placement, LayoutMethod::Free); + self.update_client_placement(&placement); // TODO: zone change - self.place_client(window, LayoutMethod::Free); + self.place_client(window, placement.method); } } } @@ -2380,6 +2375,7 @@ impl<'a> Model<'a> { let extents = *client.frame_extents(); let placement = Placement { + method: PlacementMethod::Free, kind: PlacementKind::Client(window), zone: id, region: Some(region), @@ -2393,10 +2389,8 @@ impl<'a> Model<'a> { }, }; - // TODO: zone change - self.update_client_placement(&placement, LayoutMethod::Free); - // TODO: zone change - self.place_client(window, LayoutMethod::Free); + self.update_client_placement(&placement); + self.place_client(window, placement.method); } } } @@ -2458,6 +2452,7 @@ impl<'a> Model<'a> { let extents = *client.frame_extents(); let placement = Placement { + method: PlacementMethod::Free, kind: PlacementKind::Client(window), zone: id, region: Some(region), @@ -2471,10 +2466,8 @@ impl<'a> Model<'a> { }, }; - // TODO: zone change - self.update_client_placement(&placement, LayoutMethod::Free); - // TODO: zone change - self.place_client(window, LayoutMethod::Free); + self.update_client_placement(&placement); + self.place_client(window, placement.method); } } } @@ -2570,6 +2563,7 @@ impl<'a> Model<'a> { let extents = *client.frame_extents(); let placement = Placement { + method: PlacementMethod::Free, kind: PlacementKind::Client(window), zone: id, region: Some(region), @@ -2583,10 +2577,8 @@ impl<'a> Model<'a> { }, }; - // TODO: zone change - self.update_client_placement(&placement, LayoutMethod::Free); - // TODO: zone change - self.place_client(window, LayoutMethod::Free); + self.update_client_placement(&placement); + self.place_client(window, placement.method); } } } @@ -2639,6 +2631,7 @@ impl<'a> Model<'a> { }; let placement = Placement { + method: PlacementMethod::Free, kind: PlacementKind::Client(window), zone: id, region: Some(region), @@ -2652,14 +2645,8 @@ impl<'a> Model<'a> { }, }; - // TODO: zone change - self.update_client_placement( - &placement, - LayoutMethod::Free, - ); - - // TODO: zone change - self.place_client(window, LayoutMethod::Free); + self.update_client_placement(&placement); + self.place_client(window, placement.method); } } } @@ -2763,6 +2750,7 @@ impl<'a> Model<'a> { let id = self.zone_manager.client_zone(window); let placement = Placement { + method: PlacementMethod::Free, kind: PlacementKind::Client(window), zone: id, region: Some(region), @@ -2776,10 +2764,8 @@ impl<'a> Model<'a> { }, }; - // TODO: zone change - self.update_client_placement(&placement, LayoutMethod::Free); - // TODO: zone change - self.place_client(window, LayoutMethod::Free); + self.update_client_placement(&placement); + self.place_client(window, placement.method); } } } @@ -3328,6 +3314,7 @@ impl<'a> Model<'a> { let extents = *client.frame_extents(); let placement = Placement { + method: PlacementMethod::Free, kind: PlacementKind::Client(window), zone: id, region: Some(region), @@ -3341,13 +3328,8 @@ impl<'a> Model<'a> { }, }; - // TODO: zone change - self.update_client_placement( - &placement, - LayoutMethod::Free, - ); - // TODO: zone change - self.place_client(window, LayoutMethod::Free); + self.update_client_placement(&placement); + self.place_client(window, placement.method); } } } else { diff --git a/src/core/workspace.rs b/src/core/workspace.rs @@ -7,7 +7,7 @@ use crate::common::Index; use crate::cycle::Cycle; use crate::cycle::InsertPos; use crate::cycle::Selector; -use crate::zone::LayoutMethod; +use crate::zone::PlacementMethod; use crate::zone::Placement; use crate::zone::ZoneId; use crate::zone::ZoneManager; @@ -316,16 +316,13 @@ impl Workspace { &self, zone_manager: &mut ZoneManager, screen_region: Region, - ) -> (LayoutMethod, Vec<Placement>) { + ) -> Vec<Placement> { if !self.clients.is_empty() { - // TODO: zone change - let placements = zone_manager.arrange(self.root_zone); - - println!("!!!!! {:#?}", placements); + let mut placements = zone_manager.arrange(self.root_zone); placements } else { - (LayoutMethod::Free, Vec::with_capacity(0)) + Vec::with_capacity(0) } } diff --git a/src/core/zone.rs b/src/core/zone.rs @@ -86,6 +86,15 @@ enum Disposition { Changed(Region, Decoration), } +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum PlacementMethod { + /// Does not inhibit free placement of clients + Free, + + /// Arranges clients along a predefined layout + Tile, +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum PlacementKind { Client(Window), @@ -105,6 +114,7 @@ impl PlacementKind { #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Placement { + pub method: PlacementMethod, pub kind: PlacementKind, pub zone: ZoneId, pub region: Option<Region>, @@ -144,15 +154,6 @@ impl Placement { type LayoutFn = fn(&Region, &LayoutData, Vec<bool>) -> Vec<(Disposition, bool)>; -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum LayoutMethod { - /// Does not inhibit free placement of clients - Free, - - /// Arranges clients along a predefined layout - Tile, -} - #[non_exhaustive] #[repr(u8)] #[derive( @@ -204,7 +205,7 @@ impl LayoutKind { LayoutKind::Paper => LayoutConfig::default(), LayoutKind::SStack => LayoutConfig::default(), LayoutKind::Stack => LayoutConfig { - method: LayoutMethod::Tile, + method: PlacementMethod::Tile, decoration: Decoration { frame: Some(Frame { extents: Extents { @@ -278,8 +279,6 @@ impl LayoutKind { let w = if n_stack == 0 { dim.w } else { split as u32 }; - println!("UNDER MAINCOUNT = {}", i); - ( Disposition::Changed( Region::new( @@ -293,7 +292,6 @@ impl LayoutKind { true, ) } else { - println!("OVER MAINCOUNT = {}", i); let sn = (i - data.main_count) as i32; ( @@ -325,7 +323,7 @@ impl LayoutKind { #[non_exhaustive] #[derive(Debug, PartialEq, Clone, Copy)] struct LayoutConfig { - method: LayoutMethod, + method: PlacementMethod, decoration: Decoration, root_only: bool, persistent: bool, @@ -336,7 +334,7 @@ struct LayoutConfig { impl Default for LayoutConfig { fn default() -> Self { Self { - method: LayoutMethod::Free, + method: PlacementMethod::Free, decoration: Default::default(), root_only: true, persistent: false, @@ -438,7 +436,7 @@ trait Apply { &self, region: &Region, active_map: Vec<bool>, - ) -> Vec<(Disposition, bool)>; + ) -> (PlacementMethod, Vec<(Disposition, bool)>); } impl Apply for Layout { @@ -446,11 +444,14 @@ impl Apply for Layout { &self, region: &Region, active_map: Vec<bool>, - ) -> Vec<(Disposition, bool)> { - (self.kind.func())( - region, - &self.data.get(&self.kind).unwrap(), - active_map, + ) -> (PlacementMethod, Vec<(Disposition, bool)>) { + ( + self.kind.config().method, + (self.kind.func())( + region, + &self.data.get(&self.kind).unwrap(), + active_map, + ) ) } } @@ -549,10 +550,6 @@ impl ZoneManager { } self.zone_map.insert(id, zone); - - let cycle = self.nearest_cycle(id); - self.arrange(cycle); - id } @@ -653,25 +650,30 @@ impl ZoneManager { pub fn arrange( &mut self, zone: ZoneId, - ) -> (LayoutMethod, Vec<Placement>) { - let id = self.nearest_cycle(zone); - let zone = self.zone_map.get_mut(&id).unwrap(); + ) -> Vec<Placement> { + let cycle = self.nearest_cycle(zone); + let zone = self.zone_map.get(&cycle).unwrap(); let region = zone.region; + let decoration = zone.decoration; + + let method = match &zone.content { + ZoneContent::Tab(_) => PlacementMethod::Tile, + ZoneContent::Layout(layout, _) => layout.kind.config().method, + _ => panic!("attempting to derive method from non-cycle"), + }; - zone.is_visible = true; - (LayoutMethod::Tile, self.arrange_subzones(id, region)) + self.arrange_subzones(cycle, region, decoration, method) } fn arrange_subzones( &mut self, zone: ZoneId, region: Region, + decoration: Decoration, + method: PlacementMethod, ) -> Vec<Placement> { let id = zone; let zone = self.zone_map.get(&id).unwrap(); - - let region = zone.region; - let decoration = zone.decoration; let content = &zone.content; let mut zone_changes: Vec<(ZoneId, ZoneChange)> = Vec::new(); @@ -679,6 +681,7 @@ impl ZoneManager { let mut placements = match &content { ZoneContent::Client(window) => { return vec![Placement { + method, kind: PlacementKind::Client(*window), zone: id, region: Some(region), @@ -687,6 +690,7 @@ impl ZoneManager { }, ZoneContent::Tab(zones) => { let mut placements = vec![Placement { + method, kind: PlacementKind::Tab(zones.len()), zone: id, region: Some(region), @@ -704,11 +708,7 @@ impl ZoneManager { zones .iter() .filter(|&id| { - if let Some(active_element) = active_element { - active_element != id - } else { - true - } + Some(id) != active_element }) .for_each(|&id| { zone_changes.push((id, ZoneChange::Visible(false))); @@ -733,20 +733,23 @@ impl ZoneManager { .collect::<Vec<(ZoneId, ZoneChange)>>(), ); - placements.extend(self.arrange_subzones(id, region)); + placements.extend( + self.arrange_subzones(id, region, decoration, PlacementMethod::Tile), + ); placements }, } }, ZoneContent::Layout(layout, zones) => { let mut placements = vec![Placement { + method, kind: PlacementKind::Layout, zone: id, region: Some(region), decoration, }]; - let application = layout.apply( + let (method, application) = layout.apply( &region, zones .iter() @@ -768,28 +771,36 @@ impl ZoneManager { .collect::<Vec<(ZoneId, ZoneChange)>>(), ); - let region = match disposition { - Disposition::Unchanged => zone.region, + 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), )); - *region + (*region, *decoration) }, }; if *is_visible { - subplacements.push((*id, region)); + subplacements.push((*id, region, decoration)); } }, ); - subplacements.iter().for_each(|(id, region)| { - placements.extend(self.arrange_subzones(*id, *region)); + subplacements.iter().for_each(|(id, region, decoration)| { + placements.extend(self.arrange_subzones( + *id, + *region, + *decoration, + method, + )); }); placements @@ -798,19 +809,19 @@ impl ZoneManager { zone_changes.iter().for_each(|(id, change)| { let zone = self.zone_map.get_mut(id).unwrap(); - let placement_kind = + 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: placement_kind, - zone: *id, - region: Some(region), - decoration, - }); + // placements.push(Placement { + // kind, + // zone: *id, + // region: Some(region), + // decoration, + // }); zone.is_visible = is_visible; },