mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-28 04:11:29 +01:00
feat(wm): introduce lazy monitor cache
This commit introduces a lazy monitor cache that only gets populated with a monitor has been disconnected, before the monitor is removed from the state. If and when the same monitor is reconnected and identified by its size on the virtual screen, the cached monitor state will be used to repopulate layout options, avoiding a potentially expensive full configuration reload. re #275
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::VecDeque;
|
||||
use std::io::ErrorKind;
|
||||
use std::num::NonZeroUsize;
|
||||
@@ -54,6 +55,7 @@ use crate::WORKSPACE_RULES;
|
||||
#[derive(Debug)]
|
||||
pub struct WindowManager {
|
||||
pub monitors: Ring<Monitor>,
|
||||
pub monitor_cache: HashMap<usize, Monitor>,
|
||||
pub incoming_events: Arc<Mutex<Receiver<WindowManagerEvent>>>,
|
||||
pub command_listener: UnixListener,
|
||||
pub is_paused: bool,
|
||||
@@ -166,6 +168,7 @@ impl WindowManager {
|
||||
|
||||
Ok(Self {
|
||||
monitors: Ring::default(),
|
||||
monitor_cache: HashMap::new(),
|
||||
incoming_events: incoming,
|
||||
command_listener: listener,
|
||||
is_paused: false,
|
||||
@@ -341,12 +344,15 @@ impl WindowManager {
|
||||
}
|
||||
|
||||
let mut orphaned_containers = vec![];
|
||||
let mut invalid_indices = vec![];
|
||||
|
||||
for invalid in self
|
||||
for (i, invalid) in self
|
||||
.monitors()
|
||||
.iter()
|
||||
.filter(|m| !valid_names.contains(m.name()))
|
||||
.enumerate()
|
||||
.filter(|(_, m)| !valid_names.contains(m.name()))
|
||||
{
|
||||
invalid_indices.push(i);
|
||||
for workspace in invalid.workspaces() {
|
||||
for container in workspace.containers() {
|
||||
// Save the orphaned containers from an invalid monitor
|
||||
@@ -356,6 +362,12 @@ impl WindowManager {
|
||||
}
|
||||
}
|
||||
|
||||
for i in invalid_indices {
|
||||
if let Some(monitor) = self.monitors().get(i) {
|
||||
self.monitor_cache.insert(i, monitor.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any invalid monitors from our state
|
||||
self.monitors_mut()
|
||||
.retain(|m| valid_names.contains(m.name()));
|
||||
@@ -411,9 +423,41 @@ impl WindowManager {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::needless_collect)]
|
||||
let old_sizes = self
|
||||
.monitors()
|
||||
.iter()
|
||||
.map(Monitor::size)
|
||||
.copied()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Check for and add any new monitors that may have been plugged in
|
||||
WindowsApi::load_monitor_information(&mut self.monitors)?;
|
||||
|
||||
let mut check_cache = vec![];
|
||||
|
||||
for (i, m) in self.monitors().iter().enumerate() {
|
||||
if !old_sizes.contains(m.size()) {
|
||||
check_cache.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
for i in check_cache {
|
||||
if let Some(cached) = self.monitor_cache.get(&i).cloned() {
|
||||
if let Some(monitor) = self.monitors_mut().get_mut(i) {
|
||||
for (w_idx, workspace) in monitor.workspaces_mut().iter_mut().enumerate() {
|
||||
if let Some(cached_workspace) = cached.workspaces().get(w_idx) {
|
||||
workspace.set_layout(cached_workspace.layout().clone());
|
||||
workspace.set_layout_rules(cached_workspace.layout_rules().clone());
|
||||
workspace.set_layout_flip(cached_workspace.layout_flip());
|
||||
workspace.set_workspace_padding(cached_workspace.workspace_padding());
|
||||
workspace.set_container_padding(cached_workspace.container_padding());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let final_count = self.monitors().len();
|
||||
if after_count != final_count {
|
||||
self.retile_all(true)?;
|
||||
|
||||
Reference in New Issue
Block a user