Skip to content

Commit

Permalink
feat: sort workspaces by config index
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger committed Jul 30, 2024
1 parent 99b7b38 commit ab3f1d3
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 19 deletions.
15 changes: 15 additions & 0 deletions packages/wm/src/common/commands/reload_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::Context;
use tracing::{info, warn};

use crate::{
common::vec_deque_ext::VecDequeExt,
containers::traits::{CommonGetters, TilingSizeGetters},
user_config::{ParsedConfig, UserConfig, WindowRuleEvent},
windows::{commands::run_window_rules, traits::WindowGetters},
Expand Down Expand Up @@ -92,6 +93,20 @@ fn update_workspace_configs(
if *workspace_config != workspace.config() {
workspace.set_config(workspace_config.clone());

let mut workspaces = monitor.workspaces();
config.sort_workspaces(&mut workspaces);

let target_index = workspaces
.iter()
.position(|sorted_workspace| {
sorted_workspace.id() == workspace.id()
})
.context("Failed to get workspace target index.")?;

monitor
.borrow_children_mut()
.shift_to_index(target_index, workspace.clone().into());

state.emit_event(WmEvent::WorkspaceUpdated {
updated_workspace: workspace.to_dto()?,
});
Expand Down
7 changes: 2 additions & 5 deletions packages/wm/src/monitors/commands/remove_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,8 @@ pub fn remove_monitor(
.context("No target monitor to move workspaces.")?;

// Avoid moving empty workspaces.
let workspaces_to_move = monitor
.children()
.into_iter()
.filter_map(|container| container.as_workspace().cloned())
.filter(|workspace| {
let workspaces_to_move =
monitor.workspaces().into_iter().filter(|workspace| {
workspace.has_children() || workspace.config().keep_alive
});

Expand Down
8 changes: 8 additions & 0 deletions packages/wm/src/monitors/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ impl Monitor {
.and_then(|child| child.as_workspace().cloned())
}

pub fn workspaces(&self) -> Vec<Workspace> {
self
.children()
.into_iter()
.filter_map(|container| container.as_workspace().cloned())
.collect::<Vec<_>>()
}

/// Whether there is a difference in DPI between this monitor and the
/// parent monitor of another container.
pub fn has_dpi_difference(
Expand Down
17 changes: 17 additions & 0 deletions packages/wm/src/user_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,23 @@ impl UserConfig {
.or(inactive_configs.first())
.cloned()
}

pub fn workspace_config_index(
&self,
workspace_name: &str,
) -> Option<usize> {
self
.value
.workspaces
.iter()
.position(|config| config.name == workspace_name)
}

pub fn sort_workspaces(&self, workspaces: &mut Vec<Workspace>) {
workspaces.sort_by_key(|workspace| {
self.workspace_config_index(&workspace.config().name)
});
}
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down
16 changes: 4 additions & 12 deletions packages/wm/src/wm_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,30 +154,22 @@ impl WmState {
.root_container
.children()
.iter()
.filter_map(|c| c.as_monitor().cloned())
.filter_map(|container| container.as_monitor().cloned())
.collect()
}

pub fn workspaces(&self) -> Vec<Workspace> {
self
.monitors()
.iter()
.flat_map(|c| c.children())
.filter_map(|c| c.as_workspace().cloned())
.flat_map(|monitor| monitor.workspaces())
.collect()
}

/// Gets workspaces sorted by their position in the user config.
pub fn sorted_workspaces(&self, config: &UserConfig) -> Vec<Workspace> {
let workspace_configs = &config.value.workspaces;
let mut workspaces = self.workspaces();

workspaces.sort_by_key(|workspace| {
workspace_configs
.iter()
.position(|config| config.name == workspace.config().name)
});

config.sort_workspaces(&mut workspaces);
workspaces
}

Expand Down Expand Up @@ -210,7 +202,7 @@ impl WmState {
self
.monitors()
.into_iter()
.find(|m| m.native() == *native_monitor)
.find(|monitor| monitor.native() == *native_monitor)
}

/// Gets the closest monitor in a given direction.
Expand Down
17 changes: 15 additions & 2 deletions packages/wm/src/workspaces/commands/activate_workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use anyhow::Context;

use crate::{
common::TilingDirection,
containers::{commands::attach_container, traits::PositionGetters},
containers::{
commands::attach_container,
traits::{CommonGetters, PositionGetters},
},
monitors::Monitor,
user_config::{UserConfig, WorkspaceConfig},
wm_event::WmEvent,
Expand Down Expand Up @@ -36,11 +39,21 @@ pub fn activate_workspace(
tiling_direction,
);

// Get the existing workspaces + the new workspace, and sort them.
let mut workspaces = target_monitor.workspaces();
workspaces.extend([workspace.clone()]);
config.sort_workspaces(&mut workspaces);

let target_index = workspaces
.iter()
.position(|sorted_workspace| sorted_workspace.id() == workspace.id())
.context("Failed to get workspace target index.")?;

// Attach the created workspace to the specified monitor.
attach_container(
&workspace.clone().into(),
&target_monitor.clone().into(),
None,
Some(target_index),
)?;

state.emit_event(WmEvent::WorkspaceActivated {
Expand Down

0 comments on commit ab3f1d3

Please sign in to comment.