Merge branch 'master' into fullscreen_panic_fix
This commit is contained in:
commit
00bf8fe215
43 changed files with 632 additions and 1790 deletions
6
src/wayland/handlers/fixes.rs
Normal file
6
src/wayland/handlers/fixes.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::state::State;
|
||||
use smithay::delegate_fixes;
|
||||
|
||||
delegate_fixes!(State);
|
||||
|
|
@ -1,4 +1,59 @@
|
|||
use crate::state::State;
|
||||
use crate::wayland::protocols::image_capture_source::delegate_image_capture_source;
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
delegate_image_capture_source!(State);
|
||||
use crate::{
|
||||
state::State,
|
||||
wayland::protocols::{
|
||||
image_capture_source::{ImageCaptureSourceKind, delegate_cosmic_image_capture_source},
|
||||
toplevel_info::window_from_ext,
|
||||
},
|
||||
};
|
||||
use smithay::{
|
||||
output::Output,
|
||||
wayland::{
|
||||
foreign_toplevel_list::ForeignToplevelHandle,
|
||||
image_capture_source::{
|
||||
ImageCaptureSource, ImageCaptureSourceHandler, OutputCaptureSourceHandler,
|
||||
OutputCaptureSourceState, ToplevelCaptureSourceHandler, ToplevelCaptureSourceState,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
impl ImageCaptureSourceHandler for State {
|
||||
fn source_destroyed(&mut self, _source: ImageCaptureSource) {}
|
||||
}
|
||||
|
||||
impl OutputCaptureSourceHandler for State {
|
||||
fn output_capture_source_state(&mut self) -> &mut OutputCaptureSourceState {
|
||||
&mut self.common.output_capture_source_state
|
||||
}
|
||||
|
||||
fn output_source_created(&mut self, source: ImageCaptureSource, output: &Output) {
|
||||
source
|
||||
.user_data()
|
||||
.insert_if_missing(|| ImageCaptureSourceKind::Output(output.downgrade()));
|
||||
}
|
||||
}
|
||||
|
||||
impl ToplevelCaptureSourceHandler for State {
|
||||
fn toplevel_capture_source_state(&mut self) -> &mut ToplevelCaptureSourceState {
|
||||
&mut self.common.toplevel_capture_source_state
|
||||
}
|
||||
|
||||
fn toplevel_source_created(
|
||||
&mut self,
|
||||
source: ImageCaptureSource,
|
||||
toplevel: &ForeignToplevelHandle,
|
||||
) {
|
||||
let data = match window_from_ext(self, toplevel) {
|
||||
Some(toplevel) => ImageCaptureSourceKind::Toplevel(toplevel.clone()),
|
||||
None => ImageCaptureSourceKind::Destroyed,
|
||||
};
|
||||
source.user_data().insert_if_missing(|| data);
|
||||
}
|
||||
}
|
||||
|
||||
smithay::delegate_image_capture_source!(State);
|
||||
smithay::delegate_output_capture_source!(State);
|
||||
smithay::delegate_toplevel_capture_source!(State);
|
||||
|
||||
delegate_cosmic_image_capture_source!(State);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::{borrow::Borrow, collections::HashMap, sync::Mutex};
|
||||
|
||||
use smithay::{
|
||||
|
|
@ -15,7 +17,15 @@ use smithay::{
|
|||
output::Output,
|
||||
reexports::wayland_server::protocol::wl_shm::Format as ShmFormat,
|
||||
utils::{Buffer as BufferCoords, Point, Size, Transform},
|
||||
wayland::{dmabuf::get_dmabuf, seat::WaylandFocus},
|
||||
wayland::{
|
||||
dmabuf::get_dmabuf,
|
||||
image_capture_source::ImageCaptureSource,
|
||||
image_copy_capture::{
|
||||
BufferConstraints, CursorSession, CursorSessionRef, DmabufConstraints, Frame, FrameRef,
|
||||
ImageCopyCaptureHandler, ImageCopyCaptureState, Session, SessionRef,
|
||||
},
|
||||
seat::WaylandFocus,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -24,45 +34,41 @@ use crate::{
|
|||
utils::prelude::{
|
||||
OutputExt, PointExt, PointGlobalExt, PointLocalExt, RectExt, RectLocalExt, SeatExt,
|
||||
},
|
||||
wayland::protocols::{
|
||||
image_capture_source::ImageCaptureSourceData,
|
||||
screencopy::{
|
||||
BufferConstraints, CursorSession, CursorSessionRef, DmabufConstraints, Frame, FrameRef,
|
||||
ScreencopyHandler, ScreencopyState, Session, SessionRef, delegate_screencopy,
|
||||
},
|
||||
},
|
||||
wayland::protocols::image_capture_source::ImageCaptureSourceKind,
|
||||
};
|
||||
|
||||
mod render;
|
||||
mod user_data;
|
||||
pub use self::render::*;
|
||||
use self::user_data::*;
|
||||
pub use self::user_data::{FrameHolder, ScreencopySessions, SessionData, SessionHolder};
|
||||
pub use self::user_data::{FrameHolder, ImageCopySessions, SessionData, SessionHolder};
|
||||
|
||||
impl ScreencopyHandler for State {
|
||||
fn screencopy_state(&mut self) -> &mut ScreencopyState {
|
||||
&mut self.common.screencopy_state
|
||||
impl ImageCopyCaptureHandler for State {
|
||||
fn image_copy_capture_state(&mut self) -> &mut ImageCopyCaptureState {
|
||||
&mut self.common.image_copy_capture_state
|
||||
}
|
||||
|
||||
fn capture_source(&mut self, source: &ImageCaptureSourceData) -> Option<BufferConstraints> {
|
||||
match source {
|
||||
ImageCaptureSourceData::Output(weak) => weak
|
||||
fn capture_constraints(&mut self, source: &ImageCaptureSource) -> Option<BufferConstraints> {
|
||||
let kind = source.user_data().get::<ImageCaptureSourceKind>().unwrap();
|
||||
match kind {
|
||||
ImageCaptureSourceKind::Output(weak) => weak
|
||||
.upgrade()
|
||||
.and_then(|output| constraints_for_output(&output, &mut self.backend)),
|
||||
ImageCaptureSourceData::Workspace(handle) => {
|
||||
ImageCaptureSourceKind::Workspace(handle) => {
|
||||
let shell = self.common.shell.read();
|
||||
let output = shell.workspaces.space_for_handle(handle)?.output();
|
||||
constraints_for_output(output, &mut self.backend)
|
||||
}
|
||||
ImageCaptureSourceData::Toplevel(window) => {
|
||||
ImageCaptureSourceKind::Toplevel(window) => {
|
||||
constraints_for_toplevel(window, &mut self.backend)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn capture_cursor_source(
|
||||
|
||||
fn cursor_capture_constraints(
|
||||
&mut self,
|
||||
_source: &ImageCaptureSourceData,
|
||||
_source: &ImageCaptureSource,
|
||||
) -> Option<BufferConstraints> {
|
||||
let size = if let Some((geometry, _)) = self
|
||||
.common
|
||||
|
|
@ -85,8 +91,14 @@ impl ScreencopyHandler for State {
|
|||
}
|
||||
|
||||
fn new_session(&mut self, session: Session) {
|
||||
match session.source() {
|
||||
ImageCaptureSourceData::Output(weak) => {
|
||||
let kind = session
|
||||
.source()
|
||||
.user_data()
|
||||
.get::<ImageCaptureSourceKind>()
|
||||
.unwrap()
|
||||
.clone();
|
||||
match kind {
|
||||
ImageCaptureSourceKind::Output(weak) => {
|
||||
let Some(mut output) = weak.upgrade() else {
|
||||
session.stop();
|
||||
return;
|
||||
|
|
@ -100,7 +112,7 @@ impl ScreencopyHandler for State {
|
|||
|
||||
output.add_session(session);
|
||||
}
|
||||
ImageCaptureSourceData::Workspace(handle) => {
|
||||
ImageCaptureSourceKind::Workspace(handle) => {
|
||||
let mut shell = self.common.shell.write();
|
||||
let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else {
|
||||
session.stop();
|
||||
|
|
@ -114,7 +126,7 @@ impl ScreencopyHandler for State {
|
|||
});
|
||||
workspace.add_session(session);
|
||||
}
|
||||
ImageCaptureSourceData::Toplevel(mut toplevel) => {
|
||||
ImageCaptureSourceKind::Toplevel(mut toplevel) => {
|
||||
let size = toplevel.geometry().size.to_physical(1);
|
||||
session.user_data().insert_if_missing_threadsafe(|| {
|
||||
Mutex::new(SessionUserData::new(OutputDamageTracker::new(
|
||||
|
|
@ -125,9 +137,10 @@ impl ScreencopyHandler for State {
|
|||
});
|
||||
toplevel.add_session(session);
|
||||
}
|
||||
ImageCaptureSourceData::Destroyed => unreachable!(),
|
||||
ImageCaptureSourceKind::Destroyed => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_cursor_session(&mut self, session: CursorSession) {
|
||||
let (pointer_loc, pointer_size, hotspot) = {
|
||||
let seat = self.common.shell.read().seats.last_active().clone();
|
||||
|
|
@ -154,8 +167,14 @@ impl ScreencopyHandler for State {
|
|||
)))
|
||||
});
|
||||
|
||||
match session.source() {
|
||||
ImageCaptureSourceData::Output(weak) => {
|
||||
let kind = session
|
||||
.source()
|
||||
.user_data()
|
||||
.get::<ImageCaptureSourceKind>()
|
||||
.unwrap()
|
||||
.clone();
|
||||
match kind {
|
||||
ImageCaptureSourceKind::Output(weak) => {
|
||||
let Some(mut output) = weak.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -184,7 +203,7 @@ impl ScreencopyHandler for State {
|
|||
|
||||
output.add_cursor_session(session);
|
||||
}
|
||||
ImageCaptureSourceData::Workspace(handle) => {
|
||||
ImageCaptureSourceKind::Workspace(handle) => {
|
||||
let mut shell = self.common.shell.write();
|
||||
let Some(workspace) = shell.workspaces.space_for_handle_mut(&handle) else {
|
||||
return;
|
||||
|
|
@ -215,7 +234,7 @@ impl ScreencopyHandler for State {
|
|||
|
||||
workspace.add_cursor_session(session);
|
||||
}
|
||||
ImageCaptureSourceData::Toplevel(mut toplevel) => {
|
||||
ImageCaptureSourceKind::Toplevel(mut toplevel) => {
|
||||
let shell = self.common.shell.read();
|
||||
if let Some(element) = shell.element_for_surface(&toplevel) {
|
||||
if element.has_active_window(&toplevel) {
|
||||
|
|
@ -238,38 +257,44 @@ impl ScreencopyHandler for State {
|
|||
|
||||
toplevel.add_cursor_session(session);
|
||||
}
|
||||
ImageCaptureSourceData::Destroyed => unreachable!(),
|
||||
ImageCaptureSourceKind::Destroyed => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn frame(&mut self, session: SessionRef, frame: Frame) {
|
||||
match session.source() {
|
||||
ImageCaptureSourceData::Output(weak) => {
|
||||
fn frame(&mut self, session: &SessionRef, frame: Frame) {
|
||||
let kind = session
|
||||
.source()
|
||||
.user_data()
|
||||
.get::<ImageCaptureSourceKind>()
|
||||
.unwrap()
|
||||
.clone();
|
||||
match kind {
|
||||
ImageCaptureSourceKind::Output(weak) => {
|
||||
let Some(mut output) = weak.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
output.add_frame(session, frame);
|
||||
output.add_frame(session.clone(), frame);
|
||||
self.backend.schedule_render(&output);
|
||||
}
|
||||
ImageCaptureSourceData::Workspace(handle) => {
|
||||
ImageCaptureSourceKind::Workspace(handle) => {
|
||||
render_workspace_to_buffer(self, session, frame, handle)
|
||||
}
|
||||
ImageCaptureSourceData::Toplevel(toplevel) => {
|
||||
ImageCaptureSourceKind::Toplevel(toplevel) => {
|
||||
render_window_to_buffer(self, session, frame, &toplevel)
|
||||
}
|
||||
ImageCaptureSourceData::Destroyed => unreachable!(),
|
||||
ImageCaptureSourceKind::Destroyed => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn cursor_frame(&mut self, session: CursorSessionRef, frame: Frame) {
|
||||
fn cursor_frame(&mut self, session: &CursorSessionRef, frame: Frame) {
|
||||
if !session.has_cursor() {
|
||||
frame.success(Transform::Normal, Vec::new(), self.common.clock.now());
|
||||
return;
|
||||
}
|
||||
|
||||
let seat = self.common.shell.read().seats.last_active().clone();
|
||||
render_cursor_to_buffer(self, &session, frame, &seat);
|
||||
render_cursor_to_buffer(self, session, frame, &seat);
|
||||
}
|
||||
|
||||
fn frame_aborted(&mut self, frame: FrameRef) {
|
||||
|
|
@ -280,13 +305,19 @@ impl ScreencopyHandler for State {
|
|||
}
|
||||
|
||||
fn session_destroyed(&mut self, session: SessionRef) {
|
||||
match session.source() {
|
||||
ImageCaptureSourceData::Output(weak) => {
|
||||
let kind = session
|
||||
.source()
|
||||
.user_data()
|
||||
.get::<ImageCaptureSourceKind>()
|
||||
.unwrap()
|
||||
.clone();
|
||||
match kind {
|
||||
ImageCaptureSourceKind::Output(weak) => {
|
||||
if let Some(mut output) = weak.upgrade() {
|
||||
output.remove_session(&session);
|
||||
}
|
||||
}
|
||||
ImageCaptureSourceData::Workspace(handle) => {
|
||||
ImageCaptureSourceKind::Workspace(handle) => {
|
||||
if let Some(workspace) = self
|
||||
.common
|
||||
.shell
|
||||
|
|
@ -297,19 +328,25 @@ impl ScreencopyHandler for State {
|
|||
workspace.remove_session(&session)
|
||||
}
|
||||
}
|
||||
ImageCaptureSourceData::Toplevel(mut toplevel) => toplevel.remove_session(&session),
|
||||
ImageCaptureSourceData::Destroyed => unreachable!(),
|
||||
ImageCaptureSourceKind::Toplevel(mut toplevel) => toplevel.remove_session(&session),
|
||||
ImageCaptureSourceKind::Destroyed => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn cursor_session_destroyed(&mut self, session: CursorSessionRef) {
|
||||
match session.source() {
|
||||
ImageCaptureSourceData::Output(weak) => {
|
||||
let kind = session
|
||||
.source()
|
||||
.user_data()
|
||||
.get::<ImageCaptureSourceKind>()
|
||||
.unwrap()
|
||||
.clone();
|
||||
match kind {
|
||||
ImageCaptureSourceKind::Output(weak) => {
|
||||
if let Some(mut output) = weak.upgrade() {
|
||||
output.remove_cursor_session(&session);
|
||||
}
|
||||
}
|
||||
ImageCaptureSourceData::Workspace(handle) => {
|
||||
ImageCaptureSourceKind::Workspace(handle) => {
|
||||
if let Some(workspace) = self
|
||||
.common
|
||||
.shell
|
||||
|
|
@ -320,10 +357,10 @@ impl ScreencopyHandler for State {
|
|||
workspace.remove_cursor_session(&session)
|
||||
}
|
||||
}
|
||||
ImageCaptureSourceData::Toplevel(mut toplevel) => {
|
||||
ImageCaptureSourceKind::Toplevel(mut toplevel) => {
|
||||
toplevel.remove_cursor_session(&session)
|
||||
}
|
||||
ImageCaptureSourceData::Destroyed => unreachable!(),
|
||||
ImageCaptureSourceKind::Destroyed => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -413,4 +450,4 @@ fn constraints_for_renderer(
|
|||
constraints
|
||||
}
|
||||
|
||||
delegate_screencopy!(State);
|
||||
smithay::delegate_image_copy_capture!(State);
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use calloop::LoopHandle;
|
||||
use smithay::{
|
||||
backend::{
|
||||
|
|
@ -26,6 +28,9 @@ use smithay::{
|
|||
},
|
||||
wayland::{
|
||||
dmabuf::get_dmabuf,
|
||||
image_copy_capture::{
|
||||
BufferConstraints, CaptureFailureReason, CursorSessionRef, Frame, SessionRef,
|
||||
},
|
||||
seat::WaylandFocus,
|
||||
shm::{shm_format_to_fourcc, with_buffer_contents, with_buffer_contents_mut},
|
||||
},
|
||||
|
|
@ -43,13 +48,10 @@ use crate::{
|
|||
state::{Common, KmsNodes, State},
|
||||
utils::prelude::{PointExt, PointGlobalExt, RectExt, RectLocalExt, SeatExt},
|
||||
wayland::{
|
||||
handlers::screencopy::{
|
||||
handlers::image_copy_capture::{
|
||||
SessionData, SessionUserData, constraints_for_output, constraints_for_toplevel,
|
||||
},
|
||||
protocols::{
|
||||
screencopy::{BufferConstraints, CursorSessionRef, FailureReason, Frame, SessionRef},
|
||||
workspace::WorkspaceHandle,
|
||||
},
|
||||
protocols::workspace::WorkspaceHandle,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -165,7 +167,7 @@ where
|
|||
.map_err(|err| R::Error::from_gles_error(GlesError::BufferAccessError(err)))
|
||||
.and_then(|x| x)
|
||||
{
|
||||
frame.fail(FailureReason::Unknown);
|
||||
frame.fail(CaptureFailureReason::Unknown);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
|
|
@ -223,7 +225,7 @@ where
|
|||
// TODO re-use offscreen buffer to damage track screencopy to shm
|
||||
0
|
||||
} else {
|
||||
session_damage_tracking.age_for_buffer(&buffer)
|
||||
1
|
||||
};
|
||||
let mut fb = offscreen
|
||||
.as_mut()
|
||||
|
|
@ -249,7 +251,7 @@ where
|
|||
)
|
||||
.map_err(DTError::Rendering),
|
||||
Err(err) => {
|
||||
frame.fail(FailureReason::Unknown);
|
||||
frame.fail(CaptureFailureReason::Unknown);
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -257,7 +259,7 @@ where
|
|||
|
||||
pub fn render_workspace_to_buffer(
|
||||
state: &mut State,
|
||||
session: SessionRef,
|
||||
session: &SessionRef,
|
||||
frame: Frame,
|
||||
handle: WorkspaceHandle,
|
||||
) {
|
||||
|
|
@ -278,14 +280,14 @@ pub fn render_workspace_to_buffer(
|
|||
let buffer_size = buffer_dimensions(&buffer).unwrap();
|
||||
if mode != Some(buffer_size) {
|
||||
let Some(constraints) = constraints_for_output(&output, &mut state.backend) else {
|
||||
output.remove_session(&session);
|
||||
output.remove_session(session);
|
||||
return;
|
||||
};
|
||||
session.update_constraints(constraints);
|
||||
if let Some(data) = session.user_data().get::<SessionData>() {
|
||||
*data.lock().unwrap() = SessionUserData::new(OutputDamageTracker::from_output(&output));
|
||||
}
|
||||
frame.fail(FailureReason::BufferConstraints);
|
||||
frame.fail(CaptureFailureReason::BufferConstraints);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -414,7 +416,7 @@ pub fn render_workspace_to_buffer(
|
|||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
frame.fail(CaptureFailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
@ -490,17 +492,16 @@ smithay::render_elements! {
|
|||
pub WindowCaptureElement<R> where R: ImportAll + ImportMem;
|
||||
WaylandElement=WaylandSurfaceRenderElement<R>,
|
||||
CursorElement=RelocateRenderElement<cursor::CursorRenderElement<R>>,
|
||||
AdditionalDamage=DamageElement,
|
||||
}
|
||||
|
||||
pub fn render_window_to_buffer(
|
||||
state: &mut State,
|
||||
session: SessionRef,
|
||||
session: &SessionRef,
|
||||
frame: Frame,
|
||||
toplevel: &CosmicSurface,
|
||||
) {
|
||||
if !toplevel.alive() {
|
||||
toplevel.clone().remove_session(&session);
|
||||
toplevel.clone().remove_session(session);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +510,7 @@ pub fn render_window_to_buffer(
|
|||
let buffer_size = buffer_dimensions(&buffer).unwrap();
|
||||
if buffer_size != geometry.size.to_buffer(1, Transform::Normal) {
|
||||
let Some(constraints) = constraints_for_toplevel(toplevel, &mut state.backend) else {
|
||||
toplevel.clone().remove_session(&session);
|
||||
toplevel.clone().remove_session(session);
|
||||
return;
|
||||
};
|
||||
session.update_constraints(constraints);
|
||||
|
|
@ -518,7 +519,7 @@ pub fn render_window_to_buffer(
|
|||
*data.lock().unwrap() =
|
||||
SessionUserData::new(OutputDamageTracker::new(size, 1.0, Transform::Normal));
|
||||
}
|
||||
frame.fail(FailureReason::BufferConstraints);
|
||||
frame.fail(CaptureFailureReason::BufferConstraints);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -541,22 +542,19 @@ pub fn render_window_to_buffer(
|
|||
CosmicElement<R>: RenderElement<R>,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let mut elements = Vec::new();
|
||||
|
||||
elements.extend(
|
||||
additional_damage
|
||||
.into_iter()
|
||||
.filter_map(|rect| {
|
||||
let logical_rect = rect.to_logical(
|
||||
1,
|
||||
Transform::Normal,
|
||||
&geometry.size.to_buffer(1, Transform::Normal),
|
||||
);
|
||||
logical_rect.intersection(Rectangle::from_size(geometry.size))
|
||||
})
|
||||
.map(DamageElement::new)
|
||||
.map(Into::<WindowCaptureElement<R>>::into),
|
||||
);
|
||||
let additional_damage_elements: Vec<_> = additional_damage
|
||||
.into_iter()
|
||||
.filter_map(|rect| {
|
||||
let logical_rect = rect.to_logical(
|
||||
1,
|
||||
Transform::Normal,
|
||||
&geometry.size.to_buffer(1, Transform::Normal),
|
||||
);
|
||||
logical_rect.intersection(Rectangle::from_size(geometry.size))
|
||||
})
|
||||
.map(DamageElement::new)
|
||||
.collect();
|
||||
dt.damage_output(age, &additional_damage_elements)?;
|
||||
|
||||
let shell = common.shell.read();
|
||||
let seat = shell.seats.last_active().clone();
|
||||
|
|
@ -579,6 +577,8 @@ pub fn render_window_to_buffer(
|
|||
};
|
||||
std::mem::drop(shell);
|
||||
|
||||
let mut elements = Vec::new();
|
||||
|
||||
if let Some(location) = location {
|
||||
if draw_cursor {
|
||||
elements.extend(
|
||||
|
|
@ -666,7 +666,7 @@ pub fn render_window_to_buffer(
|
|||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
frame.fail(CaptureFailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
@ -760,7 +760,7 @@ pub fn render_cursor_to_buffer(
|
|||
Transform::Normal,
|
||||
));
|
||||
}
|
||||
frame.fail(FailureReason::BufferConstraints);
|
||||
frame.fail(CaptureFailureReason::BufferConstraints);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -781,7 +781,17 @@ pub fn render_cursor_to_buffer(
|
|||
CosmicElement<R>: RenderElement<R>,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
{
|
||||
let mut elements = cursor::draw_cursor(
|
||||
let additional_damage_elements: Vec<_> = additional_damage
|
||||
.into_iter()
|
||||
.filter_map(|rect| {
|
||||
let logical_rect = rect.to_logical(1, Transform::Normal, &Size::from((64, 64)));
|
||||
logical_rect.intersection(Rectangle::from_size((64, 64).into()))
|
||||
})
|
||||
.map(DamageElement::new)
|
||||
.collect();
|
||||
dt.damage_output(age, &additional_damage_elements)?;
|
||||
|
||||
let elements = cursor::draw_cursor(
|
||||
renderer,
|
||||
seat,
|
||||
Point::from((0.0, 0.0)),
|
||||
|
|
@ -795,17 +805,6 @@ pub fn render_cursor_to_buffer(
|
|||
.map(WindowCaptureElement::from)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
elements.extend(
|
||||
additional_damage
|
||||
.into_iter()
|
||||
.filter_map(|rect| {
|
||||
let logical_rect = rect.to_logical(1, Transform::Normal, &Size::from((64, 64)));
|
||||
logical_rect.intersection(Rectangle::from_size((64, 64).into()))
|
||||
})
|
||||
.map(DamageElement::new)
|
||||
.map(Into::<WindowCaptureElement<R>>::into),
|
||||
);
|
||||
|
||||
if let Ok(dmabuf) = get_dmabuf(buffer) {
|
||||
let mut dmabuf_clone = dmabuf.clone();
|
||||
let mut fb = renderer
|
||||
|
|
@ -826,7 +825,7 @@ pub fn render_cursor_to_buffer(
|
|||
Ok(renderer) => renderer,
|
||||
Err(err) => {
|
||||
warn!(?err, "Couldn't use node for screencopy");
|
||||
frame.fail(FailureReason::Unknown);
|
||||
frame.fail(CaptureFailureReason::Unknown);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,60 +1,34 @@
|
|||
use std::{cell::RefCell, collections::HashMap, sync::Mutex};
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::{cell::RefCell, sync::Mutex};
|
||||
|
||||
use smithay::{
|
||||
backend::renderer::{damage::OutputDamageTracker, utils::CommitCounter},
|
||||
backend::renderer::damage::OutputDamageTracker,
|
||||
output::Output,
|
||||
reexports::wayland_server::{Resource, Weak, protocol::wl_buffer::WlBuffer},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
shell::{CosmicSurface, Workspace},
|
||||
wayland::protocols::screencopy::{
|
||||
wayland::image_copy_capture::{
|
||||
CursorSession, CursorSessionRef, Frame, FrameRef, Session, SessionRef,
|
||||
},
|
||||
};
|
||||
|
||||
type ScreencopySessionsData = RefCell<ScreencopySessions>;
|
||||
type PendingScreencopyBuffers = Mutex<Vec<(SessionRef, Frame)>>;
|
||||
use crate::shell::{CosmicSurface, Workspace};
|
||||
|
||||
type ImageCopySessionsData = RefCell<ImageCopySessions>;
|
||||
type PendingImageCopyBuffers = Mutex<Vec<(SessionRef, Frame)>>;
|
||||
|
||||
pub type SessionData = Mutex<SessionUserData>;
|
||||
|
||||
pub struct SessionUserData {
|
||||
pub dt: OutputDamageTracker,
|
||||
commit_counter: CommitCounter,
|
||||
buffer_age: HashMap<Weak<WlBuffer>, CommitCounter>,
|
||||
}
|
||||
|
||||
impl SessionUserData {
|
||||
pub fn new(tracker: OutputDamageTracker) -> SessionUserData {
|
||||
SessionUserData {
|
||||
dt: tracker,
|
||||
commit_counter: CommitCounter::default(),
|
||||
buffer_age: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn age_for_buffer(&mut self, buffer: &WlBuffer) -> usize {
|
||||
self.buffer_age.retain(|k, _| k.upgrade().is_ok());
|
||||
|
||||
let weak = buffer.downgrade();
|
||||
let age = self
|
||||
.commit_counter
|
||||
.distance(self.buffer_age.get(&weak).copied())
|
||||
.unwrap_or(0);
|
||||
self.buffer_age.insert(weak, self.commit_counter);
|
||||
|
||||
self.commit_counter.increment();
|
||||
age
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.commit_counter = CommitCounter::default();
|
||||
self.buffer_age.clear();
|
||||
SessionUserData { dt: tracker }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ScreencopySessions {
|
||||
pub struct ImageCopySessions {
|
||||
sessions: Vec<Session>,
|
||||
cursor_sessions: Vec<CursorSession>,
|
||||
}
|
||||
|
|
@ -78,9 +52,9 @@ pub trait FrameHolder {
|
|||
impl SessionHolder for Output {
|
||||
fn add_session(&mut self, session: Session) {
|
||||
self.user_data()
|
||||
.insert_if_missing(ScreencopySessionsData::default);
|
||||
.insert_if_missing(ImageCopySessionsData::default);
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.sessions
|
||||
|
|
@ -89,7 +63,7 @@ impl SessionHolder for Output {
|
|||
|
||||
fn remove_session(&mut self, session: &SessionRef) {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.sessions
|
||||
|
|
@ -98,7 +72,7 @@ impl SessionHolder for Output {
|
|||
|
||||
fn sessions(&self) -> Vec<SessionRef> {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.map_or(Vec::new(), |sessions| {
|
||||
sessions
|
||||
.borrow()
|
||||
|
|
@ -111,9 +85,9 @@ impl SessionHolder for Output {
|
|||
|
||||
fn add_cursor_session(&mut self, session: CursorSession) {
|
||||
self.user_data()
|
||||
.insert_if_missing(ScreencopySessionsData::default);
|
||||
.insert_if_missing(ImageCopySessionsData::default);
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.cursor_sessions
|
||||
|
|
@ -122,7 +96,7 @@ impl SessionHolder for Output {
|
|||
|
||||
fn remove_cursor_session(&mut self, session: &CursorSessionRef) {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.cursor_sessions
|
||||
|
|
@ -131,7 +105,7 @@ impl SessionHolder for Output {
|
|||
|
||||
fn cursor_sessions(&self) -> Vec<CursorSessionRef> {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.map_or(Vec::new(), |sessions| {
|
||||
sessions
|
||||
.borrow()
|
||||
|
|
@ -146,22 +120,22 @@ impl SessionHolder for Output {
|
|||
impl FrameHolder for Output {
|
||||
fn add_frame(&mut self, session: SessionRef, frame: Frame) {
|
||||
self.user_data()
|
||||
.insert_if_missing_threadsafe(PendingScreencopyBuffers::default);
|
||||
.insert_if_missing_threadsafe(PendingImageCopyBuffers::default);
|
||||
self.user_data()
|
||||
.get::<PendingScreencopyBuffers>()
|
||||
.get::<PendingImageCopyBuffers>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push((session, frame));
|
||||
}
|
||||
fn remove_frame(&mut self, frame: &FrameRef) {
|
||||
if let Some(pending) = self.user_data().get::<PendingScreencopyBuffers>() {
|
||||
if let Some(pending) = self.user_data().get::<PendingImageCopyBuffers>() {
|
||||
pending.lock().unwrap().retain(|(_, f)| f != frame);
|
||||
}
|
||||
}
|
||||
fn take_pending_frames(&self) -> Vec<(SessionRef, Frame)> {
|
||||
self.user_data()
|
||||
.get::<PendingScreencopyBuffers>()
|
||||
.get::<PendingImageCopyBuffers>()
|
||||
.map(|pending| std::mem::take(&mut *pending.lock().unwrap()))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
|
@ -169,14 +143,14 @@ impl FrameHolder for Output {
|
|||
|
||||
impl SessionHolder for Workspace {
|
||||
fn add_session(&mut self, session: Session) {
|
||||
self.screencopy.sessions.push(session);
|
||||
self.image_copy.sessions.push(session);
|
||||
}
|
||||
|
||||
fn remove_session(&mut self, session: &SessionRef) {
|
||||
self.screencopy.sessions.retain(|s| s != session);
|
||||
self.image_copy.sessions.retain(|s| s != session);
|
||||
}
|
||||
fn sessions(&self) -> Vec<SessionRef> {
|
||||
self.screencopy
|
||||
self.image_copy
|
||||
.sessions
|
||||
.iter()
|
||||
.map(|s| (*s).clone())
|
||||
|
|
@ -184,14 +158,14 @@ impl SessionHolder for Workspace {
|
|||
}
|
||||
|
||||
fn add_cursor_session(&mut self, session: CursorSession) {
|
||||
self.screencopy.cursor_sessions.push(session);
|
||||
self.image_copy.cursor_sessions.push(session);
|
||||
}
|
||||
|
||||
fn remove_cursor_session(&mut self, session: &CursorSessionRef) {
|
||||
self.screencopy.cursor_sessions.retain(|s| s != session);
|
||||
self.image_copy.cursor_sessions.retain(|s| s != session);
|
||||
}
|
||||
fn cursor_sessions(&self) -> Vec<CursorSessionRef> {
|
||||
self.screencopy
|
||||
self.image_copy
|
||||
.cursor_sessions
|
||||
.iter()
|
||||
.map(|s| (*s).clone())
|
||||
|
|
@ -202,9 +176,9 @@ impl SessionHolder for Workspace {
|
|||
impl SessionHolder for CosmicSurface {
|
||||
fn add_session(&mut self, session: Session) {
|
||||
self.user_data()
|
||||
.insert_if_missing(ScreencopySessionsData::default);
|
||||
.insert_if_missing(ImageCopySessionsData::default);
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.sessions
|
||||
|
|
@ -213,7 +187,7 @@ impl SessionHolder for CosmicSurface {
|
|||
|
||||
fn remove_session(&mut self, session: &SessionRef) {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.sessions
|
||||
|
|
@ -221,7 +195,7 @@ impl SessionHolder for CosmicSurface {
|
|||
}
|
||||
fn sessions(&self) -> Vec<SessionRef> {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.map_or(Vec::new(), |sessions| {
|
||||
sessions
|
||||
.borrow()
|
||||
|
|
@ -234,9 +208,9 @@ impl SessionHolder for CosmicSurface {
|
|||
|
||||
fn add_cursor_session(&mut self, session: CursorSession) {
|
||||
self.user_data()
|
||||
.insert_if_missing(ScreencopySessionsData::default);
|
||||
.insert_if_missing(ImageCopySessionsData::default);
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.cursor_sessions
|
||||
|
|
@ -245,7 +219,7 @@ impl SessionHolder for CosmicSurface {
|
|||
|
||||
fn remove_cursor_session(&mut self, session: &CursorSessionRef) {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.unwrap()
|
||||
.borrow_mut()
|
||||
.cursor_sessions
|
||||
|
|
@ -254,7 +228,7 @@ impl SessionHolder for CosmicSurface {
|
|||
|
||||
fn cursor_sessions(&self) -> Vec<CursorSessionRef> {
|
||||
self.user_data()
|
||||
.get::<ScreencopySessionsData>()
|
||||
.get::<ImageCopySessionsData>()
|
||||
.map_or(Vec::new(), |sessions| {
|
||||
sessions
|
||||
.borrow()
|
||||
|
|
@ -12,11 +12,13 @@ pub mod dmabuf;
|
|||
pub mod drm;
|
||||
pub mod drm_lease;
|
||||
pub mod drm_syncobj;
|
||||
pub mod fixes;
|
||||
pub mod foreign_toplevel_list;
|
||||
pub mod fractional_scale;
|
||||
pub mod idle_inhibit;
|
||||
pub mod idle_notify;
|
||||
pub mod image_capture_source;
|
||||
pub mod image_copy_capture;
|
||||
pub mod input_method;
|
||||
pub mod keyboard_shortcuts_inhibit;
|
||||
pub mod layer_shell;
|
||||
|
|
@ -29,7 +31,6 @@ pub mod pointer_gestures;
|
|||
pub mod presentation;
|
||||
pub mod primary_selection;
|
||||
pub mod relative_pointer;
|
||||
pub mod screencopy;
|
||||
pub mod seat;
|
||||
pub mod security_context;
|
||||
pub mod selection;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,10 @@ impl ToplevelManagementHandler for State {
|
|||
|
||||
std::mem::drop(shell);
|
||||
|
||||
if seat.active_output() != *output {
|
||||
// move pointer to window if it’s on a different monitor/output
|
||||
if seat.active_output() != *output
|
||||
&& self.common.config.cosmic_conf.cursor_follows_focus
|
||||
{
|
||||
if let Some(new_pos) = new_pos {
|
||||
seat.set_active_output(output);
|
||||
if let Some(ptr) = seat.get_pointer() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,35 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::state::State;
|
||||
use smithay::delegate_virtual_keyboard_manager;
|
||||
use smithay::{
|
||||
backend::input::KeyState,
|
||||
delegate_virtual_keyboard_manager,
|
||||
input::keyboard::{FilterResult, KeyboardHandle, Keycode, xkb::ModMask},
|
||||
utils::SERIAL_COUNTER,
|
||||
wayland::virtual_keyboard::VirtualKeyboardHandler,
|
||||
};
|
||||
|
||||
impl VirtualKeyboardHandler for State {
|
||||
fn on_keyboard_event(
|
||||
&mut self,
|
||||
keycode: Keycode,
|
||||
state: KeyState,
|
||||
time: u32,
|
||||
keyboard: KeyboardHandle<Self>,
|
||||
) {
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
keyboard.input(self, keycode, state, serial, time, |_, _, _| {
|
||||
FilterResult::Forward::<bool>
|
||||
});
|
||||
}
|
||||
fn on_keyboard_modifiers(
|
||||
&mut self,
|
||||
_depressed_mods: ModMask,
|
||||
_latched_mods: ModMask,
|
||||
_locked_mods: ModMask,
|
||||
_keyboard: KeyboardHandle<Self>,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
delegate_virtual_keyboard_manager!(State);
|
||||
|
|
|
|||
|
|
@ -172,12 +172,6 @@ impl XdgShellHandler for State {
|
|||
|
||||
self.common.shell.read().unconstrain_popup(&surface);
|
||||
surface.send_repositioned(token);
|
||||
if let Err(err) = surface.send_configure() {
|
||||
warn!(
|
||||
?err,
|
||||
"Client bug: Unable to re-configure repositioned popup.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
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::{
|
||||
|
|
@ -12,75 +10,54 @@ use cosmic_protocols::image_capture_source::v1::server::{
|
|||
},
|
||||
};
|
||||
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},
|
||||
output::WeakOutput,
|
||||
reexports::wayland_server::{
|
||||
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
|
||||
},
|
||||
wayland::image_capture_source::{ImageCaptureSource, ImageCaptureSourceData},
|
||||
};
|
||||
use wayland_backend::server::GlobalId;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImageCaptureSourceState {
|
||||
output_source_global: GlobalId,
|
||||
pub struct CosmicImageCaptureSourceState {
|
||||
workspace_source_global: GlobalId,
|
||||
toplevel_source_global: GlobalId,
|
||||
}
|
||||
|
||||
pub struct OutputImageCaptureSourceManagerGlobalData {
|
||||
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
|
||||
}
|
||||
pub struct WorkspaceImageCaptureSourceManagerGlobalData {
|
||||
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
|
||||
}
|
||||
pub struct ToplevelImageCaptureSourceManagerGlobalData {
|
||||
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum ImageCaptureSourceData {
|
||||
pub enum ImageCaptureSourceKind {
|
||||
Output(WeakOutput),
|
||||
Workspace(WorkspaceHandle),
|
||||
Toplevel(CosmicSurface),
|
||||
Destroyed,
|
||||
}
|
||||
|
||||
impl ImageCaptureSourceState {
|
||||
pub fn new<D, F>(display: &DisplayHandle, client_filter: F) -> ImageCaptureSourceState
|
||||
impl ImageCaptureSourceKind {
|
||||
pub fn from_resource(resource: &ExtImageCaptureSourceV1) -> Option<Self> {
|
||||
let source = ImageCaptureSource::from_resource(resource)?;
|
||||
source.user_data().get::<ImageCaptureSourceKind>().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl CosmicImageCaptureSourceState {
|
||||
pub fn new<D, F>(display: &DisplayHandle, client_filter: F) -> CosmicImageCaptureSourceState
|
||||
where
|
||||
D: GlobalDispatch<
|
||||
ExtOutputImageCaptureSourceManagerV1,
|
||||
OutputImageCaptureSourceManagerGlobalData,
|
||||
> + Dispatch<ExtOutputImageCaptureSourceManagerV1, ()>
|
||||
+ GlobalDispatch<
|
||||
ZcosmicWorkspaceImageCaptureSourceManagerV1,
|
||||
WorkspaceImageCaptureSourceManagerGlobalData,
|
||||
> + Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, ()>
|
||||
+ GlobalDispatch<
|
||||
ExtForeignToplevelImageCaptureSourceManagerV1,
|
||||
ToplevelImageCaptureSourceManagerGlobalData,
|
||||
> + Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ()>
|
||||
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
|
||||
+ WorkspaceHandler
|
||||
+ 'static,
|
||||
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + Clone + 'static,
|
||||
{
|
||||
ImageCaptureSourceState {
|
||||
output_source_global: display
|
||||
.create_global::<D, ExtOutputImageCaptureSourceManagerV1, _>(
|
||||
1,
|
||||
OutputImageCaptureSourceManagerGlobalData {
|
||||
filter: Box::new(client_filter.clone()),
|
||||
},
|
||||
),
|
||||
CosmicImageCaptureSourceState {
|
||||
workspace_source_global: display
|
||||
.create_global::<D, ZcosmicWorkspaceImageCaptureSourceManagerV1, _>(
|
||||
1,
|
||||
|
|
@ -88,57 +65,12 @@ impl ImageCaptureSourceState {
|
|||
filter: Box::new(client_filter.clone()),
|
||||
},
|
||||
),
|
||||
toplevel_source_global: display
|
||||
.create_global::<D, ExtForeignToplevelImageCaptureSourceManagerV1, _>(
|
||||
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<D>
|
||||
GlobalDispatch<
|
||||
ExtOutputImageCaptureSourceManagerV1,
|
||||
OutputImageCaptureSourceManagerGlobalData,
|
||||
D,
|
||||
> for ImageCaptureSourceState
|
||||
where
|
||||
D: GlobalDispatch<
|
||||
ExtOutputImageCaptureSourceManagerV1,
|
||||
OutputImageCaptureSourceManagerGlobalData,
|
||||
> + Dispatch<ExtOutputImageCaptureSourceManagerV1, ()>
|
||||
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
|
||||
+ 'static,
|
||||
{
|
||||
fn bind(
|
||||
_state: &mut D,
|
||||
_handle: &DisplayHandle,
|
||||
_client: &Client,
|
||||
resource: New<ExtOutputImageCaptureSourceManagerV1>,
|
||||
_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<D>
|
||||
|
|
@ -146,7 +78,7 @@ impl<D>
|
|||
ZcosmicWorkspaceImageCaptureSourceManagerV1,
|
||||
WorkspaceImageCaptureSourceManagerGlobalData,
|
||||
D,
|
||||
> for ImageCaptureSourceState
|
||||
> for CosmicImageCaptureSourceState
|
||||
where
|
||||
D: GlobalDispatch<
|
||||
ZcosmicWorkspaceImageCaptureSourceManagerV1,
|
||||
|
|
@ -174,70 +106,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<D>
|
||||
GlobalDispatch<
|
||||
ExtForeignToplevelImageCaptureSourceManagerV1,
|
||||
ToplevelImageCaptureSourceManagerGlobalData,
|
||||
D,
|
||||
> for ImageCaptureSourceState
|
||||
where
|
||||
D: GlobalDispatch<
|
||||
ExtForeignToplevelImageCaptureSourceManagerV1,
|
||||
ToplevelImageCaptureSourceManagerGlobalData,
|
||||
> + Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ()>
|
||||
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
|
||||
+ 'static,
|
||||
{
|
||||
fn bind(
|
||||
_state: &mut D,
|
||||
_handle: &DisplayHandle,
|
||||
_client: &Client,
|
||||
resource: New<ExtForeignToplevelImageCaptureSourceManagerV1>,
|
||||
_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<D> Dispatch<ExtOutputImageCaptureSourceManagerV1, (), D> for ImageCaptureSourceState
|
||||
where
|
||||
D: Dispatch<ExtOutputImageCaptureSourceManagerV1, ()>
|
||||
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
|
||||
+ 'static,
|
||||
{
|
||||
fn request(
|
||||
_state: &mut D,
|
||||
_client: &Client,
|
||||
_resource: &ExtOutputImageCaptureSourceManagerV1,
|
||||
request: <ExtOutputImageCaptureSourceManagerV1 as Resource>::Request,
|
||||
_data: &(),
|
||||
_dhandle: &DisplayHandle,
|
||||
data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
if let OutputSourceRequest::CreateSource { source, output } = request {
|
||||
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<D> Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, (), D> for ImageCaptureSourceState
|
||||
impl<D> Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, (), D>
|
||||
for CosmicImageCaptureSourceState
|
||||
where
|
||||
D: Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, ()>
|
||||
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
|
||||
|
|
@ -253,110 +123,36 @@ where
|
|||
_dhandle: &DisplayHandle,
|
||||
data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
if let CosmicWorkspaceSourceRequest::CreateSource { source, output } = request {
|
||||
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<D> Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, (), D> for ImageCaptureSourceState
|
||||
where
|
||||
D: Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ()>
|
||||
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
|
||||
+ ToplevelInfoHandler<Window = CosmicSurface>
|
||||
+ 'static,
|
||||
{
|
||||
fn request(
|
||||
state: &mut D,
|
||||
_client: &Client,
|
||||
_resource: &ExtForeignToplevelImageCaptureSourceManagerV1,
|
||||
request: <ExtForeignToplevelImageCaptureSourceManagerV1 as Resource>::Request,
|
||||
_data: &(),
|
||||
_dhandle: &DisplayHandle,
|
||||
data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
if let ToplevelSourceRequest::CreateSource {
|
||||
source,
|
||||
toplevel_handle,
|
||||
if let CosmicWorkspaceSourceRequest::CreateSource {
|
||||
source: source_handle,
|
||||
output,
|
||||
} = request
|
||||
{
|
||||
let data = match window_from_ext_handle(state, &toplevel_handle) {
|
||||
Some(toplevel) => ImageCaptureSourceData::Toplevel(toplevel.clone()),
|
||||
None => ImageCaptureSourceData::Destroyed,
|
||||
let data = match state.workspace_state().get_ext_workspace_handle(&output) {
|
||||
Some(workspace) => ImageCaptureSourceKind::Workspace(workspace),
|
||||
None => ImageCaptureSourceKind::Destroyed,
|
||||
};
|
||||
data_init.init(source, data);
|
||||
let source = ImageCaptureSource::new();
|
||||
source.user_data().insert_if_missing(|| data);
|
||||
let instance = data_init.init(
|
||||
source_handle,
|
||||
ImageCaptureSourceData {
|
||||
source: source.clone(),
|
||||
},
|
||||
);
|
||||
source.add_instance(&instance);
|
||||
}
|
||||
}
|
||||
|
||||
fn destroyed(
|
||||
_state: &mut D,
|
||||
_client: wayland_backend::server::ClientId,
|
||||
_resource: &ExtForeignToplevelImageCaptureSourceManagerV1,
|
||||
_data: &(),
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData, D> for ImageCaptureSourceState
|
||||
where
|
||||
D: Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData> + 'static,
|
||||
{
|
||||
fn request(
|
||||
_state: &mut D,
|
||||
_client: &Client,
|
||||
_resource: &ExtImageCaptureSourceV1,
|
||||
_request: <ExtImageCaptureSourceV1 as Resource>::Request,
|
||||
_data: &ImageCaptureSourceData,
|
||||
_dhandle: &DisplayHandle,
|
||||
_data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
{}
|
||||
}
|
||||
|
||||
fn destroyed(
|
||||
_state: &mut D,
|
||||
_client: wayland_backend::server::ClientId,
|
||||
_resource: &ExtImageCaptureSourceV1,
|
||||
_data: &ImageCaptureSourceData,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! delegate_image_capture_source {
|
||||
macro_rules! delegate_cosmic_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);
|
||||
] => $crate::wayland::protocols::image_capture_source::CosmicImageCaptureSourceState);
|
||||
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);
|
||||
] => $crate::wayland::protocols::image_capture_source::CosmicImageCaptureSourceState);
|
||||
};
|
||||
}
|
||||
pub(crate) use delegate_image_capture_source;
|
||||
pub(crate) use delegate_cosmic_image_capture_source;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ pub mod image_capture_source;
|
|||
pub mod output_configuration;
|
||||
pub mod output_power;
|
||||
pub mod overlap_notify;
|
||||
pub mod screencopy;
|
||||
pub mod toplevel_info;
|
||||
pub mod toplevel_management;
|
||||
pub mod workspace;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -635,14 +635,13 @@ pub fn window_from_handle<W: Window + 'static>(handle: ZcosmicToplevelHandleV1)
|
|||
.and_then(|state| state.lock().unwrap().window.clone())
|
||||
}
|
||||
|
||||
pub fn window_from_ext_handle<'a, W: Window + 'static, D>(
|
||||
pub fn window_from_ext<'a, W: Window + 'static, D>(
|
||||
state: &'a D,
|
||||
foreign_toplevel: &ExtForeignToplevelHandleV1,
|
||||
handle: &ForeignToplevelHandle,
|
||||
) -> Option<&'a W>
|
||||
where
|
||||
D: ToplevelInfoHandler<Window = W>,
|
||||
{
|
||||
let handle = ForeignToplevelHandle::from_resource(foreign_toplevel)?;
|
||||
state.toplevel_info_state().toplevels.iter().find(|w| {
|
||||
w.user_data().get::<ToplevelState>().and_then(|inner| {
|
||||
inner
|
||||
|
|
@ -655,6 +654,17 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
pub fn window_from_ext_handle<'a, W: Window + 'static, D>(
|
||||
state: &'a D,
|
||||
foreign_toplevel: &ExtForeignToplevelHandleV1,
|
||||
) -> Option<&'a W>
|
||||
where
|
||||
D: ToplevelInfoHandler<Window = W>,
|
||||
{
|
||||
let handle = ForeignToplevelHandle::from_resource(foreign_toplevel)?;
|
||||
window_from_ext(state, &handle)
|
||||
}
|
||||
|
||||
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: [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue