diff --git a/src/shell/element/resize_indicator.rs b/src/shell/element/resize_indicator.rs index d1839e6e..fb5441c3 100644 --- a/src/shell/element/resize_indicator.rs +++ b/src/shell/element/resize_indicator.rs @@ -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,48 +20,233 @@ 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; +#[derive(Debug, Clone)] +pub struct ResizeIndicator { + edges: ResizeEdge, + direction: Arc>, + size: Size, -pub fn resize_indicator( - direction: ResizeDirection, - config: &Config, - evlh: LoopHandle<'static, crate::state::State>, - theme: cosmic::Theme, -) -> ResizeIndicator { - ResizeIndicator::new( - ResizeIndicatorInternal { - edges: Mutex::new(ResizeEdge::all()), - direction, - shortcut1: config - .shortcuts - .iter() - .find_map(|(pattern, action)| { - (*action == Action::Resizing(ResizeDirection::Outwards)).then_some(pattern) - }) - .map(|pattern| format!("{}: ", pattern.to_string())) - .unwrap_or_else(|| crate::fl!("unknown-keybinding")), - shortcut2: config - .shortcuts - .iter() - .find_map(|(pattern, action)| { - (*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, - ) + center_elem: IcedElement, + left_elem: IcedElement, + top_elem: IcedElement, + right_elem: IcedElement, + down_elem: IcedElement, +} + +const ARROW_SIZE: i32 = 36; + +impl ResizeIndicator { + pub fn new( + direction: ResizeDirection, + config: &Config, + evlh: LoopHandle<'static, crate::state::State>, + 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 { + shortcut1: config + .shortcuts + .iter() + .find_map(|(pattern, action)| { + (*action == Action::Resizing(ResizeDirection::Outwards)) + .then_some(pattern) + }) + .map(|pattern| format!("{}: ", pattern.to_string())) + .unwrap_or_else(|| crate::fl!("unknown-keybinding")), + shortcut2: config + .shortcuts + .iter() + .find_map(|(pattern, action)| { + (*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.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) { + let minimum = self.center_elem.minimum_size(); + let new_size = Size::::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( + &self, + renderer: &mut R, + location: Point, + scale: Scale, + alpha: f32, + push_above: &mut dyn FnMut(IcedRenderElement), + mut push_below: Option<&mut dyn FnMut(IcedRenderElement)>, + ) 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, + loc: Point| { + 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, - 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, }, diff --git a/src/shell/element/stack_hover.rs b/src/shell/element/stack_hover.rs index d6a057c4..f1238404 100644 --- a/src/shell/element/stack_hover.rs +++ b/src/shell/element/stack_hover.rs @@ -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; +#[derive(Debug)] +pub struct StackHover { + location: Point, + elem: IcedElement, +} -pub fn stack_hover( - evlh: LoopHandle<'static, crate::state::State>, - size: Size, - theme: cosmic::Theme, -) -> StackHover { - StackHover::new(StackHoverInternal, size, evlh, theme) +impl StackHover { + pub fn new( + evlh: LoopHandle<'static, crate::state::State>, + size: Size, + 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::::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( + &self, + renderer: &mut R, + location: Point, + scale: Scale, + alpha: f32, + push_above: &mut dyn FnMut(IcedRenderElement), + push_below: Option<&mut dyn FnMut(IcedRenderElement)>, + ) 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() } } diff --git a/src/shell/element/swap_indicator.rs b/src/shell/element/swap_indicator.rs index e6fb0197..6f9498da 100644 --- a/src/shell/element/swap_indicator.rs +++ b/src/shell/element/swap_indicator.rs @@ -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; +#[derive(Debug, Clone)] +pub struct SwapIndicator { + location: Point, + elem: IcedElement, +} -pub fn swap_indicator( - evlh: LoopHandle<'static, crate::state::State>, - theme: cosmic::Theme, -) -> SwapIndicator { - SwapIndicator::new(SwapIndicatorInternal, Size::from((1, 1)), evlh, theme) +impl SwapIndicator { + pub fn new( + evlh: LoopHandle<'static, crate::state::State>, + 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) { + let minimum = self.elem.minimum_size(); + let new_size = Size::::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( + &self, + renderer: &mut R, + location: Point, + scale: Scale, + alpha: f32, + push_above: &mut dyn FnMut(IcedRenderElement), + push_below: Option<&mut dyn FnMut(IcedRenderElement)>, + ) 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() } } diff --git a/src/shell/grabs/menu/mod.rs b/src/shell/grabs/menu/mod.rs index ec82bb07..efd66886 100644 --- a/src/shell/grabs/menu/mod.rs +++ b/src/shell/grabs/menu/mod.rs @@ -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), + push: &mut dyn FnMut(IcedRenderElement), ) 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()), diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index 48ebd4ba..d8714830 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -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, push: &mut dyn FnMut(CosmicMappedRenderElement), ) where - R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + R: AsGlowRenderer + ImportAll + ImportMem, R::TextureId: Send + Clone + 'static, CosmicMappedRenderElement: RenderElement, { @@ -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(¤t_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()) }); diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index aad738f8..07ce73cf 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -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) { diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 3a3633db..5b425948 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -5330,13 +5330,12 @@ fn render_new_tree_windows( let mut group_backdrop = None; let mut indicators = SmallVec::<[CosmicMappedRenderElement; 2]>::new_const(); - let mut resize_element = None; + let mut resize_elements = SmallVec::<[CosmicMappedRenderElement; 10]>::new_const(); let mut swap_elements = SmallVec::<[CosmicMappedRenderElement; 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( .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( 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( }, ); - for elem in resize_element + for elem in resize_elements .into_iter() .chain(swap_elements) .chain(indicators) diff --git a/src/shell/mod.rs b/src/shell/mod.rs index b4559dce..1dfc528c 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -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)) diff --git a/src/shell/zoom.rs b/src/shell/zoom.rs index e0d3f1d1..11114e2d 100644 --- a/src/shell/zoom.rs +++ b/src/shell/zoom.rs @@ -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), + push: &mut dyn FnMut(IcedRenderElement), ) 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( - renderer: &mut R, - output: &Output, - push: &mut dyn FnMut(MemoryRenderBufferRenderElement), - ) where - R: Renderer + ImportMem, + pub fn render(renderer: &mut R, output: &Output, push: &mut dyn FnMut(IcedRenderElement)) + where + R: AsGlowRenderer + ImportMem, R::TextureId: Send + Clone + 'static, { let output_state = output.user_data().get::>().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);