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:
parent
0b23a01736
commit
aac8166962
10 changed files with 459 additions and 24 deletions
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
221
src/wayland/protocols/workspace/cosmic_v2.rs
Normal file
221
src/wayland/protocols/workspace/cosmic_v2.rs
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue