feat: blur
This commit is contained in:
parent
953478f801
commit
0b7803077a
5 changed files with 683 additions and 608 deletions
|
|
@ -3,12 +3,16 @@ use cosmic::iced::core::SmolStr;
|
|||
use cosmic::iced::event::wayland::{Event as WaylandEvent, OutputEvent, SessionLockEvent};
|
||||
use cosmic::iced::event::{self};
|
||||
use cosmic::iced::keyboard::{Event as KeyEvent, Key, Modifiers};
|
||||
use cosmic::iced::platform_specific::shell::commands::blur::blur;
|
||||
use cosmic::iced::runtime::core::window::Id as SurfaceId;
|
||||
use cosmic::iced::runtime::platform_specific::wayland::CornerRadius;
|
||||
use cosmic::iced::{self, Rectangle, Size, Subscription};
|
||||
use cosmic::widget;
|
||||
use cosmic::surface::corner_radius::rounded_rect_strips;
|
||||
use cosmic::widget::rectangle_tracker::{RectangleUpdate, rectangle_tracker_subscription};
|
||||
use cosmic::widget::{self, RectangleTracker};
|
||||
use cosmic_config::{ConfigSet, CosmicConfigEntry};
|
||||
use cosmic_greeter_daemon::{BgSource, CosmicCompConfig, UserData};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
use wayland_client::protocol::wl_output::WlOutput;
|
||||
|
||||
|
|
@ -39,8 +43,12 @@ pub struct Common<M> {
|
|||
pub output_names: HashMap<WlOutput, String>,
|
||||
pub power_info_opt: Option<(widget::Icon, f64)>,
|
||||
pub prompt_opt: Option<(String, bool, Option<String>)>,
|
||||
pub rectangle_tracker: Option<RectangleTracker<(SurfaceId, bool)>>,
|
||||
pub rectangles: HashMap<(SurfaceId, bool), iced::Rectangle>,
|
||||
pub include_menu: bool,
|
||||
pub subsurface_rects: HashMap<WlOutput, Rectangle>,
|
||||
pub surface_ids: HashMap<WlOutput, SurfaceId>,
|
||||
pub subsurface_outputs: HashMap<SurfaceId, WlOutput>,
|
||||
pub surface_images: HashMap<SurfaceId, widget::image::Handle>,
|
||||
pub surface_names: HashMap<SurfaceId, String>,
|
||||
pub text_input_ids: HashMap<String, widget::Id>,
|
||||
|
|
@ -54,12 +62,14 @@ pub enum Message {
|
|||
Focus(SurfaceId),
|
||||
Key(Modifiers, Key, Option<SmolStr>),
|
||||
NetworkIcon(Option<&'static str>),
|
||||
SubsurfaceOpened(SurfaceId),
|
||||
OutputEvent(OutputEvent, WlOutput),
|
||||
PowerInfo(Option<(f64, bool, bool)>),
|
||||
Prompt(String, bool, Option<String>),
|
||||
SessionLockEvent(SessionLockEvent),
|
||||
Tick,
|
||||
Tz(jiff::tz::TimeZone),
|
||||
Rectangle(RectangleUpdate<(SurfaceId, bool)>),
|
||||
}
|
||||
|
||||
impl<M: From<Message> + Send + 'static> Common<M> {
|
||||
|
|
@ -118,6 +128,10 @@ impl<M: From<Message> + Send + 'static> Common<M> {
|
|||
battery_percent: 0.0,
|
||||
on_battery: false,
|
||||
charging_limit: None,
|
||||
subsurface_outputs: HashMap::new(),
|
||||
rectangle_tracker: None,
|
||||
rectangles: HashMap::new(),
|
||||
include_menu: false,
|
||||
};
|
||||
(
|
||||
app,
|
||||
|
|
@ -322,13 +336,75 @@ impl<M: From<Message> + Send + 'static> Common<M> {
|
|||
Message::Tz(tz) => {
|
||||
self.time.set_tz(tz);
|
||||
}
|
||||
Message::SubsurfaceOpened(id) => {
|
||||
return self.blur_rects(id);
|
||||
}
|
||||
Message::Rectangle(u) => match u {
|
||||
RectangleUpdate::Rectangle(r) => {
|
||||
self.rectangles.insert(r.0, r.1);
|
||||
|
||||
return self.blur_rects(r.0.0);
|
||||
}
|
||||
RectangleUpdate::Init(tracker) => {
|
||||
self.rectangle_tracker.replace(tracker);
|
||||
}
|
||||
},
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub(crate) fn dropdown_blur_rects(&mut self, enable: bool) -> Task<M> {
|
||||
let mut ids = HashSet::new();
|
||||
for r in self.rectangles.keys() {
|
||||
ids.insert(r.0);
|
||||
}
|
||||
self.include_menu = enable;
|
||||
Task::batch(
|
||||
ids.into_iter()
|
||||
.map(|i| self.blur_rects(i))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
|
||||
fn blur_rects(&mut self, id: SurfaceId) -> Task<M> {
|
||||
if let Some(output) = self.subsurface_outputs.get(&id) {
|
||||
if let Some(rect) = self.subsurface_rects.get(output) {
|
||||
let x = rect.x;
|
||||
let y = rect.y;
|
||||
if let Some(rect) = self.rectangles.get(&(id, false)) {
|
||||
let mut offset_rect = *rect;
|
||||
offset_rect.x += x;
|
||||
offset_rect.y += y;
|
||||
let rad = CornerRadius {
|
||||
top_left: 16,
|
||||
top_right: 16,
|
||||
bottom_left: 16,
|
||||
bottom_right: 16,
|
||||
};
|
||||
let mut rects = rounded_rect_strips(offset_rect, rad);
|
||||
if let Some(other_rect) = self.rectangles.get(&(id, true))
|
||||
&& self.include_menu
|
||||
{
|
||||
let mut other = *other_rect;
|
||||
other.x += x;
|
||||
other.y += y;
|
||||
|
||||
rects.append(&mut rounded_rect_strips(other, rad));
|
||||
}
|
||||
|
||||
return blur(id, Some(rects)).discard();
|
||||
} else {
|
||||
tracing::error!("no rectangle for surface {id:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
pub fn subscription(&self) -> Subscription<Message> {
|
||||
let mut subscriptions = Vec::with_capacity(3);
|
||||
|
||||
subscriptions
|
||||
.push(rectangle_tracker_subscription(0).map(|update| Message::Rectangle(update.1)));
|
||||
subscriptions.push(event::listen_with(|event, status, id| match event {
|
||||
iced::Event::Keyboard(KeyEvent::KeyPressed {
|
||||
key,
|
||||
|
|
@ -351,6 +427,9 @@ impl<M: From<Message> + Send + 'static> Common<M> {
|
|||
WaylandEvent::SessionLock(lock_event) => {
|
||||
Some(Message::SessionLockEvent(lock_event))
|
||||
}
|
||||
iced::event::wayland::Event::Subsurface(
|
||||
iced::event::wayland::SubsurfaceEvent::Created,
|
||||
) => Some(Message::SubsurfaceOpened(id)),
|
||||
_ => None,
|
||||
},
|
||||
iced::Event::Window(iced::window::Event::Focused) => Some(Message::Focus(id)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue