protocol/workspace: Add support for ext-workspace-v1

To support both `ext-workspace-v1` and `cosmic-workspace-unstable-v1`,
the API exposed by `wayland/protocols/workspace` now uses the ext
workspace `State` and `GroupCapabilties` bitfields, and converts them to
the cosmic types for the cosmic implementation.

`WorkspaceCapabilities` is a custom type that has cosmic-specific and
ext-specific variants, and is mapped on both backends.

The ext protocol adds an `.assign` request on workspaces, which is
added here, though not currently used.

It also adds an `.id` event. Which we'll probably want when we have
persistent workspaces, but it isn't needed currently.

We still need to add an extension protocol of ext-workspaces to replace
a couple cosmic protocol features.
This commit is contained in:
Ian Douglas Scott 2025-02-11 17:00:49 -08:00 committed by Victoria Brekenfeld
parent aa15c00d12
commit 723f758439
6 changed files with 734 additions and 107 deletions

View file

@ -1,13 +1,17 @@
// SPDX-License-Identifier: GPL-3.0-only
use smithay::reexports::wayland_server::{
backend::{ClientData, ClientId},
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
use smithay::{
reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_handle_v1::{self},
reexports::wayland_server::{
backend::{ClientData, ClientId},
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
},
};
use super::{
Request, Workspace, WorkspaceClientHandler, WorkspaceData, WorkspaceGlobalData, WorkspaceGroup,
WorkspaceGroupData, WorkspaceGroupHandle, WorkspaceHandler, WorkspaceState,
GroupCapabilities, Request, Workspace, WorkspaceCapabilities, WorkspaceClientHandler,
WorkspaceData, WorkspaceGlobalData, WorkspaceGroup, WorkspaceGroupData, WorkspaceGroupHandle,
WorkspaceHandler, WorkspaceState,
};
use cosmic_protocols::workspace::v1::server::{
@ -342,7 +346,11 @@ where
let caps = group
.capabilities
.iter()
.flat_map(|cap| (*cap as u32).to_ne_bytes())
.filter_map(|cap| match cap {
GroupCapabilities::CreateWorkspace => Some(zcosmic_workspace_group_handle_v1::ZcosmicWorkspaceGroupCapabilitiesV1::CreateWorkspace),
_ => None,
})
.flat_map(|cap| (cap as u32).to_ne_bytes())
.collect::<Vec<u8>>();
instance.capabilities(caps);
handle_state.capabilities = group.capabilities.clone();
@ -424,7 +432,25 @@ where
let caps = workspace
.capabilities
.iter()
.flat_map(|cap| (*cap as u32).to_ne_bytes())
.filter_map(|cap| match cap {
WorkspaceCapabilities::Activate => {
Some(zcosmic_workspace_handle_v1::ZcosmicWorkspaceCapabilitiesV1::Activate)
}
WorkspaceCapabilities::Deactivate => {
Some(zcosmic_workspace_handle_v1::ZcosmicWorkspaceCapabilitiesV1::Deactivate)
}
WorkspaceCapabilities::Remove => {
Some(zcosmic_workspace_handle_v1::ZcosmicWorkspaceCapabilitiesV1::Remove)
}
WorkspaceCapabilities::Rename => {
Some(zcosmic_workspace_handle_v1::ZcosmicWorkspaceCapabilitiesV1::Rename)
}
WorkspaceCapabilities::SetTilingState => Some(
zcosmic_workspace_handle_v1::ZcosmicWorkspaceCapabilitiesV1::SetTilingState,
),
_ => None,
})
.flat_map(|cap| (cap as u32).to_ne_bytes())
.collect::<Vec<u8>>();
instance.capabilities(caps);
handle_state.capabilities = workspace.capabilities.clone();
@ -434,7 +460,19 @@ where
let states = workspace
.states
.iter()
.flat_map(|state| (*state as u32).to_ne_bytes())
.filter_map(|state| match state {
ext_workspace_handle_v1::State::Active => {
Some(zcosmic_workspace_handle_v1::State::Active)
}
ext_workspace_handle_v1::State::Urgent => {
Some(zcosmic_workspace_handle_v1::State::Urgent)
}
ext_workspace_handle_v1::State::Hidden => {
Some(zcosmic_workspace_handle_v1::State::Hidden)
}
_ => None,
})
.flat_map(|state| (state as u32).to_ne_bytes())
.collect::<Vec<u8>>();
instance.state(states);
handle_state.states = workspace.states.clone();