protocols/workspace: Track group a workspace is on, and update
It seems previously, workspace migration due to output add could result in a workspace being removed from a group, but not added to the new group for existing clients, because the workspace group creation didn't happen until `done`. And `send_workspace_to_client` didn't send `workspace_enter` except when a workspace instance is newly created. That logic worked with the old protocol, but now a workspace can be moved to a different group. Seems to fix the issue with workspaces disappearing from the workspaces view in https://github.com/pop-os/cosmic-comp/issues/1470. I don't seem to be able to reproduce the panel auto-hide issue, but have seen it in the past. So it may or may not be prevented from happening now.
This commit is contained in:
parent
1564b9d1a3
commit
2b4890c550
2 changed files with 26 additions and 31 deletions
|
|
@ -46,6 +46,7 @@ pub struct WorkspaceGroupData {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WorkspaceDataInner {
|
pub struct WorkspaceDataInner {
|
||||||
|
pub(super) group: Option<ExtWorkspaceGroupHandleV1>,
|
||||||
name: String,
|
name: String,
|
||||||
capabilities: Option<ext_workspace_handle_v1::WorkspaceCapabilities>,
|
capabilities: Option<ext_workspace_handle_v1::WorkspaceCapabilities>,
|
||||||
coordinates: Vec<u32>,
|
coordinates: Vec<u32>,
|
||||||
|
|
@ -403,7 +404,6 @@ where
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
mngr.workspace(&handle);
|
mngr.workspace(&handle);
|
||||||
group.workspace_enter(&handle);
|
|
||||||
if let Some(id) = workspace.ext_id.clone() {
|
if let Some(id) = workspace.ext_id.clone() {
|
||||||
handle.id(id);
|
handle.id(id);
|
||||||
}
|
}
|
||||||
|
|
@ -427,6 +427,14 @@ where
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
|
|
||||||
|
if handle_state.group.as_ref() != Some(group) {
|
||||||
|
if let Some(old_group) = &handle_state.group {
|
||||||
|
old_group.workspace_leave(&instance);
|
||||||
|
}
|
||||||
|
group.workspace_enter(&instance);
|
||||||
|
handle_state.group = Some(group.clone());
|
||||||
|
}
|
||||||
|
|
||||||
if handle_state.name != workspace.name {
|
if handle_state.name != workspace.name {
|
||||||
instance.name(workspace.name.clone());
|
instance.name(workspace.name.clone());
|
||||||
handle_state.name = workspace.name.clone();
|
handle_state.name = workspace.name.clone();
|
||||||
|
|
|
||||||
|
|
@ -405,12 +405,9 @@ where
|
||||||
for group in &mut self.0.groups {
|
for group in &mut self.0.groups {
|
||||||
if let Some(workspace) = group.workspaces.iter().find(|w| w.id == workspace.id) {
|
if let Some(workspace) = group.workspaces.iter().find(|w| w.id == workspace.id) {
|
||||||
for instance in &workspace.ext_instances {
|
for instance in &workspace.ext_instances {
|
||||||
let manager = &instance.data::<WorkspaceData>().unwrap().manager;
|
let workspace_data = instance.data::<WorkspaceData>().unwrap();
|
||||||
for group_instance in &group.ext_instances {
|
if let Some(group_instance) = &workspace_data.inner.lock().unwrap().group {
|
||||||
if *manager == group_instance.data::<WorkspaceGroupData>().unwrap().manager
|
group_instance.workspace_leave(instance);
|
||||||
{
|
|
||||||
group_instance.workspace_leave(instance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
instance.removed();
|
instance.removed();
|
||||||
}
|
}
|
||||||
|
|
@ -432,35 +429,25 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find old group index, and remove the workspace
|
// Find old group index, and remove the workspace
|
||||||
let Some((old_group_idx, workspace)) =
|
let Some(workspace) = self.0.groups.iter_mut().find_map(|group| {
|
||||||
self.0.groups.iter_mut().enumerate().find_map(|(i, group)| {
|
let idx = group
|
||||||
let idx = group
|
.workspaces
|
||||||
.workspaces
|
.iter()
|
||||||
.iter()
|
.position(|w| w.id == workspace_handle.id)?;
|
||||||
.position(|w| w.id == workspace_handle.id)?;
|
Some(group.workspaces.remove(idx))
|
||||||
let workspace = group.workspaces.remove(idx);
|
}) else {
|
||||||
Some((i, workspace))
|
|
||||||
})
|
|
||||||
else {
|
|
||||||
// Workspace not found in any group
|
// Workspace not found in any group
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send `workspace_leave` for ever instance with old group, and `workspace_enter` for new
|
// Send `workspace_leave` for ever instance with old group.
|
||||||
// one.
|
//
|
||||||
let old_group = &self.0.groups[old_group_idx];
|
// `workspace_enter` will be sent in `send_group_to_client`, but if a group is destroyed,
|
||||||
let new_group = &self.0.groups[group_idx];
|
// we need to make sure `workspace_leave` is sent first.
|
||||||
for instance in &workspace.ext_instances {
|
for instance in &workspace.ext_instances {
|
||||||
let manager = &instance.data::<WorkspaceData>().unwrap().manager;
|
let workspace_data = instance.data::<WorkspaceData>().unwrap();
|
||||||
for group_instance in &old_group.ext_instances {
|
if let Some(group_instance) = workspace_data.inner.lock().unwrap().group.take() {
|
||||||
if *manager == group_instance.data::<WorkspaceGroupData>().unwrap().manager {
|
group_instance.workspace_leave(instance);
|
||||||
group_instance.workspace_leave(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for group_instance in &new_group.ext_instances {
|
|
||||||
if *manager == group_instance.data::<WorkspaceGroupData>().unwrap().manager {
|
|
||||||
group_instance.workspace_enter(instance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue