From 4049c14311a83c384baee203654928f6e751bbe3 Mon Sep 17 00:00:00 2001 From: Lars Berger Date: Fri, 2 Aug 2024 14:42:11 +0800 Subject: [PATCH] feat: ensure monitors are sorted after display setting changes --- .../events/handle_display_settings_changed.rs | 7 +++- packages/wm/src/common/platform/platform.rs | 2 +- packages/wm/src/monitors/commands/mod.rs | 2 ++ .../wm/src/monitors/commands/sort_monitors.rs | 35 +++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 packages/wm/src/monitors/commands/sort_monitors.rs diff --git a/packages/wm/src/common/events/handle_display_settings_changed.rs b/packages/wm/src/common/events/handle_display_settings_changed.rs index 8aa48366d..637ba0048 100644 --- a/packages/wm/src/common/events/handle_display_settings_changed.rs +++ b/packages/wm/src/common/events/handle_display_settings_changed.rs @@ -7,7 +7,9 @@ use crate::{ traits::{CommonGetters, PositionGetters}, WindowContainer, }, - monitors::commands::{add_monitor, remove_monitor, update_monitor}, + monitors::commands::{ + add_monitor, remove_monitor, sort_monitors, update_monitor, + }, user_config::UserConfig, windows::traits::WindowGetters, wm_state::WmState, @@ -109,6 +111,9 @@ pub fn handle_display_settings_changed( } } + // Sort monitors by position. + sort_monitors(state.root_container.clone())?; + for window in state.windows() { // Display setting changes can spread windows out sporadically, so mark // all windows as needing a DPI adjustment (just in case). diff --git a/packages/wm/src/common/platform/platform.rs b/packages/wm/src/common/platform/platform.rs index 32f5e316a..985f8558e 100644 --- a/packages/wm/src/common/platform/platform.rs +++ b/packages/wm/src/common/platform/platform.rs @@ -63,7 +63,7 @@ impl Platform { pub fn sorted_monitors() -> anyhow::Result> { let monitors = native_monitor::available_monitors()?; - // Create a tuple of monitor and its rect. + // Create a tuple of monitors and their rects. let mut monitors_with_rect = monitors .into_iter() .map(|monitor| { diff --git a/packages/wm/src/monitors/commands/mod.rs b/packages/wm/src/monitors/commands/mod.rs index 81cc28266..63b053f11 100644 --- a/packages/wm/src/monitors/commands/mod.rs +++ b/packages/wm/src/monitors/commands/mod.rs @@ -1,7 +1,9 @@ mod add_monitor; mod remove_monitor; +mod sort_monitors; mod update_monitor; pub use add_monitor::*; pub use remove_monitor::*; +pub use sort_monitors::*; pub use update_monitor::*; diff --git a/packages/wm/src/monitors/commands/sort_monitors.rs b/packages/wm/src/monitors/commands/sort_monitors.rs new file mode 100644 index 000000000..d174a317b --- /dev/null +++ b/packages/wm/src/monitors/commands/sort_monitors.rs @@ -0,0 +1,35 @@ +use crate::containers::{ + traits::{CommonGetters, PositionGetters}, + RootContainer, +}; + +/// Sorts the root container's monitors from left-to-right and +/// top-to-bottom. +pub fn sort_monitors(root: RootContainer) -> anyhow::Result<()> { + let monitors = root.monitors(); + + // Create a tuple of monitors and their rects. + let mut monitors_with_rect = monitors + .into_iter() + .map(|monitor| { + let rect = monitor.to_rect()?.clone(); + anyhow::Ok((monitor, rect)) + }) + .try_collect::>()?; + + // Sort monitors from left-to-right, top-to-bottom. + monitors_with_rect.sort_by(|(_, rect_a), (_, rect_b)| { + if rect_a.x() == rect_b.x() { + rect_a.y().cmp(&rect_b.y()) + } else { + rect_a.x().cmp(&rect_b.x()) + } + }); + + *root.borrow_children_mut() = monitors_with_rect + .into_iter() + .map(|(monitor, _)| monitor.into()) + .collect(); + + Ok(()) +}