feat(wm): dynamic lookup for container behaviour

This commit adds a dynamic lookup method for the
window_container_behaviour configuration option.  Previously if the
behaviour was set to Append, and the workspace did not have any
containers, an error would be logged.

Now, in the same situation, the behaviour will be dynamically switched
to Create when there are no containers on a workspace, and subsequent
windows will be handled with the Append behaviour if set.

This commit also makes some tweaks to ensure that when a windows in a
container stack are closed, the container itself will remain focused if
it has at least one remaining window.

resolve #889
This commit is contained in:
LGUG2Z
2024-06-26 11:45:47 -07:00
parent 1d0ac9b555
commit b985659e30
3 changed files with 28 additions and 4 deletions

View File

@@ -329,7 +329,8 @@ impl WindowManager {
}
if proceed {
let behaviour = self.window_container_behaviour;
let behaviour =
self.window_container_behaviour(focused_monitor_idx, focused_workspace_idx);
let workspace = self.focused_workspace_mut()?;
let workspace_contains_window = workspace.contains_window(window.hwnd);
let monocle_container = workspace.monocle_container().clone();
@@ -399,10 +400,12 @@ impl WindowManager {
.monitor_idx_from_current_pos()
.ok_or_else(|| anyhow!("cannot get monitor idx from current position"))?;
let new_window_behaviour = self.window_container_behaviour;
let focused_monitor_idx = self.focused_monitor_idx();
let focused_workspace_idx = self.focused_workspace_idx().unwrap_or_default();
let window_container_behaviour =
self.window_container_behaviour(focused_monitor_idx, focused_workspace_idx);
let workspace = self.focused_workspace_mut()?;
let focused_container_idx = workspace.focused_container_idx();
let new_position = WindowsApi::window_rect(window.hwnd())?;
let old_position = *workspace
@@ -519,7 +522,7 @@ impl WindowManager {
// Here we handle a simple move on the same monitor which is treated as
// a container swap
} else {
match new_window_behaviour {
match window_container_behaviour {
WindowContainerBehaviour::Create => {
match workspace.container_idx_from_current_point() {
Some(target_idx) => {

View File

@@ -303,6 +303,24 @@ impl WindowManager {
StaticConfig::reload(pathbuf, self)
}
pub fn window_container_behaviour(
&self,
monitor_idx: usize,
workspace_idx: usize,
) -> WindowContainerBehaviour {
if let Some(monitor) = self.monitors().get(monitor_idx) {
if let Some(workspace) = monitor.workspaces().get(workspace_idx) {
return if workspace.containers().is_empty() {
WindowContainerBehaviour::Create
} else {
self.window_container_behaviour
};
}
}
WindowContainerBehaviour::Create
}
#[tracing::instrument(skip(self))]
pub fn watch_configuration(&mut self, enable: bool) -> Result<()> {
let config_pwsh = HOME_DIR.join("komorebi.ps1");

View File

@@ -748,6 +748,9 @@ impl Workspace {
self.focus_previous_container();
} else {
container.load_focused_window();
if let Some(window) = container.focused_window() {
window.focus(false)?;
}
}
Ok(())