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 bdd7f36b46c981b8fa7492d71c870b3b780918af
parent a0ce39f7bede1ae9ab926667d4dce797c3e8fa01
Author: deurzen <m.deurzen@tum.de>
Date:   Mon, 15 Mar 2021 02:12:32 +0100

implements layout changers

Diffstat:
Msrc/core/client.rs | 1-
Msrc/core/common.rs | 4+---
Msrc/core/model.rs | 64++++++++++++++++++++++++++++++++++------------------------------
Msrc/core/workspace.rs | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/core/zone.rs | 73++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
5 files changed, 179 insertions(+), 75 deletions(-)

diff --git a/src/core/client.rs b/src/core/client.rs @@ -1,5 +1,4 @@ use crate::common::Decoration; -use crate::common::Frame; use crate::common::Ident; use crate::common::Identify; use crate::zone::ZoneId; diff --git a/src/core/common.rs b/src/core/common.rs @@ -1,8 +1,6 @@ use winsys::common::Dim; use winsys::common::Extents; use winsys::common::Padding; -use winsys::common::Pos; -use winsys::common::Region; use winsys::common::Window; use std::ops::Add; @@ -77,7 +75,7 @@ impl Add<Border> for Padding { fn add( self, - border: Border, + _: Border, ) -> Self::Output { Self::Output { left: self.left + 1, diff --git a/src/core/model.rs b/src/core/model.rs @@ -2,9 +2,7 @@ use crate::binding::KeyBindings; use crate::binding::MouseBindings; use crate::client::Client; use crate::common::Change; -use crate::common::Decoration; use crate::common::Direction; -use crate::common::Frame; use crate::common::Index; use crate::common::FREE_DECORATION; use crate::common::MIN_WINDOW_DIM; @@ -27,9 +25,7 @@ use crate::zone::LayoutKind; use crate::zone::Placement; use crate::zone::PlacementKind; use crate::zone::PlacementMethod; -use crate::zone::Zone; use crate::zone::ZoneContent; -use crate::zone::ZoneId; use crate::zone::ZoneManager; #[allow(unused_imports)] @@ -38,7 +34,6 @@ use crate::util::Util; use winsys::common::Corner; use winsys::common::Dim; use winsys::common::Edge; -use winsys::common::Extents; use winsys::common::Grip; use winsys::common::Hints; use winsys::common::IcccmWindowState; @@ -351,7 +346,7 @@ impl<'a> Model<'a> { self.place_client(window, placement.method); self.map_client(frame); }, - PlacementKind::Tab(size) => {}, + PlacementKind::Tab(_) => {}, PlacementKind::Layout => {}, }; } @@ -362,7 +357,7 @@ impl<'a> Model<'a> { let frame = self.frame(window).unwrap(); self.unmap_client(frame); }, - PlacementKind::Tab(size) => {}, + PlacementKind::Tab(_) => {}, PlacementKind::Layout => {}, }; } @@ -854,13 +849,9 @@ impl<'a> Model<'a> { let active_region = client.active_region(); let current_pos = self.conn.get_pointer_position(); - println!("ACTIVE REGION {:?}", active_region); - - // if let Some(warp_pos) = - // active_region.quadrant_center_from_pos(current_pos) - // { - // self.conn.warp_pointer(warp_pos); - // } + if let Some(warp_pos) = active_region.quadrant_center_from_pos(current_pos) { + self.conn.warp_pointer(warp_pos); + } } fn remanage( @@ -1587,25 +1578,31 @@ impl<'a> Model<'a> { change: Change, ) { let workspace_index = self.active_workspace(); - let workspace = self.workspace_mut(workspace_index); - workspace.change_gap_size(change, 5); + if let Some(workspace) = self.workspaces.get(workspace_index) { + workspace.change_gap_size(change, 5, &mut self.zone_manager); + } + self.apply_layout(workspace_index, true); } pub fn reset_layout(&mut self) { let workspace_index = self.active_workspace(); - let workspace = self.workspace_mut(workspace_index); - workspace.reset_layout(); + if let Some(workspace) = self.workspaces.get(workspace_index) { + workspace.reset_layout(&mut self.zone_manager); + } + self.apply_layout(workspace_index, true); } pub fn reset_gap_size(&mut self) { let workspace_index = self.active_workspace(); - let workspace = self.workspace_mut(workspace_index); - workspace.reset_gap_size(); + if let Some(workspace) = self.workspaces.get(workspace_index) { + workspace.reset_gap_size(&mut self.zone_manager); + } + self.apply_layout(workspace_index, true); } @@ -1614,9 +1611,11 @@ impl<'a> Model<'a> { change: Change, ) { let workspace_index = self.active_workspace(); - let workspace = self.workspace_mut(workspace_index); - workspace.change_main_count(change); + if let Some(workspace) = self.workspaces.get(workspace_index) { + workspace.change_main_count(change, &mut self.zone_manager); + } + self.apply_layout(workspace_index, true); } @@ -1625,9 +1624,11 @@ impl<'a> Model<'a> { change: Change, ) { let workspace_index = self.active_workspace(); - let workspace = self.workspace_mut(workspace_index); - workspace.change_main_factor(change, 0.05f32); + if let Some(workspace) = self.workspaces.get(workspace_index) { + workspace.change_main_factor(change, 0.05f32, &mut self.zone_manager); + } + self.apply_layout(workspace_index, true); } @@ -1637,17 +1638,21 @@ impl<'a> Model<'a> { change: Change, ) { let workspace_index = self.active_workspace(); - let workspace = self.workspace_mut(workspace_index); - workspace.change_margin(edge, change, 5); + if let Some(workspace) = self.workspaces.get(workspace_index) { + workspace.change_margin(edge, change, 5, &mut self.zone_manager); + } + self.apply_layout(workspace_index, true); } pub fn reset_margin(&mut self) { let workspace_index = self.active_workspace(); - let workspace = self.workspace_mut(workspace_index); - workspace.reset_margin(); + if let Some(workspace) = self.workspaces.get(workspace_index) { + workspace.reset_margin(&mut self.zone_manager); + } + self.apply_layout(workspace_index, true); } @@ -1830,8 +1835,7 @@ impl<'a> Model<'a> { self.zone_manager.activate_zone(id); - self - .workspaces + self.workspaces .get_mut(client_workspace_index) .and_then(|ws| ws.focus_client(window)); diff --git a/src/core/workspace.rs b/src/core/workspace.rs @@ -1,9 +1,6 @@ use crate::client::Client; -use crate::common::Border; use crate::common::Change; -use crate::common::Decoration; use crate::common::Direction; -use crate::common::Frame; use crate::common::Ident; use crate::common::Identify; use crate::common::Index; @@ -12,12 +9,14 @@ use crate::common::NO_DECORATION; use crate::cycle::Cycle; use crate::cycle::InsertPos; use crate::cycle::Selector; -use crate::zone::LayoutKind; use crate::zone::Placement; use crate::zone::PlacementKind; use crate::zone::PlacementMethod; use crate::zone::ZoneId; use crate::zone::ZoneManager; +use crate::zone::MAX_GAP_SIZE; +use crate::zone::MAX_MAIN_COUNT; +use crate::zone::MAX_MARGIN; use winsys::common::Edge; use winsys::common::Grip; @@ -425,48 +424,125 @@ impl Workspace { } } - pub fn reset_layout(&mut self) { - // TODO: zone change + pub fn reset_layout( + &self, + zone_manager: &mut ZoneManager, + ) { + if let Some(&id) = self.zones.active_element() { + if let Some(default_data) = zone_manager.active_default_data(id) { + if let Some(data) = zone_manager.active_data_mut(id) { + *data = default_data; + } + } + } } pub fn change_gap_size( - &mut self, + &self, change: Change, delta: u32, + zone_manager: &mut ZoneManager, ) { - // TODO: zone change + if let Some(&id) = self.zones.active_element() { + if let Some(data) = zone_manager.active_data_mut(id) { + data.gap_size = match change { + Change::Inc => std::cmp::min(data.main_count + delta, MAX_GAP_SIZE), + Change::Dec => std::cmp::max(data.main_count as i32 - delta as i32, 0) as u32, + }; + } + } } - pub fn reset_gap_size(&mut self) { - // TODO: zone change + pub fn reset_gap_size( + &self, + zone_manager: &mut ZoneManager, + ) { + if let Some(&id) = self.zones.active_element() { + if let Some(default_data) = zone_manager.active_default_data(id) { + if let Some(data) = zone_manager.active_data_mut(id) { + data.gap_size = default_data.gap_size; + } + } + } } pub fn change_main_count( - &mut self, + &self, change: Change, + zone_manager: &mut ZoneManager, ) { - // TODO: zone change + if let Some(&id) = self.zones.active_element() { + if let Some(data) = zone_manager.active_data_mut(id) { + data.main_count = match change { + Change::Inc => std::cmp::min(data.main_count + 1, MAX_MAIN_COUNT), + Change::Dec => std::cmp::max(data.main_count as i32 - 1, 0) as u32, + }; + } + } } pub fn change_main_factor( - &mut self, + &self, change: Change, delta: f32, + zone_manager: &mut ZoneManager, ) { - // TODO: zone change + if let Some(&id) = self.zones.active_element() { + if let Some(data) = zone_manager.active_data_mut(id) { + match change { + Change::Inc => data.main_factor += delta, + Change::Dec => data.main_factor -= delta, + } + + if data.main_factor < 0.05f32 { + data.main_factor = 0.05f32; + } else if data.main_factor > 0.95f32 { + data.main_factor = 0.95f32; + } + } + } } pub fn change_margin( - &mut self, + &self, edge: Edge, change: Change, delta: u32, + zone_manager: &mut ZoneManager, ) { - // TODO: zone change + if let Some(&id) = self.zones.active_element() { + if let Some(data) = zone_manager.active_data_mut(id) { + let delta_change = match change { + Change::Inc => delta as i32, + Change::Dec => -(delta as i32), + }; + + let (edge_value, edge_max) = match edge { + Edge::Left => (&mut data.margin.left, MAX_MARGIN.left), + Edge::Right => (&mut data.margin.right, MAX_MARGIN.right), + Edge::Top => (&mut data.margin.top, MAX_MARGIN.top), + Edge::Bottom => (&mut data.margin.bottom, MAX_MARGIN.bottom), + }; + + let edge_changed = *edge_value as i32 + delta_change; + let edge_changed = std::cmp::max(edge_changed, 0); + let edge_changed = std::cmp::min(edge_changed, edge_max as i32); + *edge_value = edge_changed as u32; + } + } } - pub fn reset_margin(&mut self) { - // TODO: zone change + pub fn reset_margin( + &self, + zone_manager: &mut ZoneManager, + ) { + if let Some(&id) = self.zones.active_element() { + if let Some(default_data) = zone_manager.active_default_data(id) { + if let Some(data) = zone_manager.active_data_mut(id) { + data.margin = default_data.margin; + } + } + } } pub fn focused_icon(&self) -> Option<Window> { diff --git a/src/core/zone.rs b/src/core/zone.rs @@ -1,4 +1,3 @@ -use crate::common::Border; use crate::common::Decoration; use crate::common::Frame; use crate::common::Ident; @@ -28,9 +27,9 @@ use std::vec::Vec; pub type ZoneId = u32; -const MAX_MAIN_COUNT: u32 = 15; -const MAX_GAP_SIZE: u32 = 300; -const MAX_MARGIN: Padding = Padding { +pub const MAX_MAIN_COUNT: u32 = 15; +pub const MAX_GAP_SIZE: u32 = 300; +pub const MAX_MARGIN: Padding = Padding { left: 700, right: 700, top: 400, @@ -395,7 +394,7 @@ impl LayoutKind { }) .collect() }, - LayoutKind::Monocle => |region, data, active_map| { + LayoutKind::Monocle => |region, _, active_map| { let config = &LayoutKind::Monocle.config(); let (pos, dim) = region.values(); @@ -417,7 +416,6 @@ impl LayoutKind { }, LayoutKind::Center => |region, data, active_map| { let config = &LayoutKind::Center.config(); - let default_data = &LayoutKind::Center.default_data(); let (pos, dim) = region.values(); let h_comp = MAX_MAIN_COUNT + 1; @@ -445,7 +443,7 @@ impl LayoutKind { .collect() }, LayoutKind::Paper => |region, data, active_map| { - const min_w_ratio: f32 = 0.5; + const MIN_W_RATIO: f32 = 0.5; let config = &LayoutKind::Paper.config(); let (pos, dim) = region.values(); @@ -456,10 +454,10 @@ impl LayoutKind { } let cw = (dim.w as f32 - * if data.main_factor > min_w_ratio { + * if data.main_factor > MIN_W_RATIO { data.main_factor } else { - min_w_ratio + MIN_W_RATIO }) as u32; let w = ((dim.w - cw) as usize / (n - 1)) as i32; @@ -532,20 +530,20 @@ impl Default for LayoutConfig { #[non_exhaustive] #[derive(Debug, PartialEq, Clone, Copy)] -struct LayoutData { +pub struct LayoutData { /// Generic layout data - margin: Option<Padding>, - gap_size: u32, + pub margin: Padding, + pub gap_size: u32, /// Tiled layout data - main_count: u32, - main_factor: f32, + pub main_count: u32, + pub main_factor: f32, } impl Default for LayoutData { fn default() -> Self { Self { - margin: None, + margin: Default::default(), gap_size: 0u32, main_count: 1u32, @@ -714,6 +712,20 @@ impl Zone { self.region = region; } + pub fn default_data(&self) -> Option<LayoutData> { + match &self.content { + ZoneContent::Layout(layout, _) => Some(layout.get_default_data()), + _ => None, + } + } + + pub fn data_mut(&mut self) -> Option<&mut LayoutData> { + match self.content { + ZoneContent::Layout(ref mut layout, _) => Some(layout.get_data_mut()), + _ => None, + } + } + pub fn config(&self) -> Option<LayoutConfig> { match self.content { ZoneContent::Layout(ref layout, _) => Some(layout.kind.config()), @@ -776,12 +788,32 @@ impl ZoneManager { ZoneContent::Tab(ref mut zones) | ZoneContent::Layout(_, ref mut zones) => { zones.activate_for(&Selector::AtIdent(id)); self.activate_zone(cycle_id); - } - _ => {} + }, + _ => {}, } } } + pub fn active_default_data( + &mut self, + id: ZoneId, + ) -> Option<LayoutData> { + let cycle = self.nearest_cycle(id); + let cycle = self.zone(cycle); + + cycle.default_data() + } + + pub fn active_data_mut( + &mut self, + id: ZoneId, + ) -> Option<&mut LayoutData> { + let cycle = self.nearest_cycle(id); + let cycle = self.zone_mut(cycle); + + cycle.data_mut() + } + pub fn active_layoutconfig( &self, id: ZoneId, @@ -1025,10 +1057,7 @@ impl ZoneManager { let (method, application) = layout.apply( &region, - zones - .iter() - .map(|id| Some(id) == active_element) - .collect(), + zones.iter().map(|id| Some(id) == active_element).collect(), ); zones.iter().zip(application.iter()).for_each( @@ -1076,8 +1105,6 @@ impl ZoneManager { zone_changes.iter().for_each(|(id, change)| { let zone = self.zone_map.get_mut(id).unwrap(); - let region = zone.region; - let decoration = zone.decoration; match *change { ZoneChange::Visible(is_visible) => {