Skip to content

Commit

Permalink
WIP cosmic-workspace-v2 protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
ids1024 committed Feb 19, 2025
1 parent 288930c commit da916e0
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 26 deletions.
17 changes: 15 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ bytemuck = "1.12"
calloop = {version = "0.14.1", features = ["executor"]}
cosmic-comp-config = {path = "cosmic-comp-config"}
cosmic-config = {git = "https://github.com/pop-os/libcosmic/", features = ["calloop", "macro"]}
cosmic-protocols = {git = "https://github.com/pop-os/cosmic-protocols", rev = "29ab323", default-features = false, features = ["server"]}
cosmic-protocols = {git = "https://github.com/pop-os/cosmic-protocols", branch = "workspaces-v2", default-features = false, features = ["server"]}
cosmic-settings-config = { git = "https://github.com/pop-os/cosmic-settings-daemon" }
libdisplay-info = "0.2.0"
egui = {version = "0.30.0", optional = true}
Expand Down Expand Up @@ -115,4 +115,4 @@ inherits = "release"
lto = "fat"

[patch.crates-io]
smithay = { git = "https://github.com/smithay/smithay.git", rev = "f93476c" }
smithay = { git = "https://github.com/smithay/smithay.git", rev = "f93476c" }
2 changes: 1 addition & 1 deletion src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use cosmic_comp_config::{
workspace::{WorkspaceLayout, WorkspaceMode},
TileBehavior,
};
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};
Expand Down
2 changes: 1 addition & 1 deletion src/shell/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
2 changes: 1 addition & 1 deletion src/wayland/handlers/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
40 changes: 33 additions & 7 deletions src/wayland/protocols/workspace/cosmic.rs
Original file line number Diff line number Diff line change
@@ -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,
},
};

Expand All @@ -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>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -477,7 +491,19 @@ 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
}
_ => {
// XXX What can we do here? Either don't send, or use default?
todo!()
}
};
instance.tiling_state(tiling_state);
handle_state.tiling = Some(workspace.tiling);
changed = true;
}
Expand Down
186 changes: 186 additions & 0 deletions src/wayland/protocols/workspace/cosmic_v2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// 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 super::{
GroupCapabilities, Request, Workspace, WorkspaceCapabilities, WorkspaceClientHandler,

Check warning on line 16 in src/wayland/protocols/workspace/cosmic_v2.rs

View workflow job for this annotation

GitHub Actions / test

unused imports: `GroupCapabilities`, `WorkspaceCapabilities`, `WorkspaceGroupData`, `WorkspaceGroupHandle`, and `WorkspaceGroup`
WorkspaceData, WorkspaceDataInner, WorkspaceGlobalData, WorkspaceGroup, WorkspaceGroupData,
WorkspaceGroupHandle, WorkspaceHandler, WorkspaceState,
};

pub struct CosmicWorkspaceData {
workspace: Weak<ExtWorkspaceHandleV1>,
}

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(),
},
);
if let Some(data) = workspace.data::<WorkspaceData>() {
// TODO protocol error if workspace has a cosmic workspace
let mut data = data.lock().unwrap();
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, &mut data, 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!(),
}
}

// TODO: destroyed
}

pub fn send_workspace_to_client(
instance: &ZcosmicWorkspaceHandleV2,
handle_state: &mut WorkspaceDataInner,
workspace: &Workspace,
) -> bool {
let mut changed = false;

// TODO capabilities

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;
}

false
}
14 changes: 14 additions & 0 deletions src/wayland/protocols/workspace/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ where
}
}
};
let instance = instance.clone();

let mut handle_state = instance.data::<WorkspaceData>().unwrap().lock().unwrap();
let mut changed = false;
Expand All @@ -411,6 +412,7 @@ where
handle_state.coordinates = workspace.coordinates.clone();
changed = true;
}
// TODO have to split how capabilities are tracked with cosmic
if handle_state.capabilities != workspace.capabilities {
let caps = workspace
.capabilities
Expand Down Expand Up @@ -442,5 +444,17 @@ 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,
&mut handle_state,
workspace,
);
}

changed
}
Loading

0 comments on commit da916e0

Please sign in to comment.