commit ccbb1679d69a87ee0f104d3909acb3eacd20c970
parent bd2f9c3d2825ef05d2dac567e1c5b9f2cd74a4c9
Author: deurzen <m.deurzen@tum.de>
Date: Sun, 14 Mar 2021 11:22:33 +0100
updates zone arrangement handling
Diffstat:
M | src/core/client.rs | | | 29 | +++++++++++++++++++++++++---- |
M | src/core/common.rs | | | 148 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- |
M | src/core/model.rs | | | 166 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
M | src/core/workspace.rs | | | 87 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
M | src/core/zone.rs | | | 231 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
5 files changed, 409 insertions(+), 252 deletions(-)
diff --git a/src/core/client.rs b/src/core/client.rs
@@ -1,8 +1,9 @@
use crate::common::Ident;
use crate::common::Identify;
-use crate::common::NO_EXTENTS;
-use crate::zone::Decoration;
-use crate::zone::Frame;
+use crate::common::Decoration;
+use crate::common::Frame;
+use crate::zone::ZoneId;
+
use winsys::common::Extents;
use winsys::common::Hex32;
use winsys::common::Pid;
@@ -15,6 +16,7 @@ use winsys::common::WindowType;
use std::time::SystemTime;
pub struct Client {
+ zone: ZoneId,
window: Window,
frame: Window,
name: String,
@@ -74,6 +76,7 @@ impl Client {
ppid: Option<Pid>,
) -> Self {
Self {
+ zone: 0,
window,
frame,
name,
@@ -117,6 +120,19 @@ impl Client {
}
#[inline]
+ pub fn zone(&self) -> ZoneId {
+ self.zone
+ }
+
+ #[inline]
+ pub fn set_zone(
+ &mut self,
+ zone: ZoneId,
+ ) {
+ self.zone = zone;
+ }
+
+ #[inline]
pub fn windows(&self) -> (Window, Window) {
(self.window, self.frame)
}
@@ -299,7 +315,12 @@ impl Client {
#[inline]
pub fn frame_extents(&self) -> Extents {
- NO_EXTENTS + self.decoration
+ Extents {
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ } + self.decoration
}
#[inline]
diff --git a/src/core/common.rs b/src/core/common.rs
@@ -2,9 +2,10 @@ use winsys::common::Dim;
use winsys::common::Extents;
use winsys::common::Pos;
use winsys::common::Region;
+use winsys::common::Padding;
use winsys::common::Window;
-pub type Color = u32;
+use std::ops::Add;
#[macro_export]
macro_rules! WM_NAME (
@@ -15,22 +16,145 @@ pub const MIN_WINDOW_DIM: Dim = Dim {
w: 75,
h: 50,
};
-pub const BORDER_SIZE: u32 = 3;
-pub const FREE_EXTENTS: Extents = Extents {
- left: 3,
- right: 1,
- top: 1,
- bottom: 1,
+pub const NO_DECORATION: Decoration = Decoration {
+ border: None,
+ frame: None,
};
-pub const NO_EXTENTS: Extents = Extents {
- left: 0,
- right: 0,
- top: 0,
- bottom: 0,
+pub const FREE_DECORATION: Decoration = Decoration {
+ border: None,
+ frame: Some(Frame {
+ extents: Extents {
+ left: 3,
+ right: 1,
+ top: 1,
+ bottom: 1,
+ },
+ colors: ColorScheme::DEFAULT,
+ }),
};
+pub type Color = u32;
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct ColorScheme {
+ pub regular: Color,
+ pub focused: Color,
+ pub urgent: Color,
+ pub rdisowned: Color,
+ pub fdisowned: Color,
+ pub rsticky: Color,
+ pub fsticky: Color,
+}
+
+impl ColorScheme {
+ const DEFAULT: Self = Self {
+ regular: 0x333333,
+ focused: 0xe78a53,
+ urgent: 0xfbcb97,
+ rdisowned: 0x999999,
+ fdisowned: 0xc1c1c1,
+ rsticky: 0x444444,
+ fsticky: 0x5f8787,
+ };
+}
+
+impl Default for ColorScheme {
+ fn default() -> Self {
+ Self::DEFAULT
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct Border {
+ pub width: u32,
+ pub colors: ColorScheme,
+}
+
+impl Add<Border> for Padding {
+ type Output = Self;
+
+ fn add(
+ self,
+ border: Border,
+ ) -> Self::Output {
+ Self::Output {
+ left: self.left + 1,
+ right: self.right + 1,
+ top: self.top + 1,
+ bottom: self.bottom + 1,
+ }
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct Frame {
+ pub extents: Extents,
+ pub colors: ColorScheme,
+}
+
+impl Add<Frame> for Padding {
+ type Output = Self;
+
+ fn add(
+ self,
+ frame: Frame,
+ ) -> Self::Output {
+ Self::Output {
+ left: self.left + frame.extents.left,
+ right: self.right + frame.extents.right,
+ top: self.top + frame.extents.top,
+ bottom: self.bottom + frame.extents.bottom,
+ }
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct Decoration {
+ pub border: Option<Border>,
+ pub frame: Option<Frame>,
+}
+
+impl Default for Decoration {
+ fn default() -> Self {
+ Self {
+ border: None,
+ frame: None,
+ }
+ }
+}
+
+impl Decoration {
+ pub fn extents(&self) -> Extents {
+ Extents {
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ } + *self
+ }
+}
+
+impl Add<Decoration> for Padding {
+ type Output = Self;
+
+ fn add(
+ mut self,
+ decoration: Decoration,
+ ) -> Self::Output {
+ if let Some(border) = decoration.border {
+ self = self + border;
+ }
+
+ if let Some(frame) = decoration.frame {
+ self = self + frame;
+ }
+
+ self
+ }
+}
+
pub type Ident = u32;
pub type Index = usize;
diff --git a/src/core/model.rs b/src/core/model.rs
@@ -4,8 +4,11 @@ use crate::client::Client;
use crate::common::Change;
use crate::common::Direction;
use crate::common::Index;
-use crate::common::FREE_EXTENTS;
+use crate::common::FREE_DECORATION;
+use crate::common::NO_DECORATION;
use crate::common::MIN_WINDOW_DIM;
+use crate::common::Decoration;
+use crate::common::Frame;
use crate::consume::get_spawner_pid;
use crate::cycle::Cycle;
use crate::cycle::InsertPos;
@@ -19,13 +22,12 @@ use crate::stack::StackManager;
use crate::workspace::Buffer;
use crate::workspace::BufferKind;
use crate::workspace::Workspace;
-use crate::zone::Decoration;
-use crate::zone::Frame;
use crate::zone::Layout;
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;
@@ -331,7 +333,10 @@ impl<'a> Model<'a> {
// TODO: zone change
let region = self.active_screen().placeable_region();
- let placements = workspace.arrange(&mut self.zone_manager, &self.client_map, region);
+ let placements =
+ workspace.arrange(&mut self.zone_manager, &self.client_map, region, |client| {
+ !Self::is_applyable(client)
+ });
let (show, hide): (Vec<&Placement>, Vec<&Placement>) = placements
.iter()
@@ -480,22 +485,18 @@ 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();
-
self.conn.update_client_list(&client_list);
- let mut client_list_stacking = client_list;
-
let stack_windows: Vec<Window> = stack
.iter()
.map(|&window| self.window(window).unwrap())
.collect();
+ let mut client_list_stacking = client_list;
client_list_stacking.retain(|&window| !stack_windows.contains(&window));
-
client_list_stacking = client_list_stacking
.iter()
.chain(stack_windows.iter())
@@ -505,6 +506,24 @@ impl<'a> Model<'a> {
self.conn.update_client_list_stacking(&client_list_stacking);
}
+ fn zone(
+ &self,
+ window: Window,
+ ) -> Option<&Zone> {
+ self.zone_manager
+ .client_id_checked(window)
+ .and_then(|id| self.zone_manager.zone_checked(id))
+ }
+
+ fn zone_mut(
+ &mut self,
+ window: Window,
+ ) -> Option<&mut Zone> {
+ self.zone_manager
+ .client_id_checked(window)
+ .and_then(move |id| self.zone_manager.zone_checked_mut(id))
+ }
+
fn window(
&self,
window: Window,
@@ -682,11 +701,11 @@ impl<'a> Model<'a> {
geometry = if size_hints.is_some() {
geometry
.with_size_hints(&size_hints)
- .with_extents(&FREE_EXTENTS)
+ .with_extents(&FREE_DECORATION.extents())
} else {
geometry
.with_minimum_dim(&MIN_WINDOW_DIM)
- .with_extents(&FREE_EXTENTS)
+ .with_extents(&FREE_DECORATION.extents())
};
let parent = self.conn.get_icccm_window_transient_for(window);
@@ -769,9 +788,10 @@ impl<'a> Model<'a> {
client.set_context(context);
client.set_workspace(workspace);
+ let extents = FREE_DECORATION.extents();
self.conn.reparent_window(window, frame, Pos {
- x: FREE_EXTENTS.left as i32,
- y: FREE_EXTENTS.top as i32,
+ x: extents.left as i32,
+ y: extents.top as i32,
});
self.conn
@@ -786,6 +806,8 @@ impl<'a> Model<'a> {
.zone_manager
.new_zone(parent_zone, ZoneContent::Client(window));
+ client.set_zone(id);
+
let current_workspace = self.workspaces.get_mut(workspace).unwrap();
current_workspace.add_client(window, &InsertPos::Back);
current_workspace.add_zone(id, &InsertPos::AfterActive);
@@ -943,41 +965,32 @@ impl<'a> Model<'a> {
}
}
- fn is_applyable(
- client: &Client,
- // TODO: zone change
- // method: PlacementMethod,
- ) -> bool {
- // TODO: zone change
- // method == PlacementMethod::Free
- !client.is_floating() && !client.is_disowned() && client.is_managed()
+ fn is_applyable(client: &Client) -> bool {
+ !client.is_floating()
+ && !client.is_disowned()
+ && client.is_managed()
+ && (!client.is_fullscreen() || client.is_in_window())
}
fn is_free(
&self,
client: &Client,
) -> bool {
- (!client.is_fullscreen() || client.is_in_window())
- && (client.is_floating() || client.is_disowned() || !client.is_managed())
- // TODO: zone change
- // || self
- // .workspaces
- // .get(client.workspace())
- // .unwrap()
- // .layout_config()
- // .method
- // == PlacementMethod::Free)
+ client.is_floating() && (!client.is_fullscreen() || client.is_in_window()) || {
+ let id = self.zone_manager.client_id(client.window());
+ let zone = self.zone_manager.zone(id);
+
+ zone.method() == PlacementMethod::Free
+ }
}
fn is_focusable(
&self,
window: Window,
) -> bool {
- if let Some(client) = self.client(window) {
+ self.client(window).map_or(false, |client| {
!client.is_disowned() && !client.is_iconified()
- } else {
- false
- }
+ })
}
fn remove_window(
@@ -1115,7 +1128,6 @@ impl<'a> Model<'a> {
self.conn.place_window(window, inner_region);
- // TODO: zone change
self.conn.place_window(frame, match method {
PlacementMethod::Free => &client.free_region(),
PlacementMethod::Tile => &client.tile_region(),
@@ -1387,9 +1399,7 @@ impl<'a> Model<'a> {
client.set_free_region(&active_region);
});
- let workspace = self.workspace_mut(workspace_index);
- // TODO: zone change
- // workspace.set_layout(LayoutKind::Float);
+ self.set_layout(LayoutKind::Float);
self.apply_layout(workspace_index, false);
}
@@ -1659,7 +1669,6 @@ impl<'a> Model<'a> {
pub fn set_layout(
&mut self,
- // TODO: zone change
kind: LayoutKind,
) {
let workspace_index = self.active_workspace();
@@ -1669,35 +1678,45 @@ impl<'a> Model<'a> {
let cycle = self.zone_manager.nearest_cycle(id);
let cycle = self.zone_manager.zone_mut(cycle);
+ info!(
+ "activating layout {:?} on workspace {}",
+ kind, workspace_index
+ );
+
cycle.set_kind(kind);
+ self.apply_layout(workspace_index, true);
}
-
- info!(
- "activating layout {:?} on workspace {}",
- kind, workspace_index
- );
-
- self.apply_layout(workspace_index, true);
}
pub fn toggle_layout(&mut self) {
let workspace_index = self.active_workspace();
let workspace = self.workspace_mut(workspace_index);
- workspace.toggle_layout();
- self.apply_layout(workspace_index, true);
+ if let Some(id) = workspace.active_zone() {
+ let cycle = self.zone_manager.nearest_cycle(id);
+ let cycle = self.zone_manager.zone_mut(cycle);
+ let prev_kind = cycle.get_prev_kind();
+
+ info!(
+ "activating layout {:?} on workspace {}",
+ prev_kind, workspace_index
+ );
+
+ cycle.set_kind(prev_kind);
+ self.apply_layout(workspace_index, true);
+ }
}
pub fn toggle_in_window_focus(&mut self) {
if let Some(focus) = self.focus {
if let Some(client) = self.client_mut(focus) {
- let is_in_window = client.is_in_window();
- client.set_in_window(!is_in_window);
+ let must_in_window = !client.is_in_window();
+ client.set_in_window(must_in_window);
- if is_in_window {
- self.fullscreen(focus);
- } else {
+ if must_in_window {
self.unfullscreen(focus);
+ } else {
+ self.fullscreen(focus);
}
}
}
@@ -1706,8 +1725,8 @@ impl<'a> Model<'a> {
pub fn toggle_invincible_focus(&mut self) {
if let Some(focus) = self.focus {
if let Some(client) = self.client_mut(focus) {
- let is_invincible = client.is_invincible();
- client.set_invincible(!is_invincible);
+ let must_invincible = !client.is_invincible();
+ client.set_invincible(must_invincible);
}
}
}
@@ -1715,8 +1734,8 @@ impl<'a> Model<'a> {
pub fn toggle_producing_focus(&mut self) {
if let Some(focus) = self.focus {
if let Some(client) = self.client_mut(focus) {
- let is_producing = client.is_producing();
- client.set_producing(!is_producing);
+ let must_producing = !client.is_producing();
+ client.set_producing(must_producing);
}
}
}
@@ -1734,6 +1753,7 @@ impl<'a> Model<'a> {
if let Some(client) = self.client(window) {
let active_workspace_index = client.workspace();
let workspace_index = client.workspace();
+ let id = self.zone_manager.client_id(client.window());
let client = self.client_mut(window).unwrap();
let must_float = !client.is_floating();
@@ -1827,10 +1847,12 @@ impl<'a> Model<'a> {
let workspace = self.workspace_mut(client_workspace_index);
workspace.focus_client(window);
- // TODO: zone change
- // if workspace.layout_config().persistent {
- // self.apply_layout(client_workspace_index, false);
- // }
+ let id = self.zone_manager.client_id(window);
+ if let Some(config) = self.zone_manager.cycle_config(id) {
+ if config.persistent {
+ self.apply_layout(client_workspace_index, false);
+ }
+ }
if self.conn.get_focused_window() != window {
self.conn.focus_window(window);
@@ -1889,10 +1911,15 @@ impl<'a> Model<'a> {
window: Window,
) {
if let Some(client) = self.client(window) {
- if client.is_fullscreen() {
- self.unfullscreen(window);
- } else {
+ let must_fullscreen = !client.is_fullscreen();
+ let id = self.zone_manager.client_id(client.window());
+
+ let must_float = client.is_floating() || client.is_disowned();
+
+ if must_fullscreen {
self.fullscreen(window);
+ } else {
+ self.unfullscreen(window);
}
}
}
@@ -3363,14 +3390,9 @@ impl<'a> Model<'a> {
client.frame_extents()
} else {
if self.conn.must_manage_window(window) {
- FREE_EXTENTS
+ FREE_DECORATION.extents()
} else {
- Extents {
- left: 0,
- right: 0,
- top: 0,
- bottom: 0,
- }
+ NO_DECORATION.extents()
}
},
);
diff --git a/src/core/workspace.rs b/src/core/workspace.rs
@@ -4,10 +4,15 @@ use crate::common::Direction;
use crate::common::Ident;
use crate::common::Identify;
use crate::common::Index;
+use crate::common::Decoration;
+use crate::common::Frame;
+use crate::common::Border;
+use crate::common::FREE_DECORATION;
+use crate::common::NO_DECORATION;
use crate::cycle::Cycle;
use crate::cycle::InsertPos;
use crate::cycle::Selector;
-use crate::zone::Decoration;
+use crate::zone::LayoutKind;
use crate::zone::Placement;
use crate::zone::PlacementKind;
use crate::zone::PlacementMethod;
@@ -312,34 +317,56 @@ impl Workspace {
self.clients.remove_for(&Selector::AtActive)
}
- pub fn arrange(
+ pub fn arrange<F>(
&self,
zone_manager: &mut ZoneManager,
client_map: &HashMap<Window, Client>,
screen_region: Region,
- ) -> Vec<Placement> {
+ filter: F,
+ ) -> Vec<Placement>
+ where
+ F: Fn(&Client) -> bool,
+ {
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,
- },
- });
- }
- });
+ let (to_ignore_ids, to_ignore_clients): (Vec<_>, Vec<_>) = self
+ .clients
+ .iter()
+ .map(|window| client_map.get(window).unwrap())
+ .filter(|&client| filter(client))
+ .map(|client| (client.zone(), client))
+ .unzip();
+
+ let mut placements = zone_manager.arrange(self.root_zone, &to_ignore_ids);
+ placements.extend(to_ignore_clients
+ .iter()
+ .map(|&client| {
+ let (method, region, decoration) =
+ if client.is_fullscreen() && !client.is_in_window() {
+ (
+ PlacementMethod::Tile,
+ screen_region,
+ NO_DECORATION,
+ )
+ } else {
+ (
+ PlacementMethod::Free,
+ *client.free_region(),
+ FREE_DECORATION,
+ )
+ };
+
+ Placement {
+ method: method,
+ kind: PlacementKind::Client(client.window()),
+ zone: client.zone(),
+ region: Some(region),
+ decoration: decoration,
+ }
+ })
+ );
placements
} else {
@@ -347,24 +374,6 @@ impl Workspace {
}
}
- pub fn set_layout(
- &mut self,
- // kind: LayoutKind,
- ) {
- // TODO: zone change
- }
-
- pub fn toggle_layout(&mut self) {
- // TODO: zone change
- }
-
- pub fn cycle_layout(
- &mut self,
- dir: Direction,
- ) {
- // TODO: zone change
- }
-
pub fn cycle_focus(
&mut self,
dir: Direction,
diff --git a/src/core/zone.rs b/src/core/zone.rs
@@ -1,5 +1,8 @@
use crate::common::Ident;
use crate::common::Identify;
+use crate::common::Decoration;
+use crate::common::Frame;
+use crate::common::Border;
use crate::cycle::Cycle;
use crate::cycle::InsertPos;
@@ -16,13 +19,11 @@ use strum_macros::EnumIter;
use strum_macros::ToString;
use std::collections::HashMap;
-use std::ops::Add;
use std::string::ToString;
use std::sync::atomic;
use std::vec::Vec;
pub type ZoneId = u32;
-type Color = u32;
const MAX_MAIN_COUNT: u32 = 15;
const MAX_GAP_SIZE: u32 = 300;
@@ -39,109 +40,6 @@ fn next_id() -> ZoneId {
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct ColorScheme {
- pub regular: Color,
- pub focused: Color,
- pub urgent: Color,
- pub rdisowned: Color,
- pub fdisowned: Color,
- pub rsticky: Color,
- pub fsticky: Color,
-}
-
-impl Default for ColorScheme {
- fn default() -> Self {
- Self {
- regular: 0x333333,
- focused: 0xe78a53,
- urgent: 0xfbcb97,
- rdisowned: 0x999999,
- fdisowned: 0xc1c1c1,
- rsticky: 0x444444,
- fsticky: 0x5f8787,
- }
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct Border {
- pub width: u32,
- pub colors: ColorScheme,
-}
-
-impl Add<Border> for Padding {
- type Output = Self;
-
- fn add(
- self,
- border: Border,
- ) -> Self::Output {
- Self::Output {
- left: self.left + 1,
- right: self.right + 1,
- top: self.top + 1,
- bottom: self.bottom + 1,
- }
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct Frame {
- pub extents: Extents,
- pub colors: ColorScheme,
-}
-
-impl Add<Frame> for Padding {
- type Output = Self;
-
- fn add(
- self,
- frame: Frame,
- ) -> Self::Output {
- Self::Output {
- left: self.left + frame.extents.left,
- right: self.right + frame.extents.right,
- top: self.top + frame.extents.top,
- bottom: self.bottom + frame.extents.bottom,
- }
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct Decoration {
- pub border: Option<Border>,
- pub frame: Option<Frame>,
-}
-
-impl Default for Decoration {
- fn default() -> Self {
- Self {
- border: None,
- frame: None,
- }
- }
-}
-
-impl Add<Decoration> for Padding {
- type Output = Self;
-
- fn add(
- mut self,
- decoration: Decoration,
- ) -> Self::Output {
- if let Some(border) = decoration.border {
- self = self + border;
- }
-
- if let Some(frame) = decoration.frame {
- self = self + frame;
- }
-
- self
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Disposition {
Unchanged,
Changed(Region, Decoration),
@@ -437,7 +335,6 @@ impl LayoutKind {
fn func(&self) -> LayoutFn {
match *self {
- // TODO
LayoutKind::Float => {
|_, _, active_map| vec![(Disposition::Unchanged, true); active_map.len()]
},
@@ -624,14 +521,14 @@ impl LayoutKind {
#[non_exhaustive]
#[derive(Debug, PartialEq, Clone, Copy)]
-struct LayoutConfig {
- method: PlacementMethod,
- decoration: Decoration,
- root_only: bool,
- gap: bool,
- persistent: bool,
- single: bool,
- wraps: bool,
+pub struct LayoutConfig {
+ pub method: PlacementMethod,
+ pub decoration: Decoration,
+ pub root_only: bool,
+ pub gap: bool,
+ pub persistent: bool,
+ pub single: bool,
+ pub wraps: bool,
}
impl Default for LayoutConfig {
@@ -778,8 +675,6 @@ impl Zone {
parent: Option<ZoneId>,
content: ZoneContent,
region: Region,
- is_active: bool,
- is_visible: bool,
) -> (ZoneId, Self) {
let id = next_id();
@@ -793,23 +688,52 @@ impl Zone {
border: None,
frame: None,
},
- is_active,
- is_visible,
+ is_active: true,
+ is_visible: true,
})
}
+ pub fn set_content(
+ &mut self,
+ content: ZoneContent,
+ ) {
+ self.content = content;
+ }
+
pub fn set_kind(
&mut self,
kind: LayoutKind,
) {
match self.content {
ZoneContent::Layout(ref mut layout, _) => {
+ layout.prev_kind = layout.kind;
layout.kind = kind;
},
_ => {},
}
}
+ pub fn get_prev_kind(&self) -> LayoutKind {
+ match &self.content {
+ ZoneContent::Layout(layout, _) => layout.prev_kind,
+ _ => panic!("attempting to obtain layout kind from non-layout"),
+ }
+ }
+
+ pub fn get_kind(&self) -> LayoutKind {
+ match &self.content {
+ ZoneContent::Layout(layout, _) => layout.kind,
+ _ => panic!("attempting to obtain layout kind from non-layout"),
+ }
+ }
+
+ pub fn set_active(
+ &mut self,
+ is_active: bool,
+ ) {
+ self.is_active = is_active;
+ }
+
pub fn set_region(
&mut self,
region: Region,
@@ -817,6 +741,13 @@ impl Zone {
self.region = region;
}
+ pub fn config(&self) -> Option<LayoutConfig> {
+ match self.content {
+ ZoneContent::Layout(ref layout, _) => Some(layout.kind.config()),
+ _ => None,
+ }
+ }
+
pub fn method(&self) -> PlacementMethod {
self.method
}
@@ -848,11 +779,14 @@ impl ZoneManager {
parent: Option<ZoneId>,
content: ZoneContent,
) -> ZoneId {
- let (id, zone) = Zone::new(parent, content, Region::new(0, 0, 0, 0), true, true);
+ let (id, zone) = Zone::new(parent, content, Region::new(0, 0, 0, 0));
- if let ZoneContent::Client(window) = &zone.content {
- self.client_zones.insert(*window, id);
- }
+ match &zone.content {
+ ZoneContent::Client(window) => {
+ self.client_zones.insert(*window, id);
+ },
+ _ => {},
+ };
let parent = parent.and_then(|p| self.zone_map.get_mut(&p));
@@ -869,6 +803,13 @@ impl ZoneManager {
id
}
+ pub fn zone_checked(
+ &self,
+ id: ZoneId,
+ ) -> Option<&Zone> {
+ self.zone_map.get(&id)
+ }
+
pub fn zone(
&self,
id: ZoneId,
@@ -876,6 +817,13 @@ impl ZoneManager {
self.zone_map.get(&id).unwrap()
}
+ pub fn zone_checked_mut(
+ &mut self,
+ id: ZoneId,
+ ) -> Option<&mut Zone> {
+ self.zone_map.get_mut(&id)
+ }
+
pub fn zone_mut(
&mut self,
id: ZoneId,
@@ -890,6 +838,13 @@ impl ZoneManager {
self.client_zones.remove(&id);
}
+ pub fn client_id_checked(
+ &self,
+ client: Window,
+ ) -> Option<ZoneId> {
+ self.client_zones.get(&client).map(|&id| id)
+ }
+
pub fn client_id(
&self,
client: Window,
@@ -897,6 +852,16 @@ impl ZoneManager {
*self.client_zones.get(&client).unwrap()
}
+ pub fn cycle_config(
+ &self,
+ id: ZoneId,
+ ) -> Option<LayoutConfig> {
+ let cycle = self.nearest_cycle(id);
+ let zone = self.zone(cycle);
+
+ zone.config()
+ }
+
pub fn nearest_cycle(
&self,
id: ZoneId,
@@ -965,6 +930,7 @@ impl ZoneManager {
pub fn arrange(
&mut self,
zone: ZoneId,
+ to_ignore: &Vec<ZoneId>,
) -> Vec<Placement> {
let cycle = self.nearest_cycle(zone);
let zone = self.zone_map.get(&cycle).unwrap();
@@ -977,7 +943,7 @@ impl ZoneManager {
_ => panic!("attempting to derive method from non-cycle"),
};
- self.arrange_subzones(cycle, region, decoration, method)
+ self.arrange_subzones(cycle, region, decoration, method, to_ignore)
}
fn arrange_subzones(
@@ -986,6 +952,7 @@ impl ZoneManager {
region: Region,
decoration: Decoration,
method: PlacementMethod,
+ to_ignore: &Vec<ZoneId>,
) -> Vec<Placement> {
let id = zone;
let zone = self.zone_map.get(&id).unwrap();
@@ -1044,7 +1011,9 @@ impl ZoneManager {
zone_changes.push((id, ZoneChange::Method(method)));
});
- placements.extend(self.arrange_subzones(id, region, decoration, method));
+ placements.extend(
+ self.arrange_subzones(id, region, decoration, method, to_ignore),
+ );
placements
},
}
@@ -1059,6 +1028,12 @@ impl ZoneManager {
decoration,
}];
+ let zones: Vec<ZoneId> = zones
+ .iter()
+ .filter(|&id| !to_ignore.contains(id))
+ .map(|&id| id)
+ .collect();
+
let (method, application) = layout.apply(
®ion,
zones
@@ -1097,7 +1072,13 @@ impl ZoneManager {
);
subplacements.iter().for_each(|(id, region, decoration)| {
- placements.extend(self.arrange_subzones(*id, *region, *decoration, method));
+ placements.extend(self.arrange_subzones(
+ *id,
+ *region,
+ *decoration,
+ method,
+ to_ignore,
+ ));
});
placements