When cosmic-workspaces is shown, render only layer-shell surfaces
This allows `cosmic-workspaces` to rely on cosmic-comp for rendering the background, and just have transparency. This should be a more reliable and performant way of doing things, at least for now. Instead of adding another opaque bool argument, this defines an `ElementFilter` enum, which makes calls more readable. Window surfaces are still included in screencopy, as needed for the workspace previews.
This commit is contained in:
parent
31358d1993
commit
355b142c52
3 changed files with 83 additions and 60 deletions
|
|
@ -3,13 +3,15 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::{
|
backend::render::{
|
||||||
element::{CosmicElement, DamageElement},
|
element::{CosmicElement, DamageElement},
|
||||||
init_shaders, workspace_elements, CursorMode, GlMultiRenderer, CLEAR_COLOR,
|
init_shaders, workspace_elements, CursorMode, ElementFilter, GlMultiRenderer, CLEAR_COLOR,
|
||||||
},
|
},
|
||||||
shell::Shell,
|
shell::Shell,
|
||||||
state::SurfaceDmabufFeedback,
|
state::SurfaceDmabufFeedback,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::{
|
wayland::{
|
||||||
handlers::screencopy::{submit_buffer, FrameHolder, SessionData},
|
handlers::screencopy::{
|
||||||
|
submit_buffer, FrameHolder, SessionData, WORKSPACE_OVERVIEW_NAMESPACE,
|
||||||
|
},
|
||||||
protocols::screencopy::{
|
protocols::screencopy::{
|
||||||
FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession,
|
FailureReason, Frame as ScreencopyFrame, Session as ScreencopySession,
|
||||||
},
|
},
|
||||||
|
|
@ -46,7 +48,7 @@ use smithay::{
|
||||||
Bind, ImportDma, Offscreen, Renderer, Texture,
|
Bind, ImportDma, Offscreen, Renderer, Texture,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
desktop::utils::OutputPresentationFeedback,
|
desktop::{layer_map_for_output, utils::OutputPresentationFeedback},
|
||||||
output::{Output, OutputNoMode},
|
output::{Output, OutputNoMode},
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{
|
calloop::{
|
||||||
|
|
@ -869,6 +871,15 @@ impl SurfaceThreadState {
|
||||||
|
|
||||||
std::mem::drop(shell);
|
std::mem::drop(shell);
|
||||||
|
|
||||||
|
let element_filter = if layer_map_for_output(output)
|
||||||
|
.layers()
|
||||||
|
.any(|s| s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
|
||||||
|
{
|
||||||
|
ElementFilter::LayerShellOnly
|
||||||
|
} else {
|
||||||
|
ElementFilter::All
|
||||||
|
};
|
||||||
|
|
||||||
workspace_elements(
|
workspace_elements(
|
||||||
Some(&render_node),
|
Some(&render_node),
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
|
|
@ -878,7 +889,7 @@ impl SurfaceThreadState {
|
||||||
previous_workspace,
|
previous_workspace,
|
||||||
workspace,
|
workspace,
|
||||||
CursorMode::All,
|
CursorMode::All,
|
||||||
false,
|
element_filter,
|
||||||
#[cfg(not(feature = "debug"))]
|
#[cfg(not(feature = "debug"))]
|
||||||
None,
|
None,
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
|
|
|
||||||
|
|
@ -464,6 +464,13 @@ where
|
||||||
#[cfg(not(feature = "debug"))]
|
#[cfg(not(feature = "debug"))]
|
||||||
pub type EguiState = ();
|
pub type EguiState = ();
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
pub enum ElementFilter {
|
||||||
|
All,
|
||||||
|
ExcludeWorkspaceOverview,
|
||||||
|
LayerShellOnly,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SplitRenderElements<E> {
|
pub struct SplitRenderElements<E> {
|
||||||
pub w_elements: Vec<E>,
|
pub w_elements: Vec<E>,
|
||||||
|
|
@ -528,7 +535,7 @@ pub fn workspace_elements<R>(
|
||||||
previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>,
|
previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>,
|
||||||
current: (WorkspaceHandle, usize),
|
current: (WorkspaceHandle, usize),
|
||||||
cursor_mode: CursorMode,
|
cursor_mode: CursorMode,
|
||||||
exclude_workspace_overview: bool,
|
element_filter: ElementFilter,
|
||||||
_fps: Option<(&EguiState, &Timings)>,
|
_fps: Option<(&EguiState, &Timings)>,
|
||||||
) -> Result<Vec<CosmicElement<R>>, RenderError<R>>
|
) -> Result<Vec<CosmicElement<R>>, RenderError<R>>
|
||||||
where
|
where
|
||||||
|
|
@ -556,7 +563,7 @@ where
|
||||||
now,
|
now,
|
||||||
output,
|
output,
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
exclude_workspace_overview,
|
element_filter == ElementFilter::ExcludeWorkspaceOverview,
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
|
|
@ -642,8 +649,7 @@ where
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.filter(|f| !f.is_animating())
|
.filter(|f| !f.is_animating())
|
||||||
.is_some();
|
.is_some();
|
||||||
let overlay_elements =
|
let overlay_elements = split_layer_elements(renderer, output, Layer::Overlay, element_filter);
|
||||||
split_layer_elements(renderer, output, Layer::Overlay, exclude_workspace_overview);
|
|
||||||
|
|
||||||
// overlay is above everything
|
// overlay is above everything
|
||||||
elements
|
elements
|
||||||
|
|
@ -655,7 +661,7 @@ where
|
||||||
|
|
||||||
if !has_fullscreen {
|
if !has_fullscreen {
|
||||||
elements.extend_from_workspace_elements(
|
elements.extend_from_workspace_elements(
|
||||||
split_layer_elements(renderer, output, Layer::Top, exclude_workspace_overview),
|
split_layer_elements(renderer, output, Layer::Top, element_filter),
|
||||||
(0, 0).into(),
|
(0, 0).into(),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -669,32 +675,34 @@ where
|
||||||
// overlay redirect windows
|
// overlay redirect windows
|
||||||
// they need to be over sticky windows, because they could be popups of sticky windows,
|
// they need to be over sticky windows, because they could be popups of sticky windows,
|
||||||
// and we can't differenciate that.
|
// and we can't differenciate that.
|
||||||
elements.p_elements.extend(
|
if element_filter != ElementFilter::LayerShellOnly {
|
||||||
shell
|
elements.p_elements.extend(
|
||||||
.override_redirect_windows
|
shell
|
||||||
.iter()
|
.override_redirect_windows
|
||||||
.filter(|or| {
|
.iter()
|
||||||
(*or)
|
.filter(|or| {
|
||||||
.geometry()
|
(*or)
|
||||||
.as_global()
|
.geometry()
|
||||||
.intersection(workspace.output.geometry())
|
.as_global()
|
||||||
.is_some()
|
.intersection(workspace.output.geometry())
|
||||||
})
|
.is_some()
|
||||||
.flat_map(|or| {
|
})
|
||||||
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
|
.flat_map(|or| {
|
||||||
or,
|
AsRenderElements::<R>::render_elements::<WorkspaceRenderElement<R>>(
|
||||||
renderer,
|
or,
|
||||||
(or.geometry().loc - workspace.output.geometry().loc.as_logical())
|
renderer,
|
||||||
.to_physical_precise_round(output_scale),
|
(or.geometry().loc - workspace.output.geometry().loc.as_logical())
|
||||||
Scale::from(output_scale),
|
.to_physical_precise_round(output_scale),
|
||||||
1.0,
|
Scale::from(output_scale),
|
||||||
)
|
1.0,
|
||||||
})
|
)
|
||||||
.map(|p_element| p_element.into()),
|
})
|
||||||
);
|
.map(|p_element| p_element.into()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// sticky windows
|
// sticky windows
|
||||||
if !has_fullscreen {
|
if !has_fullscreen && element_filter != ElementFilter::LayerShellOnly {
|
||||||
let alpha = match &overview.0 {
|
let alpha = match &overview.0 {
|
||||||
OverviewMode::Started(_, started) => {
|
OverviewMode::Started(_, started) => {
|
||||||
(1.0 - (Instant::now().duration_since(*started).as_millis()
|
(1.0 - (Instant::now().duration_since(*started).as_millis()
|
||||||
|
|
@ -785,7 +793,7 @@ where
|
||||||
|
|
||||||
if !has_fullscreen {
|
if !has_fullscreen {
|
||||||
elements.extend_from_workspace_elements(
|
elements.extend_from_workspace_elements(
|
||||||
background_layer_elements(renderer, output, exclude_workspace_overview),
|
background_layer_elements(renderer, output, element_filter),
|
||||||
offset.to_physical_precise_round(output_scale),
|
offset.to_physical_precise_round(output_scale),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -800,23 +808,25 @@ where
|
||||||
None => (0, 0).into(),
|
None => (0, 0).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
elements.extend_from_workspace_elements(
|
if element_filter != ElementFilter::LayerShellOnly {
|
||||||
workspace
|
elements.extend_from_workspace_elements(
|
||||||
.render::<R>(
|
workspace
|
||||||
renderer,
|
.render::<R>(
|
||||||
(!move_active && is_active_space).then_some(&last_active_seat),
|
renderer,
|
||||||
overview,
|
(!move_active && is_active_space).then_some(&last_active_seat),
|
||||||
resize_indicator,
|
overview,
|
||||||
active_hint,
|
resize_indicator,
|
||||||
theme,
|
active_hint,
|
||||||
)
|
theme,
|
||||||
.map_err(|_| OutputNoMode)?,
|
)
|
||||||
offset.to_physical_precise_round(output_scale),
|
.map_err(|_| OutputNoMode)?,
|
||||||
);
|
offset.to_physical_precise_round(output_scale),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if !has_fullscreen {
|
if !has_fullscreen {
|
||||||
elements.extend_from_workspace_elements(
|
elements.extend_from_workspace_elements(
|
||||||
background_layer_elements(renderer, output, exclude_workspace_overview),
|
background_layer_elements(renderer, output, element_filter),
|
||||||
offset.to_physical_precise_round(output_scale),
|
offset.to_physical_precise_round(output_scale),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -828,7 +838,7 @@ pub fn split_layer_elements<R>(
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
layer: Layer,
|
layer: Layer,
|
||||||
exclude_workspace_overview: bool,
|
element_filter: ElementFilter,
|
||||||
) -> SplitRenderElements<WorkspaceRenderElement<R>>
|
) -> SplitRenderElements<WorkspaceRenderElement<R>>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
|
|
@ -845,7 +855,10 @@ where
|
||||||
layer_map
|
layer_map
|
||||||
.layers_on(layer)
|
.layers_on(layer)
|
||||||
.rev()
|
.rev()
|
||||||
.filter(|s| !(exclude_workspace_overview && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE))
|
.filter(|s| {
|
||||||
|
!(element_filter == ElementFilter::ExcludeWorkspaceOverview
|
||||||
|
&& s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)
|
||||||
|
})
|
||||||
.filter_map(|surface| {
|
.filter_map(|surface| {
|
||||||
layer_map
|
layer_map
|
||||||
.layer_geometry(surface)
|
.layer_geometry(surface)
|
||||||
|
|
@ -895,7 +908,7 @@ where
|
||||||
pub fn background_layer_elements<R>(
|
pub fn background_layer_elements<R>(
|
||||||
renderer: &mut R,
|
renderer: &mut R,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
exclude_workspace_overview: bool,
|
element_filter: ElementFilter,
|
||||||
) -> SplitRenderElements<WorkspaceRenderElement<R>>
|
) -> SplitRenderElements<WorkspaceRenderElement<R>>
|
||||||
where
|
where
|
||||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||||
|
|
@ -904,13 +917,12 @@ where
|
||||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||||
WorkspaceRenderElement<R>: RenderElement<R>,
|
WorkspaceRenderElement<R>: RenderElement<R>,
|
||||||
{
|
{
|
||||||
let mut elements =
|
let mut elements = split_layer_elements(renderer, output, Layer::Bottom, element_filter);
|
||||||
split_layer_elements(renderer, output, Layer::Bottom, exclude_workspace_overview);
|
|
||||||
elements.extend(split_layer_elements(
|
elements.extend(split_layer_elements(
|
||||||
renderer,
|
renderer,
|
||||||
output,
|
output,
|
||||||
Layer::Background,
|
Layer::Background,
|
||||||
exclude_workspace_overview,
|
element_filter,
|
||||||
));
|
));
|
||||||
elements
|
elements
|
||||||
}
|
}
|
||||||
|
|
@ -990,7 +1002,7 @@ where
|
||||||
previous_workspace,
|
previous_workspace,
|
||||||
workspace,
|
workspace,
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
false,
|
ElementFilter::All,
|
||||||
);
|
);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
|
|
@ -1102,7 +1114,7 @@ pub fn render_workspace<'d, R, Target, OffTarget>(
|
||||||
previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>,
|
previous: Option<(WorkspaceHandle, usize, WorkspaceDelta)>,
|
||||||
current: (WorkspaceHandle, usize),
|
current: (WorkspaceHandle, usize),
|
||||||
cursor_mode: CursorMode,
|
cursor_mode: CursorMode,
|
||||||
exclude_workspace_overview: bool,
|
element_filter: ElementFilter,
|
||||||
) -> Result<(RenderOutputResult<'d>, Vec<CosmicElement<R>>), RenderError<R>>
|
) -> Result<(RenderOutputResult<'d>, Vec<CosmicElement<R>>), RenderError<R>>
|
||||||
where
|
where
|
||||||
R: Renderer
|
R: Renderer
|
||||||
|
|
@ -1128,7 +1140,7 @@ where
|
||||||
previous,
|
previous,
|
||||||
current,
|
current,
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
exclude_workspace_overview,
|
element_filter,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ use crate::{
|
||||||
backend::render::{
|
backend::render::{
|
||||||
cursor,
|
cursor,
|
||||||
element::{AsGlowRenderer, CosmicElement, DamageElement, FromGlesError},
|
element::{AsGlowRenderer, CosmicElement, DamageElement, FromGlesError},
|
||||||
render_workspace, CursorMode, CLEAR_COLOR,
|
render_workspace, CursorMode, ElementFilter, CLEAR_COLOR,
|
||||||
},
|
},
|
||||||
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement},
|
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement},
|
||||||
state::{BackendData, Common, State},
|
state::{BackendData, Common, State},
|
||||||
|
|
@ -287,7 +287,7 @@ pub fn render_workspace_to_buffer(
|
||||||
None,
|
None,
|
||||||
handle,
|
handle,
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
true,
|
ElementFilter::ExcludeWorkspaceOverview,
|
||||||
)
|
)
|
||||||
.map(|res| res.0)
|
.map(|res| res.0)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -316,7 +316,7 @@ pub fn render_workspace_to_buffer(
|
||||||
None,
|
None,
|
||||||
handle,
|
handle,
|
||||||
cursor_mode,
|
cursor_mode,
|
||||||
true,
|
ElementFilter::ExcludeWorkspaceOverview,
|
||||||
)
|
)
|
||||||
.map(|res| res.0)
|
.map(|res| res.0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue