diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 5e08b235..56ba101f 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -373,43 +373,6 @@ fn create_workspace( Workspace::new(workspace_handle, output.clone(), tiling, theme.clone()) } -fn move_workspace_to_group( - workspace: &mut Workspace, - group: &WorkspaceGroupHandle, - workspace_state: &mut WorkspaceUpdateGuard<'_, State>, -) { - let old_workspace_handle = workspace.handle; - workspace.handle = workspace_state - .create_workspace( - group, - if workspace.tiling_enabled { - TilingState::TilingEnabled - } else { - TilingState::FloatingOnly - }, - // TODO Set id for persistent workspaces - None, - ) - .unwrap(); - workspace_state.set_workspace_capabilities( - &workspace.handle, - WorkspaceCapabilities::Activate | WorkspaceCapabilities::SetTilingState, - ); - for window in workspace.mapped() { - for (surface, _) in window.windows() { - toplevel_leave_workspace(&surface, &old_workspace_handle); - toplevel_enter_workspace(&surface, &workspace.handle); - } - } - for window in workspace.minimized_windows.iter() { - for (surface, _) in window.window.windows() { - toplevel_leave_workspace(&surface, &old_workspace_handle); - toplevel_enter_workspace(&surface, &workspace.handle); - } - } - workspace_state.remove_workspace(old_workspace_handle); -} - /* We will probably need this again at some point fn merge_workspaces( mut workspace: Workspace, @@ -734,7 +697,8 @@ impl Workspaces { // Add `moved_workspaces` to set, and update output and index of workspaces for workspace in &mut moved_workspaces { - move_workspace_to_group(workspace, &set.group, workspace_state); + workspace_state.remove_workspace_state(&workspace.handle, WState::Active); + workspace_state.move_workspace_to_group(set.group, workspace.handle); } set.workspaces.extend(moved_workspaces); if set.workspaces.is_empty() { @@ -791,7 +755,8 @@ impl Workspaces { workspace_state.remove_workspace(workspace.handle); } else { // update workspace protocol state - move_workspace_to_group(&mut workspace, &workspace_group, workspace_state); + workspace_state.remove_workspace_state(&workspace.handle, WState::Active); + workspace_state.move_workspace_to_group(workspace_group, workspace.handle); // update mapping workspace.set_output(&new_output, false); @@ -862,7 +827,8 @@ impl Workspaces { .and_then(|set| set.remove_workspace(workspace_state, handle)) { let new_set = self.sets.get_mut(to).unwrap(); - move_workspace_to_group(&mut workspace, &new_set.group, workspace_state); + workspace_state.remove_workspace_state(&workspace.handle, WState::Active); + workspace_state.move_workspace_to_group(new_set.group, workspace.handle); workspace.set_output(to, true); workspace.refresh(); new_set.workspaces.insert(new_set.active + 1, workspace); diff --git a/src/wayland/protocols/workspace/mod.rs b/src/wayland/protocols/workspace/mod.rs index 18170d37..c8fb2f5d 100644 --- a/src/wayland/protocols/workspace/mod.rs +++ b/src/wayland/protocols/workspace/mod.rs @@ -395,6 +395,53 @@ where WORKSPACE_IDS.lock().unwrap().remove(&workspace.id); } + pub fn move_workspace_to_group( + &mut self, + group_handle: WorkspaceGroupHandle, + workspace_handle: WorkspaceHandle, + ) { + // Get index of new group + let Some(group_idx) = self.0.groups.iter().position(|g| g.id == group_handle.id) else { + // If the new group doesn't exist, we shouldn't remove the workspace from its old group + return; + }; + + // Find old group index, and remove the workspace + let Some((old_group_idx, workspace)) = + self.0.groups.iter_mut().enumerate().find_map(|(i, group)| { + let idx = group + .workspaces + .iter() + .position(|w| w.id == workspace_handle.id)?; + let workspace = group.workspaces.remove(idx); + Some((i, workspace)) + }) + else { + // Workspace not found in any group + return; + }; + + // Send `workspace_leave` for ever instance with old group, and `workspace_enter` for new + // one. + let old_group = &self.0.groups[old_group_idx]; + let new_group = &self.0.groups[group_idx]; + for instance in &workspace.ext_instances { + let manager = &instance.data::().unwrap().manager; + for group_instance in &old_group.ext_instances { + if *manager == group_instance.data::().unwrap().manager { + group_instance.workspace_leave(instance); + } + } + for group_instance in &new_group.ext_instances { + if *manager == group_instance.data::().unwrap().manager { + group_instance.workspace_enter(instance); + } + } + } + + self.0.groups[group_idx].workspaces.push(workspace); + } + pub fn workspace_belongs_to_group( &self, group: &WorkspaceGroupHandle,