shell/elements: Handle clipping and shadows
This commit is contained in:
parent
2adebb5fe1
commit
59fd732982
7 changed files with 917 additions and 97 deletions
|
|
@ -136,6 +136,7 @@ pub enum Usage {
|
|||
FocusIndicator,
|
||||
PotentialGroupIndicator,
|
||||
SnappingIndicator,
|
||||
Border,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ impl PartialEq for CosmicMappedKey {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl Eq for CosmicMappedKey {}
|
||||
|
||||
impl PartialEq for CosmicMapped {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
|
|
@ -311,13 +312,10 @@ impl CosmicMapped {
|
|||
}
|
||||
|
||||
pub fn set_tiled(&self, tiled: bool) {
|
||||
if let Some(window) = match &self.element {
|
||||
// we use the tiled state of stack windows anyway to get rid of decorations
|
||||
CosmicMappedInternal::Stack(_) => None,
|
||||
CosmicMappedInternal::Window(w) => Some(w.surface()),
|
||||
match &self.element {
|
||||
CosmicMappedInternal::Stack(s) => s.set_tiled(tiled),
|
||||
CosmicMappedInternal::Window(w) => w.set_tiled(tiled),
|
||||
_ => unreachable!(),
|
||||
} {
|
||||
window.set_tiled(tiled)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -594,6 +592,34 @@ impl CosmicMapped {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub fn shadow_render_element<R, C>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
location: smithay::utils::Point<i32, smithay::utils::Physical>,
|
||||
scale: smithay::utils::Scale<f64>,
|
||||
alpha: f32,
|
||||
) -> Option<C>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
R::TextureId: Send + Clone + 'static,
|
||||
CosmicMappedRenderElement<R>: RenderElement<R>,
|
||||
C: From<CosmicMappedRenderElement<R>>,
|
||||
{
|
||||
match &self.element {
|
||||
CosmicMappedInternal::Stack(s) => s
|
||||
.shadow_render_element::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer, location, scale, alpha,
|
||||
)
|
||||
.map(Into::into),
|
||||
CosmicMappedInternal::Window(w) => w
|
||||
.shadow_render_element::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer, location, scale, alpha,
|
||||
)
|
||||
.map(Into::into),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_elements<R, C>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
|
|
@ -852,9 +878,7 @@ impl CosmicMapped {
|
|||
|
||||
pub fn corner_radius(&self, geometry_size: Size<i32, Logical>, default_radius: u8) -> [u8; 4] {
|
||||
match &self.element {
|
||||
CosmicMappedInternal::Window(w) => w
|
||||
.corner_radius(geometry_size)
|
||||
.unwrap_or([default_radius; 4]),
|
||||
CosmicMappedInternal::Window(w) => w.corner_radius(geometry_size, default_radius),
|
||||
CosmicMappedInternal::Stack(s) => s.corner_radius(geometry_size, default_radius),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
@ -1018,7 +1042,7 @@ impl From<CosmicStack> for CosmicMapped {
|
|||
|
||||
pub enum CosmicMappedRenderElement<R>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
R: Renderer + AsGlowRenderer + ImportAll + ImportMem,
|
||||
R::TextureId: 'static,
|
||||
{
|
||||
Stack(self::stack::CosmicStackRenderElement<R>),
|
||||
|
|
@ -1053,7 +1077,7 @@ where
|
|||
|
||||
impl<R> Element for CosmicMappedRenderElement<R>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
R: Renderer + AsGlowRenderer + ImportAll + ImportMem,
|
||||
R::TextureId: 'static,
|
||||
{
|
||||
fn id(&self) -> &smithay::backend::renderer::element::Id {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,16 @@ use super::{
|
|||
window::{Focus, RESIZE_BORDER},
|
||||
};
|
||||
use crate::{
|
||||
backend::render::cursor::CursorState,
|
||||
backend::render::{
|
||||
IndicatorShader, Key, Usage,
|
||||
clipped_surface::ClippedSurfaceRenderElement,
|
||||
cursor::CursorState,
|
||||
element::{AsGlowRenderer, FromGlesError},
|
||||
shadow::ShadowShader,
|
||||
},
|
||||
hooks::{Decorations, HOOKS},
|
||||
shell::{
|
||||
element::{CosmicMappedKey, CosmicMappedKeyInner},
|
||||
focus::target::PointerFocusTarget,
|
||||
grabs::{ReleaseMode, ResizeEdge},
|
||||
layout::tiling::NodeDesc,
|
||||
|
|
@ -34,9 +41,13 @@ use smithay::{
|
|||
renderer::{
|
||||
ImportAll, ImportMem, Renderer,
|
||||
element::{
|
||||
AsRenderElements, memory::MemoryRenderBufferRenderElement,
|
||||
AsRenderElements, Element, Id as RendererId, Kind, RenderElement,
|
||||
UnderlyingStorage, memory::MemoryRenderBufferRenderElement,
|
||||
surface::WaylandSurfaceRenderElement,
|
||||
},
|
||||
gles::element::PixelShaderElement,
|
||||
glow::GlowRenderer,
|
||||
utils::{CommitCounter, DamageSet, OpaqueRegions},
|
||||
},
|
||||
},
|
||||
desktop::{WindowSurfaceType, space::SpaceElement},
|
||||
|
|
@ -56,8 +67,7 @@ use smithay::{
|
|||
},
|
||||
output::Output,
|
||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||
render_elements,
|
||||
utils::{Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size},
|
||||
utils::{Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
use std::{
|
||||
|
|
@ -65,7 +75,7 @@ use std::{
|
|||
fmt,
|
||||
hash::Hash,
|
||||
sync::{
|
||||
LazyLock, Mutex,
|
||||
Arc, LazyLock, Mutex,
|
||||
atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering},
|
||||
},
|
||||
};
|
||||
|
|
@ -107,6 +117,8 @@ pub struct CosmicStackInternal {
|
|||
override_alive: AtomicBool,
|
||||
geometry: Mutex<Option<Rectangle<i32, Global>>>,
|
||||
mask: Mutex<Option<tiny_skia::Mask>>,
|
||||
tiled: AtomicBool,
|
||||
theme: Mutex<cosmic::Theme>,
|
||||
appearance_conf: Mutex<AppearanceConfig>,
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +174,8 @@ impl CosmicStack {
|
|||
override_alive: AtomicBool::new(true),
|
||||
geometry: Mutex::new(None),
|
||||
mask: Mutex::new(None),
|
||||
tiled: AtomicBool::new(false),
|
||||
theme: Mutex::new(theme.clone()),
|
||||
appearance_conf: Mutex::new(appearance),
|
||||
},
|
||||
(width, TAB_HEIGHT),
|
||||
|
|
@ -479,6 +493,11 @@ impl CosmicStack {
|
|||
self.0.force_redraw()
|
||||
}
|
||||
|
||||
pub fn set_tiled(&self, tiled: bool) {
|
||||
self.0
|
||||
.with_program(|p| p.tiled.store(tiled, Ordering::Release));
|
||||
}
|
||||
|
||||
pub fn surfaces(&self) -> impl Iterator<Item = CosmicSurface> {
|
||||
self.0.with_program(|p| {
|
||||
p.windows
|
||||
|
|
@ -618,7 +637,7 @@ impl CosmicStack {
|
|||
alpha: f32,
|
||||
) -> Vec<C>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
R: Renderer + AsGlowRenderer + ImportAll + ImportMem,
|
||||
R::TextureId: Send + Clone + 'static,
|
||||
C: From<CosmicStackRenderElement<R>>,
|
||||
{
|
||||
|
|
@ -637,6 +656,61 @@ impl CosmicStack {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn shadow_render_element<R, C>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
location: Point<i32, Physical>,
|
||||
scale: Scale<f64>,
|
||||
alpha: f32,
|
||||
) -> Option<C>
|
||||
where
|
||||
R: Renderer + AsGlowRenderer + ImportAll + ImportMem,
|
||||
R::TextureId: Send + Clone + 'static,
|
||||
C: From<CosmicStackRenderElement<R>>,
|
||||
{
|
||||
self.0.with_program(|p| {
|
||||
let windows = p.windows.lock().unwrap();
|
||||
let active = p.active.load(Ordering::SeqCst);
|
||||
let activated = p.activated.load(Ordering::Acquire);
|
||||
let theme = p.theme.lock().unwrap();
|
||||
let appearance = p.appearance_conf.lock().unwrap();
|
||||
let tiled = p.tiled.load(Ordering::Acquire);
|
||||
|
||||
let round = appearance.clip_tiled_windows || !tiled;
|
||||
if tiled && !appearance.shadow_tiled_windows {
|
||||
return None;
|
||||
}
|
||||
let radii = round
|
||||
.then(|| {
|
||||
theme
|
||||
.cosmic()
|
||||
.radius_s()
|
||||
.map(|x| if x < 4.0 { x } else { x + 4.0 })
|
||||
.map(|x| x.round() as u8)
|
||||
})
|
||||
.unwrap_or([0, 0, 0, 0]);
|
||||
|
||||
let mut geo = SpaceElement::geometry(&windows[active]).to_f64();
|
||||
geo.loc += location.to_f64().to_logical(scale);
|
||||
geo.size.h += TAB_HEIGHT as f64;
|
||||
|
||||
let window_key =
|
||||
CosmicMappedKey(CosmicMappedKeyInner::Stack(Arc::downgrade(&self.0.0)));
|
||||
|
||||
Some(
|
||||
CosmicStackRenderElement::Shadow(ShadowShader::element(
|
||||
renderer,
|
||||
window_key,
|
||||
geo.to_i32_round().as_local(),
|
||||
radii,
|
||||
if activated { alpha } else { alpha * 0.75 },
|
||||
scale.x,
|
||||
))
|
||||
.into(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render_elements<R, C>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
|
|
@ -646,35 +720,85 @@ impl CosmicStack {
|
|||
scanout_override: Option<bool>,
|
||||
) -> Vec<C>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
R: Renderer + AsGlowRenderer + ImportAll + ImportMem,
|
||||
R::TextureId: Send + Clone + 'static,
|
||||
C: From<CosmicStackRenderElement<R>>,
|
||||
{
|
||||
let offset = self
|
||||
let geometry = self
|
||||
.0
|
||||
.with_program(|p| {
|
||||
p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]
|
||||
.geometry()
|
||||
.loc
|
||||
})
|
||||
.with_program(|p| p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].geometry())
|
||||
.to_physical_precise_round(scale);
|
||||
let stack_loc = location + offset;
|
||||
let stack_loc = location + geometry.loc;
|
||||
let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32));
|
||||
|
||||
let mut elements = AsRenderElements::<R>::render_elements::<CosmicStackRenderElement<R>>(
|
||||
&self.0, renderer, stack_loc, scale, alpha,
|
||||
);
|
||||
|
||||
if !self.0.with_program(|p| p.tiled.load(Ordering::Acquire)) {}
|
||||
|
||||
elements.extend(self.0.with_program(|p| {
|
||||
let windows = p.windows.lock().unwrap();
|
||||
let active = p.active.load(Ordering::SeqCst);
|
||||
let theme = p.theme.lock().unwrap();
|
||||
let appearance = p.appearance_conf.lock().unwrap();
|
||||
let tiled = p.tiled.load(Ordering::Acquire);
|
||||
|
||||
windows[active].render_elements::<R, CosmicStackRenderElement<R>>(
|
||||
renderer,
|
||||
window_loc,
|
||||
scale,
|
||||
alpha,
|
||||
scanout_override,
|
||||
let round = appearance.clip_tiled_windows || !tiled;
|
||||
let radii = round.then(|| {
|
||||
theme
|
||||
.cosmic()
|
||||
.radius_s()
|
||||
.map(|x| if x < 4.0 { x } else { x + 4.0 })
|
||||
.map(|x| x.round() as u8)
|
||||
});
|
||||
|
||||
let mut geo = SpaceElement::geometry(&windows[active]).to_f64();
|
||||
geo.loc += location.to_f64().to_logical(scale);
|
||||
geo.size.h += TAB_HEIGHT as f64;
|
||||
|
||||
let window_key =
|
||||
CosmicMappedKey(CosmicMappedKeyInner::Stack(Arc::downgrade(&self.0.0)));
|
||||
|
||||
let border = {
|
||||
let (r, g, b, a) = theme.cosmic().bg_divider().into_components();
|
||||
CosmicStackRenderElement::Border(IndicatorShader::element(
|
||||
renderer,
|
||||
Key::Window(Usage::Border, window_key.clone()),
|
||||
geo.to_i32_round().as_local(),
|
||||
1,
|
||||
radii.unwrap_or([0, 0, 0, 0]),
|
||||
a * alpha,
|
||||
[r, g, b],
|
||||
))
|
||||
};
|
||||
|
||||
std::iter::once(border).chain(
|
||||
windows[active]
|
||||
.render_elements::<R, WaylandSurfaceRenderElement<R>>(
|
||||
renderer,
|
||||
window_loc,
|
||||
scale,
|
||||
alpha,
|
||||
scanout_override,
|
||||
)
|
||||
.into_iter()
|
||||
.map(move |elem| {
|
||||
let radii = radii.map(|[a, _, c, _]| [a, 0, c, 0]);
|
||||
if radii.is_some_and(|radii| {
|
||||
ClippedSurfaceRenderElement::will_clip(&elem, scale, geo, radii)
|
||||
}) {
|
||||
CosmicStackRenderElement::Clipped(ClippedSurfaceRenderElement::new(
|
||||
renderer,
|
||||
elem,
|
||||
scale,
|
||||
geo,
|
||||
radii.unwrap(),
|
||||
))
|
||||
} else {
|
||||
CosmicStackRenderElement::Window(elem)
|
||||
}
|
||||
}),
|
||||
)
|
||||
}));
|
||||
|
||||
|
|
@ -682,6 +806,9 @@ impl CosmicStack {
|
|||
}
|
||||
|
||||
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
||||
self.0.with_program(|p| {
|
||||
*p.theme.lock().unwrap() = theme.clone();
|
||||
});
|
||||
self.0.set_theme(theme);
|
||||
}
|
||||
|
||||
|
|
@ -799,14 +926,37 @@ impl CosmicStack {
|
|||
pub fn corner_radius(&self, geometry_size: Size<i32, Logical>, default_radius: u8) -> [u8; 4] {
|
||||
self.0.with_program(|p| {
|
||||
let active_window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)];
|
||||
let mut corners = active_window
|
||||
.corner_radius(geometry_size)
|
||||
.unwrap_or([default_radius; 4]);
|
||||
let is_tiled = p.tiled.load(Ordering::Acquire);
|
||||
let appearance = p.appearance_conf.lock().unwrap();
|
||||
let round = appearance.clip_tiled_windows || !is_tiled;
|
||||
let radii = p
|
||||
.theme
|
||||
.lock()
|
||||
.unwrap()
|
||||
.cosmic()
|
||||
.radius_s()
|
||||
.map(|x| if x < 4.0 { x } else { x + 4.0 })
|
||||
.map(|val| val.round() as u8);
|
||||
|
||||
corners[1] = 8;
|
||||
corners[3] = 8;
|
||||
if !round {
|
||||
let mut corners = active_window
|
||||
.corner_radius(geometry_size)
|
||||
.unwrap_or([default_radius; 4]);
|
||||
|
||||
corners
|
||||
corners[1] = 0;
|
||||
corners[3] = 0;
|
||||
|
||||
corners
|
||||
} else {
|
||||
let mut corners = active_window.corner_radius(geometry_size).unwrap_or(radii);
|
||||
|
||||
corners[0] = radii[0].max(corners[0]);
|
||||
corners[1] = radii[1];
|
||||
corners[2] = radii[2].max(corners[2]);
|
||||
corners[3] = radii[3];
|
||||
|
||||
corners
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1138,10 +1288,20 @@ impl Decorations<CosmicStackInternal, Message> for DefaultDecorations {
|
|||
.into(),
|
||||
];
|
||||
|
||||
let radius = if windows[active].is_maximized(false) {
|
||||
let radius = if windows[active].is_maximized(false)
|
||||
|| (stack.tiled.load(Ordering::Acquire)
|
||||
&& !stack.appearance_conf.lock().unwrap().clip_tiled_windows)
|
||||
{
|
||||
Radius::from(0.0)
|
||||
} else {
|
||||
Radius::from([8.0, 8.0, 0.0, 0.0])
|
||||
let radii = stack
|
||||
.theme
|
||||
.lock()
|
||||
.unwrap()
|
||||
.cosmic()
|
||||
.radius_s()
|
||||
.map(|x| if x < 4.0 { x } else { x + 4.0 });
|
||||
Radius::from([radii[0], radii[1], 0., 0.])
|
||||
};
|
||||
let group_focused = stack.group_focused.load(Ordering::SeqCst);
|
||||
|
||||
|
|
@ -1667,8 +1827,193 @@ impl TouchTarget<State> for CosmicStack {
|
|||
}
|
||||
}
|
||||
|
||||
render_elements! {
|
||||
pub CosmicStackRenderElement<R> where R: ImportAll + ImportMem;
|
||||
Header = MemoryRenderBufferRenderElement<R>,
|
||||
Window = WaylandSurfaceRenderElement<R>,
|
||||
pub enum CosmicStackRenderElement<R: Renderer + ImportAll + ImportMem> {
|
||||
Header(MemoryRenderBufferRenderElement<R>),
|
||||
Shadow(PixelShaderElement),
|
||||
Border(PixelShaderElement),
|
||||
Window(WaylandSurfaceRenderElement<R>),
|
||||
Clipped(ClippedSurfaceRenderElement<R>),
|
||||
}
|
||||
|
||||
impl<R: Renderer + ImportAll + ImportMem> From<MemoryRenderBufferRenderElement<R>>
|
||||
for CosmicStackRenderElement<R>
|
||||
{
|
||||
fn from(value: MemoryRenderBufferRenderElement<R>) -> Self {
|
||||
Self::Header(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Renderer + ImportAll + ImportMem> From<WaylandSurfaceRenderElement<R>>
|
||||
for CosmicStackRenderElement<R>
|
||||
{
|
||||
fn from(value: WaylandSurfaceRenderElement<R>) -> Self {
|
||||
Self::Window(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Renderer + ImportAll + ImportMem> From<ClippedSurfaceRenderElement<R>>
|
||||
for CosmicStackRenderElement<R>
|
||||
{
|
||||
fn from(value: ClippedSurfaceRenderElement<R>) -> Self {
|
||||
Self::Clipped(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Element for CosmicStackRenderElement<R>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
{
|
||||
fn id(&self) -> &RendererId {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.id(),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.id(),
|
||||
CosmicStackRenderElement::Border(elem) => elem.id(),
|
||||
CosmicStackRenderElement::Window(elem) => elem.id(),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.id(),
|
||||
}
|
||||
}
|
||||
|
||||
fn current_commit(&self) -> CommitCounter {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.current_commit(),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.current_commit(),
|
||||
CosmicStackRenderElement::Border(elem) => elem.current_commit(),
|
||||
CosmicStackRenderElement::Window(elem) => elem.current_commit(),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.current_commit(),
|
||||
}
|
||||
}
|
||||
|
||||
fn src(&self) -> Rectangle<f64, Buffer> {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.src(),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.src(),
|
||||
CosmicStackRenderElement::Border(elem) => elem.src(),
|
||||
CosmicStackRenderElement::Window(elem) => elem.src(),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.src(),
|
||||
}
|
||||
}
|
||||
|
||||
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.geometry(scale),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.geometry(scale),
|
||||
CosmicStackRenderElement::Border(elem) => elem.geometry(scale),
|
||||
CosmicStackRenderElement::Window(elem) => elem.geometry(scale),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.geometry(scale),
|
||||
}
|
||||
}
|
||||
|
||||
fn location(&self, scale: Scale<f64>) -> Point<i32, Physical> {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.location(scale),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.location(scale),
|
||||
CosmicStackRenderElement::Border(elem) => elem.location(scale),
|
||||
CosmicStackRenderElement::Window(elem) => elem.location(scale),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.location(scale),
|
||||
}
|
||||
}
|
||||
|
||||
fn transform(&self) -> Transform {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.transform(),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.transform(),
|
||||
CosmicStackRenderElement::Border(elem) => elem.transform(),
|
||||
CosmicStackRenderElement::Window(elem) => elem.transform(),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.transform(),
|
||||
}
|
||||
}
|
||||
|
||||
fn damage_since(
|
||||
&self,
|
||||
scale: Scale<f64>,
|
||||
commit: Option<CommitCounter>,
|
||||
) -> DamageSet<i32, Physical> {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.damage_since(scale, commit),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.damage_since(scale, commit),
|
||||
CosmicStackRenderElement::Border(elem) => elem.damage_since(scale, commit),
|
||||
CosmicStackRenderElement::Window(elem) => elem.damage_since(scale, commit),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.damage_since(scale, commit),
|
||||
}
|
||||
}
|
||||
|
||||
fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, Physical> {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.opaque_regions(scale),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.opaque_regions(scale),
|
||||
CosmicStackRenderElement::Border(elem) => elem.opaque_regions(scale),
|
||||
CosmicStackRenderElement::Window(elem) => elem.opaque_regions(scale),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.opaque_regions(scale),
|
||||
}
|
||||
}
|
||||
|
||||
fn alpha(&self) -> f32 {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.alpha(),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.alpha(),
|
||||
CosmicStackRenderElement::Border(elem) => elem.alpha(),
|
||||
CosmicStackRenderElement::Window(elem) => elem.alpha(),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.alpha(),
|
||||
}
|
||||
}
|
||||
|
||||
fn kind(&self) -> Kind {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.kind(),
|
||||
CosmicStackRenderElement::Shadow(elem) => elem.kind(),
|
||||
CosmicStackRenderElement::Border(elem) => elem.kind(),
|
||||
CosmicStackRenderElement::Window(elem) => elem.kind(),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.kind(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> RenderElement<R> for CosmicStackRenderElement<R>
|
||||
where
|
||||
R: Renderer + AsGlowRenderer + ImportAll + ImportMem,
|
||||
R::TextureId: 'static,
|
||||
R::Error: FromGlesError,
|
||||
{
|
||||
fn draw(
|
||||
&self,
|
||||
frame: &mut <R>::Frame<'_, '_>,
|
||||
src: Rectangle<f64, Buffer>,
|
||||
dst: Rectangle<i32, Physical>,
|
||||
damage: &[Rectangle<i32, Physical>],
|
||||
opaque_regions: &[Rectangle<i32, Physical>],
|
||||
) -> Result<(), <R>::Error> {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => {
|
||||
elem.draw(frame, src, dst, damage, opaque_regions)
|
||||
}
|
||||
CosmicStackRenderElement::Shadow(elem) | CosmicStackRenderElement::Border(elem) => {
|
||||
RenderElement::<GlowRenderer>::draw(
|
||||
elem,
|
||||
R::glow_frame_mut(frame),
|
||||
src,
|
||||
dst,
|
||||
damage,
|
||||
opaque_regions,
|
||||
)
|
||||
.map_err(FromGlesError::from_gles_error)
|
||||
}
|
||||
CosmicStackRenderElement::Window(elem) => {
|
||||
elem.draw(frame, src, dst, damage, opaque_regions)
|
||||
}
|
||||
CosmicStackRenderElement::Clipped(elem) => {
|
||||
elem.draw(frame, src, dst, damage, opaque_regions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn underlying_storage(&self, renderer: &mut R) -> Option<UnderlyingStorage<'_>> {
|
||||
match self {
|
||||
CosmicStackRenderElement::Header(elem) => elem.underlying_storage(renderer),
|
||||
CosmicStackRenderElement::Shadow(elem) | CosmicStackRenderElement::Border(elem) => {
|
||||
elem.underlying_storage(renderer.glow_renderer_mut())
|
||||
}
|
||||
CosmicStackRenderElement::Window(elem) => elem.underlying_storage(renderer),
|
||||
CosmicStackRenderElement::Clipped(elem) => elem.underlying_storage(renderer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
use crate::{
|
||||
backend::render::cursor::CursorState,
|
||||
backend::render::{
|
||||
IndicatorShader, Key, Usage,
|
||||
clipped_surface::ClippedSurfaceRenderElement,
|
||||
cursor::CursorState,
|
||||
element::{AsGlowRenderer, FromGlesError},
|
||||
shadow::ShadowShader,
|
||||
},
|
||||
hooks::{Decorations, HOOKS},
|
||||
shell::{
|
||||
element::{CosmicMappedKey, CosmicMappedKeyInner},
|
||||
focus::target::PointerFocusTarget,
|
||||
grabs::{ReleaseMode, ResizeEdge},
|
||||
},
|
||||
|
|
@ -20,9 +27,13 @@ use smithay::{
|
|||
renderer::{
|
||||
ImportAll, ImportMem, Renderer,
|
||||
element::{
|
||||
AsRenderElements, memory::MemoryRenderBufferRenderElement,
|
||||
AsRenderElements, Element, Id as RendererId, Kind, RenderElement,
|
||||
UnderlyingStorage, memory::MemoryRenderBufferRenderElement,
|
||||
surface::WaylandSurfaceRenderElement,
|
||||
},
|
||||
gles::element::PixelShaderElement,
|
||||
glow::GlowRenderer,
|
||||
utils::{CommitCounter, DamageSet, OpaqueRegions},
|
||||
},
|
||||
},
|
||||
desktop::{WindowSurfaceType, space::SpaceElement},
|
||||
|
|
@ -42,8 +53,7 @@ use smithay::{
|
|||
},
|
||||
output::Output,
|
||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||
render_elements,
|
||||
utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size},
|
||||
utils::{Buffer, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform},
|
||||
wayland::seat::WaylandFocus,
|
||||
};
|
||||
use std::{
|
||||
|
|
@ -51,7 +61,7 @@ use std::{
|
|||
fmt,
|
||||
hash::Hash,
|
||||
sync::{
|
||||
Mutex,
|
||||
Arc, Mutex,
|
||||
atomic::{AtomicBool, AtomicU8, Ordering},
|
||||
},
|
||||
};
|
||||
|
|
@ -80,6 +90,8 @@ pub struct CosmicWindowInternal {
|
|||
/// TODO: This needs to be per seat
|
||||
pointer_entered: AtomicU8,
|
||||
last_title: Mutex<String>,
|
||||
tiled: AtomicBool,
|
||||
theme: Mutex<cosmic::Theme>,
|
||||
appearance_conf: Mutex<AppearanceConfig>,
|
||||
}
|
||||
|
||||
|
|
@ -165,9 +177,9 @@ impl CosmicWindowInternal {
|
|||
!self.window.is_decorated(pending)
|
||||
}
|
||||
|
||||
/// returns if the window is currently or pending tiled
|
||||
pub fn is_tiled(&self, pending: bool) -> bool {
|
||||
self.window.is_tiled(pending).unwrap_or(false)
|
||||
/// returns if the window is currently tiled
|
||||
pub fn is_tiled(&self) -> bool {
|
||||
self.tiled.load(Ordering::Acquire)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,12 +193,19 @@ impl CosmicWindow {
|
|||
let window = window.into();
|
||||
let width = window.geometry().size.w;
|
||||
let last_title = window.title();
|
||||
|
||||
if appearance.clip_floating_windows {
|
||||
window.set_tiled(true);
|
||||
}
|
||||
|
||||
CosmicWindow(IcedElement::new(
|
||||
CosmicWindowInternal {
|
||||
window,
|
||||
activated: AtomicBool::new(false),
|
||||
pointer_entered: AtomicU8::new(0),
|
||||
last_title: Mutex::new(last_title),
|
||||
tiled: AtomicBool::new(false),
|
||||
theme: Mutex::new(theme.clone()),
|
||||
appearance_conf: Mutex::new(appearance),
|
||||
},
|
||||
(width, SSD_HEIGHT),
|
||||
|
|
@ -241,8 +260,7 @@ impl CosmicWindow {
|
|||
let mut offset = Point::from((0., 0.));
|
||||
let mut window_ui = None;
|
||||
let has_ssd = p.has_ssd(false);
|
||||
if (has_ssd || p.is_tiled(false)) && surface_type.contains(WindowSurfaceType::TOPLEVEL)
|
||||
{
|
||||
if (has_ssd || p.is_tiled()) && surface_type.contains(WindowSurfaceType::TOPLEVEL) {
|
||||
let geo = p.window.geometry();
|
||||
|
||||
let point_i32 = relative_pos.to_i32_round::<i32>();
|
||||
|
|
@ -330,6 +348,77 @@ impl CosmicWindow {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn shadow_render_element<R, C>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
location: Point<i32, Physical>,
|
||||
scale: Scale<f64>,
|
||||
alpha: f32,
|
||||
) -> Option<C>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
R::TextureId: Send + Clone + 'static,
|
||||
C: From<CosmicWindowRenderElement<R>>,
|
||||
{
|
||||
self.0.with_program(|p| {
|
||||
let has_ssd = p.has_ssd(false);
|
||||
let is_tiled = p.is_tiled();
|
||||
let activated = p.window.is_activated(false);
|
||||
let appearance = p.appearance_conf.lock().unwrap();
|
||||
|
||||
let clip = (!is_tiled && appearance.clip_floating_windows)
|
||||
|| (is_tiled && appearance.clip_tiled_windows);
|
||||
let should_draw_shadow = if is_tiled {
|
||||
appearance.shadow_tiled_windows
|
||||
} else {
|
||||
appearance.clip_floating_windows || has_ssd
|
||||
};
|
||||
|
||||
if !should_draw_shadow {
|
||||
return None;
|
||||
}
|
||||
let mut radii = p
|
||||
.theme
|
||||
.lock()
|
||||
.unwrap()
|
||||
.cosmic()
|
||||
.radius_s()
|
||||
.map(|x| if x < 4.0 { x } else { x + 4.0 })
|
||||
.map(|x| x.round() as u8);
|
||||
if has_ssd && !clip {
|
||||
// bottom corners
|
||||
radii[1] = 0;
|
||||
radii[3] = 0;
|
||||
if is_tiled {
|
||||
// top corners
|
||||
radii[0] = 0;
|
||||
radii[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
let mut geo = SpaceElement::geometry(&p.window).to_f64();
|
||||
geo.loc += location.to_f64().to_logical(scale);
|
||||
if has_ssd {
|
||||
geo.size.h += SSD_HEIGHT as f64;
|
||||
}
|
||||
|
||||
let window_key =
|
||||
CosmicMappedKey(CosmicMappedKeyInner::Window(Arc::downgrade(&self.0.0)));
|
||||
|
||||
Some(
|
||||
CosmicWindowRenderElement::Shadow(ShadowShader::element(
|
||||
renderer,
|
||||
window_key,
|
||||
geo.to_i32_round().as_local(),
|
||||
radii,
|
||||
if activated { alpha } else { alpha * 0.75 },
|
||||
scale.x,
|
||||
))
|
||||
.into(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render_elements<R, C>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
|
|
@ -339,11 +428,36 @@ impl CosmicWindow {
|
|||
scanout_override: Option<bool>,
|
||||
) -> Vec<C>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
|
||||
R::TextureId: Send + Clone + 'static,
|
||||
C: From<CosmicWindowRenderElement<R>>,
|
||||
{
|
||||
let has_ssd = self.0.with_program(|p| p.has_ssd(false));
|
||||
let (has_ssd, is_tiled, mut radii, appearance) = self.0.with_program(|p| {
|
||||
(
|
||||
p.has_ssd(false),
|
||||
p.is_tiled(),
|
||||
p.theme
|
||||
.lock()
|
||||
.unwrap()
|
||||
.cosmic()
|
||||
.radius_s()
|
||||
.map(|x| if x < 4.0 { x } else { x + 4.0 })
|
||||
.map(|x| x.round() as u8),
|
||||
*p.appearance_conf.lock().unwrap(),
|
||||
)
|
||||
});
|
||||
let clip = (!is_tiled && appearance.clip_floating_windows)
|
||||
|| (is_tiled && appearance.clip_tiled_windows);
|
||||
if has_ssd && !clip {
|
||||
// bottom corners
|
||||
radii[1] = 0;
|
||||
radii[3] = 0;
|
||||
if is_tiled {
|
||||
// top corners
|
||||
radii[0] = 0;
|
||||
radii[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
let window_loc = if has_ssd {
|
||||
location + Point::from((0, (SSD_HEIGHT as f64 * scale.y) as i32))
|
||||
|
|
@ -353,14 +467,60 @@ impl CosmicWindow {
|
|||
|
||||
let mut elements = Vec::new();
|
||||
|
||||
elements.extend(self.0.with_program(|p| {
|
||||
p.window.render_elements::<R, CosmicWindowRenderElement<R>>(
|
||||
renderer,
|
||||
window_loc,
|
||||
scale,
|
||||
alpha,
|
||||
scanout_override,
|
||||
let (mut geo, bg_divider) = self.0.with_program(|p| {
|
||||
(
|
||||
SpaceElement::geometry(&p.window).to_f64(),
|
||||
p.theme.lock().unwrap().cosmic().bg_divider(),
|
||||
)
|
||||
});
|
||||
geo.loc += location.to_f64().to_logical(scale);
|
||||
if has_ssd {
|
||||
geo.size.h += SSD_HEIGHT as f64;
|
||||
}
|
||||
|
||||
if has_ssd || clip {
|
||||
let window_key =
|
||||
CosmicMappedKey(CosmicMappedKeyInner::Window(Arc::downgrade(&self.0.0)));
|
||||
|
||||
let (r, g, b, a) = bg_divider.into_components();
|
||||
let elem = CosmicWindowRenderElement::Border(IndicatorShader::element(
|
||||
renderer,
|
||||
Key::Window(Usage::Border, window_key.clone()),
|
||||
geo.to_i32_round().as_local(),
|
||||
1,
|
||||
radii,
|
||||
a * alpha,
|
||||
[r, g, b],
|
||||
));
|
||||
elements.push(elem);
|
||||
}
|
||||
|
||||
elements.extend(self.0.with_program(|p| {
|
||||
p.window
|
||||
.render_elements::<R, WaylandSurfaceRenderElement<R>>(
|
||||
renderer,
|
||||
window_loc,
|
||||
scale,
|
||||
alpha,
|
||||
scanout_override,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|elem| {
|
||||
if has_ssd {
|
||||
radii[0] = 0;
|
||||
radii[2] = 0;
|
||||
}
|
||||
if radii.iter().any(|x| *x != 0)
|
||||
&& clip
|
||||
&& ClippedSurfaceRenderElement::will_clip(&elem, scale, geo, radii)
|
||||
{
|
||||
CosmicWindowRenderElement::Clipped(ClippedSurfaceRenderElement::new(
|
||||
renderer, elem, scale, geo, radii,
|
||||
))
|
||||
} else {
|
||||
CosmicWindowRenderElement::Window(elem)
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
||||
if has_ssd {
|
||||
|
|
@ -378,6 +538,9 @@ impl CosmicWindow {
|
|||
}
|
||||
|
||||
pub(crate) fn set_theme(&self, theme: cosmic::Theme) {
|
||||
self.0.with_program(|p| {
|
||||
*p.theme.lock().unwrap() = theme.clone();
|
||||
});
|
||||
self.0.set_theme(theme);
|
||||
}
|
||||
|
||||
|
|
@ -424,9 +587,62 @@ impl CosmicWindow {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn corner_radius(&self, geometry_size: Size<i32, Logical>) -> Option<[u8; 4]> {
|
||||
self.0
|
||||
.with_program(|p| p.window.corner_radius(geometry_size))
|
||||
pub fn set_tiled(&self, tiled: bool) {
|
||||
self.0.with_program(|p| {
|
||||
p.tiled.store(tiled, Ordering::Release);
|
||||
if !p.appearance_conf.lock().unwrap().clip_floating_windows {
|
||||
p.window.set_tiled(tiled);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn corner_radius(&self, geometry_size: Size<i32, Logical>, default_radius: u8) -> [u8; 4] {
|
||||
self.0.with_program(|p| {
|
||||
let has_ssd = p.has_ssd(false);
|
||||
let is_tiled = p.is_tiled();
|
||||
let appearance = p.appearance_conf.lock().unwrap();
|
||||
|
||||
let round = (!is_tiled && appearance.clip_floating_windows)
|
||||
|| (is_tiled && appearance.clip_tiled_windows);
|
||||
let radii = p
|
||||
.theme
|
||||
.lock()
|
||||
.unwrap()
|
||||
.cosmic()
|
||||
.radius_s()
|
||||
.map(|x| if x < 4.0 { x } else { x + 4.0 })
|
||||
.map(|x| x.round() as u8);
|
||||
|
||||
match (has_ssd, round) {
|
||||
(has_ssd, true) => {
|
||||
let mut corners = p.window.corner_radius(geometry_size).unwrap_or(radii);
|
||||
|
||||
corners[0] = radii[0].max(corners[0]);
|
||||
corners[1] = if has_ssd {
|
||||
radii[1]
|
||||
} else {
|
||||
radii[1].max(corners[1])
|
||||
};
|
||||
corners[2] = radii[2].max(corners[2]);
|
||||
corners[3] = if has_ssd {
|
||||
radii[3]
|
||||
} else {
|
||||
radii[3].max(corners[3])
|
||||
};
|
||||
|
||||
corners
|
||||
}
|
||||
(true, false) => p
|
||||
.window
|
||||
.corner_radius(geometry_size)
|
||||
.map(|[a, _, c, _]| [a, radii[1], c, radii[3]])
|
||||
.unwrap_or([default_radius, radii[1], default_radius, radii[3]]),
|
||||
(false, false) => p
|
||||
.window
|
||||
.corner_radius(geometry_size)
|
||||
.unwrap_or([default_radius; 4]),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +813,7 @@ impl SpaceElement for CosmicWindow {
|
|||
let mut bbox = SpaceElement::bbox(&p.window);
|
||||
let has_ssd = p.has_ssd(false);
|
||||
|
||||
if has_ssd || p.is_tiled(false) {
|
||||
if has_ssd || p.is_tiled() {
|
||||
bbox.loc -= Point::from((RESIZE_BORDER, RESIZE_BORDER));
|
||||
bbox.size += Size::from((RESIZE_BORDER * 2, RESIZE_BORDER * 2));
|
||||
}
|
||||
|
|
@ -716,7 +932,7 @@ impl PointerTarget<State> for CosmicWindow {
|
|||
let mut event = event.clone();
|
||||
self.0.with_program(|p| {
|
||||
let has_ssd = p.has_ssd(false);
|
||||
if has_ssd || p.is_tiled(false) {
|
||||
if has_ssd || p.is_tiled() {
|
||||
let Some(next) = Focus::under(
|
||||
&p.window,
|
||||
if has_ssd { SSD_HEIGHT } else { 0 },
|
||||
|
|
@ -742,7 +958,7 @@ impl PointerTarget<State> for CosmicWindow {
|
|||
let mut event = event.clone();
|
||||
self.0.with_program(|p| {
|
||||
let has_ssd = p.has_ssd(false);
|
||||
if has_ssd || p.is_tiled(false) {
|
||||
if has_ssd || p.is_tiled() {
|
||||
let Some(next) = Focus::under(
|
||||
&p.window,
|
||||
if has_ssd { SSD_HEIGHT } else { 0 },
|
||||
|
|
@ -955,8 +1171,193 @@ impl WaylandFocus for CosmicWindow {
|
|||
}
|
||||
}
|
||||
|
||||
render_elements! {
|
||||
pub CosmicWindowRenderElement<R> where R: ImportAll + ImportMem;
|
||||
Header = MemoryRenderBufferRenderElement<R>,
|
||||
Window = WaylandSurfaceRenderElement<R>,
|
||||
pub enum CosmicWindowRenderElement<R: Renderer + ImportAll + ImportMem> {
|
||||
Header(MemoryRenderBufferRenderElement<R>),
|
||||
Shadow(PixelShaderElement),
|
||||
Border(PixelShaderElement),
|
||||
Window(WaylandSurfaceRenderElement<R>),
|
||||
Clipped(ClippedSurfaceRenderElement<R>),
|
||||
}
|
||||
|
||||
impl<R: Renderer + ImportAll + ImportMem> From<MemoryRenderBufferRenderElement<R>>
|
||||
for CosmicWindowRenderElement<R>
|
||||
{
|
||||
fn from(value: MemoryRenderBufferRenderElement<R>) -> Self {
|
||||
Self::Header(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Renderer + ImportAll + ImportMem> From<WaylandSurfaceRenderElement<R>>
|
||||
for CosmicWindowRenderElement<R>
|
||||
{
|
||||
fn from(value: WaylandSurfaceRenderElement<R>) -> Self {
|
||||
Self::Window(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Renderer + ImportAll + ImportMem> From<ClippedSurfaceRenderElement<R>>
|
||||
for CosmicWindowRenderElement<R>
|
||||
{
|
||||
fn from(value: ClippedSurfaceRenderElement<R>) -> Self {
|
||||
Self::Clipped(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> Element for CosmicWindowRenderElement<R>
|
||||
where
|
||||
R: Renderer + ImportAll + ImportMem,
|
||||
{
|
||||
fn id(&self) -> &RendererId {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.id(),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.id(),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.id(),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.id(),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.id(),
|
||||
}
|
||||
}
|
||||
|
||||
fn current_commit(&self) -> CommitCounter {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.current_commit(),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.current_commit(),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.current_commit(),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.current_commit(),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.current_commit(),
|
||||
}
|
||||
}
|
||||
|
||||
fn src(&self) -> Rectangle<f64, Buffer> {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.src(),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.src(),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.src(),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.src(),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.src(),
|
||||
}
|
||||
}
|
||||
|
||||
fn geometry(&self, scale: Scale<f64>) -> Rectangle<i32, Physical> {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.geometry(scale),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.geometry(scale),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.geometry(scale),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.geometry(scale),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.geometry(scale),
|
||||
}
|
||||
}
|
||||
|
||||
fn location(&self, scale: Scale<f64>) -> Point<i32, Physical> {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.location(scale),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.location(scale),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.location(scale),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.location(scale),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.location(scale),
|
||||
}
|
||||
}
|
||||
|
||||
fn transform(&self) -> Transform {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.transform(),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.transform(),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.transform(),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.transform(),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.transform(),
|
||||
}
|
||||
}
|
||||
|
||||
fn damage_since(
|
||||
&self,
|
||||
scale: Scale<f64>,
|
||||
commit: Option<CommitCounter>,
|
||||
) -> DamageSet<i32, Physical> {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.damage_since(scale, commit),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.damage_since(scale, commit),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.damage_since(scale, commit),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.damage_since(scale, commit),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.damage_since(scale, commit),
|
||||
}
|
||||
}
|
||||
|
||||
fn opaque_regions(&self, scale: Scale<f64>) -> OpaqueRegions<i32, Physical> {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.opaque_regions(scale),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.opaque_regions(scale),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.opaque_regions(scale),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.opaque_regions(scale),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.opaque_regions(scale),
|
||||
}
|
||||
}
|
||||
|
||||
fn alpha(&self) -> f32 {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.alpha(),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.alpha(),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.alpha(),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.alpha(),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.alpha(),
|
||||
}
|
||||
}
|
||||
|
||||
fn kind(&self) -> Kind {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.kind(),
|
||||
CosmicWindowRenderElement::Shadow(elem) => elem.kind(),
|
||||
CosmicWindowRenderElement::Border(elem) => elem.kind(),
|
||||
CosmicWindowRenderElement::Window(elem) => elem.kind(),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.kind(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> RenderElement<R> for CosmicWindowRenderElement<R>
|
||||
where
|
||||
R: Renderer + AsGlowRenderer + ImportAll + ImportMem,
|
||||
R::TextureId: 'static,
|
||||
R::Error: FromGlesError,
|
||||
{
|
||||
fn draw(
|
||||
&self,
|
||||
frame: &mut <R>::Frame<'_, '_>,
|
||||
src: Rectangle<f64, Buffer>,
|
||||
dst: Rectangle<i32, Physical>,
|
||||
damage: &[Rectangle<i32, Physical>],
|
||||
opaque_regions: &[Rectangle<i32, Physical>],
|
||||
) -> Result<(), <R>::Error> {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => {
|
||||
elem.draw(frame, src, dst, damage, opaque_regions)
|
||||
}
|
||||
CosmicWindowRenderElement::Shadow(elem) | CosmicWindowRenderElement::Border(elem) => {
|
||||
RenderElement::<GlowRenderer>::draw(
|
||||
elem,
|
||||
R::glow_frame_mut(frame),
|
||||
src,
|
||||
dst,
|
||||
damage,
|
||||
opaque_regions,
|
||||
)
|
||||
.map_err(FromGlesError::from_gles_error)
|
||||
}
|
||||
CosmicWindowRenderElement::Window(elem) => {
|
||||
elem.draw(frame, src, dst, damage, opaque_regions)
|
||||
}
|
||||
CosmicWindowRenderElement::Clipped(elem) => {
|
||||
elem.draw(frame, src, dst, damage, opaque_regions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn underlying_storage(&self, renderer: &mut R) -> Option<UnderlyingStorage<'_>> {
|
||||
match self {
|
||||
CosmicWindowRenderElement::Header(elem) => elem.underlying_storage(renderer),
|
||||
CosmicWindowRenderElement::Shadow(elem) | CosmicWindowRenderElement::Border(elem) => {
|
||||
elem.underlying_storage(renderer.glow_renderer_mut())
|
||||
}
|
||||
CosmicWindowRenderElement::Window(elem) => elem.underlying_storage(renderer),
|
||||
CosmicWindowRenderElement::Clipped(elem) => elem.underlying_storage(renderer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,12 @@ impl MoveGrabState {
|
|||
output_scale,
|
||||
alpha,
|
||||
);
|
||||
let shadow_element = self.window.shadow_render_element(
|
||||
renderer,
|
||||
(render_location - self.window.geometry().loc).to_physical_precise_round(output_scale),
|
||||
output_scale,
|
||||
alpha,
|
||||
);
|
||||
|
||||
self.stacking_indicator
|
||||
.iter()
|
||||
|
|
@ -218,31 +224,36 @@ impl MoveGrabState {
|
|||
})
|
||||
.chain(p_elements)
|
||||
.chain(focus_element)
|
||||
.chain(w_elements.into_iter().map(|elem| match elem {
|
||||
CosmicMappedRenderElement::Stack(stack) => {
|
||||
CosmicMappedRenderElement::GrabbedStack(
|
||||
RescaleRenderElement::from_element(
|
||||
stack,
|
||||
render_location.to_physical_precise_round(
|
||||
output.current_scale().fractional_scale(),
|
||||
),
|
||||
scale,
|
||||
),
|
||||
)
|
||||
}
|
||||
CosmicMappedRenderElement::Window(window) => {
|
||||
CosmicMappedRenderElement::GrabbedWindow(
|
||||
RescaleRenderElement::from_element(
|
||||
window,
|
||||
render_location.to_physical_precise_round(
|
||||
output.current_scale().fractional_scale(),
|
||||
),
|
||||
scale,
|
||||
),
|
||||
)
|
||||
}
|
||||
x => x,
|
||||
}))
|
||||
.chain(
|
||||
w_elements
|
||||
.into_iter()
|
||||
.chain(shadow_element)
|
||||
.map(|elem| match elem {
|
||||
CosmicMappedRenderElement::Stack(stack) => {
|
||||
CosmicMappedRenderElement::GrabbedStack(
|
||||
RescaleRenderElement::from_element(
|
||||
stack,
|
||||
render_location.to_physical_precise_round(
|
||||
output.current_scale().fractional_scale(),
|
||||
),
|
||||
scale,
|
||||
),
|
||||
)
|
||||
}
|
||||
CosmicMappedRenderElement::Window(window) => {
|
||||
CosmicMappedRenderElement::GrabbedWindow(
|
||||
RescaleRenderElement::from_element(
|
||||
window,
|
||||
render_location.to_physical_precise_round(
|
||||
output.current_scale().fractional_scale(),
|
||||
),
|
||||
scale,
|
||||
),
|
||||
)
|
||||
}
|
||||
x => x,
|
||||
}),
|
||||
)
|
||||
.chain(snapping_indicator)
|
||||
.map(I::from)
|
||||
.collect()
|
||||
|
|
|
|||
|
|
@ -1501,6 +1501,14 @@ impl FloatingLayout {
|
|||
.unwrap_or_else(|| (self.space.element_geometry(elem).unwrap().as_local(), alpha));
|
||||
|
||||
let render_location = geometry.loc - elem.geometry().loc.as_local();
|
||||
let shadow_element = elem.shadow_render_element(
|
||||
renderer,
|
||||
render_location
|
||||
.as_logical()
|
||||
.to_physical_precise_round(output_scale),
|
||||
output_scale.into(),
|
||||
alpha,
|
||||
);
|
||||
let mut window_elements = elem.render_elements(
|
||||
renderer,
|
||||
render_location
|
||||
|
|
@ -1622,6 +1630,7 @@ impl FloatingLayout {
|
|||
}
|
||||
|
||||
elements.extend(window_elements);
|
||||
elements.extend(shadow_element.into_iter());
|
||||
}
|
||||
|
||||
elements
|
||||
|
|
|
|||
|
|
@ -4034,6 +4034,7 @@ impl TilingLayout {
|
|||
let draw_groups = overview.0.alpha();
|
||||
|
||||
let mut elements = Vec::default();
|
||||
let mut shadow_elements = Vec::default();
|
||||
|
||||
let is_overview = !matches!(overview.0, OverviewMode::None);
|
||||
let is_mouse_tiling = (matches!(overview.0.trigger(), Some(Trigger::Pointer(_))))
|
||||
|
|
@ -4076,6 +4077,7 @@ impl TilingLayout {
|
|||
percentage,
|
||||
indicator_thickness,
|
||||
swap_desc.is_some(),
|
||||
&mut shadow_elements,
|
||||
theme,
|
||||
));
|
||||
|
||||
|
|
@ -4129,6 +4131,7 @@ impl TilingLayout {
|
|||
overview,
|
||||
resize_indicator,
|
||||
swap_desc.clone(),
|
||||
&mut shadow_elements,
|
||||
&self.swapping_stack_surface_id,
|
||||
&self.backdrop_id,
|
||||
theme,
|
||||
|
|
@ -4139,6 +4142,8 @@ impl TilingLayout {
|
|||
elements.extend(group_elements);
|
||||
}
|
||||
|
||||
elements.extend(shadow_elements);
|
||||
|
||||
Ok(elements)
|
||||
}
|
||||
|
||||
|
|
@ -4987,6 +4992,7 @@ fn render_old_tree_windows<R>(
|
|||
percentage: f32,
|
||||
indicator_thickness: u8,
|
||||
is_swap_mode: bool,
|
||||
shadow_elements: &mut Vec<CosmicMappedRenderElement<R>>,
|
||||
theme: &cosmic::theme::CosmicTheme,
|
||||
) -> Vec<CosmicMappedRenderElement<R>>
|
||||
where
|
||||
|
|
@ -5007,6 +5013,17 @@ where
|
|||
percentage,
|
||||
is_swap_mode,
|
||||
|mapped, elem_geometry, geo, alpha, is_minimizing| {
|
||||
shadow_elements.extend(
|
||||
mapped
|
||||
.shadow_render_element(
|
||||
renderer,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
Scale::from(output_scale),
|
||||
alpha,
|
||||
)
|
||||
.into_iter(),
|
||||
);
|
||||
let window_elements = mapped.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale) - elem_geometry.loc,
|
||||
|
|
@ -5219,6 +5236,7 @@ fn render_new_tree_windows<R>(
|
|||
overview: (OverviewMode, Option<(SwapIndicator, Option<&Tree<Data>>)>),
|
||||
mut resize_indicator: Option<(ResizeMode, ResizeIndicator)>,
|
||||
swap_desc: Option<NodeDesc>,
|
||||
shadow_elements: &mut Vec<CosmicMappedRenderElement<R>>,
|
||||
swapping_stack_surface_id: &Id,
|
||||
backdrop_id: &Id,
|
||||
theme: &cosmic::theme::CosmicTheme,
|
||||
|
|
@ -5505,6 +5523,17 @@ where
|
|||
if let Data::Mapped { mapped, .. } = data {
|
||||
let elem_geometry = mapped.geometry().to_physical_precise_round(output_scale);
|
||||
|
||||
shadow_elements.extend(
|
||||
mapped
|
||||
.shadow_render_element(
|
||||
renderer,
|
||||
geo.loc.as_logical().to_physical_precise_round(output_scale)
|
||||
- elem_geometry.loc,
|
||||
Scale::from(output_scale),
|
||||
alpha,
|
||||
)
|
||||
.into_iter(),
|
||||
);
|
||||
let mut elements = mapped.render_elements::<R, CosmicMappedRenderElement<R>>(
|
||||
renderer,
|
||||
//original_location,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue