element: Refactor remaining libcosmic elements for blur

This commit is contained in:
Victoria Brekenfeld 2026-04-21 18:19:01 +02:00 committed by Victoria Brekenfeld
parent 6c76fdaa79
commit db06770a6b
9 changed files with 444 additions and 142 deletions

View file

@ -1,10 +1,11 @@
use std::sync::{Arc, Mutex};
use crate::{
backend::render::element::AsGlowRenderer,
config::Config,
fl,
shell::grabs::ResizeEdge,
utils::iced::{IcedElement, Program},
utils::iced::{IcedElement, IcedRenderElement, Program},
};
use calloop::LoopHandle;
@ -19,25 +20,50 @@ use cosmic::{
widget::{icon::from_name, text},
};
use cosmic_settings_config::shortcuts::action::{Action, ResizeDirection};
use smithay::utils::Size;
use smithay::{
backend::renderer::ImportMem,
desktop::space::SpaceElement,
output::Output,
utils::{Logical, Physical, Point, Rectangle, Scale, Size},
};
pub type ResizeIndicator = IcedElement<ResizeIndicatorInternal>;
#[derive(Debug, Clone)]
pub struct ResizeIndicator {
edges: ResizeEdge,
direction: Arc<Mutex<ResizeDirection>>,
size: Size<i32, Logical>,
pub fn resize_indicator(
center_elem: IcedElement<ResizeIndicatorInternal>,
left_elem: IcedElement<ResizeIndicatorArrow>,
top_elem: IcedElement<ResizeIndicatorArrow>,
right_elem: IcedElement<ResizeIndicatorArrow>,
down_elem: IcedElement<ResizeIndicatorArrow>,
}
const ARROW_SIZE: i32 = 36;
impl ResizeIndicator {
pub fn new(
direction: ResizeDirection,
config: &Config,
evlh: LoopHandle<'static, crate::state::State>,
theme: cosmic::Theme,
) -> ResizeIndicator {
ResizeIndicator::new(
mut theme: cosmic::Theme,
) -> ResizeIndicator {
theme.transparent = theme.cosmic().frosted_system_interface;
let direction = Arc::new(Mutex::new(direction));
ResizeIndicator {
edges: ResizeEdge::all(),
direction: direction.clone(),
size: Size::default(),
center_elem: IcedElement::new(
ResizeIndicatorInternal {
edges: Mutex::new(ResizeEdge::all()),
direction,
shortcut1: config
.shortcuts
.iter()
.find_map(|(pattern, action)| {
(*action == Action::Resizing(ResizeDirection::Outwards)).then_some(pattern)
(*action == Action::Resizing(ResizeDirection::Outwards))
.then_some(pattern)
})
.map(|pattern| format!("{}: ", pattern.to_string()))
.unwrap_or_else(|| crate::fl!("unknown-keybinding")),
@ -45,22 +71,182 @@ pub fn resize_indicator(
.shortcuts
.iter()
.find_map(|(pattern, action)| {
(*action == Action::Resizing(ResizeDirection::Inwards)).then_some(pattern)
(*action == Action::Resizing(ResizeDirection::Inwards))
.then_some(pattern)
})
.map(|pattern| format!("{}: ", pattern.to_string()))
.unwrap_or_else(|| crate::fl!("unknown-keybinding")),
},
Size::from((1, 1)),
evlh,
theme,
)
evlh.clone(),
theme.clone(),
),
left_elem: IcedElement::new(
ResizeIndicatorArrow {
direction: direction.clone(),
icon_outwards: "go-previous-symbolic",
icon_inwards: "go-next-symbolic",
},
Size::from((ARROW_SIZE, ARROW_SIZE)),
evlh.clone(),
theme.clone(),
),
top_elem: IcedElement::new(
ResizeIndicatorArrow {
direction: direction.clone(),
icon_outwards: "go-up-symbolic",
icon_inwards: "go-down-symbolic",
},
Size::from((ARROW_SIZE, ARROW_SIZE)),
evlh.clone(),
theme.clone(),
),
right_elem: IcedElement::new(
ResizeIndicatorArrow {
direction: direction.clone(),
icon_outwards: "go-next-symbolic",
icon_inwards: "go-previous-symbolic",
},
Size::from((ARROW_SIZE, ARROW_SIZE)),
evlh.clone(),
theme.clone(),
),
down_elem: IcedElement::new(
ResizeIndicatorArrow {
direction,
icon_outwards: "go-down-symbolic",
icon_inwards: "go-up-symbolic",
},
Size::from((ARROW_SIZE, ARROW_SIZE)),
evlh.clone(),
theme.clone(),
),
}
}
pub fn resize(&mut self, size: Size<i32, Logical>) {
let minimum = self.center_elem.minimum_size();
let new_size = Size::<i32, Logical>::new(size.w.min(minimum.w), size.h.min(minimum.h));
self.center_elem.resize(new_size);
self.size = size;
}
pub fn push_render_elements<R>(
&self,
renderer: &mut R,
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
push_above: &mut dyn FnMut(IcedRenderElement<R>),
mut push_below: Option<&mut dyn FnMut(IcedRenderElement<R>)>,
) where
R: AsGlowRenderer + ImportMem,
R::TextureId: Send + Clone + 'static,
{
let elem_size = self.center_elem.current_size();
let center_location = Point::new(
self.size.w.saturating_sub(elem_size.w) / 2,
self.size.h.saturating_sub(elem_size.h) / 2,
);
let left_location = Point::new(0, self.size.h.saturating_sub(ARROW_SIZE) / 2);
let top_location = Point::new(self.size.w.saturating_sub(ARROW_SIZE) / 2, 0);
let right_location = Point::new(
self.size.w.saturating_sub(ARROW_SIZE),
self.size.h.saturating_sub(ARROW_SIZE) / 2,
);
let down_location = Point::new(
self.size.w.saturating_sub(ARROW_SIZE) / 2,
self.size.h.saturating_sub(ARROW_SIZE),
);
let radii = self
.center_elem
.with_theme(|theme| theme.cosmic().radius_s())
.map(|x| x.round() as u8);
self.center_elem.push_render_elements(
renderer,
location + center_location.to_physical_precise_round(scale),
scale,
alpha,
radii,
push_above,
if let Some(push_below) = push_below.as_mut() {
Some(&mut **push_below)
} else {
None
},
);
let mut render = move |elem: &IcedElement<ResizeIndicatorArrow>,
loc: Point<i32, Logical>| {
elem.push_render_elements(
renderer,
location + loc.to_physical_precise_round(scale),
scale,
alpha,
radii,
push_above,
if let Some(push_below) = push_below.as_mut() {
Some(&mut **push_below)
} else {
None
},
);
};
if self.edges.contains(ResizeEdge::LEFT) {
render(&self.left_elem, left_location);
}
if self.edges.contains(ResizeEdge::TOP) {
render(&self.top_elem, top_location);
}
if self.edges.contains(ResizeEdge::RIGHT) {
render(&self.right_elem, right_location);
}
if self.edges.contains(ResizeEdge::BOTTOM) {
render(&self.down_elem, down_location);
}
}
pub fn set_edges(&mut self, edges: ResizeEdge) {
self.edges = edges;
}
pub fn set_direction(&self, direction: ResizeDirection) {
let mut dir_ref = self.direction.lock().unwrap();
if *dir_ref != direction {
*dir_ref = direction;
self.left_elem.force_redraw();
self.top_elem.force_redraw();
self.right_elem.force_redraw();
self.down_elem.force_redraw();
}
}
pub fn output_enter(&self, output: &Output) {
self.center_elem
.output_enter(output, Rectangle::default() /*unused*/);
self.left_elem
.output_enter(output, Rectangle::default() /*unused*/);
self.top_elem
.output_enter(output, Rectangle::default() /*unused*/);
self.right_elem
.output_enter(output, Rectangle::default() /*unused*/);
self.down_elem
.output_enter(output, Rectangle::default() /*unused*/);
}
pub fn output_leave(&self, output: &Output) {
self.center_elem.output_leave(output);
self.left_elem.output_leave(output);
self.top_elem.output_leave(output);
self.right_elem.output_leave(output);
self.down_elem.output_leave(output);
}
}
pub struct ResizeIndicatorInternal {
pub edges: Mutex<ResizeEdge>,
pub direction: ResizeDirection,
pub shortcut1: String,
pub shortcut2: String,
shortcut1: String,
shortcut2: String,
}
impl Program for ResizeIndicatorInternal {
@ -94,7 +280,7 @@ impl Program for ResizeIndicatorInternal {
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(background.into())),
border: Border {
radius: 18.0.into(),
radius: theme.cosmic().radius_s().into(),
width: 0.0,
color: Color::TRANSPARENT,
},

View file

@ -1,6 +1,7 @@
use crate::{
backend::render::element::AsGlowRenderer,
fl,
utils::iced::{IcedElement, Program},
utils::iced::{IcedElement, IcedRenderElement, Program},
};
use calloop::LoopHandle;
@ -14,16 +15,72 @@ use cosmic::{
theme,
widget::{icon::from_name, space, text},
};
use smithay::utils::{Logical, Size};
use smithay::{
backend::renderer::ImportMem,
desktop::space::SpaceElement,
output::Output,
utils::{Logical, Physical, Point, Rectangle, Scale, Size},
};
pub type StackHover = IcedElement<StackHoverInternal>;
#[derive(Debug)]
pub struct StackHover {
location: Point<i32, Logical>,
elem: IcedElement<StackHoverInternal>,
}
pub fn stack_hover(
impl StackHover {
pub fn new(
evlh: LoopHandle<'static, crate::state::State>,
size: Size<i32, Logical>,
theme: cosmic::Theme,
) -> StackHover {
StackHover::new(StackHoverInternal, size, evlh, theme)
mut theme: cosmic::Theme,
) -> StackHover {
theme.transparent = theme.cosmic().frosted_system_interface;
let elem = IcedElement::new(StackHoverInternal, size, evlh, theme);
let minimum = elem.minimum_size();
let new_size = Size::<i32, Logical>::new(size.w.min(minimum.w), size.h.min(minimum.h));
let location = Point::new(
size.w.saturating_sub(new_size.w) / 2,
size.h.saturating_sub(new_size.h) / 2,
);
elem.resize(new_size);
StackHover { location, elem }
}
pub fn push_render_elements<R>(
&self,
renderer: &mut R,
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
push_above: &mut dyn FnMut(IcedRenderElement<R>),
push_below: Option<&mut dyn FnMut(IcedRenderElement<R>)>,
) where
R: AsGlowRenderer + ImportMem,
R::TextureId: Send + Clone + 'static,
{
self.elem.push_render_elements(
renderer,
location + self.location.to_physical_precise_round(scale),
scale,
alpha,
self.elem
.with_theme(|theme| theme.cosmic().radius_s())
.map(|x| x.round() as u8),
push_above,
push_below,
);
}
pub fn output_enter(&self, output: &Output) {
self.elem
.output_enter(output, Rectangle::default() /*unused*/);
}
pub fn output_leave(&self, output: &Output) {
self.elem.output_leave(output);
}
}
pub struct StackHoverInternal;
@ -71,9 +128,6 @@ impl Program for StackHoverInternal {
}))
.width(Length::Shrink)
.height(Length::Shrink)
.apply(container)
.center_x(Length::Fill)
.center_y(Length::Fill)
.into()
}
}

View file

@ -1,6 +1,7 @@
use crate::{
backend::render::element::AsGlowRenderer,
fl,
utils::iced::{IcedElement, Program},
utils::iced::{IcedElement, IcedRenderElement, Program},
};
use calloop::LoopHandle;
@ -13,15 +14,75 @@ use cosmic::{
theme,
widget::{icon::from_name, text},
};
use smithay::utils::Size;
use smithay::{
backend::renderer::ImportMem,
desktop::space::SpaceElement,
output::Output,
utils::{Logical, Physical, Point, Rectangle, Scale, Size},
};
pub type SwapIndicator = IcedElement<SwapIndicatorInternal>;
#[derive(Debug, Clone)]
pub struct SwapIndicator {
location: Point<i32, Logical>,
elem: IcedElement<SwapIndicatorInternal>,
}
pub fn swap_indicator(
impl SwapIndicator {
pub fn new(
evlh: LoopHandle<'static, crate::state::State>,
theme: cosmic::Theme,
) -> SwapIndicator {
SwapIndicator::new(SwapIndicatorInternal, Size::from((1, 1)), evlh, theme)
mut theme: cosmic::Theme,
) -> SwapIndicator {
theme.transparent = theme.cosmic().frosted_system_interface;
SwapIndicator {
location: Point::default(),
elem: IcedElement::new(SwapIndicatorInternal, Size::from((1, 1)), evlh, theme),
}
}
pub fn resize(&mut self, size: Size<i32, Logical>) {
let minimum = self.elem.minimum_size();
let new_size = Size::<i32, Logical>::new(size.w.min(minimum.w), size.h.min(minimum.h));
let location = Point::new(
size.w.saturating_sub(new_size.w) / 2,
size.h.saturating_sub(new_size.h) / 2,
);
self.elem.resize(new_size);
self.location = location;
}
pub fn push_render_elements<R>(
&self,
renderer: &mut R,
location: Point<i32, Physical>,
scale: Scale<f64>,
alpha: f32,
push_above: &mut dyn FnMut(IcedRenderElement<R>),
push_below: Option<&mut dyn FnMut(IcedRenderElement<R>)>,
) where
R: AsGlowRenderer + ImportMem,
R::TextureId: Send + Clone + 'static,
{
self.elem.push_render_elements(
renderer,
location + self.location.to_physical_precise_round(scale),
scale,
alpha,
self.elem
.with_theme(|theme| theme.cosmic().radius_s())
.map(|x| x.round() as u8),
push_above,
push_below,
);
}
pub fn output_enter(&self, output: &Output) {
self.elem
.output_enter(output, Rectangle::default() /*unused*/);
}
pub fn output_leave(&self, output: &Output) {
self.elem.output_leave(output);
}
}
pub struct SwapIndicatorInternal;
@ -69,9 +130,6 @@ impl Program for SwapIndicatorInternal {
}))
.width(Length::Shrink)
.height(Length::Shrink)
.apply(container)
.center_x(Length::Fill)
.center_y(Length::Fill)
.into()
}
}

