From 2fe5897db01ec9a07f1e135b887cd1655203fcd4 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 3 Mar 2025 16:19:41 -0800 Subject: [PATCH] Replace screencopy with `ext-image-copy-capture-v1` --- src/state.rs | 9 +- src/wayland/handlers/image_capture_source.rs | 4 + src/wayland/handlers/image_source.rs | 4 - src/wayland/handlers/mod.rs | 2 +- src/wayland/handlers/screencopy/mod.rs | 57 +-- src/wayland/protocols/image_capture_source.rs | 372 +++++++++++++++ src/wayland/protocols/image_source.rs | 435 ------------------ src/wayland/protocols/mod.rs | 2 +- src/wayland/protocols/screencopy.rs | 204 ++++---- src/wayland/protocols/toplevel_info.rs | 31 +- 10 files changed, 545 insertions(+), 575 deletions(-) create mode 100644 src/wayland/handlers/image_capture_source.rs delete mode 100644 src/wayland/handlers/image_source.rs create mode 100644 src/wayland/protocols/image_capture_source.rs delete mode 100644 src/wayland/protocols/image_source.rs diff --git a/src/state.rs b/src/state.rs index 852e87de..0eaa17ae 100644 --- a/src/state.rs +++ b/src/state.rs @@ -17,7 +17,7 @@ use crate::{ a11y::A11yState, atspi::AtspiState, drm::WlDrmState, - image_source::ImageSourceState, + image_capture_source::ImageCaptureSourceState, output_configuration::OutputConfigurationState, output_power::OutputPowerState, overlap_notify::OverlapNotifyState, @@ -219,7 +219,7 @@ pub struct Common { pub presentation_state: PresentationState, pub primary_selection_state: PrimarySelectionState, pub data_control_state: Option, - pub image_source_state: ImageSourceState, + pub image_capture_source_state: ImageCaptureSourceState, pub screencopy_state: ScreencopyState, pub seat_state: SeatState, pub session_lock_manager_state: SessionLockManagerState, @@ -532,7 +532,8 @@ impl State { OverlapNotifyState::new::(dh, client_has_no_security_context); let presentation_state = PresentationState::new::(dh, clock.id() as u32); let primary_selection_state = PrimarySelectionState::new::(dh); - let image_source_state = ImageSourceState::new::(dh, client_is_privileged); + let image_capture_source_state = + ImageCaptureSourceState::new::(dh, client_is_privileged); let screencopy_state = ScreencopyState::new::(dh, client_is_privileged); let shm_state = ShmState::new::(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]); @@ -632,7 +633,7 @@ impl State { idle_notifier_state, idle_inhibit_manager_state, idle_inhibiting_surfaces, - image_source_state, + image_capture_source_state, screencopy_state, shm_state, cursor_shape_manager_state, diff --git a/src/wayland/handlers/image_capture_source.rs b/src/wayland/handlers/image_capture_source.rs new file mode 100644 index 00000000..686b2aaa --- /dev/null +++ b/src/wayland/handlers/image_capture_source.rs @@ -0,0 +1,4 @@ +use crate::state::State; +use crate::wayland::protocols::image_capture_source::delegate_image_capture_source; + +delegate_image_capture_source!(State); diff --git a/src/wayland/handlers/image_source.rs b/src/wayland/handlers/image_source.rs deleted file mode 100644 index fef8c406..00000000 --- a/src/wayland/handlers/image_source.rs +++ /dev/null @@ -1,4 +0,0 @@ -use crate::state::State; -use crate::wayland::protocols::image_source::delegate_image_source; - -delegate_image_source!(State); diff --git a/src/wayland/handlers/mod.rs b/src/wayland/handlers/mod.rs index 62ec7eed..3d446c14 100644 --- a/src/wayland/handlers/mod.rs +++ b/src/wayland/handlers/mod.rs @@ -16,7 +16,7 @@ pub mod foreign_toplevel_list; pub mod fractional_scale; pub mod idle_inhibit; pub mod idle_notify; -pub mod image_source; +pub mod image_capture_source; pub mod input_method; pub mod keyboard_shortcuts_inhibit; pub mod layer_shell; diff --git a/src/wayland/handlers/screencopy/mod.rs b/src/wayland/handlers/screencopy/mod.rs index 6bb221bd..75aed8d4 100644 --- a/src/wayland/handlers/screencopy/mod.rs +++ b/src/wayland/handlers/screencopy/mod.rs @@ -25,7 +25,7 @@ use crate::{ OutputExt, PointExt, PointGlobalExt, PointLocalExt, RectExt, RectLocalExt, SeatExt, }, wayland::protocols::{ - image_source::ImageSourceData, + image_capture_source::ImageCaptureSourceData, screencopy::{ delegate_screencopy, BufferConstraints, CursorSession, DmabufConstraints, Frame, ScreencopyHandler, ScreencopyState, Session, @@ -44,23 +44,26 @@ impl ScreencopyHandler for State { &mut self.common.screencopy_state } - fn capture_source(&mut self, source: &ImageSourceData) -> Option { + fn capture_source(&mut self, source: &ImageCaptureSourceData) -> Option { match source { - ImageSourceData::Output(weak) => weak + ImageCaptureSourceData::Output(weak) => weak .upgrade() .and_then(|output| constraints_for_output(&output, &mut self.backend)), - ImageSourceData::Workspace(handle) => { + ImageCaptureSourceData::Workspace(handle) => { let shell = self.common.shell.read().unwrap(); let output = shell.workspaces.space_for_handle(&handle)?.output(); constraints_for_output(output, &mut self.backend) } - ImageSourceData::Toplevel(window) => { + ImageCaptureSourceData::Toplevel(window) => { constraints_for_toplevel(window, &mut self.backend) } _ => None, } } - fn capture_cursor_source(&mut self, _source: &ImageSourceData) -> Option { + fn capture_cursor_source( + &mut self, + _source: &ImageCaptureSourceData, + ) -> Option { let size = if let Some((geometry, _)) = self .common .shell @@ -84,7 +87,7 @@ impl ScreencopyHandler for State { fn new_session(&mut self, session: Session) { match session.source() { - ImageSourceData::Output(weak) => { + ImageCaptureSourceData::Output(weak) => { let Some(mut output) = weak.upgrade() else { session.stop(); return; @@ -98,7 +101,7 @@ impl ScreencopyHandler for State { output.add_session(session); } - ImageSourceData::Workspace(handle) => { + ImageCaptureSourceData::Workspace(handle) => { let mut shell = self.common.shell.write().unwrap(); let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else { session.stop(); @@ -112,7 +115,7 @@ impl ScreencopyHandler for State { }); workspace.add_session(session); } - ImageSourceData::Toplevel(mut toplevel) => { + ImageCaptureSourceData::Toplevel(mut toplevel) => { let size = toplevel.geometry().size.to_physical(1); session.user_data().insert_if_missing_threadsafe(|| { Mutex::new(SessionUserData::new(OutputDamageTracker::new( @@ -123,7 +126,7 @@ impl ScreencopyHandler for State { }); toplevel.add_session(session); } - ImageSourceData::Destroyed => unreachable!(), + ImageCaptureSourceData::Destroyed => unreachable!(), } } fn new_cursor_session(&mut self, session: CursorSession) { @@ -160,7 +163,7 @@ impl ScreencopyHandler for State { }); match session.source() { - ImageSourceData::Output(weak) => { + ImageCaptureSourceData::Output(weak) => { let Some(mut output) = weak.upgrade() else { session.stop(); return; @@ -190,7 +193,7 @@ impl ScreencopyHandler for State { output.add_cursor_session(session); } - ImageSourceData::Workspace(handle) => { + ImageCaptureSourceData::Workspace(handle) => { let mut shell = self.common.shell.write().unwrap(); let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else { session.stop(); @@ -222,7 +225,7 @@ impl ScreencopyHandler for State { workspace.add_cursor_session(session); } - ImageSourceData::Toplevel(mut toplevel) => { + ImageCaptureSourceData::Toplevel(mut toplevel) => { let shell = self.common.shell.read().unwrap(); if let Some(element) = shell.element_for_surface(&toplevel) { if element.has_active_window(&toplevel) { @@ -245,13 +248,13 @@ impl ScreencopyHandler for State { toplevel.add_cursor_session(session); } - ImageSourceData::Destroyed => unreachable!(), + ImageCaptureSourceData::Destroyed => unreachable!(), } } fn frame(&mut self, session: Session, frame: Frame) { match session.source() { - ImageSourceData::Output(weak) => { + ImageCaptureSourceData::Output(weak) => { let Some(mut output) = weak.upgrade() else { session.stop(); // will fail the frame as well return; @@ -260,13 +263,13 @@ impl ScreencopyHandler for State { output.add_frame(session, frame); self.backend.schedule_render(&output); } - ImageSourceData::Workspace(handle) => { + ImageCaptureSourceData::Workspace(handle) => { render_workspace_to_buffer(self, session, frame, handle) } - ImageSourceData::Toplevel(toplevel) => { + ImageCaptureSourceData::Toplevel(toplevel) => { render_window_to_buffer(self, session, frame, &toplevel) } - ImageSourceData::Destroyed => unreachable!(), + ImageCaptureSourceData::Destroyed => unreachable!(), } } @@ -296,12 +299,12 @@ impl ScreencopyHandler for State { fn session_destroyed(&mut self, session: Session) { match session.source() { - ImageSourceData::Output(weak) => { + ImageCaptureSourceData::Output(weak) => { if let Some(mut output) = weak.upgrade() { output.remove_session(session); } } - ImageSourceData::Workspace(handle) => { + ImageCaptureSourceData::Workspace(handle) => { if let Some(workspace) = self .common .shell @@ -313,19 +316,19 @@ impl ScreencopyHandler for State { workspace.remove_session(session) } } - ImageSourceData::Toplevel(mut toplevel) => toplevel.remove_session(session), - ImageSourceData::Destroyed => unreachable!(), + ImageCaptureSourceData::Toplevel(mut toplevel) => toplevel.remove_session(session), + ImageCaptureSourceData::Destroyed => unreachable!(), } } fn cursor_session_destroyed(&mut self, session: CursorSession) { match session.source() { - ImageSourceData::Output(weak) => { + ImageCaptureSourceData::Output(weak) => { if let Some(mut output) = weak.upgrade() { output.remove_cursor_session(session); } } - ImageSourceData::Workspace(handle) => { + ImageCaptureSourceData::Workspace(handle) => { if let Some(workspace) = self .common .shell @@ -337,8 +340,10 @@ impl ScreencopyHandler for State { workspace.remove_cursor_session(session) } } - ImageSourceData::Toplevel(mut toplevel) => toplevel.remove_cursor_session(session), - ImageSourceData::Destroyed => unreachable!(), + ImageCaptureSourceData::Toplevel(mut toplevel) => { + toplevel.remove_cursor_session(session) + } + ImageCaptureSourceData::Destroyed => unreachable!(), } } } diff --git a/src/wayland/protocols/image_capture_source.rs b/src/wayland/protocols/image_capture_source.rs new file mode 100644 index 00000000..551c7523 --- /dev/null +++ b/src/wayland/protocols/image_capture_source.rs @@ -0,0 +1,372 @@ +use super::{ + toplevel_info::window_from_ext_handle, + workspace::{WorkspaceHandle, WorkspaceHandler}, +}; +use crate::{ + shell::CosmicSurface, + wayland::protocols::toplevel_info::ToplevelInfoHandler, +}; +use cosmic_protocols::image_capture_source::v1::server::{ + zcosmic_workspace_image_capture_source_manager_v1::{ + Request as CosmicWorkspaceSourceRequest, ZcosmicWorkspaceImageCaptureSourceManagerV1, + }, +}; +use smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::{ + ext_foreign_toplevel_image_capture_source_manager_v1::{ + Request as ToplevelSourceRequest, ExtForeignToplevelImageCaptureSourceManagerV1, + }, + ext_image_capture_source_v1::ExtImageCaptureSourceV1, + ext_output_image_capture_source_manager_v1::{ + Request as OutputSourceRequest, ExtOutputImageCaptureSourceManagerV1, + }, +}; +use smithay::{ + output::{Output, WeakOutput}, + reexports::wayland_server::{ + Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, + }, +}; +use wayland_backend::server::GlobalId; + +#[derive(Debug)] +pub struct ImageCaptureSourceState { + output_source_global: GlobalId, + workspace_source_global: GlobalId, + toplevel_source_global: GlobalId, +} + +pub struct OutputImageCaptureSourceManagerGlobalData { + filter: Box Fn(&'a Client) -> bool + Send + Sync>, +} +pub struct WorkspaceImageCaptureSourceManagerGlobalData { + filter: Box Fn(&'a Client) -> bool + Send + Sync>, +} +pub struct ToplevelImageCaptureSourceManagerGlobalData { + filter: Box Fn(&'a Client) -> bool + Send + Sync>, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum ImageCaptureSourceData { + Output(WeakOutput), + Workspace(WorkspaceHandle), + Toplevel(CosmicSurface), + Destroyed, +} + +impl ImageCaptureSourceState { + pub fn new(display: &DisplayHandle, client_filter: F) -> ImageCaptureSourceState + where + D: GlobalDispatch< + ExtOutputImageCaptureSourceManagerV1, + OutputImageCaptureSourceManagerGlobalData, + > + Dispatch + + GlobalDispatch< + ZcosmicWorkspaceImageCaptureSourceManagerV1, + WorkspaceImageCaptureSourceManagerGlobalData, + > + Dispatch + + GlobalDispatch< + ExtForeignToplevelImageCaptureSourceManagerV1, + ToplevelImageCaptureSourceManagerGlobalData, + > + Dispatch + + Dispatch + + WorkspaceHandler + + 'static, + F: for<'a> Fn(&'a Client) -> bool + Send + Sync + Clone + 'static, + { + ImageCaptureSourceState { + output_source_global: display + .create_global::( + 1, + OutputImageCaptureSourceManagerGlobalData { + filter: Box::new(client_filter.clone()), + }, + ), + workspace_source_global: display + .create_global::( + 1, + WorkspaceImageCaptureSourceManagerGlobalData { + filter: Box::new(client_filter.clone()), + }, + ), + toplevel_source_global: display + .create_global::( + 1, + ToplevelImageCaptureSourceManagerGlobalData { + filter: Box::new(client_filter), + }, + ), + } + } + + pub fn output_source_id(&self) -> &GlobalId { + &self.output_source_global + } + + pub fn workspace_source_id(&self) -> &GlobalId { + &self.workspace_source_global + } + + pub fn toplevel_source_id(&self) -> &GlobalId { + &self.toplevel_source_global + } +} + +impl + GlobalDispatch< + ExtOutputImageCaptureSourceManagerV1, + OutputImageCaptureSourceManagerGlobalData, + D, + > for ImageCaptureSourceState +where + D: GlobalDispatch< + ExtOutputImageCaptureSourceManagerV1, + OutputImageCaptureSourceManagerGlobalData, + > + Dispatch + + Dispatch + + 'static, +{ + fn bind( + _state: &mut D, + _handle: &DisplayHandle, + _client: &Client, + resource: New, + _global_data: &OutputImageCaptureSourceManagerGlobalData, + data_init: &mut DataInit<'_, D>, + ) { + data_init.init(resource, ()); + } + + fn can_view(client: Client, global_data: &OutputImageCaptureSourceManagerGlobalData) -> bool { + (global_data.filter)(&client) + } +} + +impl + GlobalDispatch< + ZcosmicWorkspaceImageCaptureSourceManagerV1, + WorkspaceImageCaptureSourceManagerGlobalData, + D, + > for ImageCaptureSourceState +where + D: GlobalDispatch< + ZcosmicWorkspaceImageCaptureSourceManagerV1, + WorkspaceImageCaptureSourceManagerGlobalData, + > + Dispatch + + Dispatch + + 'static, +{ + fn bind( + _state: &mut D, + _handle: &DisplayHandle, + _client: &Client, + resource: New, + _global_data: &WorkspaceImageCaptureSourceManagerGlobalData, + data_init: &mut DataInit<'_, D>, + ) { + data_init.init(resource, ()); + } + + fn can_view( + client: Client, + global_data: &WorkspaceImageCaptureSourceManagerGlobalData, + ) -> bool { + (global_data.filter)(&client) + } +} + +impl + GlobalDispatch< + ExtForeignToplevelImageCaptureSourceManagerV1, + ToplevelImageCaptureSourceManagerGlobalData, + D, + > for ImageCaptureSourceState +where + D: GlobalDispatch< + ExtForeignToplevelImageCaptureSourceManagerV1, + ToplevelImageCaptureSourceManagerGlobalData, + > + Dispatch + + Dispatch + + 'static, +{ + fn bind( + _state: &mut D, + _handle: &DisplayHandle, + _client: &Client, + resource: New, + _global_data: &ToplevelImageCaptureSourceManagerGlobalData, + data_init: &mut DataInit<'_, D>, + ) { + data_init.init(resource, ()); + } + + fn can_view(client: Client, global_data: &ToplevelImageCaptureSourceManagerGlobalData) -> bool { + (global_data.filter)(&client) + } +} + +impl Dispatch for ImageCaptureSourceState +where + D: Dispatch + + Dispatch + + 'static, +{ + fn request( + _state: &mut D, + _client: &Client, + _resource: &ExtOutputImageCaptureSourceManagerV1, + request: ::Request, + _data: &(), + _dhandle: &DisplayHandle, + data_init: &mut DataInit<'_, D>, + ) { + match request { + OutputSourceRequest::CreateSource { source, output } => { + let data = match Output::from_resource(&output) { + Some(output) => ImageCaptureSourceData::Output(output.downgrade()), + None => ImageCaptureSourceData::Destroyed, + }; + data_init.init(source, data); + } + _ => {} + } + } + + fn destroyed( + _state: &mut D, + _client: wayland_backend::server::ClientId, + _resource: &ExtOutputImageCaptureSourceManagerV1, + _data: &(), + ) { + } +} + +impl Dispatch for ImageCaptureSourceState +where + D: Dispatch + + Dispatch + + WorkspaceHandler + + 'static, +{ + fn request( + state: &mut D, + _client: &Client, + _resource: &ZcosmicWorkspaceImageCaptureSourceManagerV1, + request: ::Request, + _data: &(), + _dhandle: &DisplayHandle, + data_init: &mut DataInit<'_, D>, + ) { + match request { + CosmicWorkspaceSourceRequest::CreateSource { source, output } => { + let data = match state.workspace_state().get_ext_workspace_handle(&output) { + Some(workspace) => ImageCaptureSourceData::Workspace(workspace), + None => ImageCaptureSourceData::Destroyed, + }; + data_init.init(source, data); + } + _ => {} + } + } + + fn destroyed( + _state: &mut D, + _client: wayland_backend::server::ClientId, + _resource: &ZcosmicWorkspaceImageCaptureSourceManagerV1, + _data: &(), + ) { + } +} + +impl Dispatch for ImageCaptureSourceState +where + D: Dispatch + + Dispatch + + ToplevelInfoHandler + + 'static, +{ + fn request( + state: &mut D, + _client: &Client, + _resource: &ExtForeignToplevelImageCaptureSourceManagerV1, + request: ::Request, + _data: &(), + _dhandle: &DisplayHandle, + data_init: &mut DataInit<'_, D>, + ) { + match request { + ToplevelSourceRequest::CreateSource { + source, + toplevel_handle, + } => { + let data = match window_from_ext_handle(state, &toplevel_handle) { + Some(toplevel) => ImageCaptureSourceData::Toplevel(toplevel.clone()), + None => ImageCaptureSourceData::Destroyed, + }; + data_init.init(source, data); + } + _ => {} + } + } + + fn destroyed( + _state: &mut D, + _client: wayland_backend::server::ClientId, + _resource: &ExtForeignToplevelImageCaptureSourceManagerV1, + _data: &(), + ) { + } +} + +impl Dispatch for ImageCaptureSourceState +where + D: Dispatch + 'static, +{ + fn request( + _state: &mut D, + _client: &Client, + _resource: &ExtImageCaptureSourceV1, + request: ::Request, + _data: &ImageCaptureSourceData, + _dhandle: &DisplayHandle, + _data_init: &mut DataInit<'_, D>, + ) { + match request { + _ => {} + } + } + + fn destroyed( + _state: &mut D, + _client: wayland_backend::server::ClientId, + _resource: &ExtImageCaptureSourceV1, + _data: &ImageCaptureSourceData, + ) { + } +} + +macro_rules! delegate_image_capture_source { + ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { + smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1: $crate::wayland::protocols::image_capture_source::OutputImageCaptureSourceManagerGlobalData + ] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState); + smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1: () + ] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState); + smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + cosmic_protocols::image_capture_source::v1::server::zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1: $crate::wayland::protocols::image_capture_source::WorkspaceImageCaptureSourceManagerGlobalData + ] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState); + smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + cosmic_protocols::image_capture_source::v1::server::zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1: () + ] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState); + smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1: $crate::wayland::protocols::image_capture_source::ToplevelImageCaptureSourceManagerGlobalData + ] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState); + smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1: () + ] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState); + smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ + smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_image_capture_source_v1::ExtImageCaptureSourceV1: $crate::wayland::protocols::image_capture_source::ImageCaptureSourceData + ] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState); + }; +} +pub(crate) use delegate_image_capture_source; diff --git a/src/wayland/protocols/image_source.rs b/src/wayland/protocols/image_source.rs deleted file mode 100644 index 4835e0e3..00000000 --- a/src/wayland/protocols/image_source.rs +++ /dev/null @@ -1,435 +0,0 @@ -use super::{ - toplevel_info::window_from_handle, - workspace::{WorkspaceHandle, WorkspaceHandler}, -}; -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, - }, - zcosmic_toplevel_image_source_manager_v1::{ - Request as ToplevelSourceRequest, ZcosmicToplevelImageSourceManagerV1, - }, - zcosmic_workspace_image_source_manager_v1::{ - Request as WorkspaceSourceRequest, ZcosmicWorkspaceImageSourceManagerV1, - }, -}; -use smithay::{ - output::{Output, WeakOutput}, - reexports::wayland_server::{ - Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, - }, -}; -use wayland_backend::server::GlobalId; - -#[derive(Debug)] -pub struct ImageSourceState { - output_source_global: GlobalId, - workspace_source_global: GlobalId, - ext_workspace_source_global: GlobalId, - toplevel_source_global: GlobalId, -} - -pub struct OutputImageSourceManagerGlobalData { - filter: Box Fn(&'a Client) -> bool + Send + Sync>, -} -pub struct WorkspaceImageSourceManagerGlobalData { - filter: Box Fn(&'a Client) -> bool + Send + Sync>, -} -pub struct ToplevelImageSourceManagerGlobalData { - filter: Box Fn(&'a Client) -> bool + Send + Sync>, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum ImageSourceData { - Output(WeakOutput), - Workspace(WorkspaceHandle), - Toplevel(CosmicSurface), - Destroyed, -} - -impl ImageSourceState { - pub fn new(display: &DisplayHandle, client_filter: F) -> ImageSourceState - where - D: GlobalDispatch - + Dispatch - + GlobalDispatch< - ZcosmicWorkspaceImageSourceManagerV1, - WorkspaceImageSourceManagerGlobalData, - > + Dispatch - + GlobalDispatch< - ZcosmicExtWorkspaceImageSourceManagerV1, - WorkspaceImageSourceManagerGlobalData, - > + Dispatch - + GlobalDispatch< - ZcosmicToplevelImageSourceManagerV1, - ToplevelImageSourceManagerGlobalData, - > + Dispatch - + Dispatch - + WorkspaceHandler - + 'static, - F: for<'a> Fn(&'a Client) -> bool + Send + Sync + Clone + 'static, - { - ImageSourceState { - output_source_global: display.create_global::( - 1, - OutputImageSourceManagerGlobalData { - filter: Box::new(client_filter.clone()), - }, - ), - workspace_source_global: display - .create_global::( - 1, - WorkspaceImageSourceManagerGlobalData { - filter: Box::new(client_filter.clone()), - }, - ), - ext_workspace_source_global: display - .create_global::( - 1, - WorkspaceImageSourceManagerGlobalData { - filter: Box::new(client_filter.clone()), - }, - ), - toplevel_source_global: display - .create_global::( - 1, - ToplevelImageSourceManagerGlobalData { - filter: Box::new(client_filter), - }, - ), - } - } - - pub fn output_source_id(&self) -> &GlobalId { - &self.output_source_global - } - - pub fn workspace_source_id(&self) -> &GlobalId { - &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 - } -} - -impl GlobalDispatch - for ImageSourceState -where - D: GlobalDispatch - + Dispatch - + Dispatch - + 'static, -{ - fn bind( - _state: &mut D, - _handle: &DisplayHandle, - _client: &Client, - resource: New, - _global_data: &OutputImageSourceManagerGlobalData, - data_init: &mut DataInit<'_, D>, - ) { - data_init.init(resource, ()); - } - - fn can_view(client: Client, global_data: &OutputImageSourceManagerGlobalData) -> bool { - (global_data.filter)(&client) - } -} - -impl - GlobalDispatch - for ImageSourceState -where - D: GlobalDispatch - + Dispatch - + Dispatch - + 'static, -{ - fn bind( - _state: &mut D, - _handle: &DisplayHandle, - _client: &Client, - resource: New, - _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 - GlobalDispatch< - ZcosmicExtWorkspaceImageSourceManagerV1, - WorkspaceImageSourceManagerGlobalData, - D, - > for ImageSourceState -where - D: GlobalDispatch< - ZcosmicExtWorkspaceImageSourceManagerV1, - WorkspaceImageSourceManagerGlobalData, - > + Dispatch - + Dispatch - + 'static, -{ - fn bind( - _state: &mut D, - _handle: &DisplayHandle, - _client: &Client, - resource: New, - _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 GlobalDispatch - for ImageSourceState -where - D: GlobalDispatch - + Dispatch - + Dispatch - + 'static, -{ - fn bind( - _state: &mut D, - _handle: &DisplayHandle, - _client: &Client, - resource: New, - _global_data: &ToplevelImageSourceManagerGlobalData, - data_init: &mut DataInit<'_, D>, - ) { - data_init.init(resource, ()); - } - - fn can_view(client: Client, global_data: &ToplevelImageSourceManagerGlobalData) -> bool { - (global_data.filter)(&client) - } -} - -impl Dispatch for ImageSourceState -where - D: Dispatch - + Dispatch - + 'static, -{ - fn request( - _state: &mut D, - _client: &Client, - _resource: &ZcosmicOutputImageSourceManagerV1, - request: ::Request, - _data: &(), - _dhandle: &DisplayHandle, - data_init: &mut DataInit<'_, D>, - ) { - match request { - OutputSourceRequest::CreateSource { source, output } => { - let data = match Output::from_resource(&output) { - Some(output) => ImageSourceData::Output(output.downgrade()), - None => ImageSourceData::Destroyed, - }; - data_init.init(source, data); - } - _ => {} - } - } - - fn destroyed( - _state: &mut D, - _client: wayland_backend::server::ClientId, - _resource: &ZcosmicOutputImageSourceManagerV1, - _data: &(), - ) { - } -} - -impl Dispatch for ImageSourceState -where - D: Dispatch - + Dispatch - + WorkspaceHandler - + 'static, -{ - fn request( - state: &mut D, - _client: &Client, - _resource: &ZcosmicWorkspaceImageSourceManagerV1, - request: ::Request, - _data: &(), - _dhandle: &DisplayHandle, - data_init: &mut DataInit<'_, D>, - ) { - match request { - WorkspaceSourceRequest::CreateSource { source, output } => { - let data = match state.workspace_state().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: &ZcosmicWorkspaceImageSourceManagerV1, - _data: &(), - ) { - } -} - -impl Dispatch for ImageSourceState -where - D: Dispatch - + Dispatch - + WorkspaceHandler - + 'static, -{ - fn request( - state: &mut D, - _client: &Client, - _resource: &ZcosmicExtWorkspaceImageSourceManagerV1, - request: ::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 Dispatch for ImageSourceState -where - D: Dispatch - + Dispatch - + 'static, -{ - fn request( - _state: &mut D, - _client: &Client, - _resource: &ZcosmicToplevelImageSourceManagerV1, - request: ::Request, - _data: &(), - _dhandle: &DisplayHandle, - data_init: &mut DataInit<'_, D>, - ) { - match request { - ToplevelSourceRequest::CreateSource { - source, - toplevel_handle, - } => { - let data = match window_from_handle(toplevel_handle) { - Some(toplevel) => ImageSourceData::Toplevel(toplevel), - None => ImageSourceData::Destroyed, - }; - data_init.init(source, data); - } - _ => {} - } - } - - fn destroyed( - _state: &mut D, - _client: wayland_backend::server::ClientId, - _resource: &ZcosmicToplevelImageSourceManagerV1, - _data: &(), - ) { - } -} - -impl Dispatch for ImageSourceState -where - D: Dispatch + 'static, -{ - fn request( - _state: &mut D, - _client: &Client, - _resource: &ZcosmicImageSourceV1, - request: ::Request, - _data: &ImageSourceData, - _dhandle: &DisplayHandle, - _data_init: &mut DataInit<'_, D>, - ) { - match request { - _ => {} - } - } - - fn destroyed( - _state: &mut D, - _client: wayland_backend::server::ClientId, - _resource: &ZcosmicImageSourceV1, - _data: &ImageSourceData, - ) { - } -} - -macro_rules! delegate_image_source { - ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::image_source::v1::server::zcosmic_output_image_source_manager_v1::ZcosmicOutputImageSourceManagerV1: $crate::wayland::protocols::image_source::OutputImageSourceManagerGlobalData - ] => $crate::wayland::protocols::image_source::ImageSourceState); - smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::image_source::v1::server::zcosmic_output_image_source_manager_v1::ZcosmicOutputImageSourceManagerV1: () - ] => $crate::wayland::protocols::image_source::ImageSourceState); - smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::image_source::v1::server::zcosmic_workspace_image_source_manager_v1::ZcosmicWorkspaceImageSourceManagerV1: $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_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); - smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::image_source::v1::server::zcosmic_toplevel_image_source_manager_v1::ZcosmicToplevelImageSourceManagerV1: () - ] => $crate::wayland::protocols::image_source::ImageSourceState); - smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::image_source::v1::server::zcosmic_image_source_v1::ZcosmicImageSourceV1: $crate::wayland::protocols::image_source::ImageSourceData - ] => $crate::wayland::protocols::image_source::ImageSourceState); - }; -} -pub(crate) use delegate_image_source; diff --git a/src/wayland/protocols/mod.rs b/src/wayland/protocols/mod.rs index a04c8d64..f0c32588 100644 --- a/src/wayland/protocols/mod.rs +++ b/src/wayland/protocols/mod.rs @@ -3,7 +3,7 @@ pub mod a11y; pub mod atspi; pub mod drm; -pub mod image_source; +pub mod image_capture_source; pub mod output_configuration; pub mod output_power; pub mod overlap_notify; diff --git a/src/wayland/protocols/screencopy.rs b/src/wayland/protocols/screencopy.rs index 3b3465db..26a8a543 100644 --- a/src/wayland/protocols/screencopy.rs +++ b/src/wayland/protocols/screencopy.rs @@ -3,12 +3,14 @@ use std::{ time::Duration, }; -pub use cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_frame_v2::FailureReason; -use cosmic_protocols::screencopy::v2::server::{ - zcosmic_screencopy_cursor_session_v2::{self, ZcosmicScreencopyCursorSessionV2}, - zcosmic_screencopy_frame_v2::{self, ZcosmicScreencopyFrameV2}, - zcosmic_screencopy_manager_v2::{self, ZcosmicScreencopyManagerV2}, - zcosmic_screencopy_session_v2::{self, ZcosmicScreencopySessionV2}, +pub use smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::{ + ext_image_copy_capture_frame_v1::FailureReason, +}; +use smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::{ + ext_image_copy_capture_cursor_session_v1::{self, ExtImageCopyCaptureCursorSessionV1}, + ext_image_copy_capture_frame_v1::{self, ExtImageCopyCaptureFrameV1}, + ext_image_copy_capture_manager_v1::{self, ExtImageCopyCaptureManagerV1}, + ext_image_copy_capture_session_v1::{self, ExtImageCopyCaptureSessionV1}, }; use smithay::{ backend::{ @@ -30,7 +32,7 @@ use smithay::{ use tracing::debug; use wayland_backend::server::GlobalId; -use super::image_source::ImageSourceData; +use super::image_capture_source::ImageCaptureSourceData; #[derive(Debug)] pub struct ScreencopyState { @@ -42,18 +44,18 @@ pub struct ScreencopyState { impl ScreencopyState { pub fn new(display: &DisplayHandle, client_filter: F) -> ScreencopyState where - D: GlobalDispatch - + Dispatch - + Dispatch - + Dispatch - + Dispatch - + Dispatch + D: GlobalDispatch + + Dispatch + + Dispatch + + Dispatch + + Dispatch + + Dispatch + ScreencopyHandler + 'static, F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static, { ScreencopyState { - global: display.create_global::( + global: display.create_global::( 1, ScreencopyGlobalData { filter: Box::new(client_filter), @@ -84,7 +86,7 @@ pub struct DmabufConstraints { #[derive(Debug, Clone)] pub struct Session { - obj: ZcosmicScreencopySessionV2, + obj: ExtImageCopyCaptureSessionV1, inner: Arc>, user_data: Arc, } @@ -100,12 +102,12 @@ struct SessionInner { stopped: bool, constraints: Option, draw_cursors: bool, - source: ImageSourceData, + source: ImageCaptureSourceData, active_frames: Vec, } impl SessionInner { - fn new(source: ImageSourceData, draw_cursors: bool) -> SessionInner { + fn new(source: ImageCaptureSourceData, draw_cursors: bool) -> SessionInner { SessionInner { stopped: false, constraints: None, @@ -133,7 +135,7 @@ impl Session { self.obj .buffer_size(constraints.size.w as u32, constraints.size.h as u32); for fmt in &constraints.shm { - self.obj.shm_format(*fmt as u32); + self.obj.shm_format(*fmt); } if let Some(dma) = constraints.dma.as_ref() { let node = Vec::from(dma.node.dev_id().to_ne_bytes()); @@ -155,7 +157,7 @@ impl Session { self.inner.lock().unwrap().constraints.clone() } - pub fn source(&self) -> ImageSourceData { + pub fn source(&self) -> ImageCaptureSourceData { self.inner.lock().unwrap().source.clone() } @@ -186,7 +188,7 @@ impl Session { #[derive(Debug, Clone)] pub struct CursorSession { - obj: ZcosmicScreencopyCursorSessionV2, + obj: ExtImageCopyCaptureCursorSessionV1, inner: Arc>, user_data: Arc, } @@ -199,17 +201,17 @@ impl PartialEq for CursorSession { #[derive(Debug)] struct CursorSessionInner { - session: Option, + session: Option, stopped: bool, constraints: Option, - source: ImageSourceData, + source: ImageCaptureSourceData, position: Option>, hotspot: Point, active_frames: Vec, } impl CursorSessionInner { - fn new(source: ImageSourceData) -> CursorSessionInner { + fn new(source: ImageCaptureSourceData) -> CursorSessionInner { CursorSessionInner { session: None, stopped: false, @@ -239,7 +241,7 @@ impl CursorSession { if let Some(session_obj) = inner.session.as_ref() { session_obj.buffer_size(constrains.size.w as u32, constrains.size.h as u32); for fmt in &constrains.shm { - session_obj.shm_format(*fmt as u32); + session_obj.shm_format(*fmt); } if let Some(dma) = constrains.dma.as_ref() { let node = Vec::from(dma.node.dev_id().to_ne_bytes()); @@ -262,7 +264,7 @@ impl CursorSession { self.inner.lock().unwrap().constraints.clone() } - pub fn source(&self) -> ImageSourceData { + pub fn source(&self) -> ImageCaptureSourceData { self.inner.lock().unwrap().source.clone() } @@ -340,7 +342,7 @@ impl CursorSession { #[derive(Debug)] pub struct Frame { - obj: ZcosmicScreencopyFrameV2, + obj: ExtImageCopyCaptureFrameV1, inner: Arc>, } @@ -404,7 +406,7 @@ struct FrameInner { damage: Vec>, // `SessionInner` contains a `Vec`, so use a weak reference here to // avoid a cycle. - obj: Weak, + obj: Weak, capture_requested: bool, failed: Option, ready: bool, @@ -412,7 +414,7 @@ struct FrameInner { impl FrameInner { fn new( - obj: ZcosmicScreencopySessionV2, + obj: ExtImageCopyCaptureSessionV1, constraints: impl Into>, ) -> Self { FrameInner { @@ -426,7 +428,7 @@ impl FrameInner { } } - fn fail(&mut self, frame: &ZcosmicScreencopyFrameV2, reason: FailureReason) { + fn fail(&mut self, frame: &ExtImageCopyCaptureFrameV1, reason: FailureReason) { if self.ready || self.failed.is_some() { return; } @@ -440,8 +442,11 @@ impl FrameInner { pub trait ScreencopyHandler { fn screencopy_state(&mut self) -> &mut ScreencopyState; - fn capture_source(&mut self, source: &ImageSourceData) -> Option; - fn capture_cursor_source(&mut self, source: &ImageSourceData) -> Option; + fn capture_source(&mut self, source: &ImageCaptureSourceData) -> Option; + fn capture_cursor_source( + &mut self, + source: &ImageCaptureSourceData, + ) -> Option; fn new_session(&mut self, session: Session); fn new_cursor_session(&mut self, session: CursorSession); @@ -475,14 +480,14 @@ pub struct FrameData { inner: Arc>, } -impl GlobalDispatch for ScreencopyState +impl GlobalDispatch for ScreencopyState where - D: GlobalDispatch - + Dispatch - + Dispatch - + Dispatch - + Dispatch - + Dispatch + D: GlobalDispatch + + Dispatch + + Dispatch + + Dispatch + + Dispatch + + Dispatch + ScreencopyHandler + 'static, { @@ -490,7 +495,7 @@ where _state: &mut D, _handle: &DisplayHandle, _client: &Client, - resource: New, + resource: New, _global_data: &ScreencopyGlobalData, data_init: &mut DataInit<'_, D>, ) { @@ -502,33 +507,33 @@ where } } -impl Dispatch for ScreencopyState +impl Dispatch for ScreencopyState where - D: Dispatch - + Dispatch - + Dispatch - + Dispatch - + Dispatch + D: Dispatch + + Dispatch + + Dispatch + + Dispatch + + Dispatch + ScreencopyHandler + 'static, { fn request( state: &mut D, _client: &Client, - _resource: &ZcosmicScreencopyManagerV2, - request: ::Request, + _resource: &ExtImageCopyCaptureManagerV1, + request: ::Request, _data: &ScreencopyData, _dhandle: &DisplayHandle, data_init: &mut DataInit<'_, D>, ) { match request { - zcosmic_screencopy_manager_v2::Request::CreateSession { + ext_image_copy_capture_manager_v1::Request::CreateSession { session, source, options, } => { - if let Some(src) = source.data::() { - if *src != ImageSourceData::Destroyed { + if let Some(src) = source.data::() { + if *src != ImageCaptureSourceData::Destroyed { if let Some(buffer_constraints) = state.capture_source(src) { let session_data = Arc::new(Mutex::new(SessionInner::new( src.clone(), @@ -558,7 +563,7 @@ where } let session_data = Arc::new(Mutex::new(SessionInner::new( - ImageSourceData::Destroyed, + ImageCaptureSourceData::Destroyed, false, ))); let obj = data_init.init( @@ -574,16 +579,15 @@ where }; session.stop(); } - zcosmic_screencopy_manager_v2::Request::CreatePointerCursorSession { + ext_image_copy_capture_manager_v1::Request::CreatePointerCursorSession { session, source, pointer: _, - options: _, } => { // TODO: use pointer, but we need new smithay api for that. - if let Some(src) = source.data::() { - if *src != ImageSourceData::Destroyed { + if let Some(src) = source.data::() { + if *src != ImageCaptureSourceData::Destroyed { if let Some(buffer_constraints) = state.capture_cursor_source(src) { let session_data = Arc::new(Mutex::new(CursorSessionInner::new(src.clone()))); @@ -611,7 +615,7 @@ where } let session_data = Arc::new(Mutex::new(CursorSessionInner::new( - ImageSourceData::Destroyed, + ImageCaptureSourceData::Destroyed, ))); let obj = data_init.init( session, @@ -633,30 +637,30 @@ where fn destroyed( _state: &mut D, _client: wayland_backend::server::ClientId, - _resource: &ZcosmicScreencopyManagerV2, + _resource: &ExtImageCopyCaptureManagerV1, _data: &ScreencopyData, ) { } } -impl Dispatch for ScreencopyState +impl Dispatch for ScreencopyState where - D: Dispatch - + Dispatch + D: Dispatch + + Dispatch + ScreencopyHandler + 'static, { fn request( _state: &mut D, _client: &Client, - resource: &ZcosmicScreencopySessionV2, - request: ::Request, + resource: &ExtImageCopyCaptureSessionV1, + request: ::Request, data: &SessionData, _dhandle: &DisplayHandle, data_init: &mut DataInit<'_, D>, ) { match request { - zcosmic_screencopy_session_v2::Request::CreateFrame { frame } => { + ext_image_copy_capture_session_v1::Request::CreateFrame { frame } => { let inner = Arc::new(Mutex::new(FrameInner::new( resource.clone(), data.inner.lock().unwrap().constraints.clone(), @@ -680,7 +684,7 @@ where fn destroyed( state: &mut D, _client: wayland_backend::server::ClientId, - resource: &ZcosmicScreencopySessionV2, + resource: &ExtImageCopyCaptureSessionV1, _data: &SessionData, ) { let scpy = state.screencopy_state(); @@ -695,25 +699,25 @@ where } } -impl Dispatch for ScreencopyState +impl Dispatch for ScreencopyState where - D: Dispatch - + Dispatch - + Dispatch + D: Dispatch + + Dispatch + + Dispatch + ScreencopyHandler + 'static, { fn request( _state: &mut D, _client: &Client, - resource: &ZcosmicScreencopyCursorSessionV2, - request: ::Request, + resource: &ExtImageCopyCaptureCursorSessionV1, + request: ::Request, data: &CursorSessionData, _dhandle: &DisplayHandle, data_init: &mut DataInit<'_, D>, ) { match request { - zcosmic_screencopy_cursor_session_v2::Request::GetScreencopySession { session } => { + ext_image_copy_capture_cursor_session_v1::Request::GetCaptureSession { session } => { let new_data = CursorSessionData { inner: data.inner.clone(), }; @@ -722,7 +726,7 @@ where let mut inner = data.inner.lock().unwrap(); if inner.session.is_some() { resource.post_error( - zcosmic_screencopy_cursor_session_v2::Error::DuplicateSession, + ext_image_copy_capture_cursor_session_v1::Error::DuplicateSession, "Duplicate session", ); return; @@ -733,7 +737,7 @@ where } else if let Some(constraints) = inner.constraints.as_ref() { session.buffer_size(constraints.size.w as u32, constraints.size.h as u32); for fmt in &constraints.shm { - session.shm_format(*fmt as u32); + session.shm_format(*fmt); } if let Some(dma) = constraints.dma.as_ref() { let node = Vec::from(dma.node.dev_id().to_ne_bytes()); @@ -757,7 +761,7 @@ where fn destroyed( state: &mut D, _client: wayland_backend::server::ClientId, - resource: &ZcosmicScreencopyCursorSessionV2, + resource: &ExtImageCopyCaptureCursorSessionV1, _data: &CursorSessionData, ) { let scpy = state.screencopy_state(); @@ -772,24 +776,24 @@ where } } -impl Dispatch for ScreencopyState +impl Dispatch for ScreencopyState where - D: Dispatch - + Dispatch + D: Dispatch + + Dispatch + ScreencopyHandler + 'static, { fn request( _state: &mut D, _client: &Client, - resource: &ZcosmicScreencopySessionV2, - request: ::Request, + resource: &ExtImageCopyCaptureSessionV1, + request: ::Request, data: &CursorSessionData, _dhandle: &DisplayHandle, data_init: &mut DataInit<'_, D>, ) { match request { - zcosmic_screencopy_session_v2::Request::CreateFrame { frame } => { + ext_image_copy_capture_session_v1::Request::CreateFrame { frame } => { let inner = Arc::new(Mutex::new(FrameInner::new( resource.clone(), data.inner.lock().unwrap().constraints.clone(), @@ -813,39 +817,39 @@ where fn destroyed( _state: &mut D, _client: wayland_backend::server::ClientId, - _resource: &ZcosmicScreencopySessionV2, + _resource: &ExtImageCopyCaptureSessionV1, _data: &CursorSessionData, ) { } } -impl Dispatch for ScreencopyState +impl Dispatch for ScreencopyState where - D: Dispatch + ScreencopyHandler + 'static, + D: Dispatch + ScreencopyHandler + 'static, { fn request( state: &mut D, _client: &Client, - resource: &ZcosmicScreencopyFrameV2, - request: ::Request, + resource: &ExtImageCopyCaptureFrameV1, + request: ::Request, data: &FrameData, _dhandle: &DisplayHandle, _data_init: &mut DataInit<'_, D>, ) { match request { - zcosmic_screencopy_frame_v2::Request::AttachBuffer { buffer } => { + ext_image_copy_capture_frame_v1::Request::AttachBuffer { buffer } => { let mut inner = data.inner.lock().unwrap(); if inner.capture_requested { resource.post_error( - zcosmic_screencopy_frame_v2::Error::AlreadyCaptured, + ext_image_copy_capture_frame_v1::Error::AlreadyCaptured, "Frame was captured previously", ); } inner.buffer = Some(buffer); } - zcosmic_screencopy_frame_v2::Request::DamageBuffer { + ext_image_copy_capture_frame_v1::Request::DamageBuffer { x, y, width, @@ -855,14 +859,14 @@ where if inner.capture_requested { resource.post_error( - zcosmic_screencopy_frame_v2::Error::AlreadyCaptured, + ext_image_copy_capture_frame_v1::Error::AlreadyCaptured, "Frame was captured previously", ); } if x < 0 || y < 0 || width <= 0 || height <= 0 { resource.post_error( - zcosmic_screencopy_frame_v2::Error::InvalidBufferDamage, + ext_image_copy_capture_frame_v1::Error::InvalidBufferDamage, "Coordinates negative or size equal to zero", ); return; @@ -872,19 +876,19 @@ where .damage .push(Rectangle::new((x, y).into(), (width, height).into())); } - zcosmic_screencopy_frame_v2::Request::Capture => { + ext_image_copy_capture_frame_v1::Request::Capture => { let mut inner = data.inner.lock().unwrap(); if inner.capture_requested { resource.post_error( - zcosmic_screencopy_frame_v2::Error::AlreadyCaptured, + ext_image_copy_capture_frame_v1::Error::AlreadyCaptured, "Frame was captured previously", ); } if inner.buffer.is_none() { resource.post_error( - zcosmic_screencopy_frame_v2::Error::NoBuffer, + ext_image_copy_capture_frame_v1::Error::NoBuffer, "Attempting to capture frame without a buffer", ); } @@ -1031,7 +1035,7 @@ where fn destroyed( state: &mut D, _client: wayland_backend::server::ClientId, - resource: &ZcosmicScreencopyFrameV2, + resource: &ExtImageCopyCaptureFrameV1, data: &FrameData, ) { { @@ -1064,22 +1068,22 @@ where macro_rules! delegate_screencopy { ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_manager_v2::ZcosmicScreencopyManagerV2: $crate::wayland::protocols::screencopy::ScreencopyGlobalData + smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1: $crate::wayland::protocols::screencopy::ScreencopyGlobalData ] => $crate::wayland::protocols::screencopy::ScreencopyState); smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_manager_v2::ZcosmicScreencopyManagerV2: $crate::wayland::protocols::screencopy::ScreencopyData + smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1: $crate::wayland::protocols::screencopy::ScreencopyData ] => $crate::wayland::protocols::screencopy::ScreencopyState); smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_session_v2::ZcosmicScreencopySessionV2: $crate::wayland::protocols::screencopy::SessionData + smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1: $crate::wayland::protocols::screencopy::SessionData ] => $crate::wayland::protocols::screencopy::ScreencopyState); smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_cursor_session_v2::ZcosmicScreencopyCursorSessionV2: $crate::wayland::protocols::screencopy::CursorSessionData + smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_cursor_session_v1::ExtImageCopyCaptureCursorSessionV1: $crate::wayland::protocols::screencopy::CursorSessionData ] => $crate::wayland::protocols::screencopy::ScreencopyState); smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_session_v2::ZcosmicScreencopySessionV2: $crate::wayland::protocols::screencopy::CursorSessionData + smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1: $crate::wayland::protocols::screencopy::CursorSessionData ] => $crate::wayland::protocols::screencopy::ScreencopyState); smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_frame_v2::ZcosmicScreencopyFrameV2: $crate::wayland::protocols::screencopy::FrameData + smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_frame_v1::ExtImageCopyCaptureFrameV1: $crate::wayland::protocols::screencopy::FrameData ] => $crate::wayland::protocols::screencopy::ScreencopyState); }; } diff --git a/src/wayland/protocols/toplevel_info.rs b/src/wayland/protocols/toplevel_info.rs index e1013ae0..23415f02 100644 --- a/src/wayland/protocols/toplevel_info.rs +++ b/src/wayland/protocols/toplevel_info.rs @@ -4,10 +4,13 @@ use std::{collections::HashSet, sync::Mutex}; use smithay::{ output::Output, - reexports::wayland_server::{ - backend::{ClientId, GlobalId}, - protocol::{wl_output::WlOutput, wl_surface::WlSurface}, - Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Weak, + reexports::{ + wayland_protocols::ext::foreign_toplevel_list::v1::server::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1, + wayland_server::{ + backend::{ClientId, GlobalId}, + protocol::{wl_output::WlOutput, wl_surface::WlSurface}, + Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Weak, + }, }, utils::{user_data::UserDataMap, IsAlive, Logical, Rectangle}, wayland::foreign_toplevel_list::{ @@ -633,6 +636,26 @@ pub fn window_from_handle(handle: ZcosmicToplevelHandleV1) .and_then(|state| state.lock().unwrap().window.clone()) } +pub fn window_from_ext_handle<'a, W: Window + 'static, D>( + state: &'a D, + foreign_toplevel: &ExtForeignToplevelHandleV1, +) -> Option<&'a W> +where + D: ToplevelInfoHandler, +{ + let handle = ForeignToplevelHandle::from_resource(foreign_toplevel)?; + state.toplevel_info_state().toplevels.iter().find(|w| { + w.user_data().get::().and_then(|inner| { + inner + .lock() + .unwrap() + .foreign_handle + .as_ref() + .map(|handle| handle.identifier()) + }) == Some(handle.identifier()) + }) +} + macro_rules! delegate_toplevel_info { ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty, $window: ty) => { smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [