protocols/workspace: Store request queue in workspace manager udata
This is slightly simpler, if there's not some reason I'm missing to do this as it was previously done. And in particular provides a cleaner API (if we wanted to move this to Smithay; perhaps without the Cosmic extension). But it also should be more correct. Presumably if a client (unusually) had multiple components with their own `ext_workspace_manager_v1` instance, they should have their own queues, and `ext_workspace_manager_v1::commit` should be independent. Inevitably, there's a racy element to multiple components trying to update the workspace state like this, but it should behave the same as two clients with separate connections. (This is different from `CompositorClientState`, since the commit queue there is fundamentally tied to the client, and different components with their own compositor instance way have related surfaces.)
This commit is contained in:
parent
2f6d600502
commit
e944ee9b2f
5 changed files with 106 additions and 113 deletions
|
|
@ -24,7 +24,7 @@ use crate::{
|
|||
screencopy::ScreencopyState,
|
||||
toplevel_info::ToplevelInfoState,
|
||||
toplevel_management::{ManagementCapabilities, ToplevelManagementState},
|
||||
workspace::{WorkspaceClientState, WorkspaceState, WorkspaceUpdateGuard},
|
||||
workspace::{WorkspaceState, WorkspaceUpdateGuard},
|
||||
},
|
||||
},
|
||||
xwayland::XWaylandState,
|
||||
|
|
@ -141,7 +141,6 @@ macro_rules! fl {
|
|||
|
||||
pub struct ClientState {
|
||||
pub compositor_client_state: CompositorClientState,
|
||||
pub workspace_client_state: WorkspaceClientState,
|
||||
pub advertised_drm_node: Option<DrmNode>,
|
||||
pub privileged: bool,
|
||||
pub evls: LoopSignal,
|
||||
|
|
@ -679,7 +678,6 @@ impl State {
|
|||
pub fn new_client_state(&self) -> ClientState {
|
||||
ClientState {
|
||||
compositor_client_state: CompositorClientState::default(),
|
||||
workspace_client_state: WorkspaceClientState::default(),
|
||||
advertised_drm_node: match &self.backend {
|
||||
BackendData::Kms(kms_state) => kms_state.primary_node,
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -2,24 +2,15 @@
|
|||
|
||||
use crate::{
|
||||
shell::WorkspaceDelta,
|
||||
state::ClientState,
|
||||
utils::prelude::*,
|
||||
wayland::protocols::workspace::{
|
||||
delegate_workspace, Request, WorkspaceClientHandler, WorkspaceClientState,
|
||||
WorkspaceHandler, WorkspaceState,
|
||||
delegate_workspace, Request, WorkspaceHandler, WorkspaceState,
|
||||
},
|
||||
};
|
||||
use cosmic_protocols::workspace::v2::server::zcosmic_workspace_handle_v2::TilingState;
|
||||
use smithay::reexports::wayland_server::DisplayHandle;
|
||||
|
||||
impl WorkspaceClientHandler for ClientState {
|
||||
fn workspace_state(&self) -> &WorkspaceClientState {
|
||||
&self.workspace_client_state
|
||||
}
|
||||
}
|
||||
|
||||
impl WorkspaceHandler for State {
|
||||
type Client = ClientState;
|
||||
fn workspace_state(&self) -> &WorkspaceState<Self> {
|
||||
&self.common.workspace_state
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ use smithay::reexports::{
|
|||
use std::sync::Mutex;
|
||||
|
||||
use super::{
|
||||
Request, Workspace, WorkspaceCapabilities, WorkspaceClientHandler, WorkspaceData,
|
||||
WorkspaceGlobalData, WorkspaceHandler, WorkspaceState,
|
||||
Request, Workspace, WorkspaceCapabilities, WorkspaceData, WorkspaceGlobalData,
|
||||
WorkspaceHandler, WorkspaceManagerData, WorkspaceState,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -113,7 +113,7 @@ where
|
|||
{
|
||||
fn request(
|
||||
state: &mut D,
|
||||
client: &Client,
|
||||
_client: &Client,
|
||||
_obj: &ZcosmicWorkspaceHandleV2,
|
||||
request: zcosmic_workspace_handle_v2::Request,
|
||||
data: &CosmicWorkspaceV2Data,
|
||||
|
|
@ -128,16 +128,19 @@ where
|
|||
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,
|
||||
});
|
||||
if let Ok(manager) =
|
||||
workspace.data::<WorkspaceData>().unwrap().manager.upgrade()
|
||||
{
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Rename {
|
||||
workspace: workspace_handle,
|
||||
name,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
zcosmic_workspace_handle_v2::Request::SetTilingState {
|
||||
|
|
@ -146,16 +149,19 @@ where
|
|||
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,
|
||||
});
|
||||
if let Ok(manager) =
|
||||
workspace.data::<WorkspaceData>().unwrap().manager.upgrade()
|
||||
{
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::SetTilingState {
|
||||
workspace: workspace_handle,
|
||||
state: tiling_state,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
zcosmic_workspace_handle_v2::Request::Destroy => {}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,17 @@ use smithay::{
|
|||
use std::{collections::HashSet, sync::Mutex};
|
||||
|
||||
use super::{
|
||||
Request, Workspace, WorkspaceCapabilities, WorkspaceClientHandler, WorkspaceGlobalData,
|
||||
WorkspaceGroup, WorkspaceGroupHandle, WorkspaceHandler, WorkspaceState,
|
||||
Request, Workspace, WorkspaceCapabilities, WorkspaceGlobalData, WorkspaceGroup,
|
||||
WorkspaceGroupHandle, WorkspaceHandler, WorkspaceState,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct WorkspaceManagerDataInner {
|
||||
pub(super) requests: Vec<Request>,
|
||||
}
|
||||
|
||||
pub type WorkspaceManagerData = Mutex<WorkspaceManagerDataInner>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct WorkspaceGroupDataInner {
|
||||
outputs: Vec<Output>,
|
||||
|
|
@ -64,7 +71,7 @@ where
|
|||
data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
let state = state.workspace_state_mut();
|
||||
let instance = data_init.init(resource, ());
|
||||
let instance = data_init.init(resource, WorkspaceManagerData::default());
|
||||
for group in &mut state.groups {
|
||||
send_group_to_client::<D>(dh, &instance, group);
|
||||
}
|
||||
|
|
@ -77,29 +84,24 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<D> Dispatch<ExtWorkspaceManagerV1, (), D> for WorkspaceState<D>
|
||||
impl<D> Dispatch<ExtWorkspaceManagerV1, WorkspaceManagerData, D> for WorkspaceState<D>
|
||||
where
|
||||
D: WorkspaceHandler,
|
||||
{
|
||||
fn request(
|
||||
state: &mut D,
|
||||
client: &Client,
|
||||
_client: &Client,
|
||||
obj: &ExtWorkspaceManagerV1,
|
||||
request: ext_workspace_manager_v1::Request,
|
||||
_data: &(),
|
||||
data: &WorkspaceManagerData,
|
||||
dh: &DisplayHandle,
|
||||
_data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
match request {
|
||||
ext_workspace_manager_v1::Request::Commit => {
|
||||
if state.workspace_state().ext_instances.contains(obj) {
|
||||
let mut client_state = client
|
||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||
.unwrap()
|
||||
.workspace_state()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.commit_requests(dh, std::mem::take(&mut client_state.requests));
|
||||
let mut data = data.lock().unwrap();
|
||||
state.commit_requests(dh, std::mem::take(&mut data.requests));
|
||||
}
|
||||
}
|
||||
ext_workspace_manager_v1::Request::Stop => {
|
||||
|
|
@ -114,7 +116,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn destroyed(state: &mut D, _client: ClientId, resource: &ExtWorkspaceManagerV1, _data: &()) {
|
||||
fn destroyed(
|
||||
state: &mut D,
|
||||
_client: ClientId,
|
||||
resource: &ExtWorkspaceManagerV1,
|
||||
_data: &WorkspaceManagerData,
|
||||
) {
|
||||
state
|
||||
.workspace_state_mut()
|
||||
.ext_instances
|
||||
|
|
@ -128,10 +135,10 @@ where
|
|||
{
|
||||
fn request(
|
||||
state: &mut D,
|
||||
client: &Client,
|
||||
_client: &Client,
|
||||
obj: &ExtWorkspaceGroupHandleV1,
|
||||
request: ext_workspace_group_handle_v1::Request,
|
||||
_data: &WorkspaceGroupData,
|
||||
data: &WorkspaceGroupData,
|
||||
_dh: &DisplayHandle,
|
||||
_data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
|
|
@ -144,16 +151,17 @@ where
|
|||
.find(|g| g.ext_instances.contains(obj))
|
||||
.map(|g| g.id)
|
||||
{
|
||||
let mut state = client
|
||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||
.unwrap()
|
||||
.workspace_state()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Create {
|
||||
in_group: WorkspaceGroupHandle { id },
|
||||
name: workspace,
|
||||
});
|
||||
if let Ok(manager) = data.manager.upgrade() {
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Create {
|
||||
in_group: WorkspaceGroupHandle { id },
|
||||
name: workspace,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
ext_workspace_group_handle_v1::Request::Destroy => {
|
||||
|
|
@ -183,10 +191,10 @@ where
|
|||
{
|
||||
fn request(
|
||||
state: &mut D,
|
||||
client: &Client,
|
||||
_client: &Client,
|
||||
obj: &ExtWorkspaceHandleV1,
|
||||
request: ext_workspace_handle_v1::Request,
|
||||
_data: &WorkspaceData,
|
||||
data: &WorkspaceData,
|
||||
_dh: &DisplayHandle,
|
||||
_data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
|
|
@ -195,39 +203,42 @@ where
|
|||
if let Some(workspace_handle) =
|
||||
state.workspace_state().get_ext_workspace_handle(obj)
|
||||
{
|
||||
let mut state = client
|
||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||
.unwrap()
|
||||
.workspace_state()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Activate(workspace_handle));
|
||||
if let Ok(manager) = data.manager.upgrade() {
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Activate(workspace_handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
ext_workspace_handle_v1::Request::Deactivate => {
|
||||
if let Some(workspace_handle) =
|
||||
state.workspace_state().get_ext_workspace_handle(obj)
|
||||
{
|
||||
let mut state = client
|
||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||
.unwrap()
|
||||
.workspace_state()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Deactivate(workspace_handle));
|
||||
if let Ok(manager) = data.manager.upgrade() {
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Deactivate(workspace_handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
ext_workspace_handle_v1::Request::Remove => {
|
||||
if let Some(workspace_handle) =
|
||||
state.workspace_state().get_ext_workspace_handle(obj)
|
||||
{
|
||||
let mut state = client
|
||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||
.unwrap()
|
||||
.workspace_state()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Remove(workspace_handle));
|
||||
if let Ok(manager) = data.manager.upgrade() {
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Remove(workspace_handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
ext_workspace_handle_v1::Request::Assign { workspace_group } => {
|
||||
|
|
@ -241,16 +252,17 @@ where
|
|||
.find(|g| g.ext_instances.contains(&workspace_group))
|
||||
.map(|g| g.id)
|
||||
{
|
||||
let mut state = client
|
||||
.get_data::<<D as WorkspaceHandler>::Client>()
|
||||
.unwrap()
|
||||
.workspace_state()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Assign {
|
||||
workspace: workspace_handle,
|
||||
group: WorkspaceGroupHandle { id: group_id },
|
||||
});
|
||||
if let Ok(manager) = data.manager.upgrade() {
|
||||
let mut state = manager
|
||||
.data::<WorkspaceManagerData>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.requests.push(Request::Assign {
|
||||
workspace: workspace_handle,
|
||||
group: WorkspaceGroupHandle { id: group_id },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
use smithay::{
|
||||
output::Output,
|
||||
reexports::{
|
||||
|
|
@ -11,7 +9,7 @@ use smithay::{
|
|||
ext_workspace_manager_v1::ExtWorkspaceManagerV1,
|
||||
},
|
||||
wayland_server::{
|
||||
backend::{ClientData, GlobalId, ObjectId},
|
||||
backend::{GlobalId, ObjectId},
|
||||
Client, Dispatch, DisplayHandle, GlobalDispatch, Resource,
|
||||
},
|
||||
},
|
||||
|
|
@ -26,7 +24,7 @@ use cosmic_protocols::workspace::v2::server::{
|
|||
mod cosmic_v2;
|
||||
pub use cosmic_v2::CosmicWorkspaceV2Data;
|
||||
mod ext;
|
||||
pub use ext::{WorkspaceData, WorkspaceGroupData};
|
||||
pub use ext::{WorkspaceData, WorkspaceGroupData, WorkspaceManagerData};
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
|
|
@ -111,7 +109,7 @@ pub struct WorkspaceHandle {
|
|||
pub trait WorkspaceHandler
|
||||
where
|
||||
Self: GlobalDispatch<ExtWorkspaceManagerV1, WorkspaceGlobalData>
|
||||
+ Dispatch<ExtWorkspaceManagerV1, ()>
|
||||
+ Dispatch<ExtWorkspaceManagerV1, WorkspaceManagerData>
|
||||
+ Dispatch<ExtWorkspaceGroupHandleV1, WorkspaceGroupData>
|
||||
+ Dispatch<ExtWorkspaceHandleV1, WorkspaceData>
|
||||
+ GlobalDispatch<ZcosmicWorkspaceManagerV2, WorkspaceGlobalData>
|
||||
|
|
@ -120,8 +118,6 @@ where
|
|||
+ Sized
|
||||
+ 'static,
|
||||
{
|
||||
type Client: ClientData + WorkspaceClientHandler + 'static;
|
||||
|
||||
fn workspace_state(&self) -> &WorkspaceState<Self>;
|
||||
fn workspace_state_mut(&mut self) -> &mut WorkspaceState<Self>;
|
||||
fn commit_requests(&mut self, dh: &DisplayHandle, requests: Vec<Request>);
|
||||
|
|
@ -154,16 +150,6 @@ pub enum Request {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct WorkspaceClientStateInner {
|
||||
requests: Vec<Request>,
|
||||
}
|
||||
pub type WorkspaceClientState = Mutex<WorkspaceClientStateInner>;
|
||||
|
||||
pub trait WorkspaceClientHandler {
|
||||
fn workspace_state(&self) -> &WorkspaceClientState;
|
||||
}
|
||||
|
||||
impl<D> WorkspaceState<D>
|
||||
where
|
||||
D: WorkspaceHandler,
|
||||
|
|
@ -580,7 +566,7 @@ macro_rules! delegate_workspace {
|
|||
smithay::reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_manager_v1::ExtWorkspaceManagerV1: $crate::wayland::protocols::workspace::WorkspaceGlobalData
|
||||
] => $crate::wayland::protocols::workspace::WorkspaceState<Self>);
|
||||
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||
smithay::reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_manager_v1::ExtWorkspaceManagerV1: ()
|
||||
smithay::reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_manager_v1::ExtWorkspaceManagerV1: $crate::wayland::protocols::workspace::WorkspaceManagerData
|
||||
] => $crate::wayland::protocols::workspace::WorkspaceState<Self>);
|
||||
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||
smithay::reexports::wayland_protocols::ext::workspace::v1::server::ext_workspace_group_handle_v1::ExtWorkspaceGroupHandleV1: $crate::wayland::protocols::workspace::WorkspaceGroupData
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue