mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-10 20:59:53 +02:00
refactor(rust): remove getset dependency
This commit is contained in:
35
Cargo.lock
generated
35
Cargo.lock
generated
@@ -2148,18 +2148,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "gif"
|
||||
version = "0.11.4"
|
||||
@@ -2968,7 +2956,6 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
"ctrlc",
|
||||
"dirs 6.0.0",
|
||||
"getset",
|
||||
"hotwatch",
|
||||
"komorebi-themes",
|
||||
"lazy_static",
|
||||
@@ -4633,28 +4620,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
|
||||
@@ -200,8 +200,6 @@
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -532,7 +530,6 @@
|
||||
"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.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.13.3 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",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
|
||||
@@ -937,9 +937,9 @@ impl eframe::App for Komobar {
|
||||
) {
|
||||
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;
|
||||
}
|
||||
@@ -950,7 +950,7 @@ impl eframe::App for Komobar {
|
||||
|
||||
// Check if monitor coordinates/size has changed
|
||||
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 left = MONITOR_LEFT.load(Ordering::SeqCst);
|
||||
let right = MONITOR_RIGHT.load(Ordering::SeqCst);
|
||||
@@ -960,13 +960,13 @@ impl eframe::App for Komobar {
|
||||
bottom: monitor_size.bottom,
|
||||
right,
|
||||
};
|
||||
if *monitor_size != rect {
|
||||
if monitor_size != rect {
|
||||
tracing::info!(
|
||||
"Monitor coordinates/size has changed, storing new coordinates: {:#?}",
|
||||
monitor_size
|
||||
);
|
||||
|
||||
self.update_monitor_coordinates(monitor_size);
|
||||
self.update_monitor_coordinates(&monitor_size);
|
||||
|
||||
should_apply_config = true;
|
||||
}
|
||||
|
||||
@@ -230,17 +230,17 @@ fn main() -> color_eyre::Result<()> {
|
||||
.map_or(usr_monitor_index, |i| *i);
|
||||
|
||||
MONITOR_RIGHT.store(
|
||||
state.monitors.elements()[monitor_index].size().right,
|
||||
state.monitors.elements()[monitor_index].size.right,
|
||||
Ordering::SeqCst,
|
||||
);
|
||||
|
||||
MONITOR_TOP.store(
|
||||
state.monitors.elements()[monitor_index].size().top,
|
||||
state.monitors.elements()[monitor_index].size.top,
|
||||
Ordering::SeqCst,
|
||||
);
|
||||
|
||||
MONITOR_LEFT.store(
|
||||
state.monitors.elements()[monitor_index].size().left,
|
||||
state.monitors.elements()[monitor_index].size.left,
|
||||
Ordering::SeqCst,
|
||||
);
|
||||
|
||||
@@ -250,11 +250,11 @@ fn main() -> color_eyre::Result<()> {
|
||||
None => {
|
||||
config.position = Some(PositionConfig {
|
||||
start: Some(Position {
|
||||
x: state.monitors.elements()[monitor_index].size().left as f32,
|
||||
y: state.monitors.elements()[monitor_index].size().top as f32,
|
||||
x: state.monitors.elements()[monitor_index].size.left as f32,
|
||||
y: state.monitors.elements()[monitor_index].size.top as f32,
|
||||
}),
|
||||
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,
|
||||
}),
|
||||
})
|
||||
@@ -262,14 +262,14 @@ fn main() -> color_eyre::Result<()> {
|
||||
Some(ref mut position) => {
|
||||
if position.start.is_none() {
|
||||
position.start = Some(Position {
|
||||
x: state.monitors.elements()[monitor_index].size().left as f32,
|
||||
y: state.monitors.elements()[monitor_index].size().top as f32,
|
||||
x: state.monitors.elements()[monitor_index].size.left as f32,
|
||||
y: state.monitors.elements()[monitor_index].size.top as f32,
|
||||
});
|
||||
}
|
||||
|
||||
if position.end.is_none() {
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -817,7 +817,7 @@ impl MonitorInfo {
|
||||
self.mouse_follows_focus = state.mouse_follows_focus;
|
||||
|
||||
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());
|
||||
|
||||
// Layout
|
||||
@@ -856,7 +856,7 @@ impl MonitorInfo {
|
||||
let containers = fn_containers_from(ws);
|
||||
WorkspaceInfo {
|
||||
name: ws
|
||||
.name()
|
||||
.name
|
||||
.to_owned()
|
||||
.unwrap_or_else(|| format!("{}", index + 1)),
|
||||
focused_container_idx: containers.iter().position(|c| c.is_focused),
|
||||
@@ -864,7 +864,7 @@ impl MonitorInfo {
|
||||
.iter()
|
||||
.any(|container| container.windows.iter().any(|window| window.icon.is_some())),
|
||||
containers,
|
||||
layer: *ws.layer(),
|
||||
layer: ws.layer,
|
||||
should_show: !hide_empty_ws || focused_ws_idx == Some(index) || !ws.is_empty(),
|
||||
is_selected: focused_ws_idx == Some(index),
|
||||
}
|
||||
@@ -873,15 +873,15 @@ impl MonitorInfo {
|
||||
|
||||
/// Determines the current layout of the focused workspace
|
||||
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
|
||||
} else if !focused_ws.tile() {
|
||||
} else if !focused_ws.tile {
|
||||
KomorebiLayout::Floating
|
||||
} else if is_paused {
|
||||
KomorebiLayout::Paused
|
||||
} else {
|
||||
match focused_ws.layout() {
|
||||
komorebi_client::Layout::Default(layout) => KomorebiLayout::Default(*layout),
|
||||
match focused_ws.layout {
|
||||
komorebi_client::Layout::Default(layout) => KomorebiLayout::Default(layout),
|
||||
komorebi_client::Layout::Custom(_) => KomorebiLayout::Custom,
|
||||
}
|
||||
}
|
||||
@@ -938,7 +938,7 @@ impl ContainerInfo {
|
||||
|
||||
// Monocle container first if present
|
||||
let monocle = ws
|
||||
.monocle_container()
|
||||
.monocle_container
|
||||
.as_ref()
|
||||
.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()) {
|
||||
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))
|
||||
} else {
|
||||
ws.focused_container()
|
||||
@@ -979,7 +979,7 @@ impl ContainerInfo {
|
||||
windows: container.windows().iter().map(WindowInfo::from).collect(),
|
||||
focused_window_idx: container.focused_window_idx(),
|
||||
is_focused,
|
||||
is_locked: container.locked(),
|
||||
is_locked: container.locked,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ impl From<&komorebi_client::Monitor> for MonitorConfig {
|
||||
}
|
||||
|
||||
Self {
|
||||
size: *value.size(),
|
||||
work_area_offset: value.work_area_offset().unwrap_or_default(),
|
||||
size: value.size,
|
||||
work_area_offset: value.work_area_offset.unwrap_or_default(),
|
||||
workspaces,
|
||||
}
|
||||
}
|
||||
@@ -95,22 +95,22 @@ struct WorkspaceConfig {
|
||||
|
||||
impl From<&komorebi_client::Workspace> for WorkspaceConfig {
|
||||
fn from(value: &komorebi_client::Workspace) -> Self {
|
||||
let layout = match value.layout() {
|
||||
Layout::Default(layout) => *layout,
|
||||
let layout = match value.layout {
|
||||
Layout::Default(layout) => layout,
|
||||
Layout::Custom(_) => DefaultLayout::BSP,
|
||||
};
|
||||
|
||||
let name = value
|
||||
.name()
|
||||
.name
|
||||
.to_owned()
|
||||
.unwrap_or_else(|| random_word::get(random_word::Lang::En).to_string());
|
||||
|
||||
Self {
|
||||
layout,
|
||||
name,
|
||||
tile: *value.tile(),
|
||||
workspace_padding: value.workspace_padding().unwrap_or(20),
|
||||
container_padding: value.container_padding().unwrap_or(20),
|
||||
tile: value.tile,
|
||||
workspace_padding: value.workspace_padding.unwrap_or(20),
|
||||
container_padding: value.container_padding.unwrap_or(20),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ crossbeam-channel = { workspace = true }
|
||||
crossbeam-utils = { workspace = true }
|
||||
ctrlc = { version = "3", features = ["termination"] }
|
||||
dirs = { workspace = true }
|
||||
getset = "0.1"
|
||||
hotwatch = { workspace = true }
|
||||
lazy_static = { workspace = true }
|
||||
miow = "0.6"
|
||||
|
||||
@@ -209,9 +209,9 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
.iter()
|
||||
.map(|w| w.hwnd)
|
||||
.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]
|
||||
.layer();
|
||||
.layer;
|
||||
let foreground_window = WindowsApi::foreground_window().unwrap_or_default();
|
||||
let layer_changed = previous_layer != workspace_layer;
|
||||
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
|
||||
if let Some(ws) = m.focused_workspace() {
|
||||
// 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 {
|
||||
WindowKind::Unfocused
|
||||
} else {
|
||||
@@ -237,7 +237,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
.unwrap_or_default()
|
||||
.set_accent(window_kind_colour(window_kind))?;
|
||||
|
||||
if ws.layer() == &WorkspaceLayer::Floating {
|
||||
if ws.layer == WorkspaceLayer::Floating {
|
||||
for window in ws.floating_windows() {
|
||||
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()
|
||||
|| monitor_idx != focused_monitor_idx
|
||||
{
|
||||
if c.locked() {
|
||||
if c.locked {
|
||||
WindowKind::UnfocusedLocked
|
||||
} else {
|
||||
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
|
||||
if let Some(ws) = m.focused_workspace() {
|
||||
// Workspaces with tiling disabled don't have borders
|
||||
if !ws.tile() {
|
||||
if !ws.tile {
|
||||
// Remove all borders on this monitor
|
||||
remove_borders(
|
||||
&mut borders,
|
||||
@@ -396,16 +396,16 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
}
|
||||
|
||||
// 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 focused_window_hwnd =
|
||||
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()) {
|
||||
Entry::Occupied(entry) => entry.into_mut(),
|
||||
Entry::Vacant(entry) => {
|
||||
if let Ok(border) = Border::create(
|
||||
monocle.id(),
|
||||
&monocle.id,
|
||||
focused_window_hwnd,
|
||||
monitor_idx,
|
||||
) {
|
||||
@@ -463,7 +463,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
|
||||
let border_hwnd = border.hwnd;
|
||||
|
||||
if ws.layer() == &WorkspaceLayer::Floating {
|
||||
if ws.layer == WorkspaceLayer::Floating {
|
||||
handle_floating_borders(
|
||||
&mut 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_monitor_id =
|
||||
WindowsApi::monitor_from_window(foreground_hwnd);
|
||||
let is_maximized = foreground_monitor_id == m.id()
|
||||
&& WindowsApi::is_zoomed(foreground_hwnd);
|
||||
let is_maximized =
|
||||
foreground_monitor_id == m.id && WindowsApi::is_zoomed(foreground_hwnd);
|
||||
|
||||
if is_maximized {
|
||||
// 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
|
||||
.containers()
|
||||
.iter()
|
||||
.map(|c| c.id().clone())
|
||||
.map(|c| c.id.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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() {
|
||||
let focused_window_hwnd =
|
||||
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
|
||||
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::Vacant(entry) => {
|
||||
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;
|
||||
entry.insert(border)
|
||||
@@ -563,7 +563,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
|| monitor_idx != focused_monitor_idx
|
||||
|| focused_window_hwnd != foreground_window
|
||||
{
|
||||
if c.locked() {
|
||||
if c.locked {
|
||||
WindowKind::UnfocusedLocked
|
||||
} else {
|
||||
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) {
|
||||
Ok(rect) => rect,
|
||||
Err(_) => {
|
||||
remove_border(c.id(), &mut borders, &mut windows_borders)?;
|
||||
remove_border(&c.id, &mut borders, &mut windows_borders)?;
|
||||
continue 'containers;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use getset::CopyGetters;
|
||||
use getset::Getters;
|
||||
use getset::Setters;
|
||||
use nanoid::nanoid;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
@@ -11,14 +8,12 @@ use crate::ring::Ring;
|
||||
use crate::window::Window;
|
||||
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))]
|
||||
pub struct Container {
|
||||
#[getset(get = "pub")]
|
||||
id: String,
|
||||
pub id: String,
|
||||
#[serde(default)]
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
locked: bool,
|
||||
pub locked: bool,
|
||||
windows: Ring<Window>,
|
||||
}
|
||||
|
||||
@@ -278,8 +273,8 @@ mod tests {
|
||||
}"#;
|
||||
let container: Container = serde_json::from_str(json).expect("Should deserialize");
|
||||
|
||||
assert!(!container.locked());
|
||||
assert_eq!(container.id(), "test-1");
|
||||
assert!(!container.locked);
|
||||
assert_eq!(container.id, "test-1");
|
||||
assert!(container.windows().is_empty());
|
||||
|
||||
let json = r#"{
|
||||
@@ -287,8 +282,8 @@ mod tests {
|
||||
"windows": { "elements": [ { "hwnd": 5 }, { "hwnd": 9 } ], "focused": 1 }
|
||||
}"#;
|
||||
let container: Container = serde_json::from_str(json).unwrap();
|
||||
assert_eq!(container.id(), "test-2");
|
||||
assert!(!container.locked());
|
||||
assert_eq!(container.id, "test-2");
|
||||
assert!(!container.locked);
|
||||
assert_eq!(container.windows(), &[Window::from(5), Window::from(9)]);
|
||||
assert_eq!(container.focused_window_idx(), 1);
|
||||
}
|
||||
@@ -302,7 +297,7 @@ mod tests {
|
||||
let deserialized: Container =
|
||||
serde_json::from_str(&serialized).expect("Should deserialize");
|
||||
|
||||
assert!(deserialized.locked());
|
||||
assert_eq!(deserialized.id(), container.id());
|
||||
assert!(deserialized.locked);
|
||||
assert_eq!(deserialized.id, container.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,6 @@ use std::sync::atomic::Ordering;
|
||||
use color_eyre::eyre::bail;
|
||||
use color_eyre::eyre::OptionExt;
|
||||
use color_eyre::Result;
|
||||
use getset::CopyGetters;
|
||||
use getset::Getters;
|
||||
use getset::MutGetters;
|
||||
use getset::Setters;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
@@ -31,44 +27,26 @@ use crate::WindowsApi;
|
||||
use crate::DEFAULT_CONTAINER_PADDING;
|
||||
use crate::DEFAULT_WORKSPACE_PADDING;
|
||||
|
||||
#[derive(
|
||||
Debug, Clone, Serialize, Deserialize, Getters, CopyGetters, MutGetters, Setters, PartialEq,
|
||||
)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct Monitor {
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub id: isize,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub name: String,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub device: String,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub device_id: String,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub serial_number_id: Option<String>,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub size: Rect,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub work_area_size: Rect,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub work_area_offset: Option<Rect>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub window_based_work_area_offset: Option<Rect>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub window_based_work_area_offset_limit: isize,
|
||||
pub workspaces: Ring<Workspace>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub last_focused_workspace: Option<usize>,
|
||||
#[getset(get_mut = "pub")]
|
||||
pub workspace_names: HashMap<usize, String>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub container_padding: Option<i32>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub workspace_padding: Option<i32>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub wallpaper: Option<Wallpaper>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub floating_layer_behaviour: Option<FloatingLayerBehaviour>,
|
||||
}
|
||||
|
||||
@@ -175,14 +153,14 @@ impl Monitor {
|
||||
|
||||
pub fn focused_workspace_name(&self) -> Option<String> {
|
||||
self.focused_workspace()
|
||||
.map(|w| w.name().clone())
|
||||
.map(|w| w.name.clone())
|
||||
.unwrap_or(None)
|
||||
}
|
||||
|
||||
pub fn focused_workspace_layout(&self) -> Option<Layout> {
|
||||
self.focused_workspace().and_then(|workspace| {
|
||||
if *workspace.tile() {
|
||||
Some(workspace.layout().clone())
|
||||
if workspace.tile {
|
||||
Some(workspace.layout.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -191,7 +169,7 @@ impl Monitor {
|
||||
|
||||
pub fn load_focused_workspace(&mut self, mouse_follows_focus: bool) -> Result<()> {
|
||||
let focused_idx = self.focused_workspace_idx();
|
||||
let hmonitor = self.id();
|
||||
let hmonitor = self.id;
|
||||
let monitor_wp = self.wallpaper.clone();
|
||||
for (i, workspace) in self.workspaces_mut().iter_mut().enumerate() {
|
||||
if i == focused_idx {
|
||||
@@ -207,10 +185,10 @@ impl Monitor {
|
||||
/// Updates the `globals` field of all workspaces
|
||||
pub fn update_workspaces_globals(&mut self, offset: Option<Rect>) {
|
||||
let container_padding = self
|
||||
.container_padding()
|
||||
.container_padding
|
||||
.or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)));
|
||||
let workspace_padding = self
|
||||
.workspace_padding()
|
||||
.workspace_padding
|
||||
.or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)));
|
||||
let (border_width, border_offset) = {
|
||||
let border_enabled = BORDER_ENABLED.load(Ordering::SeqCst);
|
||||
@@ -222,11 +200,11 @@ impl Monitor {
|
||||
(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 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 floating_layer_behaviour = self.floating_layer_behaviour();
|
||||
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 floating_layer_behaviour = self.floating_layer_behaviour;
|
||||
|
||||
for workspace in self.workspaces_mut() {
|
||||
workspace.globals = WorkspaceGlobals {
|
||||
@@ -246,10 +224,10 @@ impl Monitor {
|
||||
/// Updates the `globals` field of workspace with index `workspace_idx`
|
||||
pub fn update_workspace_globals(&mut self, workspace_idx: usize, offset: Option<Rect>) {
|
||||
let container_padding = self
|
||||
.container_padding()
|
||||
.container_padding
|
||||
.or(Some(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)));
|
||||
let workspace_padding = self
|
||||
.workspace_padding()
|
||||
.workspace_padding
|
||||
.or(Some(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)));
|
||||
let (border_width, border_offset) = {
|
||||
let border_enabled = BORDER_ENABLED.load(Ordering::SeqCst);
|
||||
@@ -261,11 +239,11 @@ impl Monitor {
|
||||
(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 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 floating_layer_behaviour = self.floating_layer_behaviour();
|
||||
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 floating_layer_behaviour = self.floating_layer_behaviour;
|
||||
|
||||
if let Some(workspace) = self.workspaces_mut().get_mut(workspace_idx) {
|
||||
workspace.globals = WorkspaceGlobals {
|
||||
@@ -324,7 +302,7 @@ impl Monitor {
|
||||
OperationDirection::Left => {
|
||||
// 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)
|
||||
match workspace.layout() {
|
||||
match workspace.layout {
|
||||
Layout::Default(layout) => match layout {
|
||||
DefaultLayout::RightMainVerticalStack => {
|
||||
workspace.add_container_to_front(container);
|
||||
@@ -348,7 +326,7 @@ impl Monitor {
|
||||
OperationDirection::Right => {
|
||||
// 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)
|
||||
match workspace.layout() {
|
||||
match workspace.layout {
|
||||
Layout::Default(layout) => {
|
||||
let target_index = layout.leftmost_index(workspace.containers().len());
|
||||
|
||||
@@ -417,7 +395,7 @@ impl Monitor {
|
||||
.focused_workspace_mut()
|
||||
.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");
|
||||
}
|
||||
|
||||
@@ -440,7 +418,7 @@ impl Monitor {
|
||||
};
|
||||
|
||||
target_workspace.floating_windows_mut().push_back(window);
|
||||
target_workspace.set_layer(WorkspaceLayer::Floating);
|
||||
target_workspace.layer = WorkspaceLayer::Floating;
|
||||
}
|
||||
} else {
|
||||
let container = workspace
|
||||
@@ -458,7 +436,7 @@ impl Monitor {
|
||||
Some(workspace) => workspace,
|
||||
};
|
||||
|
||||
if target_workspace.monocle_container().is_some() {
|
||||
if target_workspace.monocle_container.is_some() {
|
||||
for container in target_workspace.containers_mut() {
|
||||
container.restore();
|
||||
}
|
||||
@@ -470,7 +448,7 @@ impl Monitor {
|
||||
target_workspace.reintegrate_monocle_container()?;
|
||||
}
|
||||
|
||||
target_workspace.set_layer(WorkspaceLayer::Tiling);
|
||||
target_workspace.layer = WorkspaceLayer::Tiling;
|
||||
|
||||
if let Some(direction) = direction {
|
||||
self.add_container_with_direction(
|
||||
@@ -500,7 +478,7 @@ impl Monitor {
|
||||
if workspaces.get(idx).is_none() {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -511,7 +489,7 @@ impl Monitor {
|
||||
self.workspaces_mut()
|
||||
.get_mut(idx)
|
||||
.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<()> {
|
||||
let offset = if self.work_area_offset().is_some() {
|
||||
self.work_area_offset()
|
||||
let offset = if self.work_area_offset.is_some() {
|
||||
self.work_area_offset
|
||||
} else {
|
||||
offset
|
||||
};
|
||||
|
||||
@@ -70,10 +70,10 @@ pub fn send_notification(notification: MonitorNotification) {
|
||||
pub fn insert_in_monitor_cache(serial_or_device_id: &str, monitor: Monitor) {
|
||||
let dip = DISPLAY_INDEX_PREFERENCES.read();
|
||||
let mut dip_ids = dip.values();
|
||||
let preferred_id = if dip_ids.any(|id| id == monitor.device_id()) {
|
||||
monitor.device_id().clone()
|
||||
} else if dip_ids.any(|id| Some(id) == monitor.serial_number_id().as_ref()) {
|
||||
monitor.serial_number_id().clone().unwrap_or_default()
|
||||
let preferred_id = if dip_ids.any(|id| id.eq(&monitor.device_id)) {
|
||||
monitor.device_id.clone()
|
||||
} else if dip_ids.any(|id| Some(id) == monitor.serial_number_id.as_ref()) {
|
||||
monitor.serial_number_id.clone().unwrap_or_default()
|
||||
} else {
|
||||
serial_or_device_id.to_string()
|
||||
};
|
||||
@@ -219,27 +219,27 @@ where
|
||||
let mut should_update = false;
|
||||
|
||||
// Update work areas as necessary
|
||||
if let Ok(reference) = WindowsApi::monitor(monitor.id()) {
|
||||
if reference.work_area_size() != monitor.work_area_size() {
|
||||
monitor.set_work_area_size(Rect {
|
||||
left: reference.work_area_size().left,
|
||||
top: reference.work_area_size().top,
|
||||
right: reference.work_area_size().right,
|
||||
bottom: reference.work_area_size().bottom,
|
||||
});
|
||||
if let Ok(reference) = WindowsApi::monitor(monitor.id) {
|
||||
if reference.work_area_size != monitor.work_area_size {
|
||||
monitor.work_area_size = Rect {
|
||||
left: reference.work_area_size.left,
|
||||
top: reference.work_area_size.top,
|
||||
right: reference.work_area_size.right,
|
||||
bottom: reference.work_area_size.bottom,
|
||||
};
|
||||
|
||||
should_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
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)?;
|
||||
border_manager::send_notification(None);
|
||||
} else {
|
||||
tracing::debug!(
|
||||
"work areas match, reconciliation not required for {}",
|
||||
monitor.device_id()
|
||||
monitor.device_id
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -251,25 +251,25 @@ where
|
||||
let mut should_update = false;
|
||||
|
||||
// Update sizes and work areas as necessary
|
||||
if let Ok(reference) = WindowsApi::monitor(monitor.id()) {
|
||||
if reference.work_area_size() != monitor.work_area_size() {
|
||||
monitor.set_work_area_size(Rect {
|
||||
left: reference.work_area_size().left,
|
||||
top: reference.work_area_size().top,
|
||||
right: reference.work_area_size().right,
|
||||
bottom: reference.work_area_size().bottom,
|
||||
});
|
||||
if let Ok(reference) = WindowsApi::monitor(monitor.id) {
|
||||
if reference.work_area_size != monitor.work_area_size {
|
||||
monitor.work_area_size = Rect {
|
||||
left: reference.work_area_size.left,
|
||||
top: reference.work_area_size.top,
|
||||
right: reference.work_area_size.right,
|
||||
bottom: reference.work_area_size.bottom,
|
||||
};
|
||||
|
||||
should_update = true;
|
||||
}
|
||||
|
||||
if reference.size() != monitor.size() {
|
||||
monitor.set_size(Rect {
|
||||
left: reference.size().left,
|
||||
top: reference.size().top,
|
||||
right: reference.size().right,
|
||||
bottom: reference.size().bottom,
|
||||
});
|
||||
if reference.size != monitor.size {
|
||||
monitor.size = Rect {
|
||||
left: reference.size.left,
|
||||
top: reference.size.top,
|
||||
right: reference.size.right,
|
||||
bottom: reference.size.bottom,
|
||||
};
|
||||
|
||||
should_update = true;
|
||||
}
|
||||
@@ -278,7 +278,7 @@ where
|
||||
if should_update {
|
||||
tracing::info!(
|
||||
"updated monitor resolution/scaling for {}",
|
||||
monitor.device_id()
|
||||
monitor.device_id
|
||||
);
|
||||
|
||||
monitor.update_focused_workspace(offset)?;
|
||||
@@ -286,7 +286,7 @@ where
|
||||
} else {
|
||||
tracing::debug!(
|
||||
"resolutions match, reconciliation not required for {}",
|
||||
monitor.device_id()
|
||||
monitor.device_id
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -311,21 +311,21 @@ where
|
||||
for monitor in wm.monitors_mut() {
|
||||
for attached in &attached_devices {
|
||||
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)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if serial_number_ids_match || attached.device_id().eq(monitor.device_id()) {
|
||||
monitor.set_id(attached.id());
|
||||
monitor.set_device(attached.device().clone());
|
||||
monitor.set_device_id(attached.device_id().clone());
|
||||
monitor.set_serial_number_id(attached.serial_number_id().clone());
|
||||
monitor.set_name(attached.name().clone());
|
||||
monitor.set_size(*attached.size());
|
||||
monitor.set_work_area_size(*attached.work_area_size());
|
||||
if serial_number_ids_match || attached.device_id.eq(&monitor.device_id) {
|
||||
monitor.id = attached.id;
|
||||
monitor.device = attached.device.clone();
|
||||
monitor.device_id = attached.device_id.clone();
|
||||
monitor.serial_number_id = attached.serial_number_id.clone();
|
||||
monitor.name = attached.name.clone();
|
||||
monitor.size = attached.size;
|
||||
monitor.work_area_size = attached.work_area_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,13 +359,13 @@ where
|
||||
|
||||
for (m_idx, m) in wm.monitors().iter().enumerate() {
|
||||
if !attached_devices.iter().any(|attached| {
|
||||
attached.serial_number_id().eq(m.serial_number_id())
|
||||
|| attached.device_id().eq(m.device_id())
|
||||
attached.serial_number_id.eq(&m.serial_number_id)
|
||||
|| attached.device_id.eq(&m.device_id)
|
||||
}) {
|
||||
let id = m
|
||||
.serial_number_id()
|
||||
.serial_number_id
|
||||
.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());
|
||||
|
||||
@@ -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);
|
||||
// Minimize the focused window since Windows might try
|
||||
// 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() {
|
||||
windows_to_remove.push(window.hwnd);
|
||||
}
|
||||
@@ -440,10 +440,10 @@ where
|
||||
// the user set as preference as the id.
|
||||
let dip = DISPLAY_INDEX_PREFERENCES.read();
|
||||
let mut dip_ids = dip.values();
|
||||
let preferred_id = if dip_ids.any(|id| id == m.device_id()) {
|
||||
m.device_id().clone()
|
||||
} else if dip_ids.any(|id| Some(id) == m.serial_number_id().as_ref()) {
|
||||
m.serial_number_id().clone().unwrap_or_default()
|
||||
let preferred_id = if dip_ids.any(|id| id.eq(&m.device_id)) {
|
||||
m.device_id.clone()
|
||||
} else if dip_ids.any(|id| Some(id) == m.serial_number_id.as_ref()) {
|
||||
m.serial_number_id.clone().unwrap_or_default()
|
||||
} else {
|
||||
id
|
||||
};
|
||||
@@ -458,8 +458,8 @@ where
|
||||
// After we have cached them, remove them from our state
|
||||
wm.monitors_mut().retain(|m| {
|
||||
!newly_removed_displays.iter().any(|id| {
|
||||
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)
|
||||
})
|
||||
});
|
||||
}
|
||||
@@ -490,7 +490,7 @@ where
|
||||
let post_removal_device_ids = wm
|
||||
.monitors()
|
||||
.iter()
|
||||
.map(Monitor::device_id)
|
||||
.map(|m| &m.device_id)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -513,14 +513,14 @@ where
|
||||
|
||||
// Look in the updated state for new monitors
|
||||
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
|
||||
if !post_removal_device_ids.contains(device_id) {
|
||||
let mut cache_hit = false;
|
||||
let mut cached_id = String::new();
|
||||
// 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
|
||||
.serial_number_id()
|
||||
.serial_number_id
|
||||
.as_ref()
|
||||
.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()
|
||||
|| known_hwnds.contains_key(&window.hwnd)
|
||||
{
|
||||
workspace.set_maximized_window(None);
|
||||
workspace.maximized_window = None;
|
||||
} else if is_focused_workspace {
|
||||
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| {
|
||||
window.exe().is_ok()
|
||||
&& !known_hwnds.contains_key(&window.hwnd)
|
||||
});
|
||||
|
||||
if container.windows().is_empty() {
|
||||
workspace.set_monocle_container(None);
|
||||
workspace.monocle_container = None;
|
||||
} else if is_focused_workspace {
|
||||
if let Some(window) = container.focused_window() {
|
||||
WindowsApi::restore_window(window.hwnd);
|
||||
@@ -657,7 +657,7 @@ where
|
||||
let mut workspace_matching_rules =
|
||||
WORKSPACE_MATCHING_RULES.lock();
|
||||
if let Some(rules) = workspace
|
||||
.workspace_config()
|
||||
.workspace_config
|
||||
.as_ref()
|
||||
.and_then(|c| c.workspace_rules.as_ref())
|
||||
{
|
||||
@@ -672,7 +672,7 @@ where
|
||||
}
|
||||
|
||||
if let Some(rules) = workspace
|
||||
.workspace_config()
|
||||
.workspace_config
|
||||
.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");
|
||||
|
||||
// hmonitor
|
||||
assert_eq!(monitors[0].id(), 1);
|
||||
assert_eq!(monitors[0].id, 1);
|
||||
|
||||
// device name
|
||||
assert_eq!(monitors[0].name(), &String::from("DISPLAY1"));
|
||||
assert_eq!(monitors[0].name, String::from("DISPLAY1"));
|
||||
|
||||
// Device
|
||||
assert_eq!(monitors[0].device(), &String::from("ABC123"));
|
||||
assert_eq!(monitors[0].device, String::from("ABC123"));
|
||||
|
||||
// Device ID
|
||||
assert_eq!(
|
||||
monitors[0].device_id(),
|
||||
&String::from("ABC123-4&123456&0&UID0")
|
||||
monitors[0].device_id,
|
||||
String::from("ABC123-4&123456&0&UID0")
|
||||
);
|
||||
|
||||
// Check monitor serial number id
|
||||
|
||||
@@ -238,7 +238,7 @@ impl WindowManager {
|
||||
// load it later after focusing the wanted window
|
||||
let focused_ws_idx = monitor.focused_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)?;
|
||||
needs_workspace_loading = true;
|
||||
}
|
||||
@@ -259,7 +259,7 @@ impl WindowManager {
|
||||
}
|
||||
WorkspaceWindowLocation::Maximized => {
|
||||
if let Some(window) =
|
||||
self.focused_workspace_mut()?.maximized_window_mut()
|
||||
&mut self.focused_workspace_mut()?.maximized_window
|
||||
{
|
||||
window.focus(self.mouse_follows_focus)?;
|
||||
}
|
||||
@@ -293,7 +293,7 @@ impl WindowManager {
|
||||
}
|
||||
SocketMessage::FocusWindow(direction) => {
|
||||
let focused_workspace = self.focused_workspace()?;
|
||||
match focused_workspace.layer() {
|
||||
match focused_workspace.layer {
|
||||
WorkspaceLayer::Tiling => {
|
||||
self.focus_container_in_direction(direction)?;
|
||||
}
|
||||
@@ -304,7 +304,7 @@ impl WindowManager {
|
||||
}
|
||||
SocketMessage::MoveWindow(direction) => {
|
||||
let focused_workspace = self.focused_workspace()?;
|
||||
match focused_workspace.layer() {
|
||||
match focused_workspace.layer {
|
||||
WorkspaceLayer::Tiling => {
|
||||
self.move_container_in_direction(direction)?;
|
||||
}
|
||||
@@ -315,7 +315,7 @@ impl WindowManager {
|
||||
}
|
||||
SocketMessage::CycleFocusWindow(direction) => {
|
||||
let focused_workspace = self.focused_workspace()?;
|
||||
match focused_workspace.layer() {
|
||||
match focused_workspace.layer {
|
||||
WorkspaceLayer::Tiling => {
|
||||
self.focus_container_in_cycle_direction(direction)?;
|
||||
}
|
||||
@@ -375,7 +375,7 @@ impl WindowManager {
|
||||
.ok_or_eyre("no workspace at the given index")?;
|
||||
|
||||
if let Some(container) = workspace.containers_mut().get_mut(container_idx) {
|
||||
container.set_locked(true);
|
||||
container.locked = true;
|
||||
}
|
||||
}
|
||||
SocketMessage::UnlockMonitorWorkspaceContainer(
|
||||
@@ -394,7 +394,7 @@ impl WindowManager {
|
||||
.ok_or_eyre("no workspace at the given index")?;
|
||||
|
||||
if let Some(container) = workspace.containers_mut().get_mut(container_idx) {
|
||||
container.set_locked(false);
|
||||
container.locked = false;
|
||||
}
|
||||
}
|
||||
SocketMessage::ToggleLock => self.toggle_lock()?,
|
||||
@@ -708,14 +708,14 @@ impl WindowManager {
|
||||
.focused_workspace_idx();
|
||||
|
||||
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.focused_monitor_mut()
|
||||
.ok_or_eyre("there is no monitor")?
|
||||
.set_last_focused_workspace(Option::from(idx));
|
||||
.last_focused_workspace = Option::from(idx);
|
||||
}
|
||||
SocketMessage::SendContainerToLastWorkspace => {
|
||||
// This is to ensure that even on an empty workspace on a secondary monitor, the
|
||||
@@ -739,13 +739,13 @@ impl WindowManager {
|
||||
.focused_workspace_idx();
|
||||
|
||||
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.focused_monitor_mut()
|
||||
.ok_or_eyre("there is no monitor")?
|
||||
.set_last_focused_workspace(Option::from(idx));
|
||||
.last_focused_workspace = Option::from(idx);
|
||||
}
|
||||
SocketMessage::MoveContainerToWorkspaceNumber(workspace_idx) => {
|
||||
self.move_container_to_workspace(workspace_idx, true, None)?;
|
||||
@@ -915,7 +915,7 @@ impl WindowManager {
|
||||
SocketMessage::ScrollingLayoutColumns(count) => {
|
||||
let focused_workspace = self.focused_workspace_mut()?;
|
||||
|
||||
let options = match focused_workspace.layout_options() {
|
||||
let options = match focused_workspace.layout_options {
|
||||
Some(mut opts) => {
|
||||
if let Some(scrolling) = &mut opts.scrolling {
|
||||
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)?;
|
||||
}
|
||||
SocketMessage::ChangeLayout(layout) => self.change_workspace_layout_default(layout)?,
|
||||
@@ -1134,9 +1134,9 @@ impl WindowManager {
|
||||
if monitor.workspaces().len() > 1
|
||||
&& workspace.containers().is_empty()
|
||||
&& workspace.floating_windows().is_empty()
|
||||
&& workspace.monocle_container().is_none()
|
||||
&& workspace.maximized_window().is_none()
|
||||
&& workspace.name().is_none()
|
||||
&& workspace.monocle_container.is_none()
|
||||
&& workspace.maximized_window.is_none()
|
||||
&& workspace.name.is_none()
|
||||
{
|
||||
can_close = true;
|
||||
}
|
||||
@@ -1174,14 +1174,14 @@ impl WindowManager {
|
||||
.focused_workspace_idx();
|
||||
|
||||
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.focused_monitor_mut()
|
||||
.ok_or_eyre("there is no monitor")?
|
||||
.set_last_focused_workspace(Option::from(idx));
|
||||
.last_focused_workspace = Option::from(idx);
|
||||
}
|
||||
SocketMessage::FocusWorkspaceNumber(workspace_idx) => {
|
||||
// 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 mut to_focus = None;
|
||||
match workspace.layer() {
|
||||
match workspace.layer {
|
||||
WorkspaceLayer::Tiling => {
|
||||
workspace.set_layer(WorkspaceLayer::Floating);
|
||||
workspace.layer = WorkspaceLayer::Floating;
|
||||
|
||||
let focused_idx = workspace.focused_floating_window_idx();
|
||||
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() {
|
||||
window.lower()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
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() {
|
||||
to_focus = Some(*window);
|
||||
window.raise()?;
|
||||
@@ -1411,7 +1411,7 @@ impl WindowManager {
|
||||
for monitor in self.monitors() {
|
||||
if let Some(ws) = monitor.focused_workspace() {
|
||||
monitor_visible_windows.insert(
|
||||
monitor.device_id().clone(),
|
||||
monitor.device_id.clone(),
|
||||
ws.visible_window_details().clone(),
|
||||
);
|
||||
}
|
||||
@@ -1493,9 +1493,9 @@ impl WindowManager {
|
||||
// with this signal
|
||||
let workspace = self.focused_workspace_mut()?;
|
||||
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) {
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
let percentage = custom
|
||||
@@ -1512,7 +1512,7 @@ impl WindowManager {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for rule in workspace.layout_rules_mut() {
|
||||
for rule in &mut workspace.layout_rules {
|
||||
if container_len >= rule.0 {
|
||||
if let Layout::Custom(ref mut custom) = rule.1 {
|
||||
match sizing {
|
||||
@@ -1868,29 +1868,28 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
|
||||
}
|
||||
SocketMessage::MonitorWorkAreaOffset(monitor_idx, rect) => {
|
||||
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)?;
|
||||
}
|
||||
}
|
||||
SocketMessage::WorkspaceWorkAreaOffset(monitor_idx, workspace_idx, rect) => {
|
||||
if let Some(monitor) = self.monitors_mut().get_mut(monitor_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)?
|
||||
}
|
||||
}
|
||||
}
|
||||
SocketMessage::ToggleWindowBasedWorkAreaOffset => {
|
||||
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)?;
|
||||
}
|
||||
SocketMessage::QuickSave => {
|
||||
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");
|
||||
|
||||
@@ -1914,12 +1913,12 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
|
||||
|
||||
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)?;
|
||||
}
|
||||
SocketMessage::Save(ref path) => {
|
||||
let workspace = self.focused_workspace_mut()?;
|
||||
let resize = workspace.resize_dimensions();
|
||||
let resize = &workspace.resize_dimensions;
|
||||
|
||||
let file = OpenOptions::new()
|
||||
.write(true)
|
||||
@@ -1937,7 +1936,7 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
|
||||
|
||||
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)?;
|
||||
}
|
||||
SocketMessage::AddSubscriberSocket(ref socket) => {
|
||||
@@ -1997,9 +1996,8 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
|
||||
}
|
||||
SocketMessage::ToggleWorkspaceWindowContainerBehaviour => {
|
||||
let current_global_behaviour = self.window_management_behaviour.current_behaviour;
|
||||
if let Some(behaviour) = self
|
||||
.focused_workspace_mut()?
|
||||
.window_container_behaviour_mut()
|
||||
if let Some(behaviour) =
|
||||
&mut self.focused_workspace_mut()?.window_container_behaviour
|
||||
{
|
||||
match behaviour {
|
||||
WindowContainerBehaviour::Create => {
|
||||
@@ -2010,20 +2008,19 @@ if (!(Get-Process komorebi-bar -ErrorAction SilentlyContinue))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.focused_workspace_mut()?
|
||||
.set_window_container_behaviour(Some(match current_global_behaviour {
|
||||
self.focused_workspace_mut()?.window_container_behaviour =
|
||||
Some(match current_global_behaviour {
|
||||
WindowContainerBehaviour::Create => WindowContainerBehaviour::Append,
|
||||
WindowContainerBehaviour::Append => WindowContainerBehaviour::Create,
|
||||
}));
|
||||
});
|
||||
};
|
||||
}
|
||||
SocketMessage::ToggleWorkspaceFloatOverride => {
|
||||
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;
|
||||
} else {
|
||||
self.focused_workspace_mut()?
|
||||
.set_float_override(Some(!current_global_override));
|
||||
self.focused_workspace_mut()?.float_override = Some(!current_global_override);
|
||||
};
|
||||
}
|
||||
SocketMessage::WindowHidingBehaviour(behaviour) => {
|
||||
|
||||
@@ -304,7 +304,7 @@ impl WindowManager {
|
||||
// containers - this makes floating windows on empty workspaces go into very
|
||||
// annoying focus change loops which prevents users from interacting with them
|
||||
if !matches!(
|
||||
self.focused_workspace()?.layout(),
|
||||
self.focused_workspace()?.layout,
|
||||
Layout::Default(DefaultLayout::Scrolling)
|
||||
) && !self.focused_workspace()?.containers().is_empty()
|
||||
{
|
||||
@@ -319,13 +319,13 @@ impl WindowManager {
|
||||
|
||||
match floating_window_idx {
|
||||
None => {
|
||||
if let Some(w) = workspace.maximized_window() {
|
||||
if let Some(w) = &workspace.maximized_window {
|
||||
if w.hwnd == window.hwnd {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(monocle) = workspace.monocle_container() {
|
||||
if let Some(monocle) = &workspace.monocle_container {
|
||||
if let Some(window) = monocle.focused_window() {
|
||||
window.focus(false)?;
|
||||
}
|
||||
@@ -333,10 +333,10 @@ impl WindowManager {
|
||||
workspace.focus_container_by_window(window.hwnd)?;
|
||||
}
|
||||
|
||||
workspace.set_layer(WorkspaceLayer::Tiling);
|
||||
workspace.layer = WorkspaceLayer::Tiling;
|
||||
|
||||
if matches!(
|
||||
self.focused_workspace()?.layout(),
|
||||
self.focused_workspace()?.layout,
|
||||
Layout::Default(DefaultLayout::Scrolling)
|
||||
) && !self.focused_workspace()?.containers().is_empty()
|
||||
{
|
||||
@@ -345,7 +345,7 @@ impl WindowManager {
|
||||
}
|
||||
Some(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_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() {
|
||||
let floating_applications = FLOATING_APPLICATIONS.lock();
|
||||
@@ -458,11 +458,11 @@ impl WindowManager {
|
||||
let center_spawned_floats =
|
||||
placement.should_center() && workspace.tile;
|
||||
workspace.floating_windows_mut().push_back(window);
|
||||
workspace.set_layer(WorkspaceLayer::Floating);
|
||||
workspace.layer = WorkspaceLayer::Floating;
|
||||
if center_spawned_floats {
|
||||
let mut floating_window = window;
|
||||
floating_window.center(
|
||||
&workspace.globals().work_area,
|
||||
&workspace.globals.work_area,
|
||||
placement.should_resize(),
|
||||
)?;
|
||||
}
|
||||
@@ -471,7 +471,7 @@ impl WindowManager {
|
||||
match behaviour.current_behaviour {
|
||||
WindowContainerBehaviour::Create => {
|
||||
workspace.new_container_for_window(window);
|
||||
workspace.set_layer(WorkspaceLayer::Tiling);
|
||||
workspace.layer = WorkspaceLayer::Tiling;
|
||||
self.update_focused_workspace(false, false)?;
|
||||
}
|
||||
WindowContainerBehaviour::Append => {
|
||||
@@ -479,7 +479,7 @@ impl WindowManager {
|
||||
.focused_container_mut()
|
||||
.ok_or_eyre("there is no focused container")?
|
||||
.add_window(window);
|
||||
workspace.set_layer(WorkspaceLayer::Tiling);
|
||||
workspace.layer = WorkspaceLayer::Tiling;
|
||||
self.update_focused_workspace(true, false)?;
|
||||
stackbar_manager::send_notification();
|
||||
}
|
||||
@@ -513,8 +513,7 @@ impl WindowManager {
|
||||
}
|
||||
|
||||
let workspace = self.focused_workspace()?;
|
||||
if !(monocle_window_event
|
||||
|| workspace.layer() != &WorkspaceLayer::Tiling)
|
||||
if !(monocle_window_event || workspace.layer != WorkspaceLayer::Tiling)
|
||||
&& monocle_container.is_some()
|
||||
{
|
||||
window.hide();
|
||||
@@ -568,7 +567,7 @@ impl WindowManager {
|
||||
let focused_container_idx = workspace.focused_container_idx();
|
||||
let new_position = WindowsApi::window_rect(window.hwnd)?;
|
||||
let old_position = *workspace
|
||||
.latest_layout()
|
||||
.latest_layout
|
||||
.get(focused_container_idx)
|
||||
// If the move was to another monitor with an empty workspace, the
|
||||
// workspace here will refer to that empty workspace, which won't
|
||||
@@ -616,7 +615,7 @@ impl WindowManager {
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
let resize = Rect {
|
||||
@@ -832,7 +831,7 @@ impl WindowManager {
|
||||
.and_then(|m| m.workspaces().get(*ws_idx))
|
||||
{
|
||||
if let Some(monocle_with_window) = target_workspace
|
||||
.monocle_container()
|
||||
.monocle_container
|
||||
.as_ref()
|
||||
.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 ws_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)?;
|
||||
}
|
||||
if let Some(workspace) = monitor.focused_workspace_mut() {
|
||||
let mut layer = WorkspaceLayer::Tiling;
|
||||
if let Some((monocle, idx)) = workspace
|
||||
.monocle_container_mut()
|
||||
.monocle_container
|
||||
.as_mut()
|
||||
.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)
|
||||
{
|
||||
layer = WorkspaceLayer::Floating;
|
||||
} else if !workspace
|
||||
.maximized_window()
|
||||
.is_some_and(|w| w.hwnd == window.hwnd)
|
||||
} else if workspace
|
||||
.maximized_window
|
||||
.is_none_or(|w| w.hwnd != window.hwnd)
|
||||
{
|
||||
// If the window is the maximized window do nothing, else we
|
||||
// reintegrate the monocle if it exists and then focus the
|
||||
// container
|
||||
if workspace.monocle_container().is_some() {
|
||||
if workspace.monocle_container.is_some() {
|
||||
tracing::info!("disabling monocle");
|
||||
for container in workspace.containers_mut() {
|
||||
container.restore();
|
||||
@@ -918,7 +917,7 @@ impl WindowManager {
|
||||
}
|
||||
workspace.focus_container_by_window(window.hwnd)?;
|
||||
}
|
||||
workspace.set_layer(layer);
|
||||
workspace.layer = layer;
|
||||
}
|
||||
monitor.load_focused_workspace(mouse_follows_focus)?;
|
||||
monitor.update_focused_workspace(offset)?;
|
||||
|
||||
@@ -111,7 +111,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
// Only operate on the focused workspace of each monitor
|
||||
if let Some(ws) = m.focused_workspace_mut() {
|
||||
// Workspaces with tiling disabled don't have stackbars
|
||||
if !ws.tile() {
|
||||
if !ws.tile {
|
||||
let mut to_remove = vec![];
|
||||
for (id, border) in stackbars.iter() {
|
||||
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());
|
||||
|
||||
// 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
|
||||
let mut to_remove = vec![];
|
||||
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
|
||||
.containers()
|
||||
.iter()
|
||||
.map(|c| c.id().clone())
|
||||
.map(|c| c.id.clone())
|
||||
.collect::<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
|
||||
.container_padding()
|
||||
.container_padding
|
||||
.unwrap_or_else(|| DEFAULT_CONTAINER_PADDING.load_consume());
|
||||
|
||||
'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 let Some(stackbar) = stackbars.get(container.id()) {
|
||||
if let Some(stackbar) = stackbars.get(&container.id) {
|
||||
stackbar.destroy()?
|
||||
}
|
||||
|
||||
stackbars.remove(container.id());
|
||||
stackbars_monitors.remove(container.id());
|
||||
stackbars.remove(&container.id);
|
||||
stackbars_monitors.remove(&container.id);
|
||||
continue 'containers;
|
||||
}
|
||||
|
||||
// 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::Vacant(entry) => {
|
||||
if let Ok(stackbar) = Stackbar::create(container.id()) {
|
||||
if let Ok(stackbar) = Stackbar::create(&container.id) {
|
||||
entry.insert(stackbar)
|
||||
} else {
|
||||
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(
|
||||
container.focused_window().copied().unwrap_or_default().hwnd,
|
||||
|
||||
@@ -250,7 +250,7 @@ pub struct WorkspaceConfig {
|
||||
impl From<&Workspace> for WorkspaceConfig {
|
||||
fn from(value: &Workspace) -> Self {
|
||||
let mut layout_rules = HashMap::new();
|
||||
for (threshold, layout) in value.layout_rules() {
|
||||
for (threshold, layout) in &value.layout_rules {
|
||||
match layout {
|
||||
Layout::Default(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 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);
|
||||
}
|
||||
|
||||
let default_container_padding = DEFAULT_CONTAINER_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 {
|
||||
None
|
||||
} 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 {
|
||||
None
|
||||
} 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 {
|
||||
name: value
|
||||
.name()
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(|| String::from("unnamed")),
|
||||
layout: value
|
||||
.tile()
|
||||
.then_some(match value.layout() {
|
||||
Layout::Default(layout) => Option::from(*layout),
|
||||
.tile
|
||||
.then_some(match value.layout {
|
||||
Layout::Default(layout) => Option::from(layout),
|
||||
Layout::Custom(_) => None,
|
||||
})
|
||||
.flatten(),
|
||||
layout_options: value.layout_options(),
|
||||
layout_options: value.layout_options,
|
||||
custom_layout: value
|
||||
.workspace_config()
|
||||
.workspace_config
|
||||
.as_ref()
|
||||
.and_then(|c| c.custom_layout.clone()),
|
||||
layout_rules,
|
||||
custom_layout_rules: value
|
||||
.workspace_config()
|
||||
.workspace_config
|
||||
.as_ref()
|
||||
.and_then(|c| c.custom_layout_rules.clone()),
|
||||
container_padding,
|
||||
workspace_padding,
|
||||
initial_workspace_rules: value
|
||||
.workspace_config()
|
||||
.workspace_config
|
||||
.as_ref()
|
||||
.and_then(|c| c.initial_workspace_rules.clone()),
|
||||
workspace_rules: value
|
||||
.workspace_config()
|
||||
.workspace_config
|
||||
.as_ref()
|
||||
.and_then(|c| c.workspace_rules.clone()),
|
||||
work_area_offset: value.work_area_offset(),
|
||||
apply_window_based_work_area_offset: Some(value.apply_window_based_work_area_offset()),
|
||||
window_container_behaviour: *value.window_container_behaviour(),
|
||||
work_area_offset: value.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_rules: Option::from(window_container_behaviour_rules),
|
||||
float_override: *value.float_override(),
|
||||
float_override: value.float_override,
|
||||
tile,
|
||||
layout_flip: value.layout_flip(),
|
||||
floating_layer_behaviour: value.floating_layer_behaviour(),
|
||||
layout_flip: value.layout_flip,
|
||||
floating_layer_behaviour: value.floating_layer_behaviour,
|
||||
wallpaper: None,
|
||||
}
|
||||
}
|
||||
@@ -369,7 +369,7 @@ impl From<&Monitor> for MonitorConfig {
|
||||
let default_container_padding = DEFAULT_CONTAINER_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 {
|
||||
None
|
||||
} 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 {
|
||||
None
|
||||
} else {
|
||||
@@ -387,13 +387,13 @@ impl From<&Monitor> for MonitorConfig {
|
||||
|
||||
Self {
|
||||
workspaces,
|
||||
work_area_offset: value.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()),
|
||||
work_area_offset: value.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),
|
||||
container_padding,
|
||||
workspace_padding,
|
||||
wallpaper: value.wallpaper().clone(),
|
||||
floating_layer_behaviour: value.floating_layer_behaviour(),
|
||||
wallpaper: value.wallpaper.clone(),
|
||||
floating_layer_behaviour: value.floating_layer_behaviour,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1364,12 +1364,9 @@ impl StaticConfig {
|
||||
let preferred_config_idx = {
|
||||
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read();
|
||||
let c_idx = display_index_preferences.iter().find_map(|(c_idx, id)| {
|
||||
(monitor
|
||||
.serial_number_id()
|
||||
.as_ref()
|
||||
.is_some_and(|sn| sn == id)
|
||||
|| monitor.device_id() == id)
|
||||
.then_some(*c_idx)
|
||||
(monitor.serial_number_id.as_ref().is_some_and(|sn| sn == id)
|
||||
|| monitor.device_id.eq(id))
|
||||
.then_some(*c_idx)
|
||||
});
|
||||
c_idx
|
||||
};
|
||||
@@ -1396,19 +1393,16 @@ impl StaticConfig {
|
||||
}
|
||||
|
||||
monitor.ensure_workspace_count(monitor_config.workspaces.len());
|
||||
monitor.set_work_area_offset(monitor_config.work_area_offset);
|
||||
monitor.set_window_based_work_area_offset(
|
||||
monitor_config.window_based_work_area_offset,
|
||||
);
|
||||
monitor.set_window_based_work_area_offset_limit(
|
||||
monitor_config
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
monitor.set_container_padding(monitor_config.container_padding);
|
||||
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.work_area_offset = monitor_config.work_area_offset;
|
||||
monitor.window_based_work_area_offset =
|
||||
monitor_config.window_based_work_area_offset;
|
||||
monitor.window_based_work_area_offset_limit = monitor_config
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1);
|
||||
monitor.container_padding = monitor_config.container_padding;
|
||||
monitor.workspace_padding = monitor_config.workspace_padding;
|
||||
monitor.wallpaper = monitor_config.wallpaper.clone();
|
||||
monitor.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
|
||||
|
||||
monitor.update_workspaces_globals(offset);
|
||||
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.
|
||||
if idx == preferred_config_idx {
|
||||
let id = monitor
|
||||
.serial_number_id()
|
||||
.serial_number_id
|
||||
.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());
|
||||
}
|
||||
|
||||
@@ -1490,18 +1484,14 @@ impl StaticConfig {
|
||||
);
|
||||
|
||||
m.ensure_workspace_count(monitor_config.workspaces.len());
|
||||
m.set_work_area_offset(monitor_config.work_area_offset);
|
||||
m.set_window_based_work_area_offset(
|
||||
monitor_config.window_based_work_area_offset,
|
||||
);
|
||||
m.set_window_based_work_area_offset_limit(
|
||||
monitor_config
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
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.work_area_offset = monitor_config.work_area_offset;
|
||||
m.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
|
||||
.unwrap_or(1);
|
||||
m.container_padding = monitor_config.container_padding;
|
||||
m.workspace_padding = monitor_config.workspace_padding;
|
||||
m.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
|
||||
|
||||
m.update_workspaces_globals(offset);
|
||||
|
||||
@@ -1543,12 +1533,9 @@ impl StaticConfig {
|
||||
let preferred_config_idx = {
|
||||
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read();
|
||||
let c_idx = display_index_preferences.iter().find_map(|(c_idx, id)| {
|
||||
(monitor
|
||||
.serial_number_id()
|
||||
.as_ref()
|
||||
.is_some_and(|sn| sn == id)
|
||||
|| monitor.device_id() == id)
|
||||
.then_some(*c_idx)
|
||||
(monitor.serial_number_id.as_ref().is_some_and(|sn| sn == id)
|
||||
|| monitor.device_id.eq(id))
|
||||
.then_some(*c_idx)
|
||||
});
|
||||
c_idx
|
||||
};
|
||||
@@ -1575,21 +1562,18 @@ impl StaticConfig {
|
||||
}
|
||||
|
||||
monitor.ensure_workspace_count(monitor_config.workspaces.len());
|
||||
if monitor.work_area_offset().is_none() {
|
||||
monitor.set_work_area_offset(monitor_config.work_area_offset);
|
||||
if monitor.work_area_offset.is_none() {
|
||||
monitor.work_area_offset = monitor_config.work_area_offset;
|
||||
}
|
||||
monitor.set_window_based_work_area_offset(
|
||||
monitor_config.window_based_work_area_offset,
|
||||
);
|
||||
monitor.set_window_based_work_area_offset_limit(
|
||||
monitor_config
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
monitor.set_container_padding(monitor_config.container_padding);
|
||||
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.window_based_work_area_offset =
|
||||
monitor_config.window_based_work_area_offset;
|
||||
monitor.window_based_work_area_offset_limit = monitor_config
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1);
|
||||
monitor.container_padding = monitor_config.container_padding;
|
||||
monitor.workspace_padding = monitor_config.workspace_padding;
|
||||
monitor.wallpaper = monitor_config.wallpaper.clone();
|
||||
monitor.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
|
||||
|
||||
monitor.update_workspaces_globals(offset);
|
||||
|
||||
@@ -1603,9 +1587,9 @@ impl StaticConfig {
|
||||
// a copy of the monitor itself on the monitor cache if it is.
|
||||
if idx == preferred_config_idx {
|
||||
let id = monitor
|
||||
.serial_number_id()
|
||||
.serial_number_id
|
||||
.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());
|
||||
}
|
||||
|
||||
@@ -1665,18 +1649,14 @@ impl StaticConfig {
|
||||
);
|
||||
|
||||
m.ensure_workspace_count(monitor_config.workspaces.len());
|
||||
m.set_work_area_offset(monitor_config.work_area_offset);
|
||||
m.set_window_based_work_area_offset(
|
||||
monitor_config.window_based_work_area_offset,
|
||||
);
|
||||
m.set_window_based_work_area_offset_limit(
|
||||
monitor_config
|
||||
.window_based_work_area_offset_limit
|
||||
.unwrap_or(1),
|
||||
);
|
||||
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.work_area_offset = monitor_config.work_area_offset;
|
||||
m.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
|
||||
.unwrap_or(1);
|
||||
m.container_padding = monitor_config.container_padding;
|
||||
m.workspace_padding = monitor_config.workspace_padding;
|
||||
m.floating_layer_behaviour = monitor_config.floating_layer_behaviour;
|
||||
|
||||
m.update_workspaces_globals(offset);
|
||||
|
||||
|
||||
@@ -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() {
|
||||
// Only operate on the focused workspace of each monitor
|
||||
// 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() {
|
||||
if let Err(error) = window.opaque() {
|
||||
let hwnd = window.hwnd;
|
||||
@@ -104,7 +104,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
}
|
||||
|
||||
// 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 monitor_idx == focused_monitor_idx {
|
||||
if let Err(error) = window.opaque() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -310,7 +310,7 @@ impl WindowsApi {
|
||||
let name = name.split('\\').collect::<Vec<_>>()[0].to_string();
|
||||
|
||||
for monitor in monitors.elements() {
|
||||
if device_id.eq(monitor.device_id()) {
|
||||
if device_id.eq(&monitor.device_id) {
|
||||
continue 'read;
|
||||
}
|
||||
}
|
||||
@@ -335,15 +335,14 @@ impl WindowsApi {
|
||||
let mut index_preference = None;
|
||||
let monitor_index_preferences = MONITOR_INDEX_PREFERENCES.lock();
|
||||
for (index, monitor_size) in &*monitor_index_preferences {
|
||||
if m.size() == monitor_size {
|
||||
if m.size == *monitor_size {
|
||||
index_preference = Option::from(index);
|
||||
}
|
||||
}
|
||||
|
||||
let display_index_preferences = DISPLAY_INDEX_PREFERENCES.read();
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -356,7 +355,7 @@ impl WindowsApi {
|
||||
let current_name = monitors
|
||||
.elements_mut()
|
||||
.get(*preference)
|
||||
.map_or("", |m| m.name());
|
||||
.map_or("", |m| &m.name);
|
||||
if current_name == "PLACEHOLDER" {
|
||||
let _ = monitors.elements_mut().remove(*preference);
|
||||
monitors.elements_mut().insert(*preference, m);
|
||||
@@ -368,16 +367,14 @@ impl WindowsApi {
|
||||
}
|
||||
}
|
||||
|
||||
monitors
|
||||
.elements_mut()
|
||||
.retain(|m| m.name().ne("PLACEHOLDER"));
|
||||
monitors.elements_mut().retain(|m| m.name.ne("PLACEHOLDER"));
|
||||
|
||||
// Rebuild monitor index map
|
||||
*monitor_usr_idx_map = HashMap::new();
|
||||
let mut added_monitor_idxs = Vec::new();
|
||||
for (index, id) in &*DISPLAY_INDEX_PREFERENCES.read() {
|
||||
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);
|
||||
added_monitor_idxs.push(m_idx);
|
||||
@@ -415,7 +412,7 @@ impl WindowsApi {
|
||||
|
||||
pub fn load_workspace_information(monitors: &mut Ring<Monitor>) -> Result<()> {
|
||||
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() {
|
||||
// EnumWindows will enumerate through windows on all monitors
|
||||
Self::enum_windows(
|
||||
@@ -426,7 +423,7 @@ impl WindowsApi {
|
||||
// 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
|
||||
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
|
||||
let mut windows_on_other_monitors = vec![];
|
||||
@@ -464,7 +461,7 @@ impl WindowsApi {
|
||||
Ok(Self::monitor(
|
||||
unsafe { MonitorFromWindow(HWND(as_ptr!(hwnd)), MONITOR_DEFAULTTONEAREST) }.0 as isize,
|
||||
)?
|
||||
.name()
|
||||
.name
|
||||
.to_string())
|
||||
}
|
||||
|
||||
|
||||
@@ -39,74 +39,44 @@ use crate::REGEX_IDENTIFIERS;
|
||||
use crate::REMOVE_TITLEBARS;
|
||||
use color_eyre::eyre::OptionExt;
|
||||
use color_eyre::Result;
|
||||
use getset::CopyGetters;
|
||||
use getset::Getters;
|
||||
use getset::MutGetters;
|
||||
use getset::Setters;
|
||||
use komorebi_themes::Base16ColourPalette;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use uds_windows::UnixStream;
|
||||
|
||||
#[allow(clippy::struct_field_names)]
|
||||
#[derive(
|
||||
Debug, Clone, Serialize, Deserialize, Getters, CopyGetters, MutGetters, Setters, PartialEq,
|
||||
)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct Workspace {
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub name: Option<String>,
|
||||
pub containers: Ring<Container>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub monocle_container: Option<Container>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub monocle_container_restore_idx: Option<usize>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub maximized_window: Option<Window>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub maximized_window_restore_idx: Option<usize>,
|
||||
pub floating_windows: Ring<Window>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub layout: Layout,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub layout_options: Option<LayoutOptions>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub layout_rules: Vec<(usize, Layout)>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub layout_flip: Option<Axis>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub workspace_padding: Option<i32>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub container_padding: Option<i32>,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub latest_layout: Vec<Rect>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub resize_dimensions: Vec<Option<Rect>>,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub tile: bool,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub work_area_offset: Option<Rect>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
pub apply_window_based_work_area_offset: bool,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub window_container_behaviour: Option<WindowContainerBehaviour>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub window_container_behaviour_rules: Option<Vec<(usize, WindowContainerBehaviour)>>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub float_override: Option<bool>,
|
||||
#[serde(skip)]
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub globals: WorkspaceGlobals,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub layer: WorkspaceLayer,
|
||||
#[getset(get_copy = "pub", get_mut = "pub", set = "pub")]
|
||||
pub floating_layer_behaviour: Option<FloatingLayerBehaviour>,
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
pub wallpaper: Option<Wallpaper>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
pub workspace_config: Option<WorkspaceConfig>,
|
||||
}
|
||||
|
||||
@@ -171,19 +141,7 @@ pub enum WorkspaceWindowLocation {
|
||||
Floating(usize), // idx in floating_windows
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
Default,
|
||||
Copy,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Getters,
|
||||
CopyGetters,
|
||||
MutGetters,
|
||||
Setters,
|
||||
PartialEq,
|
||||
)]
|
||||
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
/// Settings setup either by the parent monitor or by the `WindowManager`
|
||||
pub struct WorkspaceGlobals {
|
||||
@@ -202,9 +160,9 @@ impl Workspace {
|
||||
pub fn load_static_config(&mut self, config: &WorkspaceConfig) -> Result<()> {
|
||||
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 {
|
||||
self.layout = Layout::Default(*layout);
|
||||
@@ -229,7 +187,7 @@ impl Workspace {
|
||||
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 {
|
||||
for (count, pathbuf) in layout_rules {
|
||||
@@ -239,20 +197,19 @@ impl Workspace {
|
||||
|
||||
all_layout_rules.sort_by_key(|(i, _)| *i);
|
||||
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(
|
||||
config.apply_window_based_work_area_offset.unwrap_or(true),
|
||||
);
|
||||
self.apply_window_based_work_area_offset =
|
||||
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 window_container_behaviour_rules.is_empty() {
|
||||
self.set_window_container_behaviour_rules(None);
|
||||
self.window_container_behaviour_rules = None;
|
||||
} else {
|
||||
let mut all_rules = vec![];
|
||||
for (count, behaviour) in window_container_behaviour_rules {
|
||||
@@ -260,19 +217,19 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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 {
|
||||
self.set_window_container_behaviour_rules(None);
|
||||
self.window_container_behaviour_rules = None;
|
||||
}
|
||||
|
||||
self.set_float_override(config.float_override);
|
||||
self.set_layout_flip(config.layout_flip);
|
||||
self.set_floating_layer_behaviour(config.floating_layer_behaviour);
|
||||
self.set_wallpaper(config.wallpaper.clone());
|
||||
self.set_layout_options(config.layout_options);
|
||||
self.float_override = config.float_override;
|
||||
self.layout_flip = config.layout_flip;
|
||||
self.floating_layer_behaviour = config.floating_layer_behaviour;
|
||||
self.wallpaper = config.wallpaper.clone();
|
||||
self.layout_options = config.layout_options;
|
||||
|
||||
self.set_workspace_config(Some(config.clone()));
|
||||
self.workspace_config = Some(config.clone());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -298,11 +255,11 @@ impl Workspace {
|
||||
container.hide(omit)
|
||||
}
|
||||
|
||||
if let Some(window) = self.maximized_window() {
|
||||
if let Some(window) = self.maximized_window {
|
||||
window.hide();
|
||||
}
|
||||
|
||||
if let Some(container) = self.monocle_container_mut() {
|
||||
if let Some(container) = &self.monocle_container {
|
||||
container.hide(omit)
|
||||
}
|
||||
}
|
||||
@@ -429,7 +386,7 @@ impl Workspace {
|
||||
hmonitor: isize,
|
||||
monitor_wp: &Option<Wallpaper>,
|
||||
) -> Result<()> {
|
||||
if let Some(container) = self.monocle_container() {
|
||||
if let Some(container) = &self.monocle_container {
|
||||
if let Some(window) = container.focused_window() {
|
||||
container.restore();
|
||||
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
|
||||
// when switching to a workspace
|
||||
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)?;
|
||||
} else if let Some(maximized_window) = self.maximized_window() {
|
||||
} else if let Some(maximized_window) = self.maximized_window {
|
||||
maximized_window.restore();
|
||||
maximized_window.focus(mouse_follows_focus)?;
|
||||
} else if let Some(floating_window) = self.focused_floating_window() {
|
||||
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.focus(mouse_follows_focus)?;
|
||||
} 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());
|
||||
|
||||
let container_padding = self
|
||||
.container_padding()
|
||||
.or(self.globals().container_padding)
|
||||
.container_padding
|
||||
.or(self.globals.container_padding)
|
||||
.unwrap_or_default();
|
||||
let workspace_padding = self
|
||||
.workspace_padding()
|
||||
.or(self.globals().workspace_padding)
|
||||
.workspace_padding
|
||||
.or(self.globals.workspace_padding)
|
||||
.unwrap_or_default();
|
||||
let border_width = self.globals().border_width;
|
||||
let border_offset = self.globals().border_offset;
|
||||
let work_area = self.globals().work_area;
|
||||
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_limit =
|
||||
self.globals().window_based_work_area_offset_limit;
|
||||
let border_width = self.globals.border_width;
|
||||
let border_offset = self.globals.border_offset;
|
||||
let work_area = self.globals.work_area;
|
||||
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_limit = self.globals.window_based_work_area_offset_limit;
|
||||
|
||||
let mut adjusted_work_area = work_area_offset.map_or_else(
|
||||
|| work_area,
|
||||
@@ -518,7 +474,7 @@ impl Workspace {
|
||||
);
|
||||
|
||||
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
|
||||
{
|
||||
adjusted_work_area = window_based_work_area_offset.map_or_else(
|
||||
@@ -539,21 +495,21 @@ impl Workspace {
|
||||
|
||||
self.enforce_resize_constraints();
|
||||
|
||||
if !self.layout_rules().is_empty() {
|
||||
if !self.layout_rules.is_empty() {
|
||||
let mut updated_layout = None;
|
||||
|
||||
for (threshold, layout) in self.layout_rules() {
|
||||
for (threshold, layout) in &self.layout_rules {
|
||||
if self.containers().len() >= *threshold {
|
||||
updated_layout = Option::from(layout.clone());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
for (threshold, behaviour) in window_container_behaviour_rules {
|
||||
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 let Some(container) = self.monocle_container_mut() {
|
||||
if self.tile {
|
||||
if let Some(container) = &mut self.monocle_container {
|
||||
if let Some(window) = container.focused_window_mut() {
|
||||
adjusted_work_area.add_padding(container_padding);
|
||||
adjusted_work_area.add_padding(border_offset);
|
||||
adjusted_work_area.add_padding(border_width);
|
||||
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();
|
||||
} 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,
|
||||
NonZeroUsize::new(self.containers().len()).ok_or_eyre(
|
||||
"there must be at least one container to calculate a workspace layout",
|
||||
)?,
|
||||
Some(container_padding),
|
||||
self.layout_flip(),
|
||||
self.resize_dimensions(),
|
||||
self.layout_flip,
|
||||
&self.resize_dimensions,
|
||||
self.focused_container_idx(),
|
||||
self.layout_options(),
|
||||
self.latest_layout(),
|
||||
self.layout_options,
|
||||
&self.latest_layout,
|
||||
);
|
||||
|
||||
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
|
||||
// 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
|
||||
if self.monocle_container().is_none() {
|
||||
self.resize_dimensions_mut().resize(container_count, None);
|
||||
if self.monocle_container.is_none() {
|
||||
self.resize_dimensions.resize(container_count, None);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -709,7 +665,7 @@ impl Workspace {
|
||||
let point = WindowsApi::cursor_pos().ok()?;
|
||||
|
||||
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)) {
|
||||
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 exe == window_exe {
|
||||
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) {
|
||||
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 exe == window_exe {
|
||||
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) {
|
||||
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 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(container) = self.monocle_container() {
|
||||
if let Some(container) = &self.monocle_container {
|
||||
if container.contains_window(hwnd) {
|
||||
return true;
|
||||
}
|
||||
@@ -810,13 +766,13 @@ impl Workspace {
|
||||
|
||||
pub fn is_focused_window_monocle_or_maximized(&self) -> Result<bool> {
|
||||
let hwnd = WindowsApi::foreground_window()?;
|
||||
if let Some(window) = self.maximized_window() {
|
||||
if let Some(window) = self.maximized_window {
|
||||
if hwnd == window.hwnd {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(container) = self.monocle_container() {
|
||||
if let Some(container) = &self.monocle_container {
|
||||
if container.contains_window(hwnd) {
|
||||
return Ok(true);
|
||||
}
|
||||
@@ -827,8 +783,8 @@ impl Workspace {
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.containers().is_empty()
|
||||
&& self.maximized_window().is_none()
|
||||
&& self.monocle_container().is_none()
|
||||
&& self.maximized_window.is_none()
|
||||
&& self.monocle_container.is_none()
|
||||
&& 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 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(container) = self.monocle_container() {
|
||||
if let Some(container) = &self.monocle_container {
|
||||
if container.contains_window(hwnd) {
|
||||
return true;
|
||||
}
|
||||
@@ -861,12 +817,12 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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
|
||||
.remove_focused_container()
|
||||
.ok_or_eyre("there is no container")?;
|
||||
|
||||
let primary_idx = match self.layout() {
|
||||
let primary_idx = match &self.layout {
|
||||
Layout::Default(_) => 0,
|
||||
Layout::Custom(layout) => layout.first_container_idx(
|
||||
layout
|
||||
@@ -876,7 +832,7 @@ impl Workspace {
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
Ok(())
|
||||
@@ -899,10 +855,10 @@ impl Workspace {
|
||||
.containers_mut()
|
||||
.insert_respecting_locks(idx, container);
|
||||
|
||||
if insertion_idx > self.resize_dimensions().len() {
|
||||
self.resize_dimensions_mut().push(None);
|
||||
if insertion_idx > self.resize_dimensions.len() {
|
||||
self.resize_dimensions.push(None);
|
||||
} else {
|
||||
self.resize_dimensions_mut().insert(insertion_idx, None);
|
||||
self.resize_dimensions.insert(insertion_idx, None);
|
||||
}
|
||||
|
||||
self.focus_container(insertion_idx);
|
||||
@@ -915,8 +871,8 @@ impl Workspace {
|
||||
pub fn remove_container_by_idx(&mut self, idx: usize) -> Option<Container> {
|
||||
let container = self.containers_mut().remove_respecting_locks(idx);
|
||||
|
||||
if idx < self.resize_dimensions().len() {
|
||||
self.resize_dimensions_mut().remove(idx);
|
||||
if idx < self.resize_dimensions.len() {
|
||||
self.resize_dimensions.remove(idx);
|
||||
}
|
||||
|
||||
container
|
||||
@@ -941,7 +897,7 @@ impl Workspace {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(container) = self.monocle_container_mut() {
|
||||
if let Some(container) = &mut self.monocle_container {
|
||||
if let Some(window_idx) = container
|
||||
.windows()
|
||||
.iter()
|
||||
@@ -952,8 +908,8 @@ impl Workspace {
|
||||
.ok_or_eyre("there is no window")?;
|
||||
|
||||
if container.windows().is_empty() {
|
||||
self.set_monocle_container(None);
|
||||
self.set_monocle_container_restore_idx(None);
|
||||
self.monocle_container = None;
|
||||
self.monocle_container_restore_idx = None;
|
||||
}
|
||||
|
||||
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 {
|
||||
window.unmaximize();
|
||||
self.set_maximized_window(None);
|
||||
self.set_maximized_window_restore_idx(None);
|
||||
self.maximized_window = None;
|
||||
self.maximized_window_restore_idx = None;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
@@ -1024,8 +980,8 @@ impl Workspace {
|
||||
let len = NonZeroUsize::new(self.containers().len())?;
|
||||
|
||||
direction.destination(
|
||||
self.layout().as_boxed_direction().as_ref(),
|
||||
self.layout_flip(),
|
||||
self.layout.as_boxed_direction().as_ref(),
|
||||
self.layout_flip,
|
||||
self.focused_container_idx(),
|
||||
len,
|
||||
)
|
||||
@@ -1131,19 +1087,19 @@ impl Workspace {
|
||||
}
|
||||
|
||||
pub fn new_floating_window(&mut self) -> Result<()> {
|
||||
let window = if let Some(maximized_window) = self.maximized_window() {
|
||||
let window = *maximized_window;
|
||||
self.set_maximized_window(None);
|
||||
self.set_maximized_window_restore_idx(None);
|
||||
let window = if let Some(maximized_window) = self.maximized_window {
|
||||
let window = maximized_window;
|
||||
self.maximized_window = None;
|
||||
self.maximized_window_restore_idx = None;
|
||||
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
|
||||
.remove_focused_window()
|
||||
.ok_or_eyre("there is no window")?;
|
||||
|
||||
if monocle_container.windows().is_empty() {
|
||||
self.set_monocle_container(None);
|
||||
self.set_monocle_container_restore_idx(None);
|
||||
self.monocle_container = None;
|
||||
self.monocle_container_restore_idx = None;
|
||||
} else {
|
||||
monocle_container.load_focused_window();
|
||||
}
|
||||
@@ -1203,7 +1159,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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 {
|
||||
// Even containers can't be resized to the bottom
|
||||
if i % 2 == 0 {
|
||||
@@ -1216,20 +1172,20 @@ impl Workspace {
|
||||
}
|
||||
|
||||
// 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.left = 0;
|
||||
}
|
||||
|
||||
// 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.right = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
0 | 1 => self.enforce_no_resize(),
|
||||
_ => {
|
||||
@@ -1252,7 +1208,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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() {
|
||||
0 | 1 => self.enforce_no_resize(),
|
||||
_ => {
|
||||
@@ -1275,7 +1231,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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() {
|
||||
// Single window can not be resized at all
|
||||
0 | 1 => self.enforce_no_resize(),
|
||||
@@ -1308,7 +1264,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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() {
|
||||
// Single window can not be resized at all
|
||||
0 | 1 => self.enforce_no_resize(),
|
||||
@@ -1341,7 +1297,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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() {
|
||||
0 | 1 => self.enforce_no_resize(),
|
||||
_ => {
|
||||
@@ -1369,7 +1325,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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() {
|
||||
// Single window can not be resized at all
|
||||
0 | 1 => self.enforce_no_resize(),
|
||||
@@ -1426,7 +1382,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
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() {
|
||||
0 | 1 => self.enforce_no_resize(),
|
||||
_ => {
|
||||
@@ -1448,7 +1404,7 @@ impl Workspace {
|
||||
}
|
||||
}
|
||||
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.right = 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
|
||||
// it had before
|
||||
|
||||
self.set_monocle_container(Option::from(container));
|
||||
self.set_monocle_container_restore_idx(Option::from(focused_idx));
|
||||
self.monocle_container = Option::from(container);
|
||||
self.monocle_container_restore_idx = Option::from(focused_idx);
|
||||
self.focus_previous_container();
|
||||
|
||||
self.monocle_container_mut()
|
||||
self.monocle_container
|
||||
.as_mut()
|
||||
.ok_or_eyre("there is no monocle container")?
|
||||
.load_focused_window();
|
||||
@@ -1485,11 +1441,11 @@ impl Workspace {
|
||||
|
||||
pub fn reintegrate_monocle_container(&mut self) -> Result<()> {
|
||||
let restore_idx = self
|
||||
.monocle_container_restore_idx()
|
||||
.monocle_container_restore_idx
|
||||
.ok_or_eyre("there is no monocle restore index")?;
|
||||
|
||||
let container = self
|
||||
.monocle_container_mut()
|
||||
.monocle_container
|
||||
.as_ref()
|
||||
.ok_or_eyre("there is no monocle container")?;
|
||||
|
||||
@@ -1508,8 +1464,8 @@ impl Workspace {
|
||||
.ok_or_eyre("there is no container")?
|
||||
.load_focused_window();
|
||||
|
||||
self.set_monocle_container(None);
|
||||
self.set_monocle_container_restore_idx(None);
|
||||
self.monocle_container = None;
|
||||
self.monocle_container_restore_idx = None;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1520,31 +1476,31 @@ impl Workspace {
|
||||
if matches!(self.layer, WorkspaceLayer::Floating) {
|
||||
let floating_window_idx = self.focused_floating_window_idx();
|
||||
let floating_window = self.floating_windows_mut().remove(floating_window_idx);
|
||||
self.set_maximized_window(floating_window);
|
||||
self.set_maximized_window_restore_idx(Option::from(focused_idx));
|
||||
if let Some(window) = self.maximized_window() {
|
||||
self.maximized_window = floating_window;
|
||||
self.maximized_window_restore_idx = Option::from(focused_idx);
|
||||
if let Some(window) = self.maximized_window {
|
||||
window.maximize();
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let monocle_restore_idx = self.monocle_container_restore_idx();
|
||||
if let Some(monocle_container) = self.monocle_container_mut() {
|
||||
let monocle_restore_idx = self.monocle_container_restore_idx;
|
||||
if let Some(monocle_container) = &mut self.monocle_container {
|
||||
let window = monocle_container
|
||||
.remove_focused_window()
|
||||
.ok_or_eyre("there is no window")?;
|
||||
|
||||
if monocle_container.windows().is_empty() {
|
||||
self.set_monocle_container(None);
|
||||
self.set_monocle_container_restore_idx(None);
|
||||
self.monocle_container = None;
|
||||
self.monocle_container_restore_idx = None;
|
||||
} else {
|
||||
monocle_container.load_focused_window();
|
||||
}
|
||||
|
||||
self.set_maximized_window(Option::from(window));
|
||||
self.set_maximized_window_restore_idx(monocle_restore_idx);
|
||||
if let Some(window) = self.maximized_window() {
|
||||
self.maximized_window = Option::from(window);
|
||||
self.maximized_window_restore_idx = monocle_restore_idx;
|
||||
if let Some(window) = self.maximized_window {
|
||||
window.maximize();
|
||||
}
|
||||
|
||||
@@ -1564,17 +1520,17 @@ impl Workspace {
|
||||
// monocle and maximized toggles which take over the whole screen before being reinserted
|
||||
// at the same index to respect locked container indexes
|
||||
self.containers_mut().remove(focused_idx);
|
||||
if self.resize_dimensions().get(focused_idx).is_some() {
|
||||
self.resize_dimensions_mut().remove(focused_idx);
|
||||
if self.resize_dimensions.get(focused_idx).is_some() {
|
||||
self.resize_dimensions.remove(focused_idx);
|
||||
}
|
||||
} else {
|
||||
container.load_focused_window();
|
||||
}
|
||||
|
||||
self.set_maximized_window(Option::from(window));
|
||||
self.set_maximized_window_restore_idx(Option::from(focused_idx));
|
||||
self.maximized_window = Option::from(window);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -1585,11 +1541,11 @@ impl Workspace {
|
||||
|
||||
pub fn reintegrate_maximized_window(&mut self) -> Result<()> {
|
||||
let restore_idx = self
|
||||
.maximized_window_restore_idx()
|
||||
.maximized_window_restore_idx
|
||||
.ok_or_eyre("there is no monocle restore index")?;
|
||||
|
||||
let window = self
|
||||
.maximized_window()
|
||||
.maximized_window
|
||||
.as_ref()
|
||||
.ok_or_eyre("there is no monocle container")?;
|
||||
|
||||
@@ -1613,8 +1569,8 @@ impl Workspace {
|
||||
.ok_or_eyre("there is no container")?
|
||||
.load_focused_window();
|
||||
|
||||
self.set_maximized_window(None);
|
||||
self.set_maximized_window_restore_idx(None);
|
||||
self.maximized_window = None;
|
||||
self.maximized_window_restore_idx = None;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1656,9 +1612,9 @@ impl Workspace {
|
||||
pub fn visible_windows(&self) -> Vec<Option<&Window>> {
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -1676,13 +1632,13 @@ impl Workspace {
|
||||
pub fn visible_window_details(&self) -> Vec<WindowDetails> {
|
||||
let mut vec: Vec<WindowDetails> = vec![];
|
||||
|
||||
if let Some(maximized) = self.maximized_window() {
|
||||
if let Ok(details) = (*maximized).try_into() {
|
||||
if let Some(maximized) = self.maximized_window {
|
||||
if let Ok(details) = (maximized).try_into() {
|
||||
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 Ok(details) = (*focused).try_into() {
|
||||
vec.push(details);
|
||||
@@ -1738,9 +1694,9 @@ mod tests {
|
||||
for i in 0..4 {
|
||||
let mut container = Container::default();
|
||||
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);
|
||||
}
|
||||
assert_eq!(ws.containers().len(), 4);
|
||||
@@ -1767,7 +1723,7 @@ mod tests {
|
||||
ws.focus_container(0);
|
||||
ws.new_container_for_window(Window::from(234));
|
||||
assert_eq!(
|
||||
ws.containers()[3].id().to_string(),
|
||||
ws.containers()[3].id.to_string(),
|
||||
state.get(&3).unwrap().to_string()
|
||||
);
|
||||
}
|
||||
@@ -1781,7 +1737,7 @@ mod tests {
|
||||
let mut container = Container::default();
|
||||
container.windows_mut().push_back(Window::from(i));
|
||||
if i == 1 {
|
||||
container.set_locked(true);
|
||||
container.locked = true;
|
||||
}
|
||||
ws.add_container_to_back(container);
|
||||
}
|
||||
@@ -1803,7 +1759,7 @@ mod tests {
|
||||
let mut container = Container::default();
|
||||
container.windows_mut().push_back(Window::from(i));
|
||||
if i == 1 {
|
||||
container.set_locked(true);
|
||||
container.locked = true;
|
||||
}
|
||||
ws.add_container_to_back(container);
|
||||
}
|
||||
@@ -1845,7 +1801,7 @@ mod tests {
|
||||
let mut container = Container::default();
|
||||
container.windows_mut().push_back(Window::from(i));
|
||||
if i == 4 {
|
||||
container.set_locked(true);
|
||||
container.locked = true;
|
||||
}
|
||||
ws.add_container_to_back(container);
|
||||
}
|
||||
@@ -2508,7 +2464,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user