feat: add invariant-safe window stacks
This commit is contained in:
1 parent
6060257ffe
commit
da4aaf9fb0
3 files changed
+327
-15
No files matched your search
@@ -165,12 +165,46 @@ impl WorkspaceSet {
|
||||
));
|
||||
}
|
||||
|
||||
if self.placement(window) == Some(WindowPlacement::Tiled) {
|
||||
self.active_mut().layout.activate_window(window)?;
|
||||
}
|
||||
self.active_mut().last_focused = Some(window);
|
||||
|
||||
debug_assert!(self.validate().is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn stack_window(
|
||||
&mut self,
|
||||
window: WindowId,
|
||||
target: WindowId,
|
||||
) -> Result<(), WorkspaceError> {
|
||||
let workspace = self
|
||||
.workspace_for_window(window)
|
||||
.ok_or(LayoutError::UnknownWindow(window))?;
|
||||
|
||||
if self.workspace_for_window(target) != Some(workspace) {
|
||||
return Err(WorkspaceError::InvalidState(
|
||||
"stack windows belong to different workspaces",
|
||||
));
|
||||
}
|
||||
if self.placement(window) != Some(WindowPlacement::Tiled)
|
||||
|| self.placement(target) != Some(WindowPlacement::Tiled)
|
||||
{
|
||||
return Err(WorkspaceError::InvalidState("stack window is not tiled"));
|
||||
}
|
||||
|
||||
let workspace = self
|
||||
.workspaces
|
||||
.get_mut(&workspace)
|
||||
.ok_or(WorkspaceError::InvalidState("window workspace is missing"))?;
|
||||
workspace.layout.stack_window(window, target)?;
|
||||
workspace.last_focused = Some(window);
|
||||
|
||||
debug_assert!(self.validate().is_ok());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn ensure_numeric(&mut self, index: u32) -> Result<WorkspaceId, WorkspaceError> {
|
||||
if index == 0 {
|
||||
return Err(WorkspaceError::InvalidNumericName(index));
|
||||
@@ -796,4 +830,28 @@ mod tests {
|
||||
);
|
||||
assert!(workspaces.validate().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stacking_tiled_windows_preserves_workspace_membership() {
|
||||
let mut workspaces = WorkspaceSet::default();
|
||||
workspaces
|
||||
.insert_window(WindowId(1), Axis::Horizontal, 0.5)
|
||||
.unwrap();
|
||||
workspaces
|
||||
.insert_window(WindowId(2), Axis::Horizontal, 0.5)
|
||||
.unwrap();
|
||||
workspaces.stack_window(WindowId(2), WindowId(1)).unwrap();
|
||||
|
||||
assert_eq!(workspaces.active().last_focused, Some(WindowId(2)));
|
||||
assert_eq!(
|
||||
workspaces
|
||||
.active()
|
||||
.layout
|
||||
.geometry(Rect::new(0.0, 0.0, 100.0, 80.0))
|
||||
.unwrap()
|
||||
.len(),
|
||||
1
|
||||
);
|
||||
assert!(workspaces.validate().is_ok());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user