render: Add focus indicator

This commit is contained in:
Victoria Brekenfeld 2023-02-25 00:17:54 +01:00
parent a8920f533e
commit 9b416b5779
11 changed files with 291 additions and 68 deletions

View file

@ -1,5 +1,8 @@
use crate::{
backend::render::{element::AsGlowRenderer, GlMultiFrame, GlMultiRenderer},
backend::render::{
element::{AsGlowFrame, AsGlowRenderer},
GlMultiFrame, GlMultiRenderer,
},
state::State,
utils::prelude::SeatExt,
};
@ -9,7 +12,9 @@ use smithay::{
input::KeyState,
renderer::{
element::{AsRenderElements, Element, RenderElement, UnderlyingStorage},
gles2::element::PixelShaderElement,
glow::GlowRenderer,
multigpu::Error as MultiError,
ImportAll, ImportMem, Renderer,
},
},
@ -46,14 +51,10 @@ pub use self::stack::CosmicStack;
pub mod window;
pub use self::window::CosmicWindow;
#[cfg(feature = "debug")]
use crate::backend::render::element::AsGlowFrame;
#[cfg(feature = "debug")]
use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon};
#[cfg(feature = "debug")]
use smithay::backend::renderer::{
element::texture::TextureRenderElement, gles2::Gles2Texture, multigpu::Error as MultiError,
};
use smithay::backend::renderer::{element::texture::TextureRenderElement, gles2::Gles2Texture};
#[cfg(feature = "debug")]
use tracing::debug;
@ -659,6 +660,7 @@ where
{
Stack(self::stack::CosmicStackRenderElement<R>),
Window(self::window::CosmicWindowRenderElement<R>),
Indicator(PixelShaderElement),
#[cfg(feature = "debug")]
Egui(TextureRenderElement<Gles2Texture>),
}
@ -672,6 +674,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.id(),
CosmicMappedRenderElement::Window(elem) => elem.id(),
CosmicMappedRenderElement::Indicator(elem) => elem.id(),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.id(),
}
@ -681,6 +684,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.current_commit(),
CosmicMappedRenderElement::Window(elem) => elem.current_commit(),
CosmicMappedRenderElement::Indicator(elem) => elem.current_commit(),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.current_commit(),
}
@ -690,6 +694,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.src(),
CosmicMappedRenderElement::Window(elem) => elem.src(),
CosmicMappedRenderElement::Indicator(elem) => elem.src(),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.src(),
}
@ -699,6 +704,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale),
CosmicMappedRenderElement::Window(elem) => elem.geometry(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.geometry(scale),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale),
}
@ -708,6 +714,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.location(scale),
CosmicMappedRenderElement::Window(elem) => elem.location(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.location(scale),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.location(scale),
}
@ -717,6 +724,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.transform(),
CosmicMappedRenderElement::Window(elem) => elem.transform(),
CosmicMappedRenderElement::Indicator(elem) => elem.transform(),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.transform(),
}
@ -730,6 +738,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit),
CosmicMappedRenderElement::Indicator(elem) => elem.damage_since(scale, commit),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit),
}
@ -739,6 +748,7 @@ where
match self {
CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale),
CosmicMappedRenderElement::Indicator(elem) => elem.opaque_regions(scale),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale),
}
@ -756,6 +766,9 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
match self {
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Indicator(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
}
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame, src, dst, damage)
@ -767,6 +780,7 @@ impl RenderElement<GlowRenderer> for CosmicMappedRenderElement<GlowRenderer> {
match self {
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Indicator(elem) => elem.underlying_storage(renderer),
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer),
}
@ -786,6 +800,10 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
match self {
CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage),
CosmicMappedRenderElement::Indicator(elem) => {
RenderElement::<GlowRenderer>::draw(elem, frame.glow_frame_mut(), src, dst, damage)
.map_err(|err| MultiError::Render(err))
}
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => {
let glow_frame = frame.glow_frame_mut();
@ -802,6 +820,9 @@ impl<'a, 'b> RenderElement<GlMultiRenderer<'a, 'b>>
match self {
CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer),
CosmicMappedRenderElement::Indicator(elem) => {
elem.underlying_storage(renderer.glow_renderer_mut())
}
#[cfg(feature = "debug")]
CosmicMappedRenderElement::Egui(elem) => {
let glow_renderer = renderer.glow_renderer_mut();
@ -836,6 +857,18 @@ where
CosmicMappedRenderElement::Window(elem)
}
}
impl<R> From<PixelShaderElement> for CosmicMappedRenderElement<R>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
fn from(elem: PixelShaderElement) -> Self {
CosmicMappedRenderElement::Indicator(elem)
}
}
#[cfg(feature = "debug")]
impl<R> From<TextureRenderElement<Gles2Texture>> for CosmicMappedRenderElement<R>
where

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::{
backend::render::element::AsGlowRenderer,
backend::render::{element::AsGlowRenderer, IndicatorShader},
shell::{
element::{CosmicMapped, CosmicMappedRenderElement},
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
@ -56,13 +56,22 @@ impl MoveGrabState {
}
let scale = output.current_scale().fractional_scale().into();
AsRenderElements::<R>::render_elements::<I>(
let mut elements: Vec<I> = vec![CosmicMappedRenderElement::from(IndicatorShader::element(
renderer,
Rectangle::from_loc_and_size(
location.to_i32_round() - output.geometry().loc,
self.window.geometry().size,
),
))
.into()];
elements.extend(AsRenderElements::<R>::render_elements::<I>(
&self.window,
renderer,
(location.to_i32_round() - output.geometry().loc - self.window.geometry().loc)
.to_physical_precise_round(scale),
scale,
)
));
elements
}
pub fn send_frames(

View file

@ -1,7 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-only
use smithay::{
backend::renderer::{element::RenderElement, ImportAll, ImportMem, Renderer},
backend::renderer::{
element::{AsRenderElements, RenderElement},
ImportAll, ImportMem, Renderer,
},
desktop::{layer_map_for_output, space::SpaceElement, Space},
input::{pointer::GrabStartData as PointerGrabStartData, Seat},
output::Output,
@ -10,11 +13,11 @@ use smithay::{
use std::collections::HashMap;
use crate::{
backend::render::element::AsGlowRenderer,
backend::render::{element::AsGlowRenderer, IndicatorShader},
shell::{
element::{CosmicMapped, CosmicMappedRenderElement},
grabs::ResizeEdge,
CosmicSurface, OutputNotMapped,
CosmicSurface,
},
state::State,
utils::prelude::*,
@ -342,16 +345,37 @@ impl FloatingLayout {
&self,
renderer: &mut R,
output: &Output,
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
focused: Option<&CosmicMapped>,
) -> Vec<CosmicMappedRenderElement<R>>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
<R as Renderer>::TextureId: 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
let output_scale = output.current_scale().fractional_scale();
let output_geo = self.space.output_geometry(output).ok_or(OutputNotMapped)?;
Ok(self
.space
.render_elements_for_region(renderer, &output_geo, output_scale))
self.space
.elements_for_output(output)
.rev()
.flat_map(|elem| {
let render_location =
self.space.element_location(elem).unwrap() - elem.geometry().loc;
let mut elements = elem.render_elements(
renderer,
render_location.to_physical_precise_round(output_scale),
output_scale.into(),
);
if focused == Some(elem) {
let element = IndicatorShader::element(
renderer,
Rectangle::from_loc_and_size(
self.space.element_location(elem).unwrap(),
elem.geometry().size,
),
);
elements.insert(0, element.into());
}
elements
})
.collect()
}
}

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::{
backend::render::element::AsGlowRenderer,
backend::render::{element::AsGlowRenderer, IndicatorShader},
shell::{
element::{CosmicMapped, CosmicMappedRenderElement},
focus::{
@ -1299,6 +1299,7 @@ impl TilingLayout {
&self,
renderer: &mut R,
output: &Output,
focused: Option<&CosmicMapped>,
) -> Result<Vec<CosmicMappedRenderElement<R>>, OutputNotMapped>
where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
@ -1360,16 +1361,25 @@ impl TilingLayout {
})
.flatten()
.flat_map(|(mapped, loc)| {
AsRenderElements::<R>::render_elements::<CosmicMappedRenderElement<R>>(
mapped,
renderer,
loc.to_physical_precise_round(output_scale)
- mapped
.geometry()
.loc
.to_physical_precise_round(output_scale),
Scale::from(output_scale),
)
let mut elements =
AsRenderElements::<R>::render_elements::<CosmicMappedRenderElement<R>>(
mapped,
renderer,
loc.to_physical_precise_round(output_scale)
- mapped
.geometry()
.loc
.to_physical_precise_round(output_scale),
Scale::from(output_scale),
);
if focused == Some(mapped) {
let element = IndicatorShader::element(
renderer,
Rectangle::from_loc_and_size(loc, mapped.geometry().size),
);
elements.insert(0, element.into());
}
elements
})
.collect::<Vec<_>>())
}

View file

@ -435,6 +435,7 @@ impl Workspace {
output: &Output,
override_redirect_windows: &[X11Surface],
xwm_state: impl Iterator<Item = &'a mut XWaylandState>,
draw_focus_indicator: Option<&Seat<State>>,
exclude_workspace_overview: bool,
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
where
@ -559,10 +560,12 @@ impl Workspace {
}),
);
let focused =
draw_focus_indicator.and_then(|seat| self.focus_stack.get(seat).last().cloned());
// floating surfaces
render_elements.extend(
self.floating_layer
.render_output::<R>(renderer, output)?
.render_output::<R>(renderer, output, focused.as_ref())
.into_iter()
.map(WorkspaceRenderElement::from),
);
@ -570,7 +573,7 @@ impl Workspace {
//tiling surfaces
render_elements.extend(
self.tiling_layer
.render_output::<R>(renderer, output)?
.render_output::<R>(renderer, output, focused.as_ref())?
.into_iter()
.map(WorkspaceRenderElement::from),
);