diff --git a/komorebi/src/border_manager/mod.rs b/komorebi/src/border_manager/mod.rs index 0d7649b9..b50abe3e 100644 --- a/komorebi/src/border_manager/mod.rs +++ b/komorebi/src/border_manager/mod.rs @@ -741,8 +741,8 @@ pub fn handle_notifications(wm: Arc>) -> 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.to_hmonitor() + && WindowsApi::is_zoomed(foreground_hwnd); if is_maximized { tracing::trace!( diff --git a/komorebi/src/monitor.rs b/komorebi/src/monitor.rs index 6a769379..6e63886e 100644 --- a/komorebi/src/monitor.rs +++ b/komorebi/src/monitor.rs @@ -13,6 +13,7 @@ use crate::border_manager::BORDER_OFFSET; use crate::border_manager::BORDER_WIDTH; use crate::core::Rect; use crate::windows_backend::backend; +use komorebi_backend::MonitorId; use komorebi_backend::WindowId; use crate::DEFAULT_CONTAINER_PADDING; @@ -29,10 +30,28 @@ use crate::workspace::Workspace; use crate::workspace::WorkspaceGlobals; use crate::workspace::WorkspaceLayer; +/// `Monitor::id` is a `MonitorId` in Rust and the same plain JSON number as the `isize` handle it +/// was before: `komorebic state` and the saved state files do not change. +mod hmonitor_json { + use komorebi_backend::MonitorId; + use serde::Deserialize; + use serde::Deserializer; + use serde::Serializer; + + pub fn serialize(id: &MonitorId, serializer: S) -> Result { + serializer.serialize_i64(id.to_hmonitor() as i64) + } + + pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result { + Ok(MonitorId::from_hmonitor(isize::deserialize(deserializer)?)) + } +} #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Monitor { - pub id: isize, + #[serde(with = "hmonitor_json")] + #[cfg_attr(feature = "schemars", schemars(with = "isize"))] + pub id: MonitorId, pub name: String, pub device: String, pub device_id: String, @@ -67,7 +86,7 @@ pub struct MonitorInformation { impl From<&Monitor> for MonitorInformation { fn from(monitor: &Monitor) -> Self { Self { - id: monitor.id, + id: monitor.id.to_hmonitor(), name: monitor.name.clone(), device: monitor.device.clone(), device_id: monitor.device_id.clone(), @@ -90,7 +109,7 @@ pub fn new( workspaces.elements_mut().push_back(Workspace::default()); Monitor { - id, + id: MonitorId::from_hmonitor(id), name, device, device_id, @@ -133,7 +152,7 @@ impl Monitor { pub fn placeholder() -> Self { Self { - id: 0, + id: MonitorId(0), name: "PLACEHOLDER".to_string(), device: "".to_string(), device_id: "".to_string(), @@ -171,7 +190,7 @@ impl Monitor { pub fn load_focused_workspace(&mut self, mouse_follows_focus: bool) -> eyre::Result<()> { let focused_idx = self.focused_workspace_idx(); - let hmonitor = self.id; + let hmonitor = self.id.to_hmonitor(); let monitor_wp = self.wallpaper.clone(); for (i, workspace) in self.workspaces_mut().iter_mut().enumerate() { if i == focused_idx { diff --git a/komorebi/src/monitor_reconciliator/mod.rs b/komorebi/src/monitor_reconciliator/mod.rs index 582b0b98..0974a667 100644 --- a/komorebi/src/monitor_reconciliator/mod.rs +++ b/komorebi/src/monitor_reconciliator/mod.rs @@ -293,7 +293,7 @@ where let mut should_update = false; // Update work areas as necessary - if let Ok(reference) = WindowsApi::monitor(monitor.id) + if let Ok(reference) = WindowsApi::monitor(monitor.id.to_hmonitor()) && reference.work_area_size != monitor.work_area_size { monitor.work_area_size = Rect { @@ -325,7 +325,7 @@ where let mut should_update = false; // Update sizes and work areas as necessary - if let Ok(reference) = WindowsApi::monitor(monitor.id) { + if let Ok(reference) = WindowsApi::monitor(monitor.id.to_hmonitor()) { if reference.work_area_size != monitor.work_area_size { monitor.work_area_size = Rect { left: reference.work_area_size.left, @@ -1275,7 +1275,7 @@ mod tests { assert_eq!(monitors.len(), 1, "Expected one monitor"); // hmonitor - assert_eq!(monitors[0].id, 1); + assert_eq!(monitors[0].id.to_hmonitor(), 1); // device name assert_eq!(monitors[0].name, String::from("DISPLAY1")); diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 47183dde..8f4486ab 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -771,7 +771,7 @@ impl WindowManager { let focused_workspace_idx = monitor.focused_workspace_idx(); monitor.update_workspace_globals(focused_workspace_idx, offset); - let hmonitor = monitor.id; + let hmonitor = monitor.id.to_hmonitor(); let monitor_wp = monitor.wallpaper.clone(); let workspace = monitor .focused_workspace_mut() @@ -1572,7 +1572,7 @@ impl WindowManager { .get_mut(monitor_idx) .ok_or_eyre("there is no monitor")?; - let hmonitor = monitor.id; + let hmonitor = monitor.id.to_hmonitor(); let monitor_wp = monitor.wallpaper.clone(); let workspace = monitor @@ -2589,12 +2589,14 @@ impl WindowManager { let a = self .focused_monitor() .ok_or_eyre("there is no monitor focused monitor")? - .id; + .id + .to_hmonitor(); let b = self .monitors_mut() .get_mut(origin_monitor_idx) .ok_or_eyre("there is no monitor at this index")? - .id; + .id + .to_hmonitor(); if !WindowsApi::monitors_have_same_dpi(a, b)? { self.update_focused_workspace(self.mouse_follows_focus, true)?; @@ -3766,7 +3768,7 @@ impl WindowManager { let hmonitor = WindowsApi::monitor_from_window(window.hwnd); for (i, monitor) in self.monitors().iter().enumerate() { - if monitor.id == hmonitor { + if monitor.id.to_hmonitor() == hmonitor { return Option::from(i); } } @@ -3789,7 +3791,7 @@ impl WindowManager { let hmonitor = WindowsApi::monitor_from_point(WindowsApi::cursor_pos().ok()?); for (i, monitor) in self.monitors().iter().enumerate() { - if monitor.id == hmonitor { + if monitor.id.to_hmonitor() == hmonitor { return Option::from(i); } } diff --git a/komorebi/src/windows_backend.rs b/komorebi/src/windows_backend.rs index 640fca5d..762c0a86 100644 --- a/komorebi/src/windows_backend.rs +++ b/komorebi/src/windows_backend.rs @@ -110,7 +110,7 @@ impl Backend for WindowsBackend { .map(|(_, hmonitor)| { let monitor = WindowsApi::monitor(hmonitor).map_err(platform)?; Ok(MonitorInfo { - id: MonitorId::from_hmonitor(monitor.id), + id: monitor.id, size: monitor.size, work_area: monitor.work_area_size, name: Some(monitor.name),