refactor(rust): remove getset dependency

This commit is contained in:
LGUG2Z
2025-09-20 14:31:44 -07:00
parent bcfb058bc3
commit 539aeec965
19 changed files with 620 additions and 761 deletions
Generated
-35
View File
@@ -2148,18 +2148,6 @@ dependencies = [
"wasi 0.14.4+wasi-0.2.4", "wasi 0.14.4+wasi-0.2.4",
] ]
[[package]]
name = "getset"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912"
dependencies = [
"proc-macro-error2",
"proc-macro2",
"quote",
"syn 2.0.106",
]
[[package]] [[package]]
name = "gif" name = "gif"
version = "0.11.4" version = "0.11.4"
@@ -2968,7 +2956,6 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
"ctrlc", "ctrlc",
"dirs 6.0.0", "dirs 6.0.0",
"getset",
"hotwatch", "hotwatch",
"komorebi-themes", "komorebi-themes",
"lazy_static", "lazy_static",
@@ -4633,28 +4620,6 @@ dependencies = [
"toml_edit", "toml_edit",
] ]
[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "proc-macro-error2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn 2.0.106",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.101" version = "1.0.101"
-5
View File
@@ -200,8 +200,6 @@
"png 0.18.0 registry+https://github.com/rust-lang/crates.io-index", "png 0.18.0 registry+https://github.com/rust-lang/crates.io-index",
"powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index", "powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index", "ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro-error-attr2 2.0.0 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro-error2 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro2 1.0.101 registry+https://github.com/rust-lang/crates.io-index", "proc-macro2 1.0.101 registry+https://github.com/rust-lang/crates.io-index",
"profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index", "profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
"profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index", "profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
@@ -532,7 +530,6 @@
"getrandom 0.1.16 registry+https://github.com/rust-lang/crates.io-index", "getrandom 0.1.16 registry+https://github.com/rust-lang/crates.io-index",
"getrandom 0.2.16 registry+https://github.com/rust-lang/crates.io-index", "getrandom 0.2.16 registry+https://github.com/rust-lang/crates.io-index",
"getrandom 0.3.3 registry+https://github.com/rust-lang/crates.io-index", "getrandom 0.3.3 registry+https://github.com/rust-lang/crates.io-index",
"getset 0.1.6 registry+https://github.com/rust-lang/crates.io-index",
"gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index", "gif 0.11.4 registry+https://github.com/rust-lang/crates.io-index",
"gif 0.13.3 registry+https://github.com/rust-lang/crates.io-index", "gif 0.13.3 registry+https://github.com/rust-lang/crates.io-index",
"git2 0.20.2 registry+https://github.com/rust-lang/crates.io-index", "git2 0.20.2 registry+https://github.com/rust-lang/crates.io-index",
@@ -645,8 +642,6 @@
"powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index", "powerfmt 0.2.0 registry+https://github.com/rust-lang/crates.io-index",
"powershell_script 1.1.0 registry+https://github.com/rust-lang/crates.io-index", "powershell_script 1.1.0 registry+https://github.com/rust-lang/crates.io-index",
"ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index", "ppv-lite86 0.2.21 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro-error-attr2 2.0.0 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro-error2 2.0.1 registry+https://github.com/rust-lang/crates.io-index",
"proc-macro2 1.0.101 registry+https://github.com/rust-lang/crates.io-index", "proc-macro2 1.0.101 registry+https://github.com/rust-lang/crates.io-index",
"profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index", "profiling 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
"profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index", "profiling-procmacros 1.0.17 registry+https://github.com/rust-lang/crates.io-index",
+5 -5
View File
@@ -937,9 +937,9 @@ impl eframe::App for Komobar {
) { ) {
let monitor_index = self.monitor_index.expect("should have a monitor index"); let monitor_index = self.monitor_index.expect("should have a monitor index");
let monitor_size = state.monitors.elements()[monitor_index].size(); let monitor_size = state.monitors.elements()[monitor_index].size;
self.update_monitor_coordinates(monitor_size); self.update_monitor_coordinates(&monitor_size);
should_apply_config = true; should_apply_config = true;
} }
@@ -950,7 +950,7 @@ impl eframe::App for Komobar {
// Check if monitor coordinates/size has changed // Check if monitor coordinates/size has changed
if let Some(monitor_index) = self.monitor_index { if let Some(monitor_index) = self.monitor_index {
let monitor_size = state.monitors.elements()[monitor_index].size(); let monitor_size = state.monitors.elements()[monitor_index].size;
let top = MONITOR_TOP.load(Ordering::SeqCst); let top = MONITOR_TOP.load(Ordering::SeqCst);
let left = MONITOR_LEFT.load(Ordering::SeqCst); let left = MONITOR_LEFT.load(Ordering::SeqCst);
let right = MONITOR_RIGHT.load(Ordering::SeqCst); let right = MONITOR_RIGHT.load(Ordering::SeqCst);
@@ -960,13 +960,13 @@ impl eframe::App for Komobar {
bottom: monitor_size.bottom, bottom: monitor_size.bottom,
right, right,
}; };
if *monitor_size != rect { if monitor_size != rect {
tracing::info!( tracing::info!(
"Monitor coordinates/size has changed, storing new coordinates: {:#?}", "Monitor coordinates/size has changed, storing new coordinates: {:#?}",
monitor_size monitor_size
); );
self.update_monitor_coordinates(monitor_size); self.update_monitor_coordinates(&monitor_size);
should_apply_config = true; should_apply_config = true;
} }
+9 -9
View File
@@ -230,17 +230,17 @@ fn main() -> color_eyre::Result<()> {
.map_or(usr_monitor_index, |i| *i); .map_or(usr_monitor_index, |i| *i);
MONITOR_RIGHT.store( MONITOR_RIGHT.store(
state.monitors.elements()[monitor_index].size().right, state.monitors.elements()[monitor_index].size.right,
Ordering::SeqCst, Ordering::SeqCst,
); );
MONITOR_TOP.store( MONITOR_TOP.store(
state.monitors.elements()[monitor_index].size().top, state.monitors.elements()[monitor_index].size.top,
Ordering::SeqCst, Ordering::SeqCst,
); );
MONITOR_LEFT.store( MONITOR_LEFT.store(
state.monitors.elements()[monitor_index].size().left, state.monitors.elements()[monitor_index].size.left,
Ordering::SeqCst, Ordering::SeqCst,
); );
@@ -250,11 +250,11 @@ fn main() -> color_eyre::Result<()> {
None => { None => {
config.position = Some(PositionConfig { config.position = Some(PositionConfig {
start: Some(Position { start: Some(Position {
x: state.monitors.elements()[monitor_index].size().left as f32, x: state.monitors.elements()[monitor_index].size.left as f32,
y: state.monitors.elements()[monitor_index].size().top as f32, y: state.monitors.elements()[monitor_index].size.top as f32,
}), }),
end: Some(Position { end: Some(Position {
x: state.monitors.elements()[monitor_index].size().right as f32, x: state.monitors.elements()[monitor_index].size.right as f32,
y: 50.0, y: 50.0,
}), }),
}) })
@@ -262,14 +262,14 @@ fn main() -> color_eyre::Result<()> {
Some(ref mut position) => { Some(ref mut position) => {
if position.start.is_none() { if position.start.is_none() {
position.start = Some(Position { position.start = Some(Position {
x: state.monitors.elements()[monitor_index].size().left as f32, x: state.monitors.elements()[monitor_index].size.left as f32,
y: state.monitors.elements()[monitor_index].size().top as f32, y: state.monitors.elements()[monitor_index].size.top as f32,
}); });
} }
if position.end.is_none() { if position.end.is_none() {
position.end = Some(Position { position.end = Some(Position {
x: state.monitors.elements()[monitor_index].size().right as f32, x: state.monitors.elements()[monitor_index].size.right as f32,
y: 50.0, y: 50.0,
}) })
} }
+10 -10
View File
@@ -817,7 +817,7 @@ impl MonitorInfo {
self.mouse_follows_focus = state.mouse_follows_focus; self.mouse_follows_focus = state.mouse_follows_focus;
let monitor = &state.monitors.elements()[self.monitor_index]; let monitor = &state.monitors.elements()[self.monitor_index];
self.work_area_offset = monitor.work_area_offset(); self.work_area_offset = monitor.work_area_offset;
self.focused_workspace_idx = Some(monitor.focused_workspace_idx()); self.focused_workspace_idx = Some(monitor.focused_workspace_idx());
// Layout // Layout
@@ -856,7 +856,7 @@ impl MonitorInfo {
let containers = fn_containers_from(ws); let containers = fn_containers_from(ws);
WorkspaceInfo { WorkspaceInfo {
name: ws name: ws
.name() .name
.to_owned() .to_owned()
.unwrap_or_else(|| format!("{}", index + 1)), .unwrap_or_else(|| format!("{}", index + 1)),
focused_container_idx: containers.iter().position(|c| c.is_focused), focused_container_idx: containers.iter().position(|c| c.is_focused),
@@ -864,7 +864,7 @@ impl MonitorInfo {
.iter() .iter()
.any(|container| container.windows.iter().any(|window| window.icon.is_some())), .any(|container| container.windows.iter().any(|window| window.icon.is_some())),
containers, containers,
layer: *ws.layer(), layer: ws.layer,
should_show: !hide_empty_ws || focused_ws_idx == Some(index) || !ws.is_empty(), should_show: !hide_empty_ws || focused_ws_idx == Some(index) || !ws.is_empty(),
is_selected: focused_ws_idx == Some(index), is_selected: focused_ws_idx == Some(index),
} }
@@ -873,15 +873,15 @@ impl MonitorInfo {
/// Determines the current layout of the focused workspace /// Determines the current layout of the focused workspace
fn resolve_layout(focused_ws: &Workspace, is_paused: bool) -> KomorebiLayout { fn resolve_layout(focused_ws: &Workspace, is_paused: bool) -> KomorebiLayout {
if focused_ws.monocle_container().is_some() { if focused_ws.monocle_container.is_some() {
KomorebiLayout::Monocle KomorebiLayout::Monocle
} else if !focused_ws.tile() { } else if !focused_ws.tile {
KomorebiLayout::Floating KomorebiLayout::Floating
} else if is_paused { } else if is_paused {
KomorebiLayout::Paused KomorebiLayout::Paused
} else { } else {
match focused_ws.layout() { match focused_ws.layout {
komorebi_client::Layout::Default(layout) => KomorebiLayout::Default(*layout), komorebi_client::Layout::Default(layout) => KomorebiLayout::Default(layout),
komorebi_client::Layout::Custom(_) => KomorebiLayout::Custom, komorebi_client::Layout::Custom(_) => KomorebiLayout::Custom,
} }
} }
@@ -938,7 +938,7 @@ impl ContainerInfo {
// Monocle container first if present // Monocle container first if present
let monocle = ws let monocle = ws
.monocle_container() .monocle_container
.as_ref() .as_ref()
.map(|c| Self::from_container(c, !has_focused_float)); .map(|c| Self::from_container(c, !has_focused_float));
@@ -965,7 +965,7 @@ impl ContainerInfo {
if let Some(window) = ws.floating_windows().iter().find(|w| w.is_focused()) { if let Some(window) = ws.floating_windows().iter().find(|w| w.is_focused()) {
return Some(Self::from_window(window)); return Some(Self::from_window(window));
} }
if let Some(container) = ws.monocle_container() { if let Some(container) = &ws.monocle_container {
Some(Self::from_container(container, true)) Some(Self::from_container(container, true))
} else { } else {
ws.focused_container() ws.focused_container()
@@ -979,7 +979,7 @@ impl ContainerInfo {
windows: container.windows().iter().map(WindowInfo::from).collect(), windows: container.windows().iter().map(WindowInfo::from).collect(),
focused_window_idx: container.focused_window_idx(), focused_window_idx: container.focused_window_idx(),
is_focused, is_focused,
is_locked: container.locked(), is_locked: container.locked,
} }
} }
+8 -8
View File
@@ -78,8 +78,8 @@ impl From<&komorebi_client::Monitor> for MonitorConfig {
} }
Self { Self {
size: *value.size(), size: value.size,
work_area_offset: value.work_area_offset().unwrap_or_default(), work_area_offset: value.work_area_offset.unwrap_or_default(),
workspaces, workspaces,
} }
} }
@@ -95,22 +95,22 @@ struct WorkspaceConfig {
impl From<&komorebi_client::Workspace> for WorkspaceConfig { impl From<&komorebi_client::Workspace> for WorkspaceConfig {
fn from(value: &komorebi_client::Workspace) -> Self { fn from(value: &komorebi_client::Workspace) -> Self {
let layout = match value.layout() { let layout = match value.layout {
Layout::Default(layout) => *layout, Layout::Default(layout) => layout,
Layout::Custom(_) => DefaultLayout::BSP, Layout::Custom(_) => DefaultLayout::BSP,
}; };
let name = value let name = value
.name() .name
.to_owned() .to_owned()
.unwrap_or_else(|| random_word::get(random_word::Lang::En).to_string()); .unwrap_or_else(|| random_word::get(random_word::Lang::En).to_string());
Self { Self {
layout, layout,
name, name,
tile: *value.tile(), tile: value.tile,
workspace_padding: value.workspace_padding().unwrap_or(20), workspace_padding: value.workspace_padding.unwrap_or(20),
container_padding: value.container_padding().unwrap_or(20), container_padding: value.container_padding.unwrap_or(20),
} }
} }
} }
-1
View File
@@ -17,7 +17,6 @@ crossbeam-channel = { workspace = true }
crossbeam-utils = { workspace = true } crossbeam-utils = { workspace = true }
ctrlc = { version = "3", features = ["termination"] } ctrlc = { version = "3", features = ["termination"] }
dirs = { workspace = true } dirs = { workspace = true }
getset = "0.1"
hotwatch = { workspace = true } hotwatch = { workspace = true }
lazy_static = { workspace = true } lazy_static = { workspace = true }
miow = "0.6" miow = "0.6"
+17 -17
View File
@@ -209,9 +209,9 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
.iter() .iter()
.map(|w| w.hwnd) .map(|w| w.hwnd)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let workspace_layer = *state.monitors.elements()[focused_monitor_idx].workspaces() let workspace_layer = state.monitors.elements()[focused_monitor_idx].workspaces()
[focused_workspace_idx] [focused_workspace_idx]
.layer(); .layer;
let foreground_window = WindowsApi::foreground_window().unwrap_or_default(); let foreground_window = WindowsApi::foreground_window().unwrap_or_default();
let layer_changed = previous_layer != workspace_layer; let layer_changed = previous_layer != workspace_layer;
let forced_update = matches!(notification, Notification::ForceUpdate); let forced_update = matches!(notification, Notification::ForceUpdate);
@@ -224,7 +224,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
// Only operate on the focused workspace of each monitor // Only operate on the focused workspace of each monitor
if let Some(ws) = m.focused_workspace() { if let Some(ws) = m.focused_workspace() {
// Handle the monocle container separately // Handle the monocle container separately
if let Some(monocle) = ws.monocle_container() { if let Some(monocle) = &ws.monocle_container {
let window_kind = if monitor_idx != focused_monitor_idx { let window_kind = if monitor_idx != focused_monitor_idx {
WindowKind::Unfocused WindowKind::Unfocused
} else { } else {
@@ -237,7 +237,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
.unwrap_or_default() .unwrap_or_default()
.set_accent(window_kind_colour(window_kind))?; .set_accent(window_kind_colour(window_kind))?;
if ws.layer() == &WorkspaceLayer::Floating { if ws.layer == WorkspaceLayer::Floating {
for window in ws.floating_windows() { for window in ws.floating_windows() {
let mut window_kind = WindowKind::Unfocused; let mut window_kind = WindowKind::Unfocused;
@@ -255,7 +255,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
let window_kind = if idx != ws.focused_container_idx() let window_kind = if idx != ws.focused_container_idx()
|| monitor_idx != focused_monitor_idx || monitor_idx != focused_monitor_idx
{ {
if c.locked() { if c.locked {
WindowKind::UnfocusedLocked WindowKind::UnfocusedLocked
} else { } else {
WindowKind::Unfocused WindowKind::Unfocused
@@ -383,7 +383,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
// Only operate on the focused workspace of each monitor // Only operate on the focused workspace of each monitor
if let Some(ws) = m.focused_workspace() { if let Some(ws) = m.focused_workspace() {
// Workspaces with tiling disabled don't have borders // Workspaces with tiling disabled don't have borders
if !ws.tile() { if !ws.tile {
// Remove all borders on this monitor // Remove all borders on this monitor
remove_borders( remove_borders(
&mut borders, &mut borders,
@@ -396,16 +396,16 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
} }
// Handle the monocle container separately // Handle the monocle container separately
if let Some(monocle) = ws.monocle_container() { if let Some(monocle) = &ws.monocle_container {
let mut new_border = false; let mut new_border = false;
let focused_window_hwnd = let focused_window_hwnd =
monocle.focused_window().map(|w| w.hwnd).unwrap_or_default(); monocle.focused_window().map(|w| w.hwnd).unwrap_or_default();
let id = monocle.id().clone(); let id = monocle.id.clone();
let border = match borders.entry(id.clone()) { let border = match borders.entry(id.clone()) {
Entry::Occupied(entry) => entry.into_mut(), Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
if let Ok(border) = Border::create( if let Ok(border) = Border::create(
monocle.id(), &monocle.id,
focused_window_hwnd, focused_window_hwnd,
monitor_idx, monitor_idx,
) { ) {
@@ -463,7 +463,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
let border_hwnd = border.hwnd; let border_hwnd = border.hwnd;
if ws.layer() == &WorkspaceLayer::Floating { if ws.layer == WorkspaceLayer::Floating {
handle_floating_borders( handle_floating_borders(
&mut borders, &mut borders,
&mut windows_borders, &mut windows_borders,
@@ -502,8 +502,8 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
let foreground_hwnd = WindowsApi::foreground_window().unwrap_or_default(); let foreground_hwnd = WindowsApi::foreground_window().unwrap_or_default();
let foreground_monitor_id = let foreground_monitor_id =
WindowsApi::monitor_from_window(foreground_hwnd); WindowsApi::monitor_from_window(foreground_hwnd);
let is_maximized = foreground_monitor_id == m.id() let is_maximized =
&& WindowsApi::is_zoomed(foreground_hwnd); foreground_monitor_id == m.id && WindowsApi::is_zoomed(foreground_hwnd);
if is_maximized { if is_maximized {
// Remove all borders on this monitor // Remove all borders on this monitor
@@ -521,7 +521,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
let mut container_and_floating_window_ids = ws let mut container_and_floating_window_ids = ws
.containers() .containers()
.iter() .iter()
.map(|c| c.id().clone()) .map(|c| c.id.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for w in ws.floating_windows() { for w in ws.floating_windows() {
@@ -539,7 +539,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
'containers: for (idx, c) in ws.containers().iter().enumerate() { 'containers: for (idx, c) in ws.containers().iter().enumerate() {
let focused_window_hwnd = let focused_window_hwnd =
c.focused_window().map(|w| w.hwnd).unwrap_or_default(); c.focused_window().map(|w| w.hwnd).unwrap_or_default();
let id = c.id().clone(); let id = c.id.clone();
// Get the border entry for this container from the map or create one // Get the border entry for this container from the map or create one
let mut new_border = false; let mut new_border = false;
@@ -547,7 +547,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
Entry::Occupied(entry) => entry.into_mut(), Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
if let Ok(border) = if let Ok(border) =
Border::create(c.id(), focused_window_hwnd, monitor_idx) Border::create(&c.id, focused_window_hwnd, monitor_idx)
{ {
new_border = true; new_border = true;
entry.insert(border) entry.insert(border)
@@ -563,7 +563,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|| monitor_idx != focused_monitor_idx || monitor_idx != focused_monitor_idx
|| focused_window_hwnd != foreground_window || focused_window_hwnd != foreground_window
{ {
if c.locked() { if c.locked {
WindowKind::UnfocusedLocked WindowKind::UnfocusedLocked
} else { } else {
WindowKind::Unfocused WindowKind::Unfocused
@@ -603,7 +603,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
let rect = match WindowsApi::window_rect(focused_window_hwnd) { let rect = match WindowsApi::window_rect(focused_window_hwnd) {
Ok(rect) => rect, Ok(rect) => rect,
Err(_) => { Err(_) => {
remove_border(c.id(), &mut borders, &mut windows_borders)?; remove_border(&c.id, &mut borders, &mut windows_borders)?;
continue 'containers; continue 'containers;
} }
}; };
+9 -14
View File
@@ -1,8 +1,5 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use getset::CopyGetters;
use getset::Getters;
use getset::Setters;
use nanoid::nanoid; use nanoid::nanoid;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
@@ -11,14 +8,12 @@ use crate::ring::Ring;
use crate::window::Window; use crate::window::Window;
use crate::Lockable; use crate::Lockable;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Getters, CopyGetters, Setters)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Container { pub struct Container {
#[getset(get = "pub")] pub id: String,
id: String,
#[serde(default)] #[serde(default)]
#[getset(get_copy = "pub", set = "pub")] pub locked: bool,
locked: bool,
windows: Ring<Window>, windows: Ring<Window>,
} }
@@ -278,8 +273,8 @@ mod tests {
}"#; }"#;
let container: Container = serde_json::from_str(json).expect("Should deserialize"); let container: Container = serde_json::from_str(json).expect("Should deserialize");
assert!(!container.locked()); assert!(!container.locked);
assert_eq!(container.id(), "test-1"); assert_eq!(container.id, "test-1");
assert!(container.windows().is_empty()); assert!(container.windows().is_empty());
let json = r#"{ let json = r#"{
@@ -287,8 +282,8 @@ mod tests {
"windows": { "elements": [ { "hwnd": 5 }, { "hwnd": 9 } ], "focused": 1 } "windows": { "elements": [ { "hwnd": 5 }, { "hwnd": 9 } ], "focused": 1 }
}"#; }"#;
let container: Container = serde_json::from_str(json).unwrap(); let container: Container = serde_json::from_str(json).unwrap();
assert_eq!(container.id(), "test-2"); assert_eq!(container.id, "test-2");
assert!(!container.locked()); assert!(!container.locked);
assert_eq!(container.windows(), &[Window::from(5), Window::from(9)]); assert_eq!(container.windows(), &[Window::from(5), Window::from(9)]);
assert_eq!(container.focused_window_idx(), 1); assert_eq!(container.focused_window_idx(), 1);
} }
@@ -302,7 +297,7 @@ mod tests {
let deserialized: Container = let deserialized: Container =
serde_json::from_str(&serialized).expect("Should deserialize"); serde_json::from_str(&serialized).expect("Should deserialize");
assert!(deserialized.locked()); assert!(deserialized.locked);
assert_eq!(deserialized.id(), container.id()); assert_eq!(deserialized.id, container.id);
} }
} }
+27 -49
View File
@@ -5,10 +5,6 @@ use std::sync::atomic::Ordering;
use color_eyre::eyre::bail; use color_eyre::eyre::bail;
use color_eyre::eyre::OptionExt; use color_eyre::eyre::OptionExt;
use color_eyre::Result; use color_eyre::Result;
use getset::CopyGetters;
use getset::Getters;
use getset::MutGetters;
use getset::Setters;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
@@ -31,44 +27,26 @@ use crate::WindowsApi;
use crate::DEFAULT_CONTAINER_PADDING; use crate::DEFAULT_CONTAINER_PADDING;
use crate::DEFAULT_WORKSPACE_PADDING; use crate::DEFAULT_WORKSPACE_PADDING;
#[derive( #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
Debug, Clone, Serialize, Deserialize, Getters, CopyGetters, MutGetters, Setters, PartialEq,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Monitor { pub struct Monitor {
#[getset(get_copy = "pub", set = "pub")]
pub id: isize, pub id: isize,
#[getset(get = "pub", set = "pub")]
pub name: String, pub name: String,
#[getset(get = "pub", set = "pub")]
pub device: String, pub device: String,
#[getset(get = "pub", set = "pub")]
pub device_id: String, pub device_id: String,
#[getset(get = "pub", set = "pub")]
pub serial_number_id: Option<String>, pub serial_number_id: Option<String>,
#[getset(get = "pub", set = "pub")]
pub size: Rect, pub size: Rect,
#[getset(get = "pub", set = "pub")]
pub work_area_size: Rect, pub work_area_size: Rect,
#[getset(get_copy = "pub", set = "pub")]
pub work_area_offset: Option<Rect>, pub work_area_offset: Option<Rect>,
#[getset(get_copy = "pub", set = "pub")]
pub window_based_work_area_offset: Option<Rect>, pub window_based_work_area_offset: Option<Rect>,
#[getset(get_copy = "pub", set = "pub")]
pub window_based_work_area_offset_limit: isize, pub window_based_work_area_offset_limit: isize,
pub workspaces: Ring<Workspace>, pub workspaces: Ring<Workspace>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub", set = "pub")]
pub last_focused_workspace: Option<usize>, pub last_focused_workspace: Option<usize>,
#[getset(get_mut = "pub")]
pub workspace_names: HashMap<usize, String>, pub workspace_names: HashMap<usize, String>,
#[getset(get_copy = "pub", set = "pub")]
pub container_padding: Option<i32>, pub container_padding: Option<i32>,
#[getset(get_copy = "pub", set = "pub")]
pub workspace_padding: Option<i32>, pub workspace_padding: Option<i32>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub wallpaper: Option<Wallpaper>, pub wallpaper: Option<Wallpaper>,
#[getset(get_copy = "pub", set = "pub")]
pub floating_layer_behaviour: Option<FloatingLayerBehaviour>, pub floating_layer_behaviour: Option<FloatingLayerBehaviour>,
} }
@@ -175,14 +153,14 @@ impl Monitor {
pub fn focused_workspace_name(&self) -> Option<String> { pub fn focused_workspace_name(&self) -> Option<String> {
self.focused_workspace() self.focused_workspace()
.map(|w| w.name().clone()) .map(|w| w.name.clone())
.unwrap_or(None) .unwrap_or(None)
} }
pub fn focused_workspace_layout(&self) -> Option<Layout> { pub fn focused_workspace_layout(&self) -> Option<Layout> {
self.focused_workspace().and_then(|workspace| { self.focused_workspace().and_then(|workspace| {
if *workspace.tile() { if workspace.tile {
Some(workspace.layout().clone()) Some(workspace.layout.clone())
} else { } else {
None None
} }
@@ -191,7 +169,7 @@ impl Monitor {
pub fn load_focused_workspace(&mut self, mouse_follows_focus: bool) -> Result<()> { pub fn load_focused_workspace(&mut self, mouse_follows_focus: bool) -> Result<()> {
let focused_idx = self.focused_workspace_idx(); let focused_idx = self.focused_workspace_idx();
let hmonitor = self.id(); let hmonitor = self.id;
let monitor_wp = self.wallpaper.clone(); let monitor_wp = self.wallpaper.clone();
for (i, workspace) in self.workspaces_mut().iter_mut().enumerate() { for (i, workspace) in self.workspaces_mut().iter_mut().enumerate() {
if i == focused_idx { if i == focused_idx {
@@ -207,10 +185,10 @@ impl Monitor {
/// Updates the `globals` field of all workspaces /// Updates the `globals` field of all workspaces
pub fn update_workspaces_globals(&mut self, offset: Option<Rect>) { pub fn update_workspaces_globals(&mut self, offset: Option<Rect>) {
let container_padding = self let container_padding = self
.container_padding() .container_padding
.or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst))); .or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)));
let workspace_padding = self let workspace_padding = self
.workspace_padding() .workspace_padding
.or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst))); .or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)));
let (border_width, border_offset) = { let (border_width, border_offset) = {
let border_enabled = BORDER_ENABLED.load(Ordering::SeqCst); let border_enabled = BORDER_ENABLED.load(Ordering::SeqCst);
@@ -222,11 +200,11 @@ impl Monitor {
(0, 0) (0, 0)
} }
}; };
let work_area = *self.work_area_size(); let work_area = self.work_area_size;
let work_area_offset = self.work_area_offset.or(offset); let work_area_offset = self.work_area_offset.or(offset);
let window_based_work_area_offset = self.window_based_work_area_offset(); let window_based_work_area_offset = self.window_based_work_area_offset;
let window_based_work_area_offset_limit = self.window_based_work_area_offset_limit(); let window_based_work_area_offset_limit = self.window_based_work_area_offset_limit;
let floating_layer_behaviour = self.floating_layer_behaviour(); let floating_layer_behaviour = self.floating_layer_behaviour;
for workspace in self.workspaces_mut() { for workspace in self.workspaces_mut() {
workspace.globals = WorkspaceGlobals { workspace.globals = WorkspaceGlobals {
@@ -246,10 +224,10 @@ impl Monitor {
/// Updates the `globals` field of workspace with index `workspace_idx` /// Updates the `globals` field of workspace with index `workspace_idx`
pub fn update_workspace_globals(&mut self, workspace_idx: usize, offset: Option<Rect>) { pub fn update_workspace_globals(&mut self, workspace_idx: usize, offset: Option<Rect>) {
let container_padding = self let container_padding = self
.container_padding() .container_padding
.or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst))); .or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)));
let workspace_padding = self let workspace_padding = self
.workspace_padding() .workspace_padding
.or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst))); .or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)));
let (border_width, border_offset) = { let (border_width, border_offset) = {
let border_enabled = BORDER_ENABLED.load(Ordering::SeqCst); let border_enabled = BORDER_ENABLED.load(Ordering::SeqCst);
@@ -261,11 +239,11 @@ impl Monitor {
(0, 0) (0, 0)
} }
}; };
let work_area = *self.work_area_size(); let work_area = self.work_area_size;
let work_area_offset = self.work_area_offset.or(offset); let work_area_offset = self.work_area_offset.or(offset);
let window_based_work_area_offset = self.window_based_work_area_offset(); let window_based_work_area_offset = self.window_based_work_area_offset;
let window_based_work_area_offset_limit = self.window_based_work_area_offset_limit(); let window_based_work_area_offset_limit = self.window_based_work_area_offset_limit;
let floating_layer_behaviour = self.floating_layer_behaviour(); let floating_layer_behaviour = self.floating_layer_behaviour;
if let Some(workspace) = self.workspaces_mut().get_mut(workspace_idx) { if let Some(workspace) = self.workspaces_mut().get_mut(workspace_idx) {
workspace.globals = WorkspaceGlobals { workspace.globals = WorkspaceGlobals {
@@ -324,7 +302,7 @@ impl Monitor {
OperationDirection::Left => { OperationDirection::Left => {
// insert the container into the workspace on the monitor at the back (or rightmost position) // insert the container into the workspace on the monitor at the back (or rightmost position)
// if we are moving across a boundary to the left (back = right side of the target) // if we are moving across a boundary to the left (back = right side of the target)
match workspace.layout() { match workspace.layout {
Layout::Default(layout) => match layout { Layout::Default(layout) => match layout {
DefaultLayout::RightMainVerticalStack => { DefaultLayout::RightMainVerticalStack => {
workspace.add_container_to_front(container); workspace.add_container_to_front(container);
@@ -348,7 +326,7 @@ impl Monitor {
OperationDirection::Right => { OperationDirection::Right => {
// insert the container into the workspace on the monitor at the front (or leftmost position) // insert the container into the workspace on the monitor at the front (or leftmost position)
// if we are moving across a boundary to the right (front = left side of the target) // if we are moving across a boundary to the right (front = left side of the target)
match workspace.layout() { match workspace.layout {
Layout::Default(layout) => { Layout::Default(layout) => {
let target_index = layout.leftmost_index(workspace.containers().len()); let target_index = layout.leftmost_index(workspace.containers().len());
@@ -417,7 +395,7 @@ impl Monitor {
.focused_workspace_mut() .focused_workspace_mut()
.ok_or_eyre("there is no workspace")?; .ok_or_eyre("there is no workspace")?;
if workspace.maximized_window().is_some() { if workspace.maximized_window.is_some() {
bail!("cannot move native maximized window to another monitor or workspace"); bail!("cannot move native maximized window to another monitor or workspace");
} }
@@ -440,7 +418,7 @@ impl Monitor {
}; };
target_workspace.floating_windows_mut().push_back(window); target_workspace.floating_windows_mut().push_back(window);
target_workspace.set_layer(WorkspaceLayer::Floating); target_workspace.layer = WorkspaceLayer::Floating;
} }
} else { } else {
let container = workspace let container = workspace
@@ -458,7 +436,7 @@ impl Monitor {
Some(workspace) => workspace, Some(workspace) => workspace,
}; };
if target_workspace.monocle_container().is_some() { if target_workspace.monocle_container.is_some() {
for container in target_workspace.containers_mut() { for container in target_workspace.containers_mut() {
container.restore(); container.restore();
} }
@@ -470,7 +448,7 @@ impl Monitor {
target_workspace.reintegrate_monocle_container()?; target_workspace.reintegrate_monocle_container()?;
} }
target_workspace.set_layer(WorkspaceLayer::Tiling); target_workspace.layer = WorkspaceLayer::Tiling;
if let Some(direction) = direction { if let Some(direction) = direction {
self.add_container_with_direction( self.add_container_with_direction(
@@ -500,7 +478,7 @@ impl Monitor {
if workspaces.get(idx).is_none() { if workspaces.get(idx).is_none() {
workspaces.resize(idx + 1, Workspace::default()); workspaces.resize(idx + 1, Workspace::default());
} }
self.set_last_focused_workspace(Some(self.workspaces.focused_idx())); self.last_focused_workspace = Some(self.workspaces.focused_idx());
self.workspaces.focus(idx); self.workspaces.focus(idx);
} }
@@ -511,7 +489,7 @@ impl Monitor {
self.workspaces_mut() self.workspaces_mut()
.get_mut(idx) .get_mut(idx)
.ok_or_eyre("there is no workspace")? .ok_or_eyre("there is no workspace")?
.set_name(name); .name = name;
} }
} }
@@ -523,8 +501,8 @@ impl Monitor {
} }
pub fn update_focused_workspace(&mut self, offset: Option<Rect>) -> Result<()> { pub fn update_focused_workspace(&mut self, offset: Option<Rect>) -> Result<()> {
let offset = if self.work_area_offset().is_some() { let offset = if self.work_area_offset.is_some() {
self.work_area_offset() self.work_area_offset
} else { } else {
offset offset
}; };
+66 -66
View File
@@ -70,10 +70,10 @@ pub fn send_notification(notification: MonitorNotification) {
pub fn insert_in_monitor_cache(serial_or_device_id: &str, monitor: Monitor) { pub fn insert_in_monitor_cache(serial_or_device_id: &str, monitor: Monitor) {
let dip = DISPLAY_INDEX_PREFERENCES.read(); let dip = DISPLAY_INDEX_PREFERENCES.read();
let mut dip_ids = dip.values(); let mut dip_ids = dip.values();
let preferred_id = if dip_ids.any(|id| id == monitor.device_id()) { let preferred_id = if dip_ids.any(|id| id.eq(&monitor.device_id)) {
monitor.device_id().clone() monitor.device_id.clone()
} else if dip_ids.any(|id| Some(id) == monitor.serial_number_id().as_ref()) { } else if dip_ids.any(|id| Some(id) == monitor.serial_number_id.as_ref()) {
monitor.serial_number_id().clone().unwrap_or_default() monitor.serial_number_id.clone().unwrap_or_default()
} else { } else {
serial_or_device_id.to_string() serial_or_device_id.to_string()
}; };
@@ -219,27 +219,27 @@ where
let mut should_update = false; let mut should_update = false;
// Update work areas as necessary // Update work areas as necessary
if let Ok(reference) = WindowsApi::monitor(monitor.id()) { if let Ok(reference) = WindowsApi::monitor(monitor.id) {
if reference.work_area_size() != monitor.work_area_size() { if reference.work_area_size != monitor.work_area_size {
monitor.set_work_area_size(Rect { monitor.work_area_size = Rect {
left: reference.work_area_size().left, left: reference.work_area_size.left,
top: reference.work_area_size().top, top: reference.work_area_size.top,
right: reference.work_area_size().right, right: reference.work_area_size.right,
bottom: reference.work_area_size().bottom, bottom: reference.work_area_size.bottom,
}); };
should_update = true; should_update = true;
} }
} }
if should_update { if should_update {
tracing::info!("updated work area for {}", monitor.device_id()); tracing::info!("updated work area for {}", monitor.device_id);
monitor.update_focused_workspace(offset)?; monitor.update_focused_workspace(offset)?;
border_manager::send_notification(None); border_manager::send_notification(None);
} else { } else {
tracing::debug!( tracing::debug!(
"work areas match, reconciliation not required for {}", "work areas match, reconciliation not required for {}",
monitor.device_id() monitor.device_id
); );
} }
} }
@@ -251,25 +251,25 @@ where
let mut should_update = false; let mut should_update = false;
// Update sizes and work areas as necessary // Update sizes and work areas as necessary
if let Ok(reference) = WindowsApi::monitor(monitor.id()) { if let Ok(reference) = WindowsApi::monitor(monitor.id) {
if reference.work_area_size() != monitor.work_area_size() { if reference.work_area_size != monitor.work_area_size {
monitor.set_work_area_size(Rect { monitor.work_area_size = Rect {
left: reference.work_area_size().left, left: reference.work_area_size.left,
top: reference.work_area_size().top, top: reference.work_area_size.top,
right: reference.work_area_size().right, right: reference.work_area_size.right,
bottom: reference.work_area_size().bottom, bottom: reference.work_area_size.bottom,
}); };
should_update = true; should_update = true;
} }
if reference.size() != monitor.size() { if reference.size != monitor.size {
monitor.set_size(Rect { monitor.size = Rect {
left: reference.size().left, left: reference.size.left,
top: reference.size().top, top: reference.size.top,
right: reference.size().right, right: reference.size.right,
bottom: reference.size().bottom, bottom: reference.size.bottom,
}); };
should_update = true; should_update = true;
} }
@@ -278,7 +278,7 @@ where
if should_update { if should_update {
tracing::info!( tracing::info!(
"updated monitor resolution/scaling for {}", "updated monitor resolution/scaling for {}",
monitor.device_id() monitor.device_id
); );
monitor.update_focused_workspace(offset)?; monitor.update_focused_workspace(offset)?;
@@ -286,7 +286,7 @@ where
} else { } else {
tracing::debug!( tracing::debug!(
"resolutions match, reconciliation not required for {}", "resolutions match, reconciliation not required for {}",
monitor.device_id() monitor.device_id
); );
} }
} }
@@ -311,21 +311,21 @@ where
for monitor in wm.monitors_mut() { for monitor in wm.monitors_mut() {
for attached in &attached_devices { for attached in &attached_devices {
let serial_number_ids_match = if let (Some(attached_snid), Some(m_snid)) = let serial_number_ids_match = if let (Some(attached_snid), Some(m_snid)) =
(attached.serial_number_id(), monitor.serial_number_id()) (&attached.serial_number_id, &monitor.serial_number_id)
{ {
attached_snid.eq(m_snid) attached_snid.eq(m_snid)
} else { } else {
false false
}; };
if serial_number_ids_match || attached.device_id().eq(monitor.device_id()) { if serial_number_ids_match || attached.device_id.eq(&monitor.device_id) {
monitor.set_id(attached.id()); monitor.id = attached.id;
monitor.set_device(attached.device().clone()); monitor.device = attached.device.clone();
monitor.set_device_id(attached.device_id().clone()); monitor.device_id = attached.device_id.clone();
monitor.set_serial_number_id(attached.serial_number_id().clone()); monitor.serial_number_id = attached.serial_number_id.clone();
monitor.set_name(attached.name().clone()); monitor.name = attached.name.clone();
monitor.set_size(*attached.size()); monitor.size = attached.size;
monitor.set_work_area_size(*attached.work_area_size()); monitor.work_area_size = attached.work_area_size;
} }
} }
} }
@@ -359,13 +359,13 @@ where
for (m_idx, m) in wm.monitors().iter().enumerate() { for (m_idx, m) in wm.monitors().iter().enumerate() {
if !attached_devices.iter().any(|attached| { if !attached_devices.iter().any(|attached| {
attached.serial_number_id().eq(m.serial_number_id()) attached.serial_number_id.eq(&m.serial_number_id)
|| attached.device_id().eq(m.device_id()) || attached.device_id.eq(&m.device_id)
}) { }) {
let id = m let id = m
.serial_number_id() .serial_number_id
.as_ref() .as_ref()
.map_or(m.device_id().clone(), |sn| sn.clone()); .map_or(m.device_id.clone(), |sn| sn.clone());
newly_removed_displays.push(id.clone()); newly_removed_displays.push(id.clone());
@@ -392,7 +392,7 @@ where
} }
} }
if let Some(maximized) = workspace.maximized_window() { if let Some(maximized) = &workspace.maximized_window {
windows_to_remove.push(maximized.hwnd); windows_to_remove.push(maximized.hwnd);
// Minimize the focused window since Windows might try // Minimize the focused window since Windows might try
// to move it to another monitor if it was focused. // to move it to another monitor if it was focused.
@@ -401,7 +401,7 @@ where
} }
} }
if let Some(container) = workspace.monocle_container() { if let Some(container) = &workspace.monocle_container {
for window in container.windows() { for window in container.windows() {
windows_to_remove.push(window.hwnd); windows_to_remove.push(window.hwnd);
} }
@@ -440,10 +440,10 @@ where
// the user set as preference as the id. // the user set as preference as the id.
let dip = DISPLAY_INDEX_PREFERENCES.read(); let dip = DISPLAY_INDEX_PREFERENCES.read();
let mut dip_ids = dip.values(); let mut dip_ids = dip.values();
let preferred_id = if dip_ids.any(|id| id == m.device_id()) { let preferred_id = if dip_ids.any(|id| id.eq(&m.device_id)) {
m.device_id().clone() m.device_id.clone()
} else if dip_ids.any(|id| Some(id) == m.serial_number_id().as_ref()) { } else if dip_ids.any(|id| Some(id) == m.serial_number_id.as_ref()) {
m.serial_number_id().clone().unwrap_or_default() m.serial_number_id.clone().unwrap_or_default()
} else { } else {
id id
}; };
@@ -458,8 +458,8 @@ where
// After we have cached them, remove them from our state // After we have cached them, remove them from our state
wm.monitors_mut().retain(|m| { wm.monitors_mut().retain(|m| {
!newly_removed_displays.iter().any(|id| { !newly_removed_displays.iter().any(|id| {
m.serial_number_id().as_ref().is_some_and(|sn| sn == id) m.serial_number_id.as_ref().is_some_and(|sn| sn == id)
|| m.device_id() == id || m.device_id.eq(id)
}) })
}); });
} }
@@ -490,7 +490,7 @@ where
let post_removal_device_ids = wm let post_removal_device_ids = wm
.monitors() .monitors()
.iter() .iter()
.map(Monitor::device_id) .map(|m| &m.device_id)
.cloned() .cloned()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -513,14 +513,14 @@ where
// Look in the updated state for new monitors // Look in the updated state for new monitors
for (i, m) in wm.monitors_mut().iter_mut().enumerate() { for (i, m) in wm.monitors_mut().iter_mut().enumerate() {
let device_id = m.device_id(); let device_id = &m.device_id;
// We identify a new monitor when we encounter a new device id // We identify a new monitor when we encounter a new device id
if !post_removal_device_ids.contains(device_id) { if !post_removal_device_ids.contains(device_id) {
let mut cache_hit = false; let mut cache_hit = false;
let mut cached_id = String::new(); let mut cached_id = String::new();
// Check if that device id exists in the cache for this session // Check if that device id exists in the cache for this session
if let Some((id, cached)) = monitor_cache.get_key_value(device_id).or(m if let Some((id, cached)) = monitor_cache.get_key_value(device_id).or(m
.serial_number_id() .serial_number_id
.as_ref() .as_ref()
.and_then(|sn| monitor_cache.get_key_value(sn))) .and_then(|sn| monitor_cache.get_key_value(sn)))
{ {
@@ -608,24 +608,24 @@ where
} }
} }
if let Some(window) = workspace.maximized_window() { if let Some(window) = &workspace.maximized_window {
if window.exe().is_err() if window.exe().is_err()
|| known_hwnds.contains_key(&window.hwnd) || known_hwnds.contains_key(&window.hwnd)
{ {
workspace.set_maximized_window(None); workspace.maximized_window = None;
} else if is_focused_workspace { } else if is_focused_workspace {
WindowsApi::restore_window(window.hwnd); WindowsApi::restore_window(window.hwnd);
} }
} }
if let Some(container) = workspace.monocle_container_mut() { if let Some(container) = &mut workspace.monocle_container {
container.windows_mut().retain(|window| { container.windows_mut().retain(|window| {
window.exe().is_ok() window.exe().is_ok()
&& !known_hwnds.contains_key(&window.hwnd) && !known_hwnds.contains_key(&window.hwnd)
}); });
if container.windows().is_empty() { if container.windows().is_empty() {
workspace.set_monocle_container(None); workspace.monocle_container = None;
} else if is_focused_workspace { } else if is_focused_workspace {
if let Some(window) = container.focused_window() { if let Some(window) = container.focused_window() {
WindowsApi::restore_window(window.hwnd); WindowsApi::restore_window(window.hwnd);
@@ -657,7 +657,7 @@ where
let mut workspace_matching_rules = let mut workspace_matching_rules =
WORKSPACE_MATCHING_RULES.lock(); WORKSPACE_MATCHING_RULES.lock();
if let Some(rules) = workspace if let Some(rules) = workspace
.workspace_config() .workspace_config
.as_ref() .as_ref()
.and_then(|c| c.workspace_rules.as_ref()) .and_then(|c| c.workspace_rules.as_ref())
{ {
@@ -672,7 +672,7 @@ where
} }
if let Some(rules) = workspace if let Some(rules) = workspace
.workspace_config() .workspace_config
.as_ref() .as_ref()
.and_then(|c| c.initial_workspace_rules.as_ref()) .and_then(|c| c.initial_workspace_rules.as_ref())
{ {
@@ -1006,18 +1006,18 @@ mod tests {
assert_eq!(monitors.len(), 1, "Expected one monitor"); assert_eq!(monitors.len(), 1, "Expected one monitor");
// hmonitor // hmonitor
assert_eq!(monitors[0].id(), 1); assert_eq!(monitors[0].id, 1);
// device name // device name
assert_eq!(monitors[0].name(), &String::from("DISPLAY1")); assert_eq!(monitors[0].name, String::from("DISPLAY1"));
// Device // Device
assert_eq!(monitors[0].device(), &String::from("ABC123")); assert_eq!(monitors[0].device, String::from("ABC123"));
// Device ID // Device ID
assert_eq!( assert_eq!(
monitors[0].device_id(), monitors[0].device_id,
&String::from("ABC123-4&123456&0&UID0") String::from("ABC123-4&123456&0&UID0")
); );
// Check monitor serial number id // Check monitor serial number id
+42 -45
View File
@@ -238,7 +238,7 @@ impl WindowManager {
// load it later after focusing the wanted window // load it later after focusing the wanted window
let focused_ws_idx = monitor.focused_workspace_idx(); let focused_ws_idx = monitor.focused_workspace_idx();
if focused_ws_idx != workspace_idx { if focused_ws_idx != workspace_idx {
monitor.set_last_focused_workspace(Option::from(focused_ws_idx)); monitor.last_focused_workspace = Option::from(focused_ws_idx);
monitor.focus_workspace(workspace_idx)?; monitor.focus_workspace(workspace_idx)?;
needs_workspace_loading = true; needs_workspace_loading = true;
} }
@@ -259,7 +259,7 @@ impl WindowManager {
} }
WorkspaceWindowLocation::Maximized => { WorkspaceWindowLocation::Maximized => {
if let Some(window) = if let Some(window) =
self.focused_workspace_mut()?.maximized_window_mut() &mut self.focused_workspace_mut()?.maximized_window
{ {
window.focus(self.mouse_follows_focus)?; window.focus(self.mouse_follows_focus)?;
} }
@@ -293,7 +293,7 @@ impl WindowManager {
} }
SocketMessage::FocusWindow(direction) => { SocketMessage::FocusWindow(direction) => {
let focused_workspace = self.focused_workspace()?; let focused_workspace = self.focused_workspace()?;
match focused_workspace.layer() { match focused_workspace.layer {
WorkspaceLayer::Tiling => { WorkspaceLayer::Tiling => {
self.focus_container_in_direction(direction)?; self.focus_container_in_direction(direction)?;
} }
@@ -304,7 +304,7 @@ impl WindowManager {
} }
SocketMessage::MoveWindow(direction) => { SocketMessage::MoveWindow(direction) => {
let focused_workspace = self.focused_workspace()?; let focused_workspace = self.focused_workspace()?;
match focused_workspace.layer() { match focused_workspace.layer {
WorkspaceLayer::Tiling => { WorkspaceLayer::Tiling => {
self.move_container_in_direction(direction)?; self.move_container_in_direction(direction)?;
} }
@@ -315,7 +315,7 @@ impl WindowManager {
} }
SocketMessage::CycleFocusWindow(direction) => { SocketMessage::CycleFocusWindow(direction) => {
let focused_workspace = self.focused_workspace()?; let focused_workspace = self.focused_workspace()?;
match focused_workspace.layer() { match focused_workspace.layer {
WorkspaceLayer::Tiling => { WorkspaceLayer::Tiling => {
self.focus_container_in_cycle_direction(direction)?; self.focus_container_in_cycle_direction(direction)?;
} }
@@ -375,7 +375,7 @@ impl WindowManager {
.ok_or_eyre("no workspace at the given index")?; .ok_or_eyre("no workspace at the given index")?;
if let Some(container) = workspace.containers_mut().get_mut(container_idx) { if let Some(container) = workspace.containers_mut().get_mut(container_idx) {
container.set_locked(true); container.locked = true;
} }
} }
SocketMessage::UnlockMonitorWorkspaceContainer( SocketMessage::UnlockMonitorWorkspaceContainer(
@@ -394,7 +394,7 @@ impl WindowManager {
.ok_or_eyre("no workspace at the given index")?; .ok_or_eyre("no workspace at the given index")?;
if let Some(container) = workspace.containers_mut().get_mut(container_idx) { if let Some(container) = workspace.containers_mut().get_mut(container_idx) {
container.set_locked(false); container.locked = false;
} }
} }
SocketMessage::ToggleLock => self.toggle_lock()?, SocketMessage::ToggleLock => self.toggle_lock()?,
@@ -708,14 +708,14 @@ impl WindowManager {
.focused_workspace_idx(); .focused_workspace_idx();
if let Some(monitor) = self.focused_monitor_mut() { if let Some(monitor) = self.focused_monitor_mut() {
if let Some(last_focused_workspace) = monitor.last_focused_workspace() { if let Some(last_focused_workspace) = monitor.last_focused_workspace {
self.move_container_to_workspace(last_focused_workspace, true, None)?; self.move_container_to_workspace(last_focused_workspace, true, None)?;
} }
} }
self.focused_monitor_mut() self.focused_monitor_mut()
.ok_or_eyre("there is no monitor")? .ok_or_eyre("there is no monitor")?
.set_last_focused_workspace(Option::from(idx)); .last_focused_workspace = Option::from(idx);
} }
SocketMessage::SendContainerToLastWorkspace => { SocketMessage::SendContainerToLastWorkspace => {
// This is to ensure that even on an empty workspace on a secondary monitor, the // This is to ensure that even on an empty workspace on a secondary monitor, the
@@ -739,13 +739,13 @@ impl WindowManager {
.focused_workspace_idx(); .focused_workspace_idx();
if let Some(monitor) = self.focused_monitor_mut() { if let Some(monitor) = self.focused_monitor_mut() {
if let Some(last_focused_workspace) = monitor.last_focused_workspace() { if let Some(last_focused_workspace) = monitor.last_focused_workspace {
self.move_container_to_workspace(last_focused_workspace, false, None)?; self.move_container_to_workspace(last_focused_workspace, false, None)?;
} }
} }
self.focused_monitor_mut() self.focused_monitor_mut()
.ok_or_eyre("there is no monitor")? .ok_or_eyre("there is no monitor")?
.set_last_focused_workspace(Option::from(idx)); .last_focused_workspace = Option::from(idx);
} }
SocketMessage::MoveContainerToWorkspaceNumber(workspace_idx) => { SocketMessage::MoveContainerToWorkspaceNumber(workspace_idx) => {
self.move_container_to_workspace(workspace_idx, true, None)?; self.move_container_to_workspace(workspace_idx, true, None)?;
@@ -915,7 +915,7 @@ impl WindowManager {
SocketMessage::ScrollingLayoutColumns(count) => { SocketMessage::ScrollingLayoutColumns(count) => {
let focused_workspace = self.focused_workspace_mut()?; let focused_workspace = self.focused_workspace_mut()?;
let options = match focused_workspace.layout_options() { let options = match focused_workspace.layout_options {
Some(mut opts) => { Some(mut opts) => {
if let Some(scrolling) = &mut opts.scrolling { if let Some(scrolling) = &mut opts.scrolling {
scrolling.columns = count.into(); scrolling.columns = count.into();
@@ -930,7 +930,7 @@ impl WindowManager {
}, },
}; };
focused_workspace.set_layout_options(Some(options)); focused_workspace.layout_options = Some(options);
self.update_focused_workspace(false, false)?; self.update_focused_workspace(false, false)?;
} }
SocketMessage::ChangeLayout(layout) => self.change_workspace_layout_default(layout)?, SocketMessage::ChangeLayout(layout) => self.change_workspace_layout_default(layout)?,
@@ -1134,9 +1134,9 @@ impl WindowManager {
if monitor.workspaces().len() > 1 if monitor.workspaces().len() > 1
&& workspace.containers().is_empty() && workspace.containers().is_empty()
&& workspace.floating_windows().is_empty() && workspace.floating_windows().is_empty()
&& workspace.monocle_container().is_none() && workspace.monocle_container.is_none()
&& workspace.maximized_window().is_none() && workspace.maximized_window.is_none()
&& workspace.name().is_none() && workspace.name.is_none()
{ {
can_close = true; can_close = true;
} }
@@ -1174,14 +1174,14 @@ impl WindowManager {
.focused_workspace_idx(); .focused_workspace_idx();
if let Some(monitor) = self.focused_monitor_mut() { if let Some(monitor) = self.focused_monitor_mut() {
if let Some(last_focused_workspace) = monitor.last_focused_workspace() { if let Some(last_focused_workspace) = monitor.last_focused_workspace {
self.focus_workspace(last_focused_workspace)?; self.focus_workspace(last_focused_workspace)?;
} }
} }
self.focused_monitor_mut() self.focused_monitor_mut()
.ok_or_eyre("there is no monitor")? .ok_or_eyre("there is no monitor")?
.set_last_focused_workspace(Option::from(idx)); .last_focused_workspace = Option::from(idx);
} }
SocketMessage::FocusWorkspaceNumber(workspace_idx) => { SocketMessage::FocusWorkspaceNumber(workspace_idx) => {
// This is to ensure that even on an empty workspace on a secondary monitor, the // This is to ensure that even on an empty workspace on a secondary monitor, the
@@ -1254,9 +1254,9 @@ impl WindowManager {
let workspace = self.focused_workspace_mut()?; let workspace = self.focused_workspace_mut()?;
let mut to_focus = None; let mut to_focus = None;
match workspace.layer() { match workspace.layer {
WorkspaceLayer::Tiling => { WorkspaceLayer::Tiling => {
workspace.set_layer(WorkspaceLayer::Floating); workspace.layer = WorkspaceLayer::Floating;
let focused_idx = workspace.focused_floating_window_idx(); let focused_idx = workspace.focused_floating_window_idx();
let mut window_idx_pairs = workspace let mut window_idx_pairs = workspace
@@ -1295,16 +1295,16 @@ impl WindowManager {
} }
} }
if let Some(monocle) = workspace.monocle_container() { if let Some(monocle) = &workspace.monocle_container {
if let Some(window) = monocle.focused_window() { if let Some(window) = monocle.focused_window() {
window.lower()?; window.lower()?;
} }
} }
} }
WorkspaceLayer::Floating => { WorkspaceLayer::Floating => {
workspace.set_layer(WorkspaceLayer::Tiling); workspace.layer = WorkspaceLayer::Tiling;
if let Some(monocle) = workspace.monocle_container() { if let Some(monocle) = &workspace.monocle_container {
if let Some(window) = monocle.focused_window() { if let Some(window) = monocle.focused_window() {
to_focus = Some(*window); to_focus = Some(*window);
window.raise()?; window.raise()?;
@@ -1411,7 +1411,7 @@ impl WindowManager {
for monitor in self.monitors() { for monitor in self.monitors() {
if let Some(ws) = monitor.focused_workspace() { if let Some(ws) = monitor.focused_workspace() {
monitor_visible_windows.insert( monitor_visible_windows.insert(
monitor.device_id().clone(), monitor.device_id.clone(),
ws.visible_window_details().clone(), ws.visible_window_details().clone(),
); );
} }
@@ -1493,9 +1493,9 @@ impl WindowManager {
// with this signal // with this signal
let workspace = self.focused_workspace_mut()?; let workspace = self.focused_workspace_mut()?;
let container_len = workspace.containers().len(); let container_len = workspace.containers().len();
let no_layout_rules = workspace.layout_rules().is_empty(); let no_layout_rules = workspace.layout_rules.is_empty();
if let Layout::Custom(ref mut custom) = workspace.layout_mut() { if let Layout::Custom(ref mut custom) = &mut workspace.layout {
if matches!(axis, Axis::Horizontal) { if matches!(axis, Axis::Horizontal) {
#[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_precision_loss)]
let percentage = custom let percentage = custom
@@ -1512,7 +1512,7 @@ impl WindowManager {
} }
} }
} else { } else {
for rule in workspace.layout_rules_mut() { for rule in &mut workspace.layout_rules {
if container_len >= rule.0 { if container_len >= rule.0 {
if let Layout::Custom(ref mut custom) = rule.1 { if let Layout::Custom(ref mut custom) = rule.1 {
match sizing { match sizing {
@@ -1868,29 +1868,28 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
} }
SocketMessage::MonitorWorkAreaOffset(monitor_idx, rect) => { SocketMessage::MonitorWorkAreaOffset(monitor_idx, rect) => {
if let Some(monitor) = self.monitors_mut().get_mut(monitor_idx) { if let Some(monitor) = self.monitors_mut().get_mut(monitor_idx) {
monitor.set_work_area_offset(Option::from(rect)); monitor.work_area_offset = Option::from(rect);
self.retile_all(false)?; self.retile_all(false)?;
} }
} }
SocketMessage::WorkspaceWorkAreaOffset(monitor_idx, workspace_idx, rect) => { SocketMessage::WorkspaceWorkAreaOffset(monitor_idx, workspace_idx, rect) => {
if let Some(monitor) = self.monitors_mut().get_mut(monitor_idx) { if let Some(monitor) = self.monitors_mut().get_mut(monitor_idx) {
if let Some(workspace) = monitor.workspaces_mut().get_mut(workspace_idx) { if let Some(workspace) = monitor.workspaces_mut().get_mut(workspace_idx) {
workspace.set_work_area_offset(Option::from(rect)); workspace.work_area_offset = Option::from(rect);
self.retile_all(false)? self.retile_all(false)?
} }
} }
} }
SocketMessage::ToggleWindowBasedWorkAreaOffset => { SocketMessage::ToggleWindowBasedWorkAreaOffset => {
let workspace = self.focused_workspace_mut()?; let workspace = self.focused_workspace_mut()?;
workspace.set_apply_window_based_work_area_offset( workspace.apply_window_based_work_area_offset =
!workspace.apply_window_based_work_area_offset(), !workspace.apply_window_based_work_area_offset;
);
self.retile_all(true)?; self.retile_all(true)?;
} }
SocketMessage::QuickSave => { SocketMessage::QuickSave => {
let workspace = self.focused_workspace()?; let workspace = self.focused_workspace()?;
let resize = workspace.resize_dimensions(); let resize = &workspace.resize_dimensions;
let quicksave_json = std::env::temp_dir().join("komorebi.quicksave.json"); let quicksave_json = std::env::temp_dir().join("komorebi.quicksave.json");
@@ -1914,12 +1913,12 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
let resize: Vec<Option<Rect>> = serde_json::from_reader(file)?; let resize: Vec<Option<Rect>> = serde_json::from_reader(file)?;
workspace.set_resize_dimensions(resize); workspace.resize_dimensions = resize;
self.update_focused_workspace(false, false)?; self.update_focused_workspace(false, false)?;
} }
SocketMessage::Save(ref path) => { SocketMessage::Save(ref path) => {
let workspace = self.focused_workspace_mut()?; let workspace = self.focused_workspace_mut()?;
let resize = workspace.resize_dimensions(); let resize = &workspace.resize_dimensions;
let file = OpenOptions::new() let file = OpenOptions::new()
.write(true) .write(true)
@@ -1937,7 +1936,7 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
let resize: Vec<Option<Rect>> = serde_json::from_reader(file)?; let resize: Vec<Option<Rect>> = serde_json::from_reader(file)?;
workspace.set_resize_dimensions(resize); workspace.resize_dimensions = resize;
self.update_focused_workspace(false, false)?; self.update_focused_workspace(false, false)?;
} }
SocketMessage::AddSubscriberSocket(ref socket) => { SocketMessage::AddSubscriberSocket(ref socket) => {
@@ -1997,9 +1996,8 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
} }
SocketMessage::ToggleWorkspaceWindowContainerBehaviour => { SocketMessage::ToggleWorkspaceWindowContainerBehaviour => {
let current_global_behaviour = self.window_management_behaviour.current_behaviour; let current_global_behaviour = self.window_management_behaviour.current_behaviour;
if let Some(behaviour) = self if let Some(behaviour) =
.focused_workspace_mut()? &mut self.focused_workspace_mut()?.window_container_behaviour
.window_container_behaviour_mut()
{ {
match behaviour { match behaviour {
WindowContainerBehaviour::Create => { WindowContainerBehaviour::Create => {
@@ -2010,20 +2008,19 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
} }
} }
} else { } else {
self.focused_workspace_mut()? self.focused_workspace_mut()?.window_container_behaviour =
.set_window_container_behaviour(Some(match current_global_behaviour { Some(match current_global_behaviour {
WindowContainerBehaviour::Create => WindowContainerBehaviour::Append, WindowContainerBehaviour::Create => WindowContainerBehaviour::Append,
WindowContainerBehaviour::Append => WindowContainerBehaviour::Create, WindowContainerBehaviour::Append => WindowContainerBehaviour::Create,
})); });
}; };
} }
SocketMessage::ToggleWorkspaceFloatOverride => { SocketMessage::ToggleWorkspaceFloatOverride => {
let current_global_override = self.window_management_behaviour.float_override; let current_global_override = self.window_management_behaviour.float_override;
if let Some(float_override) = self.focused_workspace_mut()?.float_override_mut() { if let Some(float_override) = &mut self.focused_workspace_mut()?.float_override {
*float_override = !*float_override; *float_override = !*float_override;
} else { } else {
self.focused_workspace_mut()? self.focused_workspace_mut()?.float_override = Some(!current_global_override);
.set_float_override(Some(!current_global_override));
}; };
} }
SocketMessage::WindowHidingBehaviour(behaviour) => { SocketMessage::WindowHidingBehaviour(behaviour) => {
+22 -23
View File
@@ -304,7 +304,7 @@ impl WindowManager {
// containers - this makes floating windows on empty workspaces go into very // containers - this makes floating windows on empty workspaces go into very
// annoying focus change loops which prevents users from interacting with them // annoying focus change loops which prevents users from interacting with them
if !matches!( if !matches!(
self.focused_workspace()?.layout(), self.focused_workspace()?.layout,
Layout::Default(DefaultLayout::Scrolling) Layout::Default(DefaultLayout::Scrolling)
) && !self.focused_workspace()?.containers().is_empty() ) && !self.focused_workspace()?.containers().is_empty()
{ {
@@ -319,13 +319,13 @@ impl WindowManager {
match floating_window_idx { match floating_window_idx {
None => { None => {
if let Some(w) = workspace.maximized_window() { if let Some(w) = &workspace.maximized_window {
if w.hwnd == window.hwnd { if w.hwnd == window.hwnd {
return Ok(()); return Ok(());
} }
} }
if let Some(monocle) = workspace.monocle_container() { if let Some(monocle) = &workspace.monocle_container {
if let Some(window) = monocle.focused_window() { if let Some(window) = monocle.focused_window() {
window.focus(false)?; window.focus(false)?;
} }
@@ -333,10 +333,10 @@ impl WindowManager {
workspace.focus_container_by_window(window.hwnd)?; workspace.focus_container_by_window(window.hwnd)?;
} }
workspace.set_layer(WorkspaceLayer::Tiling); workspace.layer = WorkspaceLayer::Tiling;
if matches!( if matches!(
self.focused_workspace()?.layout(), self.focused_workspace()?.layout,
Layout::Default(DefaultLayout::Scrolling) Layout::Default(DefaultLayout::Scrolling)
) && !self.focused_workspace()?.containers().is_empty() ) && !self.focused_workspace()?.containers().is_empty()
{ {
@@ -345,7 +345,7 @@ impl WindowManager {
} }
Some(idx) => { Some(idx) => {
if let Some(_window) = workspace.floating_windows().get(idx) { if let Some(_window) = workspace.floating_windows().get(idx) {
workspace.set_layer(WorkspaceLayer::Floating); workspace.layer = WorkspaceLayer::Floating;
} }
} }
} }
@@ -415,7 +415,7 @@ impl WindowManager {
); );
let workspace = self.focused_workspace_mut()?; let workspace = self.focused_workspace_mut()?;
let workspace_contains_window = workspace.contains_window(window.hwnd); let workspace_contains_window = workspace.contains_window(window.hwnd);
let monocle_container = workspace.monocle_container().clone(); let monocle_container = workspace.monocle_container.clone();
if !workspace_contains_window && needs_reconciliation.is_none() { if !workspace_contains_window && needs_reconciliation.is_none() {
let floating_applications = FLOATING_APPLICATIONS.lock(); let floating_applications = FLOATING_APPLICATIONS.lock();
@@ -458,11 +458,11 @@ impl WindowManager {
let center_spawned_floats = let center_spawned_floats =
placement.should_center() && workspace.tile; placement.should_center() && workspace.tile;
workspace.floating_windows_mut().push_back(window); workspace.floating_windows_mut().push_back(window);
workspace.set_layer(WorkspaceLayer::Floating); workspace.layer = WorkspaceLayer::Floating;
if center_spawned_floats { if center_spawned_floats {
let mut floating_window = window; let mut floating_window = window;
floating_window.center( floating_window.center(
&workspace.globals().work_area, &workspace.globals.work_area,
placement.should_resize(), placement.should_resize(),
)?; )?;
} }
@@ -471,7 +471,7 @@ impl WindowManager {
match behaviour.current_behaviour { match behaviour.current_behaviour {
WindowContainerBehaviour::Create => { WindowContainerBehaviour::Create => {
workspace.new_container_for_window(window); workspace.new_container_for_window(window);
workspace.set_layer(WorkspaceLayer::Tiling); workspace.layer = WorkspaceLayer::Tiling;
self.update_focused_workspace(false, false)?; self.update_focused_workspace(false, false)?;
} }
WindowContainerBehaviour::Append => { WindowContainerBehaviour::Append => {
@@ -479,7 +479,7 @@ impl WindowManager {
.focused_container_mut() .focused_container_mut()
.ok_or_eyre("there is no focused container")? .ok_or_eyre("there is no focused container")?
.add_window(window); .add_window(window);
workspace.set_layer(WorkspaceLayer::Tiling); workspace.layer = WorkspaceLayer::Tiling;
self.update_focused_workspace(true, false)?; self.update_focused_workspace(true, false)?;
stackbar_manager::send_notification(); stackbar_manager::send_notification();
} }
@@ -513,8 +513,7 @@ impl WindowManager {
} }
let workspace = self.focused_workspace()?; let workspace = self.focused_workspace()?;
if !(monocle_window_event if !(monocle_window_event || workspace.layer != WorkspaceLayer::Tiling)
|| workspace.layer() != &WorkspaceLayer::Tiling)
&& monocle_container.is_some() && monocle_container.is_some()
{ {
window.hide(); window.hide();
@@ -568,7 +567,7 @@ impl WindowManager {
let focused_container_idx = workspace.focused_container_idx(); let focused_container_idx = workspace.focused_container_idx();
let new_position = WindowsApi::window_rect(window.hwnd)?; let new_position = WindowsApi::window_rect(window.hwnd)?;
let old_position = *workspace let old_position = *workspace
.latest_layout() .latest_layout
.get(focused_container_idx) .get(focused_container_idx)
// If the move was to another monitor with an empty workspace, the // If the move was to another monitor with an empty workspace, the
// workspace here will refer to that empty workspace, which won't // workspace here will refer to that empty workspace, which won't
@@ -616,7 +615,7 @@ impl WindowManager {
} }
let workspace = self.focused_workspace_mut()?; let workspace = self.focused_workspace_mut()?;
if (*workspace.tile() && workspace.contains_managed_window(window.hwnd)) if (workspace.tile && workspace.contains_managed_window(window.hwnd))
|| moved_across_monitors || moved_across_monitors
{ {
let resize = Rect { let resize = Rect {
@@ -832,7 +831,7 @@ impl WindowManager {
.and_then(|m| m.workspaces().get(*ws_idx)) .and_then(|m| m.workspaces().get(*ws_idx))
{ {
if let Some(monocle_with_window) = target_workspace if let Some(monocle_with_window) = target_workspace
.monocle_container() .monocle_container
.as_ref() .as_ref()
.and_then(|m| m.contains_window(window.hwnd).then_some(m)) .and_then(|m| m.contains_window(window.hwnd).then_some(m))
{ {
@@ -882,13 +881,13 @@ impl WindowManager {
if let Some(monitor) = self.focused_monitor_mut() { if let Some(monitor) = self.focused_monitor_mut() {
if ws_idx != monitor.focused_workspace_idx() { if ws_idx != monitor.focused_workspace_idx() {
let previous_idx = monitor.focused_workspace_idx(); let previous_idx = monitor.focused_workspace_idx();
monitor.set_last_focused_workspace(Option::from(previous_idx)); monitor.last_focused_workspace = Option::from(previous_idx);
monitor.focus_workspace(ws_idx)?; monitor.focus_workspace(ws_idx)?;
} }
if let Some(workspace) = monitor.focused_workspace_mut() { if let Some(workspace) = monitor.focused_workspace_mut() {
let mut layer = WorkspaceLayer::Tiling; let mut layer = WorkspaceLayer::Tiling;
if let Some((monocle, idx)) = workspace if let Some((monocle, idx)) = workspace
.monocle_container_mut() .monocle_container
.as_mut() .as_mut()
.and_then(|m| m.idx_for_window(window.hwnd).map(|i| (m, i))) .and_then(|m| m.idx_for_window(window.hwnd).map(|i| (m, i)))
{ {
@@ -899,14 +898,14 @@ impl WindowManager {
.any(|w| w.hwnd == window.hwnd) .any(|w| w.hwnd == window.hwnd)
{ {
layer = WorkspaceLayer::Floating; layer = WorkspaceLayer::Floating;
} else if !workspace } else if workspace
.maximized_window() .maximized_window
.is_some_and(|w| w.hwnd == window.hwnd) .is_none_or(|w| w.hwnd != window.hwnd)
{ {
// If the window is the maximized window do nothing, else we // If the window is the maximized window do nothing, else we
// reintegrate the monocle if it exists and then focus the // reintegrate the monocle if it exists and then focus the
// container // container
if workspace.monocle_container().is_some() { if workspace.monocle_container.is_some() {
tracing::info!("disabling monocle"); tracing::info!("disabling monocle");
for container in workspace.containers_mut() { for container in workspace.containers_mut() {
container.restore(); container.restore();
@@ -918,7 +917,7 @@ impl WindowManager {
} }
workspace.focus_container_by_window(window.hwnd)?; workspace.focus_container_by_window(window.hwnd)?;
} }
workspace.set_layer(layer); workspace.layer = layer;
} }
monitor.load_focused_workspace(mouse_follows_focus)?; monitor.load_focused_workspace(mouse_follows_focus)?;
monitor.update_focused_workspace(offset)?; monitor.update_focused_workspace(offset)?;
+10 -10
View File
@@ -111,7 +111,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
// Only operate on the focused workspace of each monitor // Only operate on the focused workspace of each monitor
if let Some(ws) = m.focused_workspace_mut() { if let Some(ws) = m.focused_workspace_mut() {
// Workspaces with tiling disabled don't have stackbars // Workspaces with tiling disabled don't have stackbars
if !ws.tile() { if !ws.tile {
let mut to_remove = vec![]; let mut to_remove = vec![];
for (id, border) in stackbars.iter() { for (id, border) in stackbars.iter() {
if stackbars_monitors.get(id).copied().unwrap_or_default() == monitor_idx { if stackbars_monitors.get(id).copied().unwrap_or_default() == monitor_idx {
@@ -131,7 +131,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
WindowsApi::is_zoomed(WindowsApi::foreground_window().unwrap_or_default()); WindowsApi::is_zoomed(WindowsApi::foreground_window().unwrap_or_default());
// Handle the monocle container separately // Handle the monocle container separately
if ws.monocle_container().is_some() || is_maximized { if ws.monocle_container.is_some() || is_maximized {
// Destroy any stackbars associated with the focused workspace // Destroy any stackbars associated with the focused workspace
let mut to_remove = vec![]; let mut to_remove = vec![];
for (id, stackbar) in stackbars.iter() { for (id, stackbar) in stackbars.iter() {
@@ -152,7 +152,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
let container_ids = ws let container_ids = ws
.containers() .containers()
.iter() .iter()
.map(|c| c.id().clone()) .map(|c| c.id.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut to_remove = vec![]; let mut to_remove = vec![];
@@ -170,7 +170,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
} }
let container_padding = ws let container_padding = ws
.container_padding() .container_padding
.unwrap_or_else(|| DEFAULT_CONTAINER_PADDING.load_consume()); .unwrap_or_else(|| DEFAULT_CONTAINER_PADDING.load_consume());
'containers: for container in ws.containers_mut() { 'containers: for container in ws.containers_mut() {
@@ -181,20 +181,20 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
}; };
if !should_add_stackbar { if !should_add_stackbar {
if let Some(stackbar) = stackbars.get(container.id()) { if let Some(stackbar) = stackbars.get(&container.id) {
stackbar.destroy()? stackbar.destroy()?
} }
stackbars.remove(container.id()); stackbars.remove(&container.id);
stackbars_monitors.remove(container.id()); stackbars_monitors.remove(&container.id);
continue 'containers; continue 'containers;
} }
// Get the stackbar entry for this container from the map or create one // Get the stackbar entry for this container from the map or create one
let stackbar = match stackbars.entry(container.id().clone()) { let stackbar = match stackbars.entry(container.id.clone()) {
Entry::Occupied(entry) => entry.into_mut(), Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
if let Ok(stackbar) = Stackbar::create(container.id()) { if let Ok(stackbar) = Stackbar::create(&container.id) {
entry.insert(stackbar) entry.insert(stackbar)
} else { } else {
continue 'receiver; continue 'receiver;
@@ -202,7 +202,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
} }
}; };
stackbars_monitors.insert(container.id().clone(), monitor_idx); stackbars_monitors.insert(container.id.clone(), monitor_idx);
let rect = WindowsApi::window_rect( let rect = WindowsApi::window_rect(
container.focused_window().copied().unwrap_or_default().hwnd, container.focused_window().copied().unwrap_or_default().hwnd,
+74 -94
View File
@@ -250,7 +250,7 @@ pub struct WorkspaceConfig {
impl From<&Workspace> for WorkspaceConfig { impl From<&Workspace> for WorkspaceConfig {
fn from(value: &Workspace) -> Self { fn from(value: &Workspace) -> Self {
let mut layout_rules = HashMap::new(); let mut layout_rules = HashMap::new();
for (threshold, layout) in value.layout_rules() { for (threshold, layout) in &value.layout_rules {
match layout { match layout {
Layout::Default(value) => { Layout::Default(value) => {
layout_rules.insert(*threshold, *value); layout_rules.insert(*threshold, *value);
@@ -261,14 +261,14 @@ impl From<&Workspace> for WorkspaceConfig {
let layout_rules = (!layout_rules.is_empty()).then_some(layout_rules); let layout_rules = (!layout_rules.is_empty()).then_some(layout_rules);
let mut window_container_behaviour_rules = HashMap::new(); let mut window_container_behaviour_rules = HashMap::new();
for (threshold, behaviour) in value.window_container_behaviour_rules().iter().flatten() { for (threshold, behaviour) in value.window_container_behaviour_rules.iter().flatten() {
window_container_behaviour_rules.insert(*threshold, *behaviour); window_container_behaviour_rules.insert(*threshold, *behaviour);
} }
let default_container_padding = DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst); let default_container_padding = DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst);
let default_workspace_padding = DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst); let default_workspace_padding = DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst);
let container_padding = value.container_padding().and_then(|container_padding| { let container_padding = value.container_padding.and_then(|container_padding| {
if container_padding == default_container_padding { if container_padding == default_container_padding {
None None
} else { } else {
@@ -276,7 +276,7 @@ impl From<&Workspace> for WorkspaceConfig {
} }
}); });
let workspace_padding = value.workspace_padding().and_then(|workspace_padding| { let workspace_padding = value.workspace_padding.and_then(|workspace_padding| {
if workspace_padding == default_workspace_padding { if workspace_padding == default_workspace_padding {
None None
} else { } else {
@@ -284,48 +284,48 @@ impl From<&Workspace> for WorkspaceConfig {
} }
}); });
let tile = if *value.tile() { None } else { Some(false) }; let tile = if value.tile { None } else { Some(false) };
Self { Self {
name: value name: value
.name() .name
.clone() .clone()
.unwrap_or_else(|| String::from("unnamed")), .unwrap_or_else(|| String::from("unnamed")),
layout: value layout: value
.tile() .tile
.then_some(match value.layout() { .then_some(match value.layout {
Layout::Default(layout) => Option::from(*layout), Layout::Default(layout) => Option::from(layout),
Layout::Custom(_) => None, Layout::Custom(_) => None,
}) })
.flatten(), .flatten(),
layout_options: value.layout_options(), layout_options: value.layout_options,
custom_layout: value custom_layout: value
.workspace_config() .workspace_config
.as_ref() .as_ref()
.and_then(|c| c.custom_layout.clone()), .and_then(|c| c.custom_layout.clone()),
layout_rules, layout_rules,
custom_layout_rules: value custom_layout_rules: value
.workspace_config() .workspace_config
.as_ref() .as_ref()
.and_then(|c| c.custom_layout_rules.clone()), .and_then(|c| c.custom_layout_rules.clone()),
container_padding, container_padding,
workspace_padding, workspace_padding,
initial_workspace_rules: value initial_workspace_rules: value
.workspace_config() .workspace_config
.as_ref() .as_ref()
.and_then(|c| c.initial_workspace_rules.clone()), .and_then(|c| c.initial_workspace_rules.clone()),
workspace_rules: value workspace_rules: value
.workspace_config() .workspace_config
.as_ref() .as_ref()
.and_then(|c| c.workspace_rules.clone()), .and_then(|c| c.workspace_rules.clone()),
work_area_offset: value.work_area_offset(), work_area_offset: value.work_area_offset,
apply_window_based_work_area_offset: Some(value.apply_window_based_work_area_offset()), apply_window_based_work_area_offset: Some(value.apply_window_based_work_area_offset),
window_container_behaviour: *value.window_container_behaviour(), window_container_behaviour: value.window_container_behaviour,
window_container_behaviour_rules: Option::from(window_container_behaviour_rules), window_container_behaviour_rules: Option::from(window_container_behaviour_rules),
float_override: *value.float_override(), float_override: value.float_override,
tile, tile,
layout_flip: value.layout_flip(), layout_flip: value.layout_flip,
floating_layer_behaviour: value.floating_layer_behaviour(), floating_layer_behaviour: value.floating_layer_behaviour,
wallpaper: None, wallpaper: None,
} }
} }
@@ -369,7 +369,7 @@ impl From<&Monitor> for MonitorConfig {
let default_container_padding = DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst); let default_container_padding = DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst);
let default_workspace_padding = DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst); let default_workspace_padding = DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst);
let container_padding = value.container_padding().and_then(|container_padding| { let container_padding = value.container_padding.and_then(|container_padding| {
if container_padding == default_container_padding { if container_padding == default_container_padding {
None None
} else { } else {
@@ -377,7 +377,7 @@ impl From<&Monitor> for MonitorConfig {
} }
}); });
let workspace_padding = value.workspace_padding().and_then(|workspace_padding| { let workspace_padding = value.workspace_padding.and_then(|workspace_padding| {
if workspace_padding == default_workspace_padding { if workspace_padding == default_workspace_padding {
None None
} else { } else {
@@ -387,13 +387,13 @@ impl From<&Monitor> for MonitorConfig {
Self { Self {
workspaces, workspaces,
work_area_offset: value.work_area_offset(), work_area_offset: value.work_area_offset,
window_based_work_area_offset: value.window_based_work_area_offset(), window_based_work_area_offset: value.window_based_work_area_offset,
window_based_work_area_offset_limit: Some(value.window_based_work_area_offset_limit()), window_based_work_area_offset_limit: Some(value.window_based_work_area_offset_limit),
container_padding, container_padding,
workspace_padding, workspace_padding,
wallpaper: value.wallpaper().clone(), wallpaper: value.wallpaper.clone(),
floating_layer_behaviour: value.floating_layer_behaviour(), floating_layer_behaviour: value.floating_layer_behaviour,
} }
} }
} }
@@ -1364,12 +1364,9 @@ impl StaticConfig {
let preferred_config_idx = { let preferred_config_idx = {
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read(); let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read();
let c_idx = display_index_preferences.iter().find_map(|(c_idx, id)| { let c_idx = display_index_preferences.iter().find_map(|(c_idx, id)| {
(monitor (monitor.serial_number_id.as_ref().is_some_and(|sn| sn == id)
.serial_number_id() || monitor.device_id.eq(id))
.as_ref() .then_some(*c_idx)
.is_some_and(|sn| sn == id)
|| monitor.device_id() == id)
.then_some(*c_idx)
}); });
c_idx c_idx
}; };
@@ -1396,19 +1393,16 @@ impl StaticConfig {
} }
monitor.ensure_workspace_count(monitor_config.workspaces.len()); monitor.ensure_workspace_count(monitor_config.workspaces.len());
monitor.set_work_area_offset(monitor_config.work_area_offset); monitor.work_area_offset = monitor_config.work_area_offset;
monitor.set_window_based_work_area_offset( monitor.window_based_work_area_offset =
monitor_config.window_based_work_area_offset, monitor_config.window_based_work_area_offset;
); monitor.window_based_work_area_offset_limit = monitor_config
monitor.set_window_based_work_area_offset_limit( .window_based_work_area_offset_limit
monitor_config .unwrap_or(1);
.window_based_work_area_offset_limit monitor.container_padding = monitor_config.container_padding;
.unwrap_or(1), monitor.workspace_padding = monitor_config.workspace_padding;
); monitor.wallpaper = monitor_config.wallpaper.clone();
monitor.set_container_padding(monitor_config.container_padding); monitor.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
monitor.set_workspace_padding(monitor_config.workspace_padding);
monitor.set_wallpaper(monitor_config.wallpaper.clone());
monitor.set_floating_layer_behaviour(monitor_config.floating_layer_behaviour);
monitor.update_workspaces_globals(offset); monitor.update_workspaces_globals(offset);
for (j, ws) in monitor.workspaces_mut().iter_mut().enumerate() { for (j, ws) in monitor.workspaces_mut().iter_mut().enumerate() {
@@ -1428,9 +1422,9 @@ impl StaticConfig {
// a copy of the monitor itself on the monitor cache if it is. // a copy of the monitor itself on the monitor cache if it is.
if idx == preferred_config_idx { if idx == preferred_config_idx {
let id = monitor let id = monitor
.serial_number_id() .serial_number_id
.as_ref() .as_ref()
.map_or(monitor.device_id(), |sn| sn); .map_or(&monitor.device_id, |sn| sn);
monitor_reconciliator::insert_in_monitor_cache(id, monitor.clone()); monitor_reconciliator::insert_in_monitor_cache(id, monitor.clone());
} }
@@ -1490,18 +1484,14 @@ impl StaticConfig {
); );
m.ensure_workspace_count(monitor_config.workspaces.len()); m.ensure_workspace_count(monitor_config.workspaces.len());
m.set_work_area_offset(monitor_config.work_area_offset); m.work_area_offset = monitor_config.work_area_offset;
m.set_window_based_work_area_offset( m.window_based_work_area_offset = monitor_config.window_based_work_area_offset;
monitor_config.window_based_work_area_offset, m.window_based_work_area_offset_limit = monitor_config
); .window_based_work_area_offset_limit
m.set_window_based_work_area_offset_limit( .unwrap_or(1);
monitor_config m.container_padding = monitor_config.container_padding;
.window_based_work_area_offset_limit m.workspace_padding = monitor_config.workspace_padding;
.unwrap_or(1), m.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
);
m.set_container_padding(monitor_config.container_padding);
m.set_workspace_padding(monitor_config.workspace_padding);
m.set_floating_layer_behaviour(monitor_config.floating_layer_behaviour);
m.update_workspaces_globals(offset); m.update_workspaces_globals(offset);
@@ -1543,12 +1533,9 @@ impl StaticConfig {
let preferred_config_idx = { let preferred_config_idx = {
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read(); let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read();
let c_idx = display_index_preferences.iter().find_map(|(c_idx, id)| { let c_idx = display_index_preferences.iter().find_map(|(c_idx, id)| {
(monitor (monitor.serial_number_id.as_ref().is_some_and(|sn| sn == id)
.serial_number_id() || monitor.device_id.eq(id))
.as_ref() .then_some(*c_idx)
.is_some_and(|sn| sn == id)
|| monitor.device_id() == id)
.then_some(*c_idx)
}); });
c_idx c_idx
}; };
@@ -1575,21 +1562,18 @@ impl StaticConfig {
} }
monitor.ensure_workspace_count(monitor_config.workspaces.len()); monitor.ensure_workspace_count(monitor_config.workspaces.len());
if monitor.work_area_offset().is_none() { if monitor.work_area_offset.is_none() {
monitor.set_work_area_offset(monitor_config.work_area_offset); monitor.work_area_offset = monitor_config.work_area_offset;
} }
monitor.set_window_based_work_area_offset( monitor.window_based_work_area_offset =
monitor_config.window_based_work_area_offset, monitor_config.window_based_work_area_offset;
); monitor.window_based_work_area_offset_limit = monitor_config
monitor.set_window_based_work_area_offset_limit( .window_based_work_area_offset_limit
monitor_config .unwrap_or(1);
.window_based_work_area_offset_limit monitor.container_padding = monitor_config.container_padding;
.unwrap_or(1), monitor.workspace_padding = monitor_config.workspace_padding;
); monitor.wallpaper = monitor_config.wallpaper.clone();
monitor.set_container_padding(monitor_config.container_padding); monitor.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
monitor.set_workspace_padding(monitor_config.workspace_padding);
monitor.set_wallpaper(monitor_config.wallpaper.clone());
monitor.set_floating_layer_behaviour(monitor_config.floating_layer_behaviour);
monitor.update_workspaces_globals(offset); monitor.update_workspaces_globals(offset);
@@ -1603,9 +1587,9 @@ impl StaticConfig {
// a copy of the monitor itself on the monitor cache if it is. // a copy of the monitor itself on the monitor cache if it is.
if idx == preferred_config_idx { if idx == preferred_config_idx {
let id = monitor let id = monitor
.serial_number_id() .serial_number_id
.as_ref() .as_ref()
.map_or(monitor.device_id(), |sn| sn); .map_or(&monitor.device_id, |sn| sn);
monitor_reconciliator::insert_in_monitor_cache(id, monitor.clone()); monitor_reconciliator::insert_in_monitor_cache(id, monitor.clone());
} }
@@ -1665,18 +1649,14 @@ impl StaticConfig {
); );
m.ensure_workspace_count(monitor_config.workspaces.len()); m.ensure_workspace_count(monitor_config.workspaces.len());
m.set_work_area_offset(monitor_config.work_area_offset); m.work_area_offset = monitor_config.work_area_offset;
m.set_window_based_work_area_offset( m.window_based_work_area_offset = monitor_config.window_based_work_area_offset;
monitor_config.window_based_work_area_offset, m.window_based_work_area_offset_limit = monitor_config
); .window_based_work_area_offset_limit
m.set_window_based_work_area_offset_limit( .unwrap_or(1);
monitor_config m.container_padding = monitor_config.container_padding;
.window_based_work_area_offset_limit m.workspace_padding = monitor_config.workspace_padding;
.unwrap_or(1), m.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
);
m.set_container_padding(monitor_config.container_padding);
m.set_workspace_padding(monitor_config.workspace_padding);
m.set_floating_layer_behaviour(monitor_config.floating_layer_behaviour);
m.update_workspaces_globals(offset); m.update_workspaces_globals(offset);
+2 -2
View File
@@ -92,7 +92,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
'workspaces: for (workspace_idx, ws) in m.workspaces().iter().enumerate() { 'workspaces: for (workspace_idx, ws) in m.workspaces().iter().enumerate() {
// Only operate on the focused workspace of each monitor // Only operate on the focused workspace of each monitor
// Workspaces with tiling disabled don't have transparent windows // Workspaces with tiling disabled don't have transparent windows
if !ws.tile() || workspace_idx != focused_workspace_idx { if !ws.tile || workspace_idx != focused_workspace_idx {
for window in ws.visible_windows().iter().flatten() { for window in ws.visible_windows().iter().flatten() {
if let Err(error) = window.opaque() { if let Err(error) = window.opaque() {
let hwnd = window.hwnd; let hwnd = window.hwnd;
@@ -104,7 +104,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
} }
// Monocle container is never transparent // Monocle container is never transparent
if let Some(monocle) = ws.monocle_container() { if let Some(monocle) = &ws.monocle_container {
if let Some(window) = monocle.focused_window() { if let Some(window) = monocle.focused_window() {
if monitor_idx == focused_monitor_idx { if monitor_idx == focused_monitor_idx {
if let Err(error) = window.opaque() { if let Err(error) = window.opaque() {
File diff suppressed because it is too large Load Diff
+9 -12
View File
@@ -310,7 +310,7 @@ impl WindowsApi {
let name = name.split('\\').collect::<Vec<_>>()[0].to_string(); let name = name.split('\\').collect::<Vec<_>>()[0].to_string();
for monitor in monitors.elements() { for monitor in monitors.elements() {
if device_id.eq(monitor.device_id()) { if device_id.eq(&monitor.device_id) {
continue 'read; continue 'read;
} }
} }
@@ -335,15 +335,14 @@ impl WindowsApi {
let mut index_preference = None; let mut index_preference = None;
let monitor_index_preferences = MONITOR_INDEX_PREFERENCES.lock(); let monitor_index_preferences = MONITOR_INDEX_PREFERENCES.lock();
for (index, monitor_size) in &*monitor_index_preferences { for (index, monitor_size) in &*monitor_index_preferences {
if m.size() == monitor_size { if m.size == *monitor_size {
index_preference = Option::from(index); index_preference = Option::from(index);
} }
} }
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read(); let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read();
for (index, id) in &*display_index_preferences { for (index, id) in &*display_index_preferences {
if m.serial_number_id().as_ref().is_some_and(|sn| sn == id) || id.eq(m.device_id()) if m.serial_number_id.as_ref().is_some_and(|sn| sn == id) || id.eq(&m.device_id) {
{
index_preference = Option::from(index); index_preference = Option::from(index);
} }
} }
@@ -356,7 +355,7 @@ impl WindowsApi {
let current_name = monitors let current_name = monitors
.elements_mut() .elements_mut()
.get(*preference) .get(*preference)
.map_or("", |m| m.name()); .map_or("", |m| &m.name);
if current_name == "PLACEHOLDER" { if current_name == "PLACEHOLDER" {
let _ = monitors.elements_mut().remove(*preference); let _ = monitors.elements_mut().remove(*preference);
monitors.elements_mut().insert(*preference, m); monitors.elements_mut().insert(*preference, m);
@@ -368,16 +367,14 @@ impl WindowsApi {
} }
} }
monitors monitors.elements_mut().retain(|m| m.name.ne("PLACEHOLDER"));
.elements_mut()
.retain(|m| m.name().ne("PLACEHOLDER"));
// Rebuild monitor index map // Rebuild monitor index map
*monitor_usr_idx_map = HashMap::new(); *monitor_usr_idx_map = HashMap::new();
let mut added_monitor_idxs = Vec::new(); let mut added_monitor_idxs = Vec::new();
for (index, id) in &*DISPLAY_INDEX_PREFERENCES.read() { for (index, id) in &*DISPLAY_INDEX_PREFERENCES.read() {
if let Some(m_idx) = monitors.elements().iter().position(|m| { if let Some(m_idx) = monitors.elements().iter().position(|m| {
m.serial_number_id().as_ref().is_some_and(|sn| sn == id) || m.device_id() == id m.serial_number_id.as_ref().is_some_and(|sn| sn == id) || m.device_id.eq(id)
}) { }) {
monitor_usr_idx_map.insert(*index, m_idx); monitor_usr_idx_map.insert(*index, m_idx);
added_monitor_idxs.push(m_idx); added_monitor_idxs.push(m_idx);
@@ -415,7 +412,7 @@ impl WindowsApi {
pub fn load_workspace_information(monitors: &mut Ring<Monitor>) -> Result<()> { pub fn load_workspace_information(monitors: &mut Ring<Monitor>) -> Result<()> {
for monitor in monitors.elements_mut() { for monitor in monitors.elements_mut() {
let monitor_name = monitor.name().clone(); let monitor_name = monitor.name.clone();
if let Some(workspace) = monitor.workspaces_mut().front_mut() { if let Some(workspace) = monitor.workspaces_mut().front_mut() {
// EnumWindows will enumerate through windows on all monitors // EnumWindows will enumerate through windows on all monitors
Self::enum_windows( Self::enum_windows(
@@ -426,7 +423,7 @@ impl WindowsApi {
// Ensure that the resize_dimensions Vec length matches the number of containers for // Ensure that the resize_dimensions Vec length matches the number of containers for
// the potential later calls to workspace.remove_window later in this fn // the potential later calls to workspace.remove_window later in this fn
let len = workspace.containers().len(); let len = workspace.containers().len();
workspace.resize_dimensions_mut().resize(len, None); workspace.resize_dimensions.resize(len, None);
// We have to prune each monitor's primary workspace of undesired windows here // We have to prune each monitor's primary workspace of undesired windows here
let mut windows_on_other_monitors = vec![]; let mut windows_on_other_monitors = vec![];
@@ -464,7 +461,7 @@ impl WindowsApi {
Ok(Self::monitor( Ok(Self::monitor(
unsafe { MonitorFromWindow(HWND(as_ptr!(hwnd)), MONITOR_DEFAULTTONEAREST) }.0 as isize, unsafe { MonitorFromWindow(HWND(as_ptr!(hwnd)), MONITOR_DEFAULTTONEAREST) }.0 as isize,
)? )?
.name() .name
.to_string()) .to_string())
} }
+138 -182
View File
@@ -39,74 +39,44 @@ use crate::REGEX_IDENTIFIERS;
use crate::REMOVE_TITLEBARS; use crate::REMOVE_TITLEBARS;
use color_eyre::eyre::OptionExt; use color_eyre::eyre::OptionExt;
use color_eyre::Result; use color_eyre::Result;
use getset::CopyGetters;
use getset::Getters;
use getset::MutGetters;
use getset::Setters;
use komorebi_themes::Base16ColourPalette; use komorebi_themes::Base16ColourPalette;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use uds_windows::UnixStream; use uds_windows::UnixStream;
#[allow(clippy::struct_field_names)] #[allow(clippy::struct_field_names)]
#[derive( #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
Debug, Clone, Serialize, Deserialize, Getters, CopyGetters, MutGetters, Setters, PartialEq,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Workspace { pub struct Workspace {
#[getset(get = "pub", set = "pub")]
pub name: Option<String>, pub name: Option<String>,
pub containers: Ring<Container>, pub containers: Ring<Container>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub monocle_container: Option<Container>, pub monocle_container: Option<Container>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub", set = "pub")]
pub monocle_container_restore_idx: Option<usize>, pub monocle_container_restore_idx: Option<usize>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub maximized_window: Option<Window>, pub maximized_window: Option<Window>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[getset(get_copy = "pub", set = "pub")]
pub maximized_window_restore_idx: Option<usize>, pub maximized_window_restore_idx: Option<usize>,
pub floating_windows: Ring<Window>, pub floating_windows: Ring<Window>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub layout: Layout, pub layout: Layout,
#[getset(get_copy = "pub", set = "pub")]
pub layout_options: Option<LayoutOptions>, pub layout_options: Option<LayoutOptions>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub layout_rules: Vec<(usize, Layout)>, pub layout_rules: Vec<(usize, Layout)>,
#[getset(get_copy = "pub", set = "pub")]
pub layout_flip: Option<Axis>, pub layout_flip: Option<Axis>,
#[getset(get_copy = "pub", set = "pub")]
pub workspace_padding: Option<i32>, pub workspace_padding: Option<i32>,
#[getset(get_copy = "pub", set = "pub")]
pub container_padding: Option<i32>, pub container_padding: Option<i32>,
#[getset(get = "pub", set = "pub")]
pub latest_layout: Vec<Rect>, pub latest_layout: Vec<Rect>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub resize_dimensions: Vec<Option<Rect>>, pub resize_dimensions: Vec<Option<Rect>>,
#[getset(get = "pub", set = "pub")]
pub tile: bool, pub tile: bool,
#[getset(get_copy = "pub", set = "pub")]
pub work_area_offset: Option<Rect>, pub work_area_offset: Option<Rect>,
#[getset(get_copy = "pub", set = "pub")]
pub apply_window_based_work_area_offset: bool, pub apply_window_based_work_area_offset: bool,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub window_container_behaviour: Option<WindowContainerBehaviour>, pub window_container_behaviour: Option<WindowContainerBehaviour>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub window_container_behaviour_rules: Option<Vec<(usize, WindowContainerBehaviour)>>, pub window_container_behaviour_rules: Option<Vec<(usize, WindowContainerBehaviour)>>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub float_override: Option<bool>, pub float_override: Option<bool>,
#[serde(skip)] #[serde(skip)]
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub globals: WorkspaceGlobals, pub globals: WorkspaceGlobals,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub layer: WorkspaceLayer, pub layer: WorkspaceLayer,
#[getset(get_copy = "pub", get_mut = "pub", set = "pub")]
pub floating_layer_behaviour: Option<FloatingLayerBehaviour>, pub floating_layer_behaviour: Option<FloatingLayerBehaviour>,
#[getset(get = "pub", get_mut = "pub", set = "pub")]
pub wallpaper: Option<Wallpaper>, pub wallpaper: Option<Wallpaper>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
#[getset(get = "pub", set = "pub")]
pub workspace_config: Option<WorkspaceConfig>, pub workspace_config: Option<WorkspaceConfig>,
} }
@@ -171,19 +141,7 @@ pub enum WorkspaceWindowLocation {
Floating(usize), // idx in floating_windows Floating(usize), // idx in floating_windows
} }
#[derive( #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, PartialEq)]
Debug,
Default,
Copy,
Clone,
Serialize,
Deserialize,
Getters,
CopyGetters,
MutGetters,
Setters,
PartialEq,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
/// Settings setup either by the parent monitor or by the `WindowManager` /// Settings setup either by the parent monitor or by the `WindowManager`
pub struct WorkspaceGlobals { pub struct WorkspaceGlobals {
@@ -202,9 +160,9 @@ impl Workspace {
pub fn load_static_config(&mut self, config: &WorkspaceConfig) -> Result<()> { pub fn load_static_config(&mut self, config: &WorkspaceConfig) -> Result<()> {
self.name = Option::from(config.name.clone()); self.name = Option::from(config.name.clone());
self.set_container_padding(config.container_padding); self.container_padding = config.container_padding;
self.set_workspace_padding(config.workspace_padding); self.workspace_padding = config.workspace_padding;
if let Some(layout) = &config.layout { if let Some(layout) = &config.layout {
self.layout = Layout::Default(*layout); self.layout = Layout::Default(*layout);
@@ -229,7 +187,7 @@ impl Workspace {
self.tile = true; self.tile = true;
} }
self.set_layout_rules(all_layout_rules.clone()); self.layout_rules = all_layout_rules.clone();
if let Some(layout_rules) = &config.custom_layout_rules { if let Some(layout_rules) = &config.custom_layout_rules {
for (count, pathbuf) in layout_rules { for (count, pathbuf) in layout_rules {
@@ -239,20 +197,19 @@ impl Workspace {
all_layout_rules.sort_by_key(|(i, _)| *i); all_layout_rules.sort_by_key(|(i, _)| *i);
self.tile = true; self.tile = true;
self.set_layout_rules(all_layout_rules); self.layout_rules = all_layout_rules;
} }
self.set_work_area_offset(config.work_area_offset); self.work_area_offset = config.work_area_offset;
self.set_apply_window_based_work_area_offset( self.apply_window_based_work_area_offset =
config.apply_window_based_work_area_offset.unwrap_or(true), config.apply_window_based_work_area_offset.unwrap_or(true);
);
self.set_window_container_behaviour(config.window_container_behaviour); self.window_container_behaviour = config.window_container_behaviour;
if let Some(window_container_behaviour_rules) = &config.window_container_behaviour_rules { if let Some(window_container_behaviour_rules) = &config.window_container_behaviour_rules {
if window_container_behaviour_rules.is_empty() { if window_container_behaviour_rules.is_empty() {
self.set_window_container_behaviour_rules(None); self.window_container_behaviour_rules = None;
} else { } else {
let mut all_rules = vec![]; let mut all_rules = vec![];
for (count, behaviour) in window_container_behaviour_rules { for (count, behaviour) in window_container_behaviour_rules {
@@ -260,19 +217,19 @@ impl Workspace {
} }
all_rules.sort_by_key(|(i, _)| *i); all_rules.sort_by_key(|(i, _)| *i);
self.set_window_container_behaviour_rules(Some(all_rules)); self.window_container_behaviour_rules = Some(all_rules);
} }
} else { } else {
self.set_window_container_behaviour_rules(None); self.window_container_behaviour_rules = None;
} }
self.set_float_override(config.float_override); self.float_override = config.float_override;
self.set_layout_flip(config.layout_flip); self.layout_flip = config.layout_flip;
self.set_floating_layer_behaviour(config.floating_layer_behaviour); self.floating_layer_behaviour = config.floating_layer_behaviour;
self.set_wallpaper(config.wallpaper.clone()); self.wallpaper = config.wallpaper.clone();
self.set_layout_options(config.layout_options); self.layout_options = config.layout_options;
self.set_workspace_config(Some(config.clone())); self.workspace_config = Some(config.clone());
Ok(()) Ok(())
} }
@@ -298,11 +255,11 @@ impl Workspace {
container.hide(omit) container.hide(omit)
} }
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
window.hide(); window.hide();
} }
if let Some(container) = self.monocle_container_mut() { if let Some(container) = &self.monocle_container {
container.hide(omit) container.hide(omit)
} }
} }
@@ -429,7 +386,7 @@ impl Workspace {
hmonitor: isize, hmonitor: isize,
monitor_wp: &Option<Wallpaper>, monitor_wp: &Option<Wallpaper>,
) -> Result<()> { ) -> Result<()> {
if let Some(container) = self.monocle_container() { if let Some(container) = &self.monocle_container {
if let Some(window) = container.focused_window() { if let Some(window) = container.focused_window() {
container.restore(); container.restore();
window.focus(mouse_follows_focus)?; window.focus(mouse_follows_focus)?;
@@ -462,15 +419,15 @@ impl Workspace {
// Maximised windows and floating windows should always be drawn at the top of the Z order // Maximised windows and floating windows should always be drawn at the top of the Z order
// when switching to a workspace // when switching to a workspace
if let Some(window) = to_focus { if let Some(window) = to_focus {
if self.maximized_window().is_none() && matches!(self.layer, WorkspaceLayer::Tiling) { if self.maximized_window.is_none() && matches!(self.layer, WorkspaceLayer::Tiling) {
window.focus(mouse_follows_focus)?; window.focus(mouse_follows_focus)?;
} else if let Some(maximized_window) = self.maximized_window() { } else if let Some(maximized_window) = self.maximized_window {
maximized_window.restore(); maximized_window.restore();
maximized_window.focus(mouse_follows_focus)?; maximized_window.focus(mouse_follows_focus)?;
} else if let Some(floating_window) = self.focused_floating_window() { } else if let Some(floating_window) = self.focused_floating_window() {
floating_window.focus(mouse_follows_focus)?; floating_window.focus(mouse_follows_focus)?;
} }
} else if let Some(maximized_window) = self.maximized_window() { } else if let Some(maximized_window) = self.maximized_window {
maximized_window.restore(); maximized_window.restore();
maximized_window.focus(mouse_follows_focus)?; maximized_window.focus(mouse_follows_focus)?;
} else if let Some(floating_window) = self.focused_floating_window() { } else if let Some(floating_window) = self.focused_floating_window() {
@@ -489,20 +446,19 @@ impl Workspace {
self.containers_mut().retain(|c| !c.windows().is_empty()); self.containers_mut().retain(|c| !c.windows().is_empty());
let container_padding = self let container_padding = self
.container_padding() .container_padding
.or(self.globals().container_padding) .or(self.globals.container_padding)
.unwrap_or_default(); .unwrap_or_default();
let workspace_padding = self let workspace_padding = self
.workspace_padding() .workspace_padding
.or(self.globals().workspace_padding) .or(self.globals.workspace_padding)
.unwrap_or_default(); .unwrap_or_default();
let border_width = self.globals().border_width; let border_width = self.globals.border_width;
let border_offset = self.globals().border_offset; let border_offset = self.globals.border_offset;
let work_area = self.globals().work_area; let work_area = self.globals.work_area;
let work_area_offset = self.work_area_offset().or(self.globals().work_area_offset); let work_area_offset = self.work_area_offset.or(self.globals.work_area_offset);
let window_based_work_area_offset = self.globals().window_based_work_area_offset; let window_based_work_area_offset = self.globals.window_based_work_area_offset;
let window_based_work_area_offset_limit = let window_based_work_area_offset_limit = self.globals.window_based_work_area_offset_limit;
self.globals().window_based_work_area_offset_limit;
let mut adjusted_work_area = work_area_offset.map_or_else( let mut adjusted_work_area = work_area_offset.map_or_else(
|| work_area, || work_area,
@@ -518,7 +474,7 @@ impl Workspace {
); );
if (self.containers().len() <= window_based_work_area_offset_limit as usize if (self.containers().len() <= window_based_work_area_offset_limit as usize
|| self.monocle_container().is_some() && window_based_work_area_offset_limit > 0) || self.monocle_container.is_some() && window_based_work_area_offset_limit > 0)
&& self.apply_window_based_work_area_offset && self.apply_window_based_work_area_offset
{ {
adjusted_work_area = window_based_work_area_offset.map_or_else( adjusted_work_area = window_based_work_area_offset.map_or_else(
@@ -539,21 +495,21 @@ impl Workspace {
self.enforce_resize_constraints(); self.enforce_resize_constraints();
if !self.layout_rules().is_empty() { if !self.layout_rules.is_empty() {
let mut updated_layout = None; let mut updated_layout = None;
for (threshold, layout) in self.layout_rules() { for (threshold, layout) in &self.layout_rules {
if self.containers().len() >= *threshold { if self.containers().len() >= *threshold {
updated_layout = Option::from(layout.clone()); updated_layout = Option::from(layout.clone());
} }
} }
if let Some(updated_layout) = updated_layout { if let Some(updated_layout) = updated_layout {
self.set_layout(updated_layout); self.layout = updated_layout;
} }
} }
if let Some(window_container_behaviour_rules) = self.window_container_behaviour_rules() { if let Some(window_container_behaviour_rules) = &self.window_container_behaviour_rules {
let mut updated_behaviour = None; let mut updated_behaviour = None;
for (threshold, behaviour) in window_container_behaviour_rules { for (threshold, behaviour) in window_container_behaviour_rules {
if self.containers().len() >= *threshold { if self.containers().len() >= *threshold {
@@ -561,33 +517,33 @@ impl Workspace {
} }
} }
self.set_window_container_behaviour(updated_behaviour); self.window_container_behaviour = updated_behaviour;
} }
let managed_maximized_window = self.maximized_window().is_some(); let managed_maximized_window = self.maximized_window.is_some();
if *self.tile() { if self.tile {
if let Some(container) = self.monocle_container_mut() { if let Some(container) = &mut self.monocle_container {
if let Some(window) = container.focused_window_mut() { if let Some(window) = container.focused_window_mut() {
adjusted_work_area.add_padding(container_padding); adjusted_work_area.add_padding(container_padding);
adjusted_work_area.add_padding(border_offset); adjusted_work_area.add_padding(border_offset);
adjusted_work_area.add_padding(border_width); adjusted_work_area.add_padding(border_width);
window.set_position(&adjusted_work_area, true)?; window.set_position(&adjusted_work_area, true)?;
}; };
} else if let Some(window) = self.maximized_window_mut() { } else if let Some(window) = &mut self.maximized_window {
window.maximize(); window.maximize();
} else if !self.containers().is_empty() { } else if !self.containers().is_empty() {
let mut layouts = self.layout().as_boxed_arrangement().calculate( let mut layouts = self.layout.as_boxed_arrangement().calculate(
&adjusted_work_area, &adjusted_work_area,
NonZeroUsize::new(self.containers().len()).ok_or_eyre( NonZeroUsize::new(self.containers().len()).ok_or_eyre(
"there must be at least one container to calculate a workspace layout", "there must be at least one container to calculate a workspace layout",
)?, )?,
Some(container_padding), Some(container_padding),
self.layout_flip(), self.layout_flip,
self.resize_dimensions(), &self.resize_dimensions,
self.focused_container_idx(), self.focused_container_idx(),
self.layout_options(), self.layout_options,
self.latest_layout(), &self.latest_layout,
); );
let should_remove_titlebars = REMOVE_TITLEBARS.load(Ordering::SeqCst); let should_remove_titlebars = REMOVE_TITLEBARS.load(Ordering::SeqCst);
@@ -643,7 +599,7 @@ impl Workspace {
} }
} }
self.set_latest_layout(layouts); self.latest_layout = layouts;
} }
} }
@@ -658,8 +614,8 @@ impl Workspace {
// without this check, if there are exactly two containers, when one is toggled to monocle // without this check, if there are exactly two containers, when one is toggled to monocle
// the resize dimensions will be truncated to len == 1, and when it is reintegrated, if it // the resize dimensions will be truncated to len == 1, and when it is reintegrated, if it
// had a resize adjustment before, that will have been lost // had a resize adjustment before, that will have been lost
if self.monocle_container().is_none() { if self.monocle_container.is_none() {
self.resize_dimensions_mut().resize(container_count, None); self.resize_dimensions.resize(container_count, None);
} }
Ok(()) Ok(())
@@ -709,7 +665,7 @@ impl Workspace {
let point = WindowsApi::cursor_pos().ok()?; let point = WindowsApi::cursor_pos().ok()?;
for (i, _container) in self.containers().iter().enumerate() { for (i, _container) in self.containers().iter().enumerate() {
if let Some(rect) = self.latest_layout().get(i) { if let Some(rect) = self.latest_layout.get(i) {
if rect.contains_point((point.x, point.y)) { if rect.contains_point((point.x, point.y)) {
idx = Option::from(i); idx = Option::from(i);
} }
@@ -726,7 +682,7 @@ impl Workspace {
} }
} }
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
if let Ok(window_exe) = window.exe() { if let Ok(window_exe) = window.exe() {
if exe == window_exe { if exe == window_exe {
return Option::from(window.hwnd); return Option::from(window.hwnd);
@@ -734,7 +690,7 @@ impl Workspace {
} }
} }
if let Some(container) = self.monocle_container() { if let Some(container) = &self.monocle_container {
if let Some(hwnd) = container.hwnd_from_exe(exe) { if let Some(hwnd) = container.hwnd_from_exe(exe) {
return Option::from(hwnd); return Option::from(hwnd);
} }
@@ -761,7 +717,7 @@ impl Workspace {
} }
} }
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
if let Ok(window_exe) = window.exe() { if let Ok(window_exe) = window.exe() {
if exe == window_exe { if exe == window_exe {
return Some(WorkspaceWindowLocation::Maximized); return Some(WorkspaceWindowLocation::Maximized);
@@ -769,7 +725,7 @@ impl Workspace {
} }
} }
if let Some(container) = self.monocle_container() { if let Some(container) = &self.monocle_container {
if let Some(window_idx) = container.idx_from_exe(exe) { if let Some(window_idx) = container.idx_from_exe(exe) {
return Some(WorkspaceWindowLocation::Monocle(window_idx)); return Some(WorkspaceWindowLocation::Monocle(window_idx));
} }
@@ -793,13 +749,13 @@ impl Workspace {
} }
} }
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
if hwnd == window.hwnd { if hwnd == window.hwnd {
return true; return true;
} }
} }
if let Some(container) = self.monocle_container() { if let Some(container) = &self.monocle_container {
if container.contains_window(hwnd) { if container.contains_window(hwnd) {
return true; return true;
} }
@@ -810,13 +766,13 @@ impl Workspace {
pub fn is_focused_window_monocle_or_maximized(&self) -> Result<bool> { pub fn is_focused_window_monocle_or_maximized(&self) -> Result<bool> {
let hwnd = WindowsApi::foreground_window()?; let hwnd = WindowsApi::foreground_window()?;
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
if hwnd == window.hwnd { if hwnd == window.hwnd {
return Ok(true); return Ok(true);
} }
} }
if let Some(container) = self.monocle_container() { if let Some(container) = &self.monocle_container {
if container.contains_window(hwnd) { if container.contains_window(hwnd) {
return Ok(true); return Ok(true);
} }
@@ -827,8 +783,8 @@ impl Workspace {
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.containers().is_empty() self.containers().is_empty()
&& self.maximized_window().is_none() && self.maximized_window.is_none()
&& self.monocle_container().is_none() && self.monocle_container.is_none()
&& self.floating_windows().is_empty() && self.floating_windows().is_empty()
} }
@@ -839,13 +795,13 @@ impl Workspace {
} }
} }
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
if hwnd == window.hwnd { if hwnd == window.hwnd {
return true; return true;
} }
} }
if let Some(container) = self.monocle_container() { if let Some(container) = &self.monocle_container {
if container.contains_window(hwnd) { if container.contains_window(hwnd) {
return true; return true;
} }
@@ -861,12 +817,12 @@ impl Workspace {
} }
pub fn promote_container(&mut self) -> Result<()> { pub fn promote_container(&mut self) -> Result<()> {
let resize = self.resize_dimensions_mut().remove(0); let resize = self.resize_dimensions.remove(0);
let container = self let container = self
.remove_focused_container() .remove_focused_container()
.ok_or_eyre("there is no container")?; .ok_or_eyre("there is no container")?;
let primary_idx = match self.layout() { let primary_idx = match &self.layout {
Layout::Default(_) => 0, Layout::Default(_) => 0,
Layout::Custom(layout) => layout.first_container_idx( Layout::Custom(layout) => layout.first_container_idx(
layout layout
@@ -876,7 +832,7 @@ impl Workspace {
}; };
let insertion_idx = self.insert_container_at_idx(primary_idx, container); let insertion_idx = self.insert_container_at_idx(primary_idx, container);
self.resize_dimensions_mut()[insertion_idx] = resize; self.resize_dimensions[insertion_idx] = resize;
self.focus_container(primary_idx); self.focus_container(primary_idx);
Ok(()) Ok(())
@@ -899,10 +855,10 @@ impl Workspace {
.containers_mut() .containers_mut()
.insert_respecting_locks(idx, container); .insert_respecting_locks(idx, container);
if insertion_idx > self.resize_dimensions().len() { if insertion_idx > self.resize_dimensions.len() {
self.resize_dimensions_mut().push(None); self.resize_dimensions.push(None);
} else { } else {
self.resize_dimensions_mut().insert(insertion_idx, None); self.resize_dimensions.insert(insertion_idx, None);
} }
self.focus_container(insertion_idx); self.focus_container(insertion_idx);
@@ -915,8 +871,8 @@ impl Workspace {
pub fn remove_container_by_idx(&mut self, idx: usize) -> Option<Container> { pub fn remove_container_by_idx(&mut self, idx: usize) -> Option<Container> {
let container = self.containers_mut().remove_respecting_locks(idx); let container = self.containers_mut().remove_respecting_locks(idx);
if idx < self.resize_dimensions().len() { if idx < self.resize_dimensions.len() {
self.resize_dimensions_mut().remove(idx); self.resize_dimensions.remove(idx);
} }
container container
@@ -941,7 +897,7 @@ impl Workspace {
return Ok(()); return Ok(());
} }
if let Some(container) = self.monocle_container_mut() { if let Some(container) = &mut self.monocle_container {
if let Some(window_idx) = container if let Some(window_idx) = container
.windows() .windows()
.iter() .iter()
@@ -952,8 +908,8 @@ impl Workspace {
.ok_or_eyre("there is no window")?; .ok_or_eyre("there is no window")?;
if container.windows().is_empty() { if container.windows().is_empty() {
self.set_monocle_container(None); self.monocle_container = None;
self.set_monocle_container_restore_idx(None); self.monocle_container_restore_idx = None;
} }
for c in self.containers() { for c in self.containers() {
@@ -964,11 +920,11 @@ impl Workspace {
} }
} }
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
if window.hwnd == hwnd { if window.hwnd == hwnd {
window.unmaximize(); window.unmaximize();
self.set_maximized_window(None); self.maximized_window = None;
self.set_maximized_window_restore_idx(None); self.maximized_window_restore_idx = None;
return Ok(()); return Ok(());
} }
} }
@@ -1024,8 +980,8 @@ impl Workspace {
let len = NonZeroUsize::new(self.containers().len())?; let len = NonZeroUsize::new(self.containers().len())?;
direction.destination( direction.destination(
self.layout().as_boxed_direction().as_ref(), self.layout.as_boxed_direction().as_ref(),
self.layout_flip(), self.layout_flip,
self.focused_container_idx(), self.focused_container_idx(),
len, len,
) )
@@ -1131,19 +1087,19 @@ impl Workspace {
} }
pub fn new_floating_window(&mut self) -> Result<()> { pub fn new_floating_window(&mut self) -> Result<()> {
let window = if let Some(maximized_window) = self.maximized_window() { let window = if let Some(maximized_window) = self.maximized_window {
let window = *maximized_window; let window = maximized_window;
self.set_maximized_window(None); self.maximized_window = None;
self.set_maximized_window_restore_idx(None); self.maximized_window_restore_idx = None;
window window
} else if let Some(monocle_container) = self.monocle_container_mut() { } else if let Some(monocle_container) = &mut self.monocle_container {
let window = monocle_container let window = monocle_container
.remove_focused_window() .remove_focused_window()
.ok_or_eyre("there is no window")?; .ok_or_eyre("there is no window")?;
if monocle_container.windows().is_empty() { if monocle_container.windows().is_empty() {
self.set_monocle_container(None); self.monocle_container = None;
self.set_monocle_container_restore_idx(None); self.monocle_container_restore_idx = None;
} else { } else {
monocle_container.load_focused_window(); monocle_container.load_focused_window();
} }
@@ -1203,7 +1159,7 @@ impl Workspace {
} }
fn enforce_resize_constraints_for_bsp(&mut self) { fn enforce_resize_constraints_for_bsp(&mut self) {
for (i, rect) in self.resize_dimensions_mut().iter_mut().enumerate() { for (i, rect) in self.resize_dimensions.iter_mut().enumerate() {
if let Some(rect) = rect { if let Some(rect) = rect {
// Even containers can't be resized to the bottom // Even containers can't be resized to the bottom
if i % 2 == 0 { if i % 2 == 0 {
@@ -1216,20 +1172,20 @@ impl Workspace {
} }
// The first container can never be resized to the left or the top // The first container can never be resized to the left or the top
if let Some(Some(first)) = self.resize_dimensions_mut().first_mut() { if let Some(Some(first)) = self.resize_dimensions.first_mut() {
first.top = 0; first.top = 0;
first.left = 0; first.left = 0;
} }
// The last container can never be resized to the bottom or the right // The last container can never be resized to the bottom or the right
if let Some(Some(last)) = self.resize_dimensions_mut().last_mut() { if let Some(Some(last)) = self.resize_dimensions.last_mut() {
last.bottom = 0; last.bottom = 0;
last.right = 0; last.right = 0;
} }
} }
fn enforce_resize_for_columns(&mut self) { fn enforce_resize_for_columns(&mut self) {
let resize_dimensions = self.resize_dimensions_mut(); let resize_dimensions = &mut self.resize_dimensions;
match resize_dimensions.len() { match resize_dimensions.len() {
0 | 1 => self.enforce_no_resize(), 0 | 1 => self.enforce_no_resize(),
_ => { _ => {
@@ -1252,7 +1208,7 @@ impl Workspace {
} }
fn enforce_resize_for_rows(&mut self) { fn enforce_resize_for_rows(&mut self) {
let resize_dimensions = self.resize_dimensions_mut(); let resize_dimensions = &mut self.resize_dimensions;
match resize_dimensions.len() { match resize_dimensions.len() {
0 | 1 => self.enforce_no_resize(), 0 | 1 => self.enforce_no_resize(),
_ => { _ => {
@@ -1275,7 +1231,7 @@ impl Workspace {
} }
fn enforce_resize_for_vertical_stack(&mut self) { fn enforce_resize_for_vertical_stack(&mut self) {
let resize_dimensions = self.resize_dimensions_mut(); let resize_dimensions = &mut self.resize_dimensions;
match resize_dimensions.len() { match resize_dimensions.len() {
// Single window can not be resized at all // Single window can not be resized at all
0 | 1 => self.enforce_no_resize(), 0 | 1 => self.enforce_no_resize(),
@@ -1308,7 +1264,7 @@ impl Workspace {
} }
fn enforce_resize_for_right_vertical_stack(&mut self) { fn enforce_resize_for_right_vertical_stack(&mut self) {
let resize_dimensions = self.resize_dimensions_mut(); let resize_dimensions = &mut self.resize_dimensions;
match resize_dimensions.len() { match resize_dimensions.len() {
// Single window can not be resized at all // Single window can not be resized at all
0 | 1 => self.enforce_no_resize(), 0 | 1 => self.enforce_no_resize(),
@@ -1341,7 +1297,7 @@ impl Workspace {
} }
fn enforce_resize_for_horizontal_stack(&mut self) { fn enforce_resize_for_horizontal_stack(&mut self) {
let resize_dimensions = self.resize_dimensions_mut(); let resize_dimensions = &mut self.resize_dimensions;
match resize_dimensions.len() { match resize_dimensions.len() {
0 | 1 => self.enforce_no_resize(), 0 | 1 => self.enforce_no_resize(),
_ => { _ => {
@@ -1369,7 +1325,7 @@ impl Workspace {
} }
fn enforce_resize_for_ultrawide(&mut self) { fn enforce_resize_for_ultrawide(&mut self) {
let resize_dimensions = self.resize_dimensions_mut(); let resize_dimensions = &mut self.resize_dimensions;
match resize_dimensions.len() { match resize_dimensions.len() {
// Single window can not be resized at all // Single window can not be resized at all
0 | 1 => self.enforce_no_resize(), 0 | 1 => self.enforce_no_resize(),
@@ -1426,7 +1382,7 @@ impl Workspace {
} }
fn enforce_resize_for_scrolling(&mut self) { fn enforce_resize_for_scrolling(&mut self) {
let resize_dimensions = self.resize_dimensions_mut(); let resize_dimensions = &mut self.resize_dimensions;
match resize_dimensions.len() { match resize_dimensions.len() {
0 | 1 => self.enforce_no_resize(), 0 | 1 => self.enforce_no_resize(),
_ => { _ => {
@@ -1448,7 +1404,7 @@ impl Workspace {
} }
} }
fn enforce_no_resize(&mut self) { fn enforce_no_resize(&mut self) {
for rect in self.resize_dimensions_mut().iter_mut().flatten() { for rect in self.resize_dimensions.iter_mut().flatten() {
rect.left = 0; rect.left = 0;
rect.right = 0; rect.right = 0;
rect.top = 0; rect.top = 0;
@@ -1471,11 +1427,11 @@ impl Workspace {
// inevitably reintegrated, it would be weird if it doesn't go back to the dimensions // inevitably reintegrated, it would be weird if it doesn't go back to the dimensions
// it had before // it had before
self.set_monocle_container(Option::from(container)); self.monocle_container = Option::from(container);
self.set_monocle_container_restore_idx(Option::from(focused_idx)); self.monocle_container_restore_idx = Option::from(focused_idx);
self.focus_previous_container(); self.focus_previous_container();
self.monocle_container_mut() self.monocle_container
.as_mut() .as_mut()
.ok_or_eyre("there is no monocle container")? .ok_or_eyre("there is no monocle container")?
.load_focused_window(); .load_focused_window();
@@ -1485,11 +1441,11 @@ impl Workspace {
pub fn reintegrate_monocle_container(&mut self) -> Result<()> { pub fn reintegrate_monocle_container(&mut self) -> Result<()> {
let restore_idx = self let restore_idx = self
.monocle_container_restore_idx() .monocle_container_restore_idx
.ok_or_eyre("there is no monocle restore index")?; .ok_or_eyre("there is no monocle restore index")?;
let container = self let container = self
.monocle_container_mut() .monocle_container
.as_ref() .as_ref()
.ok_or_eyre("there is no monocle container")?; .ok_or_eyre("there is no monocle container")?;
@@ -1508,8 +1464,8 @@ impl Workspace {
.ok_or_eyre("there is no container")? .ok_or_eyre("there is no container")?
.load_focused_window(); .load_focused_window();
self.set_monocle_container(None); self.monocle_container = None;
self.set_monocle_container_restore_idx(None); self.monocle_container_restore_idx = None;
Ok(()) Ok(())
} }
@@ -1520,31 +1476,31 @@ impl Workspace {
if matches!(self.layer, WorkspaceLayer::Floating) { if matches!(self.layer, WorkspaceLayer::Floating) {
let floating_window_idx = self.focused_floating_window_idx(); let floating_window_idx = self.focused_floating_window_idx();
let floating_window = self.floating_windows_mut().remove(floating_window_idx); let floating_window = self.floating_windows_mut().remove(floating_window_idx);
self.set_maximized_window(floating_window); self.maximized_window = floating_window;
self.set_maximized_window_restore_idx(Option::from(focused_idx)); self.maximized_window_restore_idx = Option::from(focused_idx);
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
window.maximize(); window.maximize();
} }
return Ok(()); return Ok(());
} }
let monocle_restore_idx = self.monocle_container_restore_idx(); let monocle_restore_idx = self.monocle_container_restore_idx;
if let Some(monocle_container) = self.monocle_container_mut() { if let Some(monocle_container) = &mut self.monocle_container {
let window = monocle_container let window = monocle_container
.remove_focused_window() .remove_focused_window()
.ok_or_eyre("there is no window")?; .ok_or_eyre("there is no window")?;
if monocle_container.windows().is_empty() { if monocle_container.windows().is_empty() {
self.set_monocle_container(None); self.monocle_container = None;
self.set_monocle_container_restore_idx(None); self.monocle_container_restore_idx = None;
} else { } else {
monocle_container.load_focused_window(); monocle_container.load_focused_window();
} }
self.set_maximized_window(Option::from(window)); self.maximized_window = Option::from(window);
self.set_maximized_window_restore_idx(monocle_restore_idx); self.maximized_window_restore_idx = monocle_restore_idx;
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
window.maximize(); window.maximize();
} }
@@ -1564,17 +1520,17 @@ impl Workspace {
// monocle and maximized toggles which take over the whole screen before being reinserted // monocle and maximized toggles which take over the whole screen before being reinserted
// at the same index to respect locked container indexes // at the same index to respect locked container indexes
self.containers_mut().remove(focused_idx); self.containers_mut().remove(focused_idx);
if self.resize_dimensions().get(focused_idx).is_some() { if self.resize_dimensions.get(focused_idx).is_some() {
self.resize_dimensions_mut().remove(focused_idx); self.resize_dimensions.remove(focused_idx);
} }
} else { } else {
container.load_focused_window(); container.load_focused_window();
} }
self.set_maximized_window(Option::from(window)); self.maximized_window = Option::from(window);
self.set_maximized_window_restore_idx(Option::from(focused_idx)); self.maximized_window_restore_idx = Option::from(focused_idx);
if let Some(window) = self.maximized_window() { if let Some(window) = self.maximized_window {
window.maximize(); window.maximize();
} }
@@ -1585,11 +1541,11 @@ impl Workspace {
pub fn reintegrate_maximized_window(&mut self) -> Result<()> { pub fn reintegrate_maximized_window(&mut self) -> Result<()> {
let restore_idx = self let restore_idx = self
.maximized_window_restore_idx() .maximized_window_restore_idx
.ok_or_eyre("there is no monocle restore index")?; .ok_or_eyre("there is no monocle restore index")?;
let window = self let window = self
.maximized_window() .maximized_window
.as_ref() .as_ref()
.ok_or_eyre("there is no monocle container")?; .ok_or_eyre("there is no monocle container")?;
@@ -1613,8 +1569,8 @@ impl Workspace {
.ok_or_eyre("there is no container")? .ok_or_eyre("there is no container")?
.load_focused_window(); .load_focused_window();
self.set_maximized_window(None); self.maximized_window = None;
self.set_maximized_window_restore_idx(None); self.maximized_window_restore_idx = None;
Ok(()) Ok(())
} }
@@ -1656,9 +1612,9 @@ impl Workspace {
pub fn visible_windows(&self) -> Vec<Option<&Window>> { pub fn visible_windows(&self) -> Vec<Option<&Window>> {
let mut vec = vec![]; let mut vec = vec![];
vec.push(self.maximized_window().as_ref()); vec.push(self.maximized_window.as_ref());
if let Some(monocle) = self.monocle_container() { if let Some(monocle) = &self.monocle_container {
vec.push(monocle.focused_window()); vec.push(monocle.focused_window());
} }
@@ -1676,13 +1632,13 @@ impl Workspace {
pub fn visible_window_details(&self) -> Vec<WindowDetails> { pub fn visible_window_details(&self) -> Vec<WindowDetails> {
let mut vec: Vec<WindowDetails> = vec![]; let mut vec: Vec<WindowDetails> = vec![];
if let Some(maximized) = self.maximized_window() { if let Some(maximized) = self.maximized_window {
if let Ok(details) = (*maximized).try_into() { if let Ok(details) = (maximized).try_into() {
vec.push(details); vec.push(details);
} }
} }
if let Some(monocle) = self.monocle_container() { if let Some(monocle) = &self.monocle_container {
if let Some(focused) = monocle.focused_window() { if let Some(focused) = monocle.focused_window() {
if let Ok(details) = (*focused).try_into() { if let Ok(details) = (*focused).try_into() {
vec.push(details); vec.push(details);
@@ -1738,9 +1694,9 @@ mod tests {
for i in 0..4 { for i in 0..4 {
let mut container = Container::default(); let mut container = Container::default();
if i == 3 { if i == 3 {
container.set_locked(true); // set index 3 locked container.locked = true; // set index 3 locked
} }
state.insert(i, container.id().to_string()); state.insert(i, container.id.to_string());
ws.add_container_to_back(container); ws.add_container_to_back(container);
} }
assert_eq!(ws.containers().len(), 4); assert_eq!(ws.containers().len(), 4);
@@ -1767,7 +1723,7 @@ mod tests {
ws.focus_container(0); ws.focus_container(0);
ws.new_container_for_window(Window::from(234)); ws.new_container_for_window(Window::from(234));
assert_eq!( assert_eq!(
ws.containers()[3].id().to_string(), ws.containers()[3].id.to_string(),
state.get(&3).unwrap().to_string() state.get(&3).unwrap().to_string()
); );
} }
@@ -1781,7 +1737,7 @@ mod tests {
let mut container = Container::default(); let mut container = Container::default();
container.windows_mut().push_back(Window::from(i)); container.windows_mut().push_back(Window::from(i));
if i == 1 { if i == 1 {
container.set_locked(true); container.locked = true;
} }
ws.add_container_to_back(container); ws.add_container_to_back(container);
} }
@@ -1803,7 +1759,7 @@ mod tests {
let mut container = Container::default(); let mut container = Container::default();
container.windows_mut().push_back(Window::from(i)); container.windows_mut().push_back(Window::from(i));
if i == 1 { if i == 1 {
container.set_locked(true); container.locked = true;
} }
ws.add_container_to_back(container); ws.add_container_to_back(container);
} }
@@ -1845,7 +1801,7 @@ mod tests {
let mut container = Container::default(); let mut container = Container::default();
container.windows_mut().push_back(Window::from(i)); container.windows_mut().push_back(Window::from(i));
if i == 4 { if i == 4 {
container.set_locked(true); container.locked = true;
} }
ws.add_container_to_back(container); ws.add_container_to_back(container);
} }
@@ -2508,7 +2464,7 @@ mod tests {
} }
// Maximize window 200 // Maximize window 200
workspace.set_maximized_window(Some(Window { hwnd: 200 })); workspace.maximized_window = Some(Window { hwnd: 200 });
{ {
// visible_windows should return 200, 100, and 300 // visible_windows should return 200, 100, and 300