View file

@ -20,7 +20,7 @@ use cosmic::{
use smithay::{
backend::{
input::{ButtonState, TouchSlot},
renderer::{ImportMem, Renderer, element::memory::MemoryRenderBufferRenderElement},
renderer::ImportMem,
},
desktop::space::SpaceElement,
input::{
@ -42,10 +42,11 @@ use smithay::{
};
use crate::{
backend::render::element::AsGlowRenderer,
shell::{SeatExt, focus::target::PointerFocusTarget},
state::State,
utils::{
iced::{IcedElement, Program},
iced::{IcedElement, IcedRenderElement, Program},
prelude::*,
},
};
@ -68,9 +69,9 @@ impl MenuGrabState {
&self,
renderer: &mut R,
output: &Output,
push: &mut dyn FnMut(MemoryRenderBufferRenderElement<R>),
push: &mut dyn FnMut(IcedRenderElement<R>),
) where
R: Renderer + ImportMem,
R: AsGlowRenderer + ImportMem,
R::TextureId: Send + Clone + 'static,
{
let scale = output.current_scale().fractional_scale();
@ -83,7 +84,11 @@ impl MenuGrabState {
.to_physical_precise_round(scale),
scale.into(),
1.0,
elem.iced
.with_theme(|theme| theme.cosmic().radius_s())
.map(|x| x.round() as u8),
push,
None,
)
}
}
@ -274,11 +279,13 @@ impl Program for ContextMenu {
let mut elements = grab_state.elements.lock().unwrap();
let position = elements.last().unwrap().position;
let mut theme = state.common.theme.clone();
theme.transparent = theme.cosmic().frosted_system_interface;
let element = IcedElement::new(
ContextMenu::new(items),
Size::default(),
state.common.event_loop_handle.clone(),
state.common.theme.clone(),
theme,
);
let min_size = element.minimum_size();
@ -474,7 +481,7 @@ impl Program for ContextMenu {
.padding(1)
.class(theme::Container::custom(|theme| {
let cosmic = theme.cosmic();
let component = &cosmic.background(false).component;
let component = &cosmic.background(theme.cosmic().frosted_windows).component;
iced_widget::container::Style {
snap: true,
icon_color: Some(cosmic.accent.base.into()),

View file

@ -6,10 +6,7 @@ use crate::{
},
shell::{
CosmicMapped, CosmicSurface, Direction, ManagedLayer,
element::{
CosmicMappedRenderElement,
stack_hover::{StackHover, stack_hover},
},
element::{CosmicMappedRenderElement, stack_hover::StackHover},
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
layout::floating::TiledCorners,
},
@ -25,7 +22,7 @@ use smithay::{
drm::DrmNode,
input::ButtonState,
renderer::{
ImportAll, ImportMem, Renderer,
ImportAll, ImportMem,
element::{RenderElement, utils::RescaleRenderElement},
},
},
@ -78,7 +75,7 @@ impl MoveGrabState {
scanout_node: Option<DrmNode>,
push: &mut dyn FnMut(CosmicMappedRenderElement<R>),
) where
R: Renderer + ImportAll + ImportMem + AsGlowRenderer,
R: AsGlowRenderer + ImportAll + ImportMem,
R::TextureId: Send + Clone + 'static,
CosmicMappedRenderElement<R>: RenderElement<R>,
{
@ -122,6 +119,7 @@ impl MoveGrabState {
output_scale,
1.0,
&mut |elem| push(elem.into()),
None,
);
}
@ -441,7 +439,7 @@ impl MoveGrab {
if let Some(indicator) =
grab_state.stacking_indicator.as_ref().map(|x| &x.0)
{
indicator.output_enter(output, overlap);
indicator.output_enter(output);
}
}
} else if self.window_outputs.remove(output) {
@ -455,16 +453,14 @@ impl MoveGrab {
let indicator_location = shell.stacking_indicator(&current_output, self.previous);
if indicator_location.is_some() != grab_state.stacking_indicator.is_some() {
grab_state.stacking_indicator = indicator_location.map(|geo| {
let element = stack_hover(
let size = geo.size.as_logical();
let element = StackHover::new(
state.common.event_loop_handle.clone(),
geo.size.as_logical(),
size,
state.common.theme.clone(),
);
for output in &self.window_outputs {
element.output_enter(
output,
Rectangle::from_size(output.geometry().size.as_logical()),
);
element.output_enter(output);
}
(element, geo.loc.as_logical())
});

View file

@ -1525,6 +1525,27 @@ impl FloatingLayout {
if focused == Some(elem) && !elem.is_maximized(false) {
let active_window_hint = crate::theme::active_window_hint(theme);
let radius = elem.corner_radius(geometry.size.as_logical(), indicator_thickness);
if let Some((mode, resize)) = resize_indicator.as_mut() {
let mut resize_geometry = geometry;
resize_geometry.loc -= (18, 18).into();
resize_geometry.size += (36, 36).into();
resize.resize(resize_geometry.size.as_logical());
resize.output_enter(output);
resize.push_render_elements(
renderer,
resize_geometry
.loc
.as_logical()
.to_physical_precise_round(output_scale),
output_scale.into(),
alpha * mode.alpha().unwrap_or(1.0),
&mut |elem| push(CosmicMappedRenderElement::Window(elem.into())),
None,
);
}
if indicator_thickness > 0 {
let element = IndicatorShader::focus_element(
renderer,
@ -1542,25 +1563,6 @@ impl FloatingLayout {
);
push(element.into());
}
if let Some((mode, resize)) = resize_indicator.as_mut() {
let mut resize_geometry = geometry;
resize_geometry.loc -= (18, 18).into();
resize_geometry.size += (36, 36).into();
resize.resize(resize_geometry.size.as_logical());
resize.output_enter(output, Rectangle::default() /* unused */);
resize.push_render_elements(
renderer,
resize_geometry
.loc
.as_logical()
.to_physical_precise_round(output_scale),
output_scale.into(),
alpha * mode.alpha().unwrap_or(1.0),
&mut |elem| push(CosmicMappedRenderElement::Window(elem.into())),
);
}
}
let maybe_map = if let Some(anim) = self.animations.get(elem) {

View file

@ -5330,13 +5330,12 @@ fn render_new_tree_windows<R>(
let mut group_backdrop = None;
let mut indicators = SmallVec::<[CosmicMappedRenderElement<R>; 2]>::new_const();
let mut resize_element = None;
let mut resize_elements = SmallVec::<[CosmicMappedRenderElement<R>; 10]>::new_const();
let mut swap_elements = SmallVec::<[CosmicMappedRenderElement<R>; 4]>::new_const();
let output_geo = output.geometry();
let output_scale = output.current_scale().fractional_scale();
let (swap_indicator, swap_tree) = overview.1.unzip();
let (mut swap_indicator, swap_tree) = overview.1.unzip();
let swap_desc = swap_desc.filter(|_| is_active_output);
let swap_tree = swap_tree.flatten().filter(|_| is_active_output);
let window_hint = crate::theme::active_window_hint(theme);
@ -5540,16 +5539,18 @@ fn render_new_tree_windows<R>(
.unwrap_or(false)
})
.unwrap_or(false))
&& let Some(swap) = swap_indicator.as_ref()
&& let Some(swap) = swap_indicator.as_mut()
{
swap.resize(geo.size.as_logical());
swap.output_enter(output, output_geo.as_logical());
let size = geo.size.as_logical();
swap.resize(size);
swap.output_enter(output);
swap.push_render_elements(
renderer,
geo.loc.as_logical().to_physical_precise_round(output_scale),
output_scale.into(),
alpha * overview.0.alpha().unwrap_or(1.0),
&mut |elem| swap_elements.push(elem.into()),
None,
);
}
}
@ -5560,29 +5561,20 @@ fn render_new_tree_windows<R>(
geo.size += (36, 36).into();
resize.resize(geo.size.as_logical());
resize.output_enter(output, output_geo.as_logical());
resize.output_enter(output);
let possible_edges =
TilingLayout::possible_resizes(target_tree, node_id.clone());
if !possible_edges.is_empty() {
if resize.with_program(|internal| {
let mut edges = internal.edges.lock().unwrap();
if *edges != possible_edges {
*edges = possible_edges;
true
} else {
false
}
}) {
resize.force_update();
}
resize.set_edges(possible_edges);
resize.push_render_elements(
renderer,
geo.loc.as_logical().to_physical_precise_round(output_scale),
output_scale.into(),
alpha * mode.alpha().unwrap_or(1.0),
&mut |elem| {
resize_element = Some(elem.into());
resize_elements.push(elem.into());
},
None,
);
}
}
@ -5743,7 +5735,7 @@ fn render_new_tree_windows<R>(
},
);
for elem in resize_element
for elem in resize_elements
.into_iter()
.chain(swap_elements)
.chain(indicators)

View file

@ -102,9 +102,8 @@ use self::zoom::{OutputZoomState, ZoomState};
use self::{
element::{
CosmicWindow, MaximizedState,
resize_indicator::{ResizeIndicator, resize_indicator},
swap_indicator::{SwapIndicator, swap_indicator},
CosmicWindow, MaximizedState, resize_indicator::ResizeIndicator,
swap_indicator::SwapIndicator,
},
focus::target::{KeyboardFocusTarget, PointerFocusTarget},
grabs::{
@ -2291,7 +2290,7 @@ impl Shell {
OverviewMode::Started(_, _) | OverviewMode::Active(_)
) {
if matches!(trigger, Trigger::KeyboardSwap(_, _)) {
self.swap_indicator = Some(swap_indicator(evlh, self.theme.clone()));
self.swap_indicator = Some(SwapIndicator::new(evlh, self.theme.clone()));
}
self.overview_mode = OverviewMode::Started(trigger, Instant::now());
}
@ -2344,7 +2343,7 @@ impl Shell {
} else {
self.resize_mode = ResizeMode::Started(pattern, Instant::now(), direction);
}
self.resize_indicator = Some(resize_indicator(
self.resize_indicator = Some(ResizeIndicator::new(
direction,
config,
evlh,
@ -3668,6 +3667,8 @@ impl Shell {
return None;
};
let mut theme = self.theme.clone();
theme.transparent = theme.cosmic().frosted_windows;
let grab = MenuGrab::new(
GrabStartData::Pointer(start_data),
seat,
@ -3676,7 +3677,7 @@ impl Shell {
MenuAlignment::CORNER,
None,
evlh.clone(),
self.theme.clone(),
theme,
);
Some((grab, Focus::Keep))

View file

@ -11,7 +11,7 @@ use cosmic_comp_config::ZoomMovement;
use cosmic_config::ConfigSet;
use keyframe::{ease, functions::Linear};
use smithay::{
backend::renderer::{ImportMem, Renderer, element::memory::MemoryRenderBufferRenderElement},
backend::renderer::ImportMem,
desktop::space::SpaceElement,
input::{
Seat,
@ -32,9 +32,10 @@ use smithay::{
use tracing::error;
use crate::{
backend::render::element::AsGlowRenderer,
state::State,
utils::{
iced::{IcedElement, Program},
iced::{IcedElement, IcedRenderElement, Program},
prelude::*,
tween::EasePoint,
},
@ -71,8 +72,9 @@ impl OutputZoomState {
increment: u32,
movement: ZoomMovement,
loop_handle: LoopHandle<'static, State>,
theme: cosmic::Theme,
mut theme: cosmic::Theme,
) -> OutputZoomState {
theme.transparent = theme.cosmic().frosted_system_interface;
let cursor_position = seat.get_pointer().unwrap().current_location().as_global();
let output_geometry = output.geometry().to_f64();
let focal_point = if output_geometry.contains(cursor_position) {
@ -108,8 +110,7 @@ impl OutputZoomState {
let program = ZoomProgram::new(level, movement, increment);
let element = IcedElement::new(program, Size::default(), loop_handle, theme);
let mut size = element.minimum_size();
size.w = (size.w + 32/*TODO: figure out why iced is calculating too little*/)
.min(output_geometry.size.w.round() as i32);
size.w = size.w.min(output_geometry.size.w.round() as i32);
element.set_activate(true);
element.resize(size);
element.output_enter(output, Rectangle::new(Point::from((0, 0)), size));
@ -196,9 +197,9 @@ impl OutputZoomState {
&mut self,
renderer: &mut R,
output: &Output,
push: &mut dyn FnMut(MemoryRenderBufferRenderElement<R>),
push: &mut dyn FnMut(IcedRenderElement<R>),
) where
R: Renderer + ImportMem,
R: AsGlowRenderer + ImportMem,
R::TextureId: Send + Clone + 'static,
{
let size = self.element.current_size().to_f64();
@ -216,7 +217,11 @@ impl OutputZoomState {
location,
scale.fractional_scale().into(),
1.0,
self.element
.with_theme(|theme| theme.cosmic().radius_s())
.map(|x| x.round() as u8),
push,
None,
)
}
}
@ -390,12 +395,9 @@ impl ZoomState {
None
}
pub fn render<R>(
renderer: &mut R,
output: &Output,
push: &mut dyn FnMut(MemoryRenderBufferRenderElement<R>),
) where
R: Renderer + ImportMem,
pub fn render<R>(renderer: &mut R, output: &Output, push: &mut dyn FnMut(IcedRenderElement<R>))
where
R: AsGlowRenderer + ImportMem,
R::TextureId: Send + Clone + 'static,
{
let output_state = output.user_data().get::<Mutex<OutputZoomState>>().unwrap();
@ -515,7 +517,7 @@ impl Program for ZoomProgram {
.padding(8)
.class(theme::Container::custom(|theme| {
let cosmic = theme.cosmic();
let component = &cosmic.background(false).component;
let component = &cosmic.background(theme.transparent).component;
iced_widget::container::Style {
snap: true,
icon_color: Some(component.on.into()),
@ -591,6 +593,8 @@ impl Program for ZoomProgram {
let level = output_state_ref.level;
std::mem::drop(output_state_ref);
let mut theme = state.common.theme.clone();
theme.transparent = theme.cosmic().frosted_system_interface;
let grab = MenuGrab::new(
start_data,
&seat,
@ -703,7 +707,7 @@ impl Program for ZoomProgram {
),
Some(level.min(4.)),
state.common.event_loop_handle.clone(),
state.common.theme.clone(),
theme,
);
std::mem::drop(shell);
@ -756,6 +760,8 @@ impl Program for ZoomProgram {
let level = output_state_ref.level;
std::mem::drop(output_state_ref);
let mut theme = state.common.theme.clone();
theme.transparent = theme.cosmic().frosted_system_interface;
let grab = MenuGrab::new(
start_data,
&seat,
@ -788,7 +794,7 @@ impl Program for ZoomProgram {
MenuAlignment::PREFER_CENTERED,
Some(level.min(4.)),
state.common.event_loop_handle.clone(),
state.common.theme.clone(),
theme,
);
std::mem::drop(shell);