Skip to content

Commit

Permalink
feat(wm): add monitor_usr_idx_map to window_manager
Browse files Browse the repository at this point in the history
This commit creates a new field on the `WindowManager` called
`monitor_usr_idx_map` which contains a map of user intended index for
monitors to their actual monitors' index. It will be rebuilt on
`load_monitor_information` by taking into account the
`display_index_preferences`.
  • Loading branch information
alex-ds13 committed Jan 29, 2025
1 parent f91a34c commit 941f3db
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
1 change: 1 addition & 0 deletions komorebi/src/static_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,7 @@ impl StaticConfig {

let mut wm = WindowManager {
monitors: Ring::default(),
monitor_usr_idx_map: HashMap::new(),
incoming_events: incoming,
command_listener: listener,
is_paused: false,
Expand Down
6 changes: 5 additions & 1 deletion komorebi/src/window_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ use crate::WORKSPACE_MATCHING_RULES;
#[derive(Debug)]
pub struct WindowManager {
pub monitors: Ring<Monitor>,
pub monitor_usr_idx_map: HashMap<usize, usize>,
pub incoming_events: Receiver<WindowManagerEvent>,
pub command_listener: UnixListener,
pub is_paused: bool,
Expand All @@ -122,6 +123,7 @@ pub struct WindowManager {
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct State {
pub monitors: Ring<Monitor>,
pub monitor_usr_idx_map: HashMap<usize, usize>,
pub is_paused: bool,
pub resize_delta: i32,
pub new_window_behaviour: WindowContainerBehaviour,
Expand Down Expand Up @@ -283,6 +285,7 @@ impl From<&WindowManager> for State {
fn from(wm: &WindowManager) -> Self {
Self {
monitors: wm.monitors.clone(),
monitor_usr_idx_map: wm.monitor_usr_idx_map.clone(),
is_paused: wm.is_paused,
work_area_offset: wm.work_area_offset,
resize_delta: wm.resize_delta,
Expand Down Expand Up @@ -343,6 +346,7 @@ impl WindowManager {

Ok(Self {
monitors: Ring::default(),
monitor_usr_idx_map: HashMap::new(),
incoming_events: incoming,
command_listener: listener,
is_paused: false,
Expand All @@ -366,7 +370,7 @@ impl WindowManager {
#[tracing::instrument(skip(self))]
pub fn init(&mut self) -> Result<()> {
tracing::info!("initialising");
WindowsApi::load_monitor_information(&mut self.monitors)?;
WindowsApi::load_monitor_information(self)?;
WindowsApi::load_workspace_information(&mut self.monitors)
}

Expand Down
40 changes: 39 additions & 1 deletion komorebi/src/windows_api.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::collections::VecDeque;
use std::convert::TryFrom;
use std::ffi::c_void;
Expand Down Expand Up @@ -143,6 +144,7 @@ use crate::ring::Ring;
use crate::set_window_position::SetWindowPosition;
use crate::windows_callbacks;
use crate::Window;
use crate::WindowManager;
use crate::DISPLAY_INDEX_PREFERENCES;
use crate::MONITOR_INDEX_PREFERENCES;

Expand Down Expand Up @@ -252,7 +254,10 @@ impl WindowsApi {
.collect::<Vec<_>>())
}

pub fn load_monitor_information(monitors: &mut Ring<Monitor>) -> Result<()> {
pub fn load_monitor_information(wm: &mut WindowManager) -> Result<()> {
let monitors = &mut wm.monitors;
let monitor_usr_idx_map = &mut wm.monitor_usr_idx_map;

'read: for display in win32_display_data::connected_displays_all().flatten() {
let path = display.device_path.clone();

Expand Down Expand Up @@ -326,6 +331,39 @@ impl WindowsApi {
.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.lock() {
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
}) {
monitor_usr_idx_map.insert(*index, m_idx);
added_monitor_idxs.push(m_idx);
}
}

let max_usr_idx = monitors
.elements()
.len()
.max(monitor_usr_idx_map.keys().max().map_or(0, |v| *v));

let available_usr_idxs = (0..max_usr_idx)
.filter(|i| !monitor_usr_idx_map.contains_key(i))
.collect::<Vec<_>>();

let not_added_monitor_idxs = (0..monitors.elements().len())
.filter(|i| !added_monitor_idxs.contains(i))
.collect::<Vec<_>>();

for i in not_added_monitor_idxs {
if let Some(next_usr_idx) = available_usr_idxs.first() {
monitor_usr_idx_map.insert(*next_usr_idx, i);
} else if let Some(idx) = monitor_usr_idx_map.keys().max() {
monitor_usr_idx_map.insert(*idx, i);
}
}

Ok(())
}

Expand Down

0 comments on commit 941f3db

Please sign in to comment.