Exclude "cosmic-workspace-overview" from workspace screencopy
This commit is contained in:
parent
5ba068ec82
commit
26a652f039
4 changed files with 113 additions and 40 deletions
|
|
@ -239,10 +239,12 @@ pub fn init_backend(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Err(err) =
|
if let Err(err) = data.state.device_added(
|
||||||
data.state
|
dev,
|
||||||
.device_added(dev, path.into(), &data.display.handle(), true)
|
path.into(),
|
||||||
{
|
&data.display.handle(),
|
||||||
|
true,
|
||||||
|
) {
|
||||||
slog_scope::error!(
|
slog_scope::error!(
|
||||||
"Failed to add drm device {}: {}",
|
"Failed to add drm device {}: {}",
|
||||||
path.display(),
|
path.display(),
|
||||||
|
|
@ -325,7 +327,13 @@ pub fn init_backend(
|
||||||
|
|
||||||
// HACK: amdgpu doesn't like us initializing vulkan too early..
|
// HACK: amdgpu doesn't like us initializing vulkan too early..
|
||||||
// so lets do that delayed until mesa fixes that.
|
// so lets do that delayed until mesa fixes that.
|
||||||
let devices = state.backend.kms().devices.iter().map(|(drm_node, device)| (*drm_node, device.render_node)).collect::<Vec<_>>();
|
let devices = state
|
||||||
|
.backend
|
||||||
|
.kms()
|
||||||
|
.devices
|
||||||
|
.iter()
|
||||||
|
.map(|(drm_node, device)| (*drm_node, device.render_node))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
for (drm_node, render_node) in devices {
|
for (drm_node, render_node) in devices {
|
||||||
state.init_vulkan(drm_node, render_node);
|
state.init_vulkan(drm_node, render_node);
|
||||||
}
|
}
|
||||||
|
|
@ -333,7 +341,13 @@ pub fn init_backend(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
fn device_added(&mut self, dev: dev_t, path: PathBuf, dh: &DisplayHandle, try_vulkan: bool) -> Result<()> {
|
fn device_added(
|
||||||
|
&mut self,
|
||||||
|
dev: dev_t,
|
||||||
|
path: PathBuf,
|
||||||
|
dh: &DisplayHandle,
|
||||||
|
try_vulkan: bool,
|
||||||
|
) -> Result<()> {
|
||||||
if !self.backend.kms().session.is_active() {
|
if !self.backend.kms().session.is_active() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ where
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
screencopy,
|
screencopy,
|
||||||
fps,
|
fps,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
result
|
result
|
||||||
|
|
@ -175,6 +176,7 @@ pub fn render_workspace<'frame, R, Target, OffTarget, Source>(
|
||||||
mut cursor_mode: CursorMode,
|
mut cursor_mode: CursorMode,
|
||||||
screencopy: Option<(Source, &[(ScreencopySession, BufferParams)])>,
|
screencopy: Option<(Source, &[(ScreencopySession, BufferParams)])>,
|
||||||
mut fps: Option<&mut Fps>,
|
mut fps: Option<&mut Fps>,
|
||||||
|
exclude_workspace_overview: bool,
|
||||||
) -> Result<(Option<Vec<Rectangle<i32, Physical>>>, RenderElementStates), RenderError<R>>
|
) -> Result<(Option<Vec<Rectangle<i32, Physical>>>, RenderElementStates), RenderError<R>>
|
||||||
where
|
where
|
||||||
R: Renderer
|
R: Renderer
|
||||||
|
|
@ -254,6 +256,7 @@ where
|
||||||
output,
|
output,
|
||||||
&state.shell.override_redirect_windows,
|
&state.shell.override_redirect_windows,
|
||||||
state.xwayland_state.values_mut(),
|
state.xwayland_state.values_mut(),
|
||||||
|
exclude_workspace_overview,
|
||||||
)
|
)
|
||||||
.map_err(|_| OutputNoMode)?
|
.map_err(|_| OutputNoMode)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
state::State,
|
state::State,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::screencopy::DropableSession,
|
handlers::screencopy::{DropableSession, WORKSPACE_OVERVIEW_NAMESPACE},
|
||||||
protocols::{
|
protocols::{
|
||||||
screencopy::{BufferParams, Session as ScreencopySession},
|
screencopy::{BufferParams, Session as ScreencopySession},
|
||||||
toplevel_info::ToplevelInfoState,
|
toplevel_info::ToplevelInfoState,
|
||||||
|
|
@ -434,6 +434,7 @@ impl Workspace {
|
||||||
output: &Output,
|
output: &Output,
|
||||||
override_redirect_windows: &[X11Surface],
|
override_redirect_windows: &[X11Surface],
|
||||||
xwm_state: impl Iterator<Item = &'a mut XWaylandState>,
|
xwm_state: impl Iterator<Item = &'a mut XWaylandState>,
|
||||||
|
exclude_workspace_overview: bool,
|
||||||
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
|
|
@ -451,7 +452,11 @@ impl Workspace {
|
||||||
layer_map
|
layer_map
|
||||||
.layers()
|
.layers()
|
||||||
.rev()
|
.rev()
|
||||||
.filter(|s| s.layer() == Layer::Overlay)
|
.filter(|s| {
|
||||||
|
s.layer() == Layer::Overlay
|
||||||
|
&& !(exclude_workspace_overview
|
||||||
|
&& s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
|
||||||
|
})
|
||||||
.filter_map(|surface| {
|
.filter_map(|surface| {
|
||||||
layer_map
|
layer_map
|
||||||
.layer_geometry(surface)
|
.layer_geometry(surface)
|
||||||
|
|
@ -510,6 +515,10 @@ impl Workspace {
|
||||||
let (lower, upper): (Vec<&LayerSurface>, Vec<&LayerSurface>) = layer_map
|
let (lower, upper): (Vec<&LayerSurface>, Vec<&LayerSurface>) = layer_map
|
||||||
.layers()
|
.layers()
|
||||||
.rev()
|
.rev()
|
||||||
|
.filter(|s| {
|
||||||
|
!(exclude_workspace_overview
|
||||||
|
&& s.namespace() == "cosmic-workspace-overview")
|
||||||
|
})
|
||||||
.partition(|s| matches!(s.layer(), Layer::Background | Layer::Bottom));
|
.partition(|s| matches!(s.layer(), Layer::Background | Layer::Bottom));
|
||||||
|
|
||||||
render_elements.extend(
|
render_elements.extend(
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use calloop::LoopHandle;
|
||||||
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::{
|
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::{
|
||||||
FailureReason, InputType,
|
FailureReason, InputType,
|
||||||
};
|
};
|
||||||
|
|
@ -24,7 +25,7 @@ use smithay::{
|
||||||
Bind, Blit, BufferType, ExportMem, ImportAll, ImportMem, Offscreen, Renderer,
|
Bind, Blit, BufferType, ExportMem, ImportAll, ImportMem, Offscreen, Renderer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
desktop::space::SpaceElement,
|
desktop::{layer_map_for_output, space::SpaceElement},
|
||||||
output::Output,
|
output::Output,
|
||||||
reexports::wayland_server::{
|
reexports::wayland_server::{
|
||||||
protocol::{wl_buffer::WlBuffer, wl_shm::Format as ShmFormat, wl_surface::WlSurface},
|
protocol::{wl_buffer::WlBuffer, wl_shm::Format as ShmFormat, wl_surface::WlSurface},
|
||||||
|
|
@ -46,7 +47,7 @@ use crate::{
|
||||||
render_output, render_workspace, CursorMode, CLEAR_COLOR,
|
render_output, render_workspace, CursorMode, CLEAR_COLOR,
|
||||||
},
|
},
|
||||||
shell::{CosmicMappedRenderElement, CosmicSurface},
|
shell::{CosmicMappedRenderElement, CosmicSurface},
|
||||||
state::{BackendData, ClientState, Common, State},
|
state::{BackendData, ClientState, Common, Data, State},
|
||||||
utils::prelude::OutputExt,
|
utils::prelude::OutputExt,
|
||||||
wayland::protocols::{
|
wayland::protocols::{
|
||||||
screencopy::{
|
screencopy::{
|
||||||
|
|
@ -59,6 +60,8 @@ use crate::{
|
||||||
|
|
||||||
use super::data_device::get_dnd_icon;
|
use super::data_device::get_dnd_icon;
|
||||||
|
|
||||||
|
pub const WORKSPACE_OVERVIEW_NAMESPACE: &str = "cosmic-workspace-overview";
|
||||||
|
|
||||||
pub type PendingScreencopyBuffers = RefCell<Vec<(Session, BufferParams)>>;
|
pub type PendingScreencopyBuffers = RefCell<Vec<(Session, BufferParams)>>;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|
@ -767,6 +770,7 @@ pub fn render_workspace_to_buffer(
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let size = buffer_dimensions(buffer).unwrap();
|
let size = buffer_dimensions(buffer).unwrap();
|
||||||
|
|
@ -784,6 +788,7 @@ pub fn render_workspace_to_buffer(
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1144,8 +1149,30 @@ impl State {
|
||||||
output: &Output,
|
output: &Output,
|
||||||
) -> Option<Vec<(Session, BufferParams)>> {
|
) -> Option<Vec<(Session, BufferParams)>> {
|
||||||
let workspace = self.common.shell.active_space_mut(output);
|
let workspace = self.common.shell.active_space_mut(output);
|
||||||
if !workspace.pending_buffers.is_empty() {
|
let mut pending_buffers = std::mem::take(&mut workspace.pending_buffers);
|
||||||
Some(std::mem::take(&mut workspace.pending_buffers))
|
|
||||||
|
let mut i = 0;
|
||||||
|
while i < pending_buffers.len() {
|
||||||
|
let layer_map = layer_map_for_output(&output);
|
||||||
|
if layer_map
|
||||||
|
.layers()
|
||||||
|
.any(|s| s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
|
||||||
|
{
|
||||||
|
let (session, params) = pending_buffers.remove(i);
|
||||||
|
schedule_offscreen_workspace_session(
|
||||||
|
&self.common.event_loop_handle,
|
||||||
|
session,
|
||||||
|
params,
|
||||||
|
output.clone(),
|
||||||
|
workspace.handle.clone(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !pending_buffers.is_empty() {
|
||||||
|
Some(pending_buffers)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -1174,7 +1201,12 @@ impl State {
|
||||||
if let SessionType::Workspace(o, w) =
|
if let SessionType::Workspace(o, w) =
|
||||||
workspace.pending_buffers[i].0.session_type()
|
workspace.pending_buffers[i].0.session_type()
|
||||||
{
|
{
|
||||||
if active_spaces.contains(&(o.clone(), w)) {
|
let layer_map = layer_map_for_output(&o);
|
||||||
|
if active_spaces.contains(&(o.clone(), w))
|
||||||
|
&& !layer_map
|
||||||
|
.layers()
|
||||||
|
.any(|s| s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
|
||||||
|
{
|
||||||
// surface is on an active workspace/output combo, add to workspace_sessions
|
// surface is on an active workspace/output combo, add to workspace_sessions
|
||||||
let (session, params) = workspace.pending_buffers.remove(i);
|
let (session, params) = workspace.pending_buffers.remove(i);
|
||||||
output_sessions
|
output_sessions
|
||||||
|
|
@ -1183,32 +1215,13 @@ impl State {
|
||||||
} else if handle == w && output == o {
|
} else if handle == w && output == o {
|
||||||
// surface is visible on an offscreen workspace session, schedule a new render
|
// surface is visible on an offscreen workspace session, schedule a new render
|
||||||
let (session, params) = workspace.pending_buffers.remove(i);
|
let (session, params) = workspace.pending_buffers.remove(i);
|
||||||
let output = output.clone();
|
schedule_offscreen_workspace_session(
|
||||||
self.common.event_loop_handle.insert_idle(move |data| {
|
&self.common.event_loop_handle,
|
||||||
if !session.alive() {
|
session,
|
||||||
return;
|
params,
|
||||||
}
|
output.clone(),
|
||||||
if !data.state.common.shell.outputs.contains(&output) {
|
handle,
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
match render_workspace_to_buffer(
|
|
||||||
&mut data.state,
|
|
||||||
&session,
|
|
||||||
params.clone(),
|
|
||||||
&output,
|
|
||||||
&handle,
|
|
||||||
) {
|
|
||||||
Ok(false) => {
|
|
||||||
// rendering yielded no new damage, buffer still pending
|
|
||||||
data.state.common.still_pending(session, params);
|
|
||||||
}
|
|
||||||
Ok(true) => {}
|
|
||||||
Err((reason, err)) => {
|
|
||||||
slog_scope::warn!("Screencopy session failed: {}", err);
|
|
||||||
session.failed(reason);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -1223,4 +1236,38 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn schedule_offscreen_workspace_session(
|
||||||
|
event_loop_handle: &LoopHandle<'static, Data>,
|
||||||
|
session: Session,
|
||||||
|
params: BufferParams,
|
||||||
|
output: Output,
|
||||||
|
handle: WorkspaceHandle,
|
||||||
|
) {
|
||||||
|
event_loop_handle.insert_idle(move |data| {
|
||||||
|
if !session.alive() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if !data.state.common.shell.outputs.contains(&output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
match render_workspace_to_buffer(
|
||||||
|
&mut data.state,
|
||||||
|
&session,
|
||||||
|
params.clone(),
|
||||||
|
&output,
|
||||||
|
&handle,
|
||||||
|
) {
|
||||||
|
Ok(false) => {
|
||||||
|
// rendering yielded no new damage, buffer still pending
|
||||||
|
data.state.common.still_pending(session, params);
|
||||||
|
}
|
||||||
|
Ok(true) => {}
|
||||||
|
Err((reason, err)) => {
|
||||||
|
slog_scope::warn!("Screencopy session failed: {}", err);
|
||||||
|
session.failed(reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
delegate_screencopy!(State);
|
delegate_screencopy!(State);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue