Add cosmic-workspace-v2, image source, toplevel info changes

This new protocol extends `ext-workspace-v1` with the same additional
functionality `cosmic-workspace-v1` provided. Toplevel info and toplevel
management are also updated to use ext handles, and there's an image
source for ext workspaces.

For now, the old protocol is still supported.
This commit is contained in:
Ian Douglas Scott 2025-02-19 14:07:51 -08:00 committed by Victoria Brekenfeld
parent 0b23a01736
commit aac8166962
10 changed files with 459 additions and 24 deletions

View file

@ -15,7 +15,7 @@ use cosmic_comp_config::{
workspace::{WorkspaceLayout, WorkspaceMode},
TileBehavior, ZoomConfig, ZoomMovement,
};
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::TilingState;
use cosmic_protocols::workspace::v2::server::zcosmic_workspace_handle_v2::TilingState;
use cosmic_settings_config::shortcuts::action::{Direction, FocusDirection, ResizeDirection};
use cosmic_settings_config::{shortcuts, window_rules::ApplicationException};
use keyframe::{ease, functions::EaseInOutCubic};

View file

@ -19,7 +19,7 @@ use crate::{
};
use cosmic::theme::CosmicTheme;
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::TilingState;
use cosmic_protocols::workspace::v2::server::zcosmic_workspace_handle_v2::TilingState;
use id_tree::Tree;
use indexmap::IndexSet;
use keyframe::{ease, functions::EaseInOutCubic};

View file

@ -9,7 +9,7 @@ use crate::{
WorkspaceHandler, WorkspaceState,
},
};
use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::TilingState;
use cosmic_protocols::workspace::v2::server::zcosmic_workspace_handle_v2::TilingState;
use smithay::reexports::wayland_server::DisplayHandle;
impl WorkspaceClientHandler for ClientState {

View file

@ -4,6 +4,9 @@ use super::{
};
use crate::shell::CosmicSurface;
use cosmic_protocols::image_source::v1::server::{
zcosmic_ext_workspace_image_source_manager_v1::{
Request as ExtWorkspaceSourceRequest, ZcosmicExtWorkspaceImageSourceManagerV1,
},
zcosmic_image_source_v1::ZcosmicImageSourceV1,
zcosmic_output_image_source_manager_v1::{
Request as OutputSourceRequest, ZcosmicOutputImageSourceManagerV1,
@ -27,6 +30,7 @@ use wayland_backend::server::GlobalId;
pub struct ImageSourceState {
output_source_global: GlobalId,
workspace_source_global: GlobalId,
ext_workspace_source_global: GlobalId,
toplevel_source_global: GlobalId,
}
@ -57,6 +61,10 @@ impl ImageSourceState {
ZcosmicWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
> + Dispatch<ZcosmicWorkspaceImageSourceManagerV1, ()>
+ GlobalDispatch<
ZcosmicExtWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
> + Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, ()>
+ GlobalDispatch<
ZcosmicToplevelImageSourceManagerV1,
ToplevelImageSourceManagerGlobalData,
@ -80,6 +88,13 @@ impl ImageSourceState {
filter: Box::new(client_filter.clone()),
},
),
ext_workspace_source_global: display
.create_global::<D, ZcosmicExtWorkspaceImageSourceManagerV1, _>(
1,
WorkspaceImageSourceManagerGlobalData {
filter: Box::new(client_filter.clone()),
},
),
toplevel_source_global: display
.create_global::<D, ZcosmicToplevelImageSourceManagerV1, _>(
1,
@ -98,6 +113,10 @@ impl ImageSourceState {
&self.workspace_source_global
}
pub fn ext_workspace_source_id(&self) -> &GlobalId {
&self.ext_workspace_source_global
}
pub fn toplevel_source_id(&self) -> &GlobalId {
&self.toplevel_source_global
}
@ -152,6 +171,36 @@ where
}
}
impl<D>
GlobalDispatch<
ZcosmicExtWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
D,
> for ImageSourceState
where
D: GlobalDispatch<
ZcosmicExtWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
> + Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicExtWorkspaceImageSourceManagerV1>,
_global_data: &WorkspaceImageSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &WorkspaceImageSourceManagerGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D> GlobalDispatch<ZcosmicToplevelImageSourceManagerV1, ToplevelImageSourceManagerGlobalData, D>
for ImageSourceState
where
@ -249,6 +298,43 @@ where
}
}
impl<D> Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, (), D> for ImageSourceState
where
D: Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ WorkspaceHandler
+ 'static,
{
fn request(
state: &mut D,
_client: &Client,
_resource: &ZcosmicExtWorkspaceImageSourceManagerV1,
request: <ZcosmicExtWorkspaceImageSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
ExtWorkspaceSourceRequest::CreateSource { source, output } => {
let data = match state.workspace_state().get_ext_workspace_handle(&output) {
Some(workspace) => ImageSourceData::Workspace(workspace),
None => ImageSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicExtWorkspaceImageSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ZcosmicToplevelImageSourceManagerV1, (), D> for ImageSourceState
where
D: Dispatch<ZcosmicToplevelImageSourceManagerV1, ()>
@ -329,6 +415,12 @@ macro_rules! delegate_image_source {
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_workspace_image_source_manager_v1::ZcosmicWorkspaceImageSourceManagerV1: ()
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_ext_workspace_image_source_manager_v1::ZcosmicExtWorkspaceImageSourceManagerV1: $crate::wayland::protocols::image_source::WorkspaceImageSourceManagerGlobalData
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_ext_workspace_image_source_manager_v1::ZcosmicExtWorkspaceImageSourceManagerV1: ()
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_toplevel_image_source_manager_v1::ZcosmicToplevelImageSourceManagerV1: $crate::wayland::protocols::image_source::ToplevelImageSourceManagerGlobalData
] => $crate::wayland::protocols::image_source::ImageSourceState);

View file

@ -309,7 +309,7 @@ where
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + Clone + 'static,
{
let global = dh.create_global::<D, ZcosmicToplevelInfoV1, _>(
2,
3,
ToplevelInfoGlobalData {
filter: Box::new(client_filter.clone()),
},
@ -594,6 +594,10 @@ where
instance.workspace_enter(&handle);
changed = true;
}
for handle in workspace_state.raw_ext_workspace_handles(&new_workspace, &instance.id()) {
instance.ext_workspace_enter(&handle);
changed = true;
}
}
for old_workspace in handle_state
.workspaces
@ -604,6 +608,10 @@ where
instance.workspace_leave(&handle);
changed = true;
}
for handle in workspace_state.raw_ext_workspace_handles(&old_workspace, &instance.id()) {
instance.ext_workspace_leave(&handle);
changed = true;
}
}
handle_state.workspaces = state.workspaces.clone();

View file

@ -116,7 +116,7 @@ impl ToplevelManagementState {
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static,
{
let global = dh.create_global::<D, ZcosmicToplevelManagerV1, _>(
3,
4,
ToplevelManagerGlobalData {
filter: Box::new(client_filter),
},
@ -263,6 +263,20 @@ where
}
}
}
zcosmic_toplevel_manager_v1::Request::MoveToExtWorkspace {
toplevel,
workspace,
output,
} => {
let window = window_from_handle(toplevel).unwrap();
if let Some(workspace_handle) =
state.workspace_state().get_ext_workspace_handle(&workspace)
{
if let Some(output) = Output::from_resource(&output) {
state.move_to_workspace(dh, &window, workspace_handle, output);
}
}
}
_ => unreachable!(),
}
}

View file

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-only
use smithay::{
reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_handle_v1::{self},
reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_handle_v1,
reexports::wayland_server::{
backend::{ClientData, ClientId},
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, WEnum,
},
};
@ -14,10 +14,13 @@ use super::{
WorkspaceHandler, WorkspaceState,
};
use cosmic_protocols::workspace::v1::server::{
zcosmic_workspace_group_handle_v1::{self, ZcosmicWorkspaceGroupHandleV1},
zcosmic_workspace_handle_v1::{self, ZcosmicWorkspaceHandleV1},
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
use cosmic_protocols::workspace::{
v1::server::{
zcosmic_workspace_group_handle_v1::{self, ZcosmicWorkspaceGroupHandleV1},
zcosmic_workspace_handle_v1::{self, ZcosmicWorkspaceHandleV1},
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
},
v2::server::zcosmic_workspace_handle_v2,
};
impl<D> GlobalDispatch<ZcosmicWorkspaceManagerV1, WorkspaceGlobalData, D> for WorkspaceState<D>
@ -243,6 +246,17 @@ where
.workspace_state()
.lock()
.unwrap();
let tiling_state = match tiling_state {
WEnum::Value(zcosmic_workspace_handle_v1::TilingState::FloatingOnly) => {
WEnum::Value(zcosmic_workspace_handle_v2::TilingState::FloatingOnly)
}
WEnum::Value(zcosmic_workspace_handle_v1::TilingState::TilingEnabled) => {
WEnum::Value(zcosmic_workspace_handle_v2::TilingState::TilingEnabled)
}
// Won't be adding more variants to v1, at least
WEnum::Value(_) => unreachable!(),
WEnum::Unknown(value) => WEnum::Unknown(value),
};
state.requests.push(Request::SetTilingState {
workspace: workspace_handle,
state: tiling_state,
@ -477,7 +491,21 @@ where
.map(|state| state != workspace.tiling)
.unwrap_or(true)
{
instance.tiling_state(workspace.tiling);
let tiling_state = match workspace.tiling {
zcosmic_workspace_handle_v2::TilingState::FloatingOnly => {
zcosmic_workspace_handle_v1::TilingState::FloatingOnly
}
zcosmic_workspace_handle_v2::TilingState::TilingEnabled => {
zcosmic_workspace_handle_v1::TilingState::TilingEnabled
}
_ => {
// Not clear what to do if state doesn't match. Which
// shouldn't happen (or protocol will be irrelevant by
// then).
zcosmic_workspace_handle_v1::TilingState::TilingEnabled
}
};
instance.tiling_state(tiling_state);
handle_state.tiling = Some(workspace.tiling);
changed = true;
}

View file

@ -0,0 +1,221 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic_protocols::workspace::v2::server::{
zcosmic_workspace_handle_v2::{self, ZcosmicWorkspaceHandleV2},
zcosmic_workspace_manager_v2::{self, ZcosmicWorkspaceManagerV2},
};
use smithay::reexports::{
wayland_protocols::ext::workspace::v1::server::ext_workspace_handle_v1::ExtWorkspaceHandleV1,
wayland_server::{
backend::ClientData, Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New,
Resource, Weak,
},
};
use std::sync::Mutex;
use super::{
Request, Workspace, WorkspaceCapabilities, WorkspaceClientHandler, WorkspaceData,
WorkspaceGlobalData, WorkspaceHandler, WorkspaceState,
};
#[derive(Default)]
pub struct CosmicWorkspaceDataInner {
capabilities: Option<WorkspaceCapabilities>,
tiling: Option<zcosmic_workspace_handle_v2::TilingState>,
}
pub struct CosmicWorkspaceData {
workspace: Weak<ExtWorkspaceHandleV1>,
inner: Mutex<CosmicWorkspaceDataInner>,
}
impl<D> GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData, D> for WorkspaceState<D>
where
D: GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ WorkspaceHandler
+ 'static,
<D as WorkspaceHandler>::Client: ClientData + WorkspaceClientHandler + 'static,
{
fn bind(
_state: &mut D,
_dh: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicWorkspaceManagerV2>,
_global_data: &WorkspaceGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &WorkspaceGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D> Dispatch<ZcosmicWorkspaceManagerV2, (), D> for WorkspaceState<D>
where
D: GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ WorkspaceHandler
+ 'static,
<D as WorkspaceHandler>::Client: ClientData + WorkspaceClientHandler + 'static,
{
fn request(
state: &mut D,
_client: &Client,
obj: &ZcosmicWorkspaceManagerV2,
request: zcosmic_workspace_manager_v2::Request,
_data: &(),
_dh: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
zcosmic_workspace_manager_v2::Request::GetCosmicWorkspace {
cosmic_workspace,
workspace,
} => {
let cosmic_workspace = data_init.init(
cosmic_workspace,
CosmicWorkspaceData {
workspace: workspace.downgrade(),
inner: Mutex::new(CosmicWorkspaceDataInner::default()),
},
);
if let Some(data) = workspace.data::<WorkspaceData>() {
let mut data = data.lock().unwrap();
if data.cosmic_v2_handle.as_ref().is_some_and(|x| x.is_alive()) {
obj.post_error(
zcosmic_workspace_manager_v2::Error::WorkspaceExists,
"zcosmic_workspace_handle_v2 already exists for ext_workspace_handle_v1",
);
return;
}
data.cosmic_v2_handle = Some(cosmic_workspace.downgrade());
if let Some((workspace, ext_mngr, _)) = state
.workspace_state()
.groups
.iter()
.flat_map(|g| &g.workspaces)
.flat_map(|w| w.ext_instances.iter().map(move |(mngr, i)| (w, mngr, i)))
.find(|(_, _, i)| **i == workspace)
{
if let Ok(ext_mngr) = ext_mngr.upgrade() {
send_workspace_to_client(&cosmic_workspace, workspace);
ext_mngr.done();
}
}
}
}
_ => unreachable!(),
}
}
}
impl<D> Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData, D> for WorkspaceState<D>
where
D: GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ WorkspaceHandler
+ 'static,
<D as WorkspaceHandler>::Client: ClientData + WorkspaceClientHandler + 'static,
{
fn request(
state: &mut D,
client: &Client,
_obj: &ZcosmicWorkspaceHandleV2,
request: zcosmic_workspace_handle_v2::Request,
data: &CosmicWorkspaceData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
let Ok(workspace) = data.workspace.upgrade() else {
return;
};
match request {
zcosmic_workspace_handle_v2::Request::Rename { name } => {
if let Some(workspace_handle) =
state.workspace_state().get_ext_workspace_handle(&workspace)
{
let mut state = client
.get_data::<<D as WorkspaceHandler>::Client>()
.unwrap()
.workspace_state()
.lock()
.unwrap();
state.requests.push(Request::Rename {
workspace: workspace_handle,
name,
});
}
}
zcosmic_workspace_handle_v2::Request::SetTilingState {
state: tiling_state,
} => {
if let Some(workspace_handle) =
state.workspace_state().get_ext_workspace_handle(&workspace)
{
let mut state = client
.get_data::<<D as WorkspaceHandler>::Client>()
.unwrap()
.workspace_state()
.lock()
.unwrap();
state.requests.push(Request::SetTilingState {
workspace: workspace_handle,
state: tiling_state,
});
}
}
_ => unreachable!(),
}
}
}
pub fn send_workspace_to_client(
instance: &ZcosmicWorkspaceHandleV2,
workspace: &Workspace,
) -> bool {
let mut changed = false;
let mut handle_state = instance
.data::<CosmicWorkspaceData>()
.unwrap()
.inner
.lock()
.unwrap();
if handle_state.capabilities != Some(workspace.capabilities) {
let caps = workspace
.capabilities
.iter()
.filter_map(|cap| match cap {
WorkspaceCapabilities::Rename => {
Some(zcosmic_workspace_handle_v2::WorkspaceCapabilities::Rename)
}
WorkspaceCapabilities::SetTilingState => {
Some(zcosmic_workspace_handle_v2::WorkspaceCapabilities::SetTilingState)
}
_ => None,
})
.collect::<zcosmic_workspace_handle_v2::WorkspaceCapabilities>();
instance.capabilities(caps);
handle_state.capabilities = Some(workspace.capabilities);
changed = true;
}
if handle_state
.tiling
.map(|state| state != workspace.tiling)
.unwrap_or(true)
{
instance.tiling_state(workspace.tiling);
handle_state.tiling = Some(workspace.tiling);
changed = true;
}
changed
}

View file

@ -392,6 +392,7 @@ where
}
}
};
let instance = instance.clone();
let mut handle_state = instance.data::<WorkspaceData>().unwrap().lock().unwrap();
let mut changed = false;
@ -442,5 +443,13 @@ where
}
// TODO ext_workspace_handle_v1::id
if let Some(cosmic_v2_handle) = handle_state
.cosmic_v2_handle
.as_ref()
.and_then(|x| x.upgrade().ok())
{
changed |= super::cosmic_v2::send_workspace_to_client(&cosmic_v2_handle, workspace);
}
changed
}

View file

@ -19,13 +19,21 @@ use smithay::{
};
use wayland_backend::protocol::WEnum;
use cosmic_protocols::workspace::v1::server::{
zcosmic_workspace_group_handle_v1::ZcosmicWorkspaceGroupHandleV1,
zcosmic_workspace_handle_v1::{self, ZcosmicWorkspaceHandleV1},
zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1,
use cosmic_protocols::workspace::{
v1::server::{
zcosmic_workspace_group_handle_v1::ZcosmicWorkspaceGroupHandleV1,
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
zcosmic_workspace_manager_v1::ZcosmicWorkspaceManagerV1,
},
v2::server::{
zcosmic_workspace_handle_v2::{self, ZcosmicWorkspaceHandleV2},
zcosmic_workspace_manager_v2::ZcosmicWorkspaceManagerV2,
},
};
mod cosmic;
mod cosmic_v2;
pub use cosmic_v2::CosmicWorkspaceData;
mod ext;
pub use smithay::reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_group_handle_v1::GroupCapabilities;
@ -56,6 +64,9 @@ where
+ Dispatch<ExtWorkspaceManagerV1, ()>
+ Dispatch<ExtWorkspaceGroupHandleV1, WorkspaceGroupData>
+ Dispatch<ExtWorkspaceHandleV1, WorkspaceData>
+ GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ WorkspaceHandler
+ 'static,
<D as WorkspaceHandler>::Client: ClientData + WorkspaceClientHandler + 'static,
@ -63,6 +74,7 @@ where
dh: DisplayHandle,
cosmic_global: GlobalId,
ext_global: GlobalId,
cosmic_v2_global: GlobalId,
instances: Vec<ZcosmicWorkspaceManagerV1>,
ext_instances: Vec<ExtWorkspaceManagerV1>,
groups: Vec<WorkspaceGroup>,
@ -134,7 +146,7 @@ pub struct Workspace {
capabilities: WorkspaceCapabilities,
coordinates: Vec<u32>,
states: ext_workspace_handle_v1::State,
tiling: zcosmic_workspace_handle_v1::TilingState,
tiling: zcosmic_workspace_handle_v2::TilingState,
ext_id: Option<String>,
}
@ -149,7 +161,8 @@ pub struct WorkspaceDataInner {
capabilities: Option<WorkspaceCapabilities>,
coordinates: Vec<u32>,
states: Option<ext_workspace_handle_v1::State>,
tiling: Option<zcosmic_workspace_handle_v1::TilingState>,
tiling: Option<zcosmic_workspace_handle_v2::TilingState>,
cosmic_v2_handle: Option<Weak<ZcosmicWorkspaceHandleV2>>,
}
pub type WorkspaceData = Mutex<WorkspaceDataInner>;
@ -164,6 +177,9 @@ where
+ Dispatch<ExtWorkspaceManagerV1, ()>
+ Dispatch<ExtWorkspaceGroupHandleV1, WorkspaceGroupData>
+ Dispatch<ExtWorkspaceHandleV1, WorkspaceData>
+ GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ Sized
+ 'static,
{
@ -189,7 +205,7 @@ pub enum Request {
},
SetTilingState {
workspace: WorkspaceHandle,
state: WEnum<zcosmic_workspace_handle_v1::TilingState>,
state: WEnum<zcosmic_workspace_handle_v2::TilingState>,
},
Create {
in_group: WorkspaceGroupHandle,
@ -221,6 +237,9 @@ where
+ Dispatch<ExtWorkspaceManagerV1, ()>
+ Dispatch<ExtWorkspaceGroupHandleV1, WorkspaceGroupData>
+ Dispatch<ExtWorkspaceHandleV1, WorkspaceData>
+ GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ WorkspaceHandler
+ 'static,
<D as WorkspaceHandler>::Client: ClientData + WorkspaceClientHandler + 'static,
@ -239,7 +258,14 @@ where
let ext_global = dh.create_global::<D, ExtWorkspaceManagerV1, _>(
1,
WorkspaceGlobalData {
filter: Box::new(client_filter),
filter: Box::new(client_filter.clone()),
},
);
let cosmic_v2_global = dh.create_global::<D, ZcosmicWorkspaceManagerV2, _>(
1,
WorkspaceGlobalData {
filter: Box::new(client_filter.clone()),
},
);
@ -247,6 +273,7 @@ where
dh: dh.clone(),
cosmic_global,
ext_global,
cosmic_v2_global,
instances: Vec::new(),
ext_instances: Vec::new(),
groups: Vec::new(),
@ -324,7 +351,7 @@ where
pub fn workspace_tiling_state(
&self,
workspace: &WorkspaceHandle,
) -> Option<zcosmic_workspace_handle_v1::TilingState> {
) -> Option<zcosmic_workspace_handle_v2::TilingState> {
self.groups.iter().find_map(|g| {
g.workspaces
.iter()
@ -342,6 +369,7 @@ where
.find(|g| g.instances.iter().any(|(_, i)| i == group))
.map(|g| WorkspaceGroupHandle { id: g.id })
}
pub fn workspace_handle(
&self,
workspace: &ZcosmicWorkspaceHandleV1,
@ -368,6 +396,7 @@ where
.map(|(_, i)| i)
.filter(|i| i.id().same_client_as(client))
}
pub fn raw_workspace_handles<'a>(
&'a self,
workspace: &'a WorkspaceHandle,
@ -382,6 +411,20 @@ where
.filter(|i| i.id().same_client_as(client))
}
pub fn raw_ext_workspace_handles<'a>(
&'a self,
workspace: &'a WorkspaceHandle,
client: &'a ObjectId,
) -> impl Iterator<Item = &ExtWorkspaceHandleV1> + 'a {
self.groups
.iter()
.find_map(|g| g.workspaces.iter().find(|w| w.id == workspace.id))
.into_iter()
.flat_map(|w| &w.ext_instances)
.map(|(_, i)| i)
.filter(|i| Resource::id(*i).same_client_as(client))
}
pub fn update(&mut self) -> WorkspaceUpdateGuard<'_, D> {
WorkspaceUpdateGuard(self)
}
@ -447,6 +490,10 @@ where
pub fn ext_global_id(&self) -> GlobalId {
self.ext_global.clone()
}
pub fn cosmic_v2_global_id(&self) -> GlobalId {
self.cosmic_v2_global.clone()
}
}
impl<'a, D> WorkspaceUpdateGuard<'a, D>
@ -458,6 +505,9 @@ where
+ Dispatch<ExtWorkspaceManagerV1, ()>
+ Dispatch<ExtWorkspaceGroupHandleV1, WorkspaceGroupData>
+ Dispatch<ExtWorkspaceHandleV1, WorkspaceData>
+ GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ WorkspaceHandler
+ 'static,
<D as WorkspaceHandler>::Client: ClientData + WorkspaceClientHandler + 'static,
@ -475,7 +525,7 @@ where
pub fn create_workspace(
&mut self,
group: &WorkspaceGroupHandle,
tiling: zcosmic_workspace_handle_v1::TilingState,
tiling: zcosmic_workspace_handle_v2::TilingState,
ext_id: Option<String>,
) -> Option<WorkspaceHandle> {
if let Some(group) = self.0.groups.iter_mut().find(|g| g.id == group.id) {
@ -688,14 +738,14 @@ where
pub fn workspace_tiling_state(
&self,
workspace: &WorkspaceHandle,
) -> Option<zcosmic_workspace_handle_v1::TilingState> {
) -> Option<zcosmic_workspace_handle_v2::TilingState> {
self.0.workspace_tiling_state(workspace)
}
pub fn set_workspace_tiling_state(
&mut self,
workspace: &WorkspaceHandle,
state: zcosmic_workspace_handle_v1::TilingState,
state: zcosmic_workspace_handle_v2::TilingState,
) {
if let Some(workspace) = self
.0
@ -718,6 +768,9 @@ where
+ Dispatch<ExtWorkspaceManagerV1, ()>
+ Dispatch<ExtWorkspaceGroupHandleV1, WorkspaceGroupData>
+ Dispatch<ExtWorkspaceHandleV1, WorkspaceData>
+ GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
+ Dispatch<ZcosmicWorkspaceManagerV2, ()>
+ Dispatch<ZcosmicWorkspaceHandleV2, CosmicWorkspaceData>
+ WorkspaceHandler
+ 'static,
<D as WorkspaceHandler>::Client: ClientData + WorkspaceClientHandler + 'static,
@ -754,6 +807,16 @@ macro_rules! delegate_workspace {
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
smithay::reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_handle_v1::ExtWorkspaceHandleV1: $crate::wayland::protocols::workspace::WorkspaceData
] => $crate::wayland::protocols::workspace::WorkspaceState<Self>);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::workspace::v2::server::zcosmic_workspace_manager_v2::ZcosmicWorkspaceManagerV2: $crate::wayland::protocols::workspace::WorkspaceGlobalData
] => $crate::wayland::protocols::workspace::WorkspaceState<Self>);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::workspace::v2::server::zcosmic_workspace_manager_v2::ZcosmicWorkspaceManagerV2: ()
] => $crate::wayland::protocols::workspace::WorkspaceState<Self>);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::workspace::v2::server::zcosmic_workspace_handle_v2::ZcosmicWorkspaceHandleV2: $crate::wayland::protocols::workspace::CosmicWorkspaceData
] => $crate::wayland::protocols::workspace::WorkspaceState<Self>);
};
}
pub(crate) use delegate_workspace;