Skip to content

Commit d1f4e7b

Browse files
committed
protocols/workspace: Make move_workspace_to_group move existing handle
The older protocol didn't have a way to do this, but ext-workspace-v1 supports it. And it should be the correct way to do things.
1 parent e944ee9 commit d1f4e7b

File tree

2 files changed

+53
-40
lines changed

2 files changed

+53
-40
lines changed

src/shell/mod.rs

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -373,43 +373,6 @@ fn create_workspace(
373373
Workspace::new(workspace_handle, output.clone(), tiling, theme.clone())
374374
}
375375

376-
fn move_workspace_to_group(
377-
workspace: &mut Workspace,
378-
group: &WorkspaceGroupHandle,
379-
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
380-
) {
381-
let old_workspace_handle = workspace.handle;
382-
workspace.handle = workspace_state
383-
.create_workspace(
384-
group,
385-
if workspace.tiling_enabled {
386-
TilingState::TilingEnabled
387-
} else {
388-
TilingState::FloatingOnly
389-
},
390-
// TODO Set id for persistent workspaces
391-
None,
392-
)
393-
.unwrap();
394-
workspace_state.set_workspace_capabilities(
395-
&workspace.handle,
396-
WorkspaceCapabilities::Activate | WorkspaceCapabilities::SetTilingState,
397-
);
398-
for window in workspace.mapped() {
399-
for (surface, _) in window.windows() {
400-
toplevel_leave_workspace(&surface, &old_workspace_handle);
401-
toplevel_enter_workspace(&surface, &workspace.handle);
402-
}
403-
}
404-
for window in workspace.minimized_windows.iter() {
405-
for (surface, _) in window.window.windows() {
406-
toplevel_leave_workspace(&surface, &old_workspace_handle);
407-
toplevel_enter_workspace(&surface, &workspace.handle);
408-
}
409-
}
410-
workspace_state.remove_workspace(old_workspace_handle);
411-
}
412-
413376
/* We will probably need this again at some point
414377
fn merge_workspaces(
415378
mut workspace: Workspace,
@@ -734,7 +697,8 @@ impl Workspaces {
734697

735698
// Add `moved_workspaces` to set, and update output and index of workspaces
736699
for workspace in &mut moved_workspaces {
737-
move_workspace_to_group(workspace, &set.group, workspace_state);
700+
workspace_state.remove_workspace_state(&workspace.handle, WState::Active);
701+
workspace_state.move_workspace_to_group(set.group, workspace.handle);
738702
}
739703
set.workspaces.extend(moved_workspaces);
740704
if set.workspaces.is_empty() {
@@ -791,7 +755,8 @@ impl Workspaces {
791755
workspace_state.remove_workspace(workspace.handle);
792756
} else {
793757
// update workspace protocol state
794-
move_workspace_to_group(&mut workspace, &workspace_group, workspace_state);
758+
workspace_state.remove_workspace_state(&workspace.handle, WState::Active);
759+
workspace_state.move_workspace_to_group(workspace_group, workspace.handle);
795760

796761
// update mapping
797762
workspace.set_output(&new_output, false);
@@ -862,7 +827,8 @@ impl Workspaces {
862827
.and_then(|set| set.remove_workspace(workspace_state, handle))
863828
{
864829
let new_set = self.sets.get_mut(to).unwrap();
865-
move_workspace_to_group(&mut workspace, &new_set.group, workspace_state);
830+
workspace_state.remove_workspace_state(&workspace.handle, WState::Active);
831+
workspace_state.move_workspace_to_group(new_set.group, workspace.handle);
866832
workspace.set_output(to, true);
867833
workspace.refresh();
868834
new_set.workspaces.insert(new_set.active + 1, workspace);

src/wayland/protocols/workspace/mod.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,53 @@ where
395395
WORKSPACE_IDS.lock().unwrap().remove(&workspace.id);
396396
}
397397

398+
pub fn move_workspace_to_group(
399+
&mut self,
400+
group_handle: WorkspaceGroupHandle,
401+
workspace_handle: WorkspaceHandle,
402+
) {
403+
// Get index of new group
404+
let Some(group_idx) = self.0.groups.iter().position(|g| g.id == group_handle.id) else {
405+
// If the new group doesn't exist, we shouldn't remove the workspace from its old group
406+
return;
407+
};
408+
409+
// Find old group index, and remove the workspace
410+
let Some((old_group_idx, workspace)) =
411+
self.0.groups.iter_mut().enumerate().find_map(|(i, group)| {
412+
let idx = group
413+
.workspaces
414+
.iter()
415+
.position(|w| w.id == workspace_handle.id)?;
416+
let workspace = group.workspaces.remove(idx);
417+
Some((i, workspace))
418+
})
419+
else {
420+
// Workspace not found in any group
421+
return;
422+
};
423+
424+
// Send `workspace_leave` for ever instance with old group, and `workspace_enter` for new
425+
// one.
426+
let old_group = &self.0.groups[old_group_idx];
427+
let new_group = &self.0.groups[group_idx];
428+
for instance in &workspace.ext_instances {
429+
let manager = &instance.data::<WorkspaceData>().unwrap().manager;
430+
for group_instance in &old_group.ext_instances {
431+
if *manager == group_instance.data::<WorkspaceGroupData>().unwrap().manager {
432+
group_instance.workspace_leave(instance);
433+
}
434+
}
435+
for group_instance in &new_group.ext_instances {
436+
if *manager == group_instance.data::<WorkspaceGroupData>().unwrap().manager {
437+
group_instance.workspace_enter(instance);
438+
}
439+
}
440+
}
441+
442+
self.0.groups[group_idx].workspaces.push(workspace);
443+
}
444+
398445
pub fn workspace_belongs_to_group(
399446
&self,
400447
group: &WorkspaceGroupHandle,

0 commit comments

Comments
 (0)