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 1b8584dd1843e49379ebff746b082fb3c168e968
parent bdd7f36b46c981b8fa7492d71c870b3b780918af
Author: deurzen <m.deurzen@tum.de>
Date:   Mon, 15 Mar 2021 02:20:19 +0100

implements master jumping

Diffstat:
Msrc/core/main.rs | 3+--
Msrc/core/model.rs | 41++++++++++++++++++-----------------------
Msrc/core/workspace.rs | 16+++++++++++++---
Msrc/core/zone.rs | 59+++++++++++++++++++++++++++++++++--------------------------
4 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/src/core/main.rs b/src/core/main.rs @@ -47,9 +47,8 @@ pub fn main() -> Result<()> { SimpleLogger::init(LevelFilter::Debug, simplelog::Config::default())?; let (conn, screen_num) = x11rb::connect(None)?; - let mut xconn = XConnection::new(&conn, screen_num)?; - let (mouse_bindings, key_bindings) = init_bindings(); + let mut xconn = XConnection::new(&conn, screen_num)?; Model::new(&mut xconn, &key_bindings, &mouse_bindings).run(key_bindings, mouse_bindings); diff --git a/src/core/model.rs b/src/core/model.rs @@ -163,7 +163,7 @@ impl<'a> Model<'a> { .collect::<Vec<&(winsys::input::MouseEventKey, winsys::input::MouseShortcut)>>(), ); - model.conn.top_level_windows().iter().for_each(|&window| { + model.conn.top_level_windows().into_iter().for_each(|window| { if model.conn.must_manage_window(window) { model.manage(window, false); } @@ -384,8 +384,8 @@ impl<'a> Model<'a> { let stack: Vec<Window> = workspace .stack_after_focus() - .iter() - .map(|&window| self.frame(window).unwrap()) + .into_iter() + .map(|window| self.frame(window).unwrap()) .collect(); let (regular, fullscreen): (Vec<Window>, Vec<Window>) = @@ -395,7 +395,7 @@ impl<'a> Model<'a> { }) }); - let (free, regular): (Vec<Window>, Vec<Window>) = regular.iter().partition(|&&window| { + let (free, regular): (Vec<Window>, Vec<Window>) = regular.into_iter().partition(|&window| { self.client(window).map_or(true, |client| { let id = client.zone(); let zone = self.zone_manager.zone(id); @@ -461,7 +461,7 @@ impl<'a> Model<'a> { let mut stack_walk = windows.iter(); let mut order_changed = false; - let mut prev_window = stack_walk.next().map(|&w| w); + let mut prev_window = stack_walk.next().cloned(); for (i, &window) in stack_walk.enumerate() { order_changed |= self.stacking_order.get(i + 1) != Some(&window); @@ -482,12 +482,12 @@ impl<'a> Model<'a> { let mut client_list: Vec<&Client> = self.client_map.values().collect::<Vec<&Client>>(); client_list.sort_by_key(|&a| a.managed_since()); - let client_list: Vec<Window> = client_list.iter().map(|client| client.window()).collect(); + let client_list: Vec<Window> = client_list.into_iter().map(|client| client.window()).collect(); self.conn.update_client_list(&client_list); let stack_windows: Vec<Window> = stack - .iter() - .map(|&window| self.window(window).unwrap()) + .into_iter() + .map(|window| self.window(window).unwrap()) .collect(); let mut client_list_stacking = client_list; @@ -1364,9 +1364,9 @@ impl<'a> Model<'a> { pub fn apply_float_retain_region(&mut self) { let workspace_index = self.active_workspace(); let workspace = self.workspace(workspace_index); - let windows = workspace.iter().map(|&w| w).collect::<Vec<Window>>(); + let windows = workspace.iter().copied().collect::<Vec<Window>>(); - windows.iter().for_each(|&w| { + windows.into_iter().for_each(|w| { let client = self.client(w).unwrap(); let active_region = *client.active_region(); @@ -1549,24 +1549,19 @@ impl<'a> Model<'a> { }); clients_to_map - .iter() - .for_each(|&window| self.map_client(window)); + .into_iter() + .for_each(|window| self.map_client(window)); windows_to_unmap - .iter() - .for_each(|&window| self.unmap_client(window)); - - let mut sticky_windows = Vec::with_capacity(self.sticky_clients.len()); - - for &window in self.sticky_clients.iter() { - sticky_windows.push(window); - } + .into_iter() + .for_each(|window| self.unmap_client(window)); - for window in sticky_windows { + let sticky_windows = self.sticky_clients.iter().copied().collect::<Vec<_>>(); + sticky_windows.into_iter().for_each(|window| { if let Some(client) = self.client_mut(window) { client.set_workspace(index); } - } + }); self.apply_layout(self.active_workspace(), true); self.sync_focus(); @@ -1925,7 +1920,7 @@ impl<'a> Model<'a> { } let workspace = self.workspace(index); - let window = workspace.get_client_for(sel); + let window = workspace.get_client_for(sel, &self.zone_manager); if window.is_none() { return; diff --git a/src/core/workspace.rs b/src/core/workspace.rs @@ -222,12 +222,22 @@ impl Workspace { pub fn get_client_for( &self, sel: &ClientSelector, + zone_manager: &ZoneManager, ) -> Option<&Window> { let sel = match sel { ClientSelector::AtActive => Selector::AtActive, ClientSelector::AtMaster => { - // TODO: zone change - return None; + if let Some(&id) = self.zones.active_element() { + let cycle = zone_manager.nearest_cycle(id); + let cycle = zone_manager.zone(cycle); + + Selector::AtIndex(std::cmp::min( + cycle.data().unwrap().main_count as usize, + self.clients.len(), + )) + } else { + return None; + } }, ClientSelector::AtIndex(index) => Selector::AtIndex(*index), ClientSelector::AtIdent(window) => Selector::AtIdent(*window as Ident), @@ -339,7 +349,7 @@ impl Workspace { .unzip(); let mut placements = zone_manager.arrange(self.root_zone, &to_ignore_ids); - placements.extend(to_ignore_clients.iter().map(|&client| { + 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) diff --git a/src/core/zone.rs b/src/core/zone.rs @@ -336,8 +336,8 @@ impl LayoutKind { }, LayoutKind::SingleFloat => |_, _, active_map| { active_map - .iter() - .map(|&b| (Disposition::Unchanged, b)) + .into_iter() + .map(|b| (Disposition::Unchanged, b)) .collect() }, LayoutKind::Stack => |region, data, active_map| { @@ -360,7 +360,7 @@ impl LayoutKind { let config = &LayoutKind::Stack.config(); active_map - .iter() + .into_iter() .enumerate() .map(|(i, _)| { let i = i as u32; @@ -399,7 +399,7 @@ impl LayoutKind { let (pos, dim) = region.values(); active_map - .iter() + .into_iter() .map(|_| { ( Disposition::Changed( @@ -423,7 +423,7 @@ impl LayoutKind { let h_ratio: f32 = (h_comp - data.main_count) as f32 / h_comp as f32; active_map - .iter() + .into_iter() .map(|_| { ( Disposition::Changed( @@ -464,9 +464,9 @@ impl LayoutKind { let mut after_active = false; active_map - .iter() + .into_iter() .enumerate() - .map(|(i, &active)| { + .map(|(i, active)| { if active { after_active = true; @@ -719,6 +719,13 @@ impl Zone { } } + pub fn data(&self) -> Option<&LayoutData> { + match self.content { + ZoneContent::Layout(ref layout, _) => Some(layout.get_data()), + _ => None, + } + } + pub fn data_mut(&mut self) -> Option<&mut LayoutData> { match self.content { ZoneContent::Layout(ref mut layout, _) => Some(layout.get_data_mut()), @@ -1000,10 +1007,10 @@ impl ZoneManager { }]; let active_element = zones.active_element(); - active_element.iter().for_each(|&&id| { + active_element.into_iter().for_each(|&id| { zone_changes.push((id, ZoneChange::Visible(true))); - self.gather_subzones(id, true).iter().for_each(|&id| { + self.gather_subzones(id, true).into_iter().for_each(|id| { zone_changes.push((id, ZoneChange::Visible(true))); }); }); @@ -1014,7 +1021,7 @@ impl ZoneManager { .for_each(|&id| { zone_changes.push((id, ZoneChange::Visible(false))); - self.gather_subzones(id, true).iter().for_each(|&id| { + self.gather_subzones(id, true).into_iter().for_each(|id| { zone_changes.push((id, ZoneChange::Visible(false))); }); }); @@ -1025,7 +1032,7 @@ impl ZoneManager { let subzones = self.gather_subzones(id, true); let method = PlacementMethod::Tile; - subzones.iter().for_each(|&id| { + subzones.into_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))); @@ -1060,40 +1067,40 @@ impl ZoneManager { zones.iter().map(|id| Some(id) == active_element).collect(), ); - zones.iter().zip(application.iter()).for_each( - |(&id, (disposition, is_visible))| { + 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 - .iter() - .map(|&id| (id, ZoneChange::Visible(true))) + .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::Region(region))); + zone_changes.push((id, ZoneChange::Decoration(decoration))); zone_changes.push((id, ZoneChange::Method(method))); - (*region, *decoration) + (region, decoration) }, }; - if *is_visible { + if is_visible { subplacements.push((id, region, decoration)); } }, ); - subplacements.iter().for_each(|(id, region, decoration)| { + subplacements.into_iter().for_each(|(id, region, decoration)| { placements.extend(self.arrange_subzones( - *id, - *region, - *decoration, + id, + region, + decoration, method, to_ignore, )); @@ -1103,10 +1110,10 @@ impl ZoneManager { }, }; - zone_changes.iter().for_each(|(id, change)| { - let zone = self.zone_map.get_mut(id).unwrap(); + zone_changes.into_iter().for_each(|(id, change)| { + let zone = self.zone_map.get_mut(&id).unwrap(); - match *change { + match change { ZoneChange::Visible(is_visible) => { zone.is_visible = is_visible; },