Unify per-monitor workspace numbering and lifecycle policy
This commit is contained in:
1 parent
07bda5a21c
commit
1441875096
20 files changed
+707
-316
No files matched your search
@@ -313,7 +313,7 @@ impl Ferese {
|
||||
})
|
||||
.collect::<HashSet<_>>();
|
||||
self.unmap_invisible_windows(&visible_windows);
|
||||
self.prune_empty_workspaces(&visible);
|
||||
self.reconcile_workspaces(&visible);
|
||||
self.send_shell_snapshots();
|
||||
active_animation = true;
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ impl Ferese {
|
||||
visible
|
||||
}
|
||||
|
||||
pub(super) fn prune_empty_workspaces(&mut self, visible: &HashSet<WorkspaceId>) {
|
||||
let mut protected = visible.clone();
|
||||
protected.extend(self.output_workspaces.history_workspaces());
|
||||
for workspace in self.workspaces.prune_empty(&protected) {
|
||||
self.output_workspaces.forget_workspace(workspace);
|
||||
pub(super) fn reconcile_workspaces(&mut self, visible: &HashSet<WorkspaceId>) {
|
||||
for workspace in self
|
||||
.output_workspaces
|
||||
.reconcile_workspaces(&mut self.workspaces, visible)
|
||||
{
|
||||
self.viewport_animations.remove(&workspace);
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ impl Ferese {
|
||||
pub fn relayout(&mut self) {
|
||||
self.refresh_input_capture_zones();
|
||||
let visible_workspaces = self.visible_workspace_ids();
|
||||
self.prune_empty_workspaces(&visible_workspaces);
|
||||
self.reconcile_workspaces(&visible_workspaces);
|
||||
if self.session_lock.active {
|
||||
self.configure_lock_surfaces();
|
||||
}
|
||||
|
||||
@@ -394,16 +394,13 @@ impl Ferese {
|
||||
slide_direction: Option<SwipeDirection>,
|
||||
auto_back_and_forth: bool,
|
||||
) {
|
||||
let workspace = match self.workspaces.ensure_numeric(index) {
|
||||
Ok(workspace) => workspace,
|
||||
Err(error) => {
|
||||
tracing::error!(%error, index, "failed to switch workspace");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let Some(output) = self.output_workspaces.focused_output() else {
|
||||
return;
|
||||
};
|
||||
let Some(workspace) = self.output_workspaces.workspace_at(&self.workspaces, output, index) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let previous = self.output_workspaces.active_workspace(output);
|
||||
let owner = match self
|
||||
.output_workspaces
|
||||
@@ -526,26 +523,23 @@ impl Ferese {
|
||||
let Some(window) = self.focused_window else {
|
||||
return;
|
||||
};
|
||||
let Some(output) = self.output_workspaces.focused_output() else {
|
||||
return;
|
||||
};
|
||||
let Some(destination) = self.output_workspaces.workspace_at(&self.workspaces, output, index) else {
|
||||
return;
|
||||
};
|
||||
let axis = self
|
||||
.output_bounds()
|
||||
.and_then(|bounds| {
|
||||
let workspace = self.workspaces.ensure_numeric(index).ok()?;
|
||||
let target = self.workspaces.workspace(workspace)?;
|
||||
let target = self.workspaces.workspace(destination)?;
|
||||
target.layout.automatic_axis(target.last_focused, bounds).ok()
|
||||
})
|
||||
.unwrap_or(Axis::Horizontal);
|
||||
|
||||
let destination = match self.workspaces.move_window_to_numeric(window, index, axis, 0.5) {
|
||||
Ok(destination) => destination,
|
||||
Err(error) => {
|
||||
tracing::error!(%error, ?window, index, "failed to move window to workspace");
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let Some(output) = self.output_workspaces.focused_output()
|
||||
&& let Err(error) = self.output_workspaces.assign_workspace(output, destination)
|
||||
{
|
||||
tracing::error!(%error, ?destination, "failed to assign destination workspace");
|
||||
if let Err(error) = self.workspaces.move_window_to_workspace(window, destination, axis, 0.5) {
|
||||
tracing::error!(%error, ?window, index, "failed to move window to workspace");
|
||||
return;
|
||||
}
|
||||
|
||||
self.focused_window = self.workspaces.active().last_focused;
|
||||
|
||||
@@ -15,25 +15,23 @@ impl Ferese {
|
||||
self.next_output_id = self.next_output_id.saturating_add(1);
|
||||
id
|
||||
});
|
||||
let fallback_workspace = (1..)
|
||||
.find_map(|index| {
|
||||
let workspace = self.workspaces.ensure_numeric(index).ok()?;
|
||||
self.output_workspaces
|
||||
.output_for_workspace(workspace)
|
||||
.is_none()
|
||||
.then_some(workspace)
|
||||
})
|
||||
.expect("numeric workspaces are inexhaustible");
|
||||
let fallback_workspace = self
|
||||
.workspaces
|
||||
.iter()
|
||||
.filter(|workspace| self.output_workspaces.output_for_workspace(workspace.id).is_none())
|
||||
.map(|workspace| workspace.id)
|
||||
.min_by_key(|id| id.0)
|
||||
.unwrap_or_else(|| self.workspaces.create_workspace());
|
||||
let geometry = OutputGeometry::new(geometry.loc.x, geometry.loc.y, geometry.size.w, geometry.size.h);
|
||||
|
||||
let registration = self.output_workspaces.connect(output_id, geometry, fallback_workspace);
|
||||
|
||||
match registration {
|
||||
Ok(workspace) => {
|
||||
Ok(_) => {
|
||||
self.output_ids.insert(output.clone(), output_id);
|
||||
if self.output_workspaces.focused_output() == Some(output_id) {
|
||||
self.activate_output_workspace(output_id, workspace);
|
||||
}
|
||||
self.restore_output_focus();
|
||||
let visible = self.visible_workspace_ids();
|
||||
self.reconcile_workspaces(&visible);
|
||||
self.send_shell_snapshots();
|
||||
}
|
||||
Err(error) => {
|
||||
|
||||
@@ -287,10 +287,15 @@ impl Ferese {
|
||||
.automatic_axis(self.focused_window, bounds)
|
||||
.unwrap_or(Axis::Horizontal);
|
||||
|
||||
if let Some(workspace) = rule.workspace
|
||||
&& let Err(error) = self.workspaces.move_window_to_numeric(id, workspace, axis, 0.5)
|
||||
if let Some(index) = rule.workspace
|
||||
&& let Some(output) = self
|
||||
.workspaces
|
||||
.workspace_for_window(id)
|
||||
.and_then(|workspace| self.output_workspaces.output_for_workspace(workspace))
|
||||
&& let Some(workspace) = self.output_workspaces.workspace_at(&self.workspaces, output, index)
|
||||
&& let Err(error) = self.workspaces.move_window_to_workspace(id, workspace, axis, 0.5)
|
||||
{
|
||||
tracing::warn!(%error, ?id, workspace, "failed to apply window workspace rule");
|
||||
tracing::warn!(%error, ?id, ?workspace, "failed to apply window workspace rule");
|
||||
}
|
||||
|
||||
let bounds = self.floating_bounds_for_window(id).unwrap_or(bounds);
|
||||
|
||||
Reference in new issue
Block a user