wip: blurred transparency
This commit is contained in:
parent
ded784a4e3
commit
1b74c6f999
5 changed files with 177 additions and 13 deletions
|
|
@ -90,7 +90,8 @@ pub struct Theme {
|
||||||
/// cosmic-comp custom window hint color
|
/// cosmic-comp custom window hint color
|
||||||
pub window_hint: Option<Srgb>,
|
pub window_hint: Option<Srgb>,
|
||||||
/// enables blurred transparency
|
/// enables blurred transparency
|
||||||
pub is_frosted: bool,
|
/// If None, frosted effect is disabled.
|
||||||
|
pub frosted: Option<BlurStrength>,
|
||||||
/// shade color for dialogs
|
/// shade color for dialogs
|
||||||
#[serde(with = "color_serde")]
|
#[serde(with = "color_serde")]
|
||||||
#[cosmic_config_entry(with = ColorRepr)]
|
#[cosmic_config_entry(with = ColorRepr)]
|
||||||
|
|
@ -814,7 +815,7 @@ pub struct ThemeBuilder {
|
||||||
#[cosmic_config_entry(with = ColorReprOption)]
|
#[cosmic_config_entry(with = ColorReprOption)]
|
||||||
pub destructive: Option<Srgb>,
|
pub destructive: Option<Srgb>,
|
||||||
/// enabled blurred transparency
|
/// enabled blurred transparency
|
||||||
pub is_frosted: bool, // TODO handle
|
pub frosted: Option<BlurStrength>,
|
||||||
/// cosmic-comp window gaps size (outer, inner)
|
/// cosmic-comp window gaps size (outer, inner)
|
||||||
pub gaps: (u32, u32),
|
pub gaps: (u32, u32),
|
||||||
/// cosmic-comp active hint window outline width
|
/// cosmic-comp active hint window outline width
|
||||||
|
|
@ -840,7 +841,7 @@ impl Default for ThemeBuilder {
|
||||||
success: Default::default(),
|
success: Default::default(),
|
||||||
warning: Default::default(),
|
warning: Default::default(),
|
||||||
destructive: Default::default(),
|
destructive: Default::default(),
|
||||||
is_frosted: false,
|
frosted: None,
|
||||||
// cosmic-comp theme settings
|
// cosmic-comp theme settings
|
||||||
gaps: (0, 8),
|
gaps: (0, 8),
|
||||||
active_hint: 3,
|
active_hint: 3,
|
||||||
|
|
@ -986,9 +987,11 @@ impl ThemeBuilder {
|
||||||
gaps,
|
gaps,
|
||||||
active_hint,
|
active_hint,
|
||||||
window_hint,
|
window_hint,
|
||||||
is_frosted,
|
frosted,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
let container_alpha = frosted.map_or(1.0, |f| f.alpha());
|
||||||
|
|
||||||
let is_dark = palette.is_dark();
|
let is_dark = palette.is_dark();
|
||||||
let is_high_contrast = palette.is_high_contrast();
|
let is_high_contrast = palette.is_high_contrast();
|
||||||
|
|
||||||
|
|
@ -1034,12 +1037,14 @@ impl ThemeBuilder {
|
||||||
NonZeroUsize::new(100).unwrap(),
|
NonZeroUsize::new(100).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let bg = if let Some(bg_color) = bg_color {
|
let mut bg = if let Some(bg_color) = bg_color {
|
||||||
bg_color
|
bg_color
|
||||||
} else {
|
} else {
|
||||||
p_ref.gray_1
|
p_ref.gray_1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bg.alpha = container_alpha;
|
||||||
|
|
||||||
let step_array = steps(bg, NonZeroUsize::new(100).unwrap());
|
let step_array = steps(bg, NonZeroUsize::new(100).unwrap());
|
||||||
let bg_index = color_index(bg, step_array.len());
|
let bg_index = color_index(bg, step_array.len());
|
||||||
|
|
||||||
|
|
@ -1070,11 +1075,12 @@ impl ThemeBuilder {
|
||||||
);
|
);
|
||||||
|
|
||||||
let primary = {
|
let primary = {
|
||||||
let container_bg = if let Some(primary_container_bg_color) = primary_container_bg {
|
let mut container_bg = if let Some(primary_container_bg_color) = primary_container_bg {
|
||||||
primary_container_bg_color
|
primary_container_bg_color
|
||||||
} else {
|
} else {
|
||||||
get_surface_color(bg_index, 5, &step_array, is_dark, &control_steps_array[1])
|
get_surface_color(bg_index, 5, &step_array, is_dark, &control_steps_array[1])
|
||||||
};
|
};
|
||||||
|
container_bg.alpha = container_alpha;
|
||||||
|
|
||||||
let step_array = steps(container_bg, NonZeroUsize::new(100).unwrap());
|
let step_array = steps(container_bg, NonZeroUsize::new(100).unwrap());
|
||||||
let base_index: usize = color_index(container_bg, step_array.len());
|
let base_index: usize = color_index(container_bg, step_array.len());
|
||||||
|
|
@ -1191,11 +1197,13 @@ impl ThemeBuilder {
|
||||||
),
|
),
|
||||||
primary,
|
primary,
|
||||||
secondary: {
|
secondary: {
|
||||||
let container_bg = if let Some(secondary_container_bg) = secondary_container_bg {
|
let mut container_bg = if let Some(secondary_container_bg) = secondary_container_bg
|
||||||
|
{
|
||||||
secondary_container_bg
|
secondary_container_bg
|
||||||
} else {
|
} else {
|
||||||
get_surface_color(bg_index, 10, &step_array, is_dark, &control_steps_array[2])
|
get_surface_color(bg_index, 10, &step_array, is_dark, &control_steps_array[2])
|
||||||
};
|
};
|
||||||
|
container_bg.alpha = container_alpha;
|
||||||
|
|
||||||
let step_array = steps(container_bg, NonZeroUsize::new(100).unwrap());
|
let step_array = steps(container_bg, NonZeroUsize::new(100).unwrap());
|
||||||
let base_index = color_index(container_bg, step_array.len());
|
let base_index = color_index(container_bg, step_array.len());
|
||||||
|
|
@ -1347,7 +1355,7 @@ impl ThemeBuilder {
|
||||||
gaps,
|
gaps,
|
||||||
active_hint,
|
active_hint,
|
||||||
window_hint,
|
window_hint,
|
||||||
is_frosted,
|
frosted,
|
||||||
accent_text,
|
accent_text,
|
||||||
control_tint: neutral_tint,
|
control_tint: neutral_tint,
|
||||||
text_tint,
|
text_tint,
|
||||||
|
|
@ -1369,3 +1377,69 @@ impl ThemeBuilder {
|
||||||
Config::new(LIGHT_THEME_BUILDER_ID, Self::VERSION)
|
Config::new(LIGHT_THEME_BUILDER_ID, Self::VERSION)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum BlurStrength {
|
||||||
|
ExtremelyLow = 1,
|
||||||
|
ExtremelyLow2,
|
||||||
|
VeryLow,
|
||||||
|
VeryLow2,
|
||||||
|
Low,
|
||||||
|
Low2,
|
||||||
|
Medium,
|
||||||
|
Medium2,
|
||||||
|
High,
|
||||||
|
High2,
|
||||||
|
VeryHigh,
|
||||||
|
VeryHigh2,
|
||||||
|
ExtremelyHigh,
|
||||||
|
ExtremelyHigh2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlurStrength {
|
||||||
|
/// Get the alpha value corresponding to the blur strength
|
||||||
|
/// Lower alpha values correspond to stronger blur effects, and higher alpha values correspond to weaker blur effects. The mapping is as follows:
|
||||||
|
pub fn alpha(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
Self::ExtremelyLow => 0.95,
|
||||||
|
Self::ExtremelyLow2 => 0.85,
|
||||||
|
Self::VeryLow => 0.8,
|
||||||
|
Self::VeryLow2 => 0.75,
|
||||||
|
Self::Low => 0.7,
|
||||||
|
Self::Low2 => 0.65,
|
||||||
|
Self::Medium => 0.6,
|
||||||
|
Self::Medium2 => 0.55,
|
||||||
|
Self::High => 0.5,
|
||||||
|
Self::High2 => 0.45,
|
||||||
|
Self::VeryHigh => 0.4,
|
||||||
|
Self::VeryHigh2 => 0.35,
|
||||||
|
Self::ExtremelyHigh => 0.2,
|
||||||
|
Self::ExtremelyHigh2 => 0.05,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u8> for BlurStrength {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
1 => Ok(BlurStrength::ExtremelyLow),
|
||||||
|
2 => Ok(BlurStrength::ExtremelyLow2),
|
||||||
|
3 => Ok(BlurStrength::VeryLow),
|
||||||
|
4 => Ok(BlurStrength::VeryLow2),
|
||||||
|
5 => Ok(BlurStrength::Low),
|
||||||
|
6 => Ok(BlurStrength::Low2),
|
||||||
|
7 => Ok(BlurStrength::Medium),
|
||||||
|
8 => Ok(BlurStrength::Medium2),
|
||||||
|
9 => Ok(BlurStrength::High),
|
||||||
|
10 => Ok(BlurStrength::High2),
|
||||||
|
11 => Ok(BlurStrength::VeryHigh),
|
||||||
|
12 => Ok(BlurStrength::VeryHigh2),
|
||||||
|
13 => Ok(BlurStrength::ExtremelyHigh),
|
||||||
|
14 => Ok(BlurStrength::ExtremelyHigh2),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
2
iced
2
iced
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7fd263d99e6ae1b07e51f25bda3367f7463806b1
|
Subproject commit 46b65a3c3e2fb6f1627d117ca061743417806aaf
|
||||||
|
|
@ -773,10 +773,31 @@ impl<T: Application> Cosmic<T> {
|
||||||
if a.distance_squared(*t_inner.accent_color()) > 0.00001 {
|
if a.distance_squared(*t_inner.accent_color()) > 0.00001 {
|
||||||
theme = Theme::system(Arc::new(t_inner.with_accent(a)));
|
theme = Theme::system(Arc::new(t_inner.with_accent(a)));
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let new_blur = theme.cosmic().frosted.is_some();
|
||||||
THEME.lock().unwrap().set_theme(theme.theme_type);
|
THEME.lock().unwrap().set_theme(theme.theme_type);
|
||||||
|
|
||||||
|
let core = self.app.core();
|
||||||
|
if core.auto_blur {
|
||||||
|
let mut cmds = Vec::with_capacity(1 + self.tracked_windows.len());
|
||||||
|
let blur = if new_blur {
|
||||||
|
iced::window::enable_blur
|
||||||
|
} else {
|
||||||
|
iced::window::disable_blur
|
||||||
|
};
|
||||||
|
cmds.push(blur(
|
||||||
|
self.app
|
||||||
|
.core()
|
||||||
|
.main_window_id()
|
||||||
|
.unwrap_or(window::Id::RESERVED),
|
||||||
|
));
|
||||||
|
for id in &self.tracked_windows {
|
||||||
|
cmds.push(blur(*id));
|
||||||
|
}
|
||||||
|
return Task::batch(cmds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Action::SystemThemeChange(keys, theme) => {
|
Action::SystemThemeChange(keys, theme) => {
|
||||||
|
|
@ -809,6 +830,8 @@ impl<T: Application> Cosmic<T> {
|
||||||
theme
|
theme
|
||||||
};
|
};
|
||||||
new_theme.theme_type.prefer_dark(prefer_dark);
|
new_theme.theme_type.prefer_dark(prefer_dark);
|
||||||
|
// TODO adjust theme container alphas to remove transparency?
|
||||||
|
// if auto-blur is disabled & theme is frosted, should we make container colors in theme opaque?
|
||||||
|
|
||||||
cosmic_theme.set_theme(new_theme.theme_type);
|
cosmic_theme.set_theme(new_theme.theme_type);
|
||||||
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
||||||
|
|
@ -873,7 +896,7 @@ impl<T: Application> Cosmic<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update radius for all tracked windows
|
// Update radius for all tracked windows
|
||||||
for id in self.tracked_windows.iter() {
|
for id in &self.tracked_windows {
|
||||||
cmds.push(
|
cmds.push(
|
||||||
corner_radius(
|
corner_radius(
|
||||||
*id,
|
*id,
|
||||||
|
|
@ -956,6 +979,9 @@ impl<T: Application> Cosmic<T> {
|
||||||
|
|
||||||
// Only apply update if the theme is set to load a system theme
|
// Only apply update if the theme is set to load a system theme
|
||||||
if let ThemeType::System { .. } = cosmic_theme.theme_type {
|
if let ThemeType::System { .. } = cosmic_theme.theme_type {
|
||||||
|
// TODO adjust theme container alphas to remove transparency?
|
||||||
|
// if auto-blur is disabled & theme is frosted, should we make container colors in theme opaque?
|
||||||
|
let new_blur = new_theme.cosmic().frosted.is_some();
|
||||||
cosmic_theme.set_theme(new_theme.theme_type);
|
cosmic_theme.set_theme(new_theme.theme_type);
|
||||||
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
||||||
if self.app.core().sync_window_border_radii_to_theme() {
|
if self.app.core().sync_window_border_radii_to_theme() {
|
||||||
|
|
@ -1019,7 +1045,7 @@ impl<T: Application> Cosmic<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update radius for all tracked windows
|
// Update radius for all tracked windows
|
||||||
for id in self.tracked_windows.iter() {
|
for id in &self.tracked_windows {
|
||||||
cmds.push(
|
cmds.push(
|
||||||
corner_radius(
|
corner_radius(
|
||||||
*id,
|
*id,
|
||||||
|
|
@ -1039,6 +1065,25 @@ impl<T: Application> Cosmic<T> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let core = self.app.core();
|
||||||
|
if core.auto_blur {
|
||||||
|
let blur = if new_blur {
|
||||||
|
iced::window::enable_blur
|
||||||
|
} else {
|
||||||
|
iced::window::disable_blur
|
||||||
|
};
|
||||||
|
|
||||||
|
cmds.push(blur(
|
||||||
|
self.app
|
||||||
|
.core()
|
||||||
|
.main_window_id()
|
||||||
|
.unwrap_or(window::Id::RESERVED),
|
||||||
|
));
|
||||||
|
for id in &self.tracked_windows {
|
||||||
|
cmds.push(blur(*id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Task::batch(cmds);
|
return Task::batch(cmds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1147,7 +1192,26 @@ impl<T: Application> Cosmic<T> {
|
||||||
|
|
||||||
// Only apply update if the theme is set to load a system theme
|
// Only apply update if the theme is set to load a system theme
|
||||||
if let ThemeType::System { theme: _, .. } = cosmic_theme.theme_type {
|
if let ThemeType::System { theme: _, .. } = cosmic_theme.theme_type {
|
||||||
|
let mut cmds = Vec::with_capacity(1 + self.tracked_windows.len());
|
||||||
|
|
||||||
|
if core.auto_blur {
|
||||||
|
let blur = if new_theme.cosmic().frosted.is_some() {
|
||||||
|
iced::window::enable_blur
|
||||||
|
} else {
|
||||||
|
iced::window::disable_blur
|
||||||
|
};
|
||||||
|
cmds.push(blur(
|
||||||
|
self.app
|
||||||
|
.core()
|
||||||
|
.main_window_id()
|
||||||
|
.unwrap_or(window::Id::RESERVED),
|
||||||
|
));
|
||||||
|
for id in &self.tracked_windows {
|
||||||
|
cmds.push(blur(*id));
|
||||||
|
}
|
||||||
|
}
|
||||||
cosmic_theme.set_theme(new_theme.theme_type);
|
cosmic_theme.set_theme(new_theme.theme_type);
|
||||||
|
return Task::batch(cmds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1263,8 +1327,24 @@ impl<T: Application> Cosmic<T> {
|
||||||
};
|
};
|
||||||
// TODO do we need per window sharp corners?
|
// TODO do we need per window sharp corners?
|
||||||
let rounded = !self.app.core().window.sharp_corners;
|
let rounded = !self.app.core().window.sharp_corners;
|
||||||
|
let core = self.app.core();
|
||||||
|
let blur_cmd = if core.auto_blur {
|
||||||
|
let blur = if t.frosted.is_some() {
|
||||||
|
iced::window::enable_blur
|
||||||
|
} else {
|
||||||
|
iced::window::disable_blur
|
||||||
|
};
|
||||||
|
let mut cmds = Vec::with_capacity(1 + self.tracked_windows.len());
|
||||||
|
cmds.push(blur(id));
|
||||||
|
for id in &self.tracked_windows {
|
||||||
|
cmds.push(blur(*id));
|
||||||
|
}
|
||||||
|
Task::batch(cmds)
|
||||||
|
} else {
|
||||||
|
Task::none()
|
||||||
|
};
|
||||||
return Task::batch([
|
return Task::batch([
|
||||||
|
blur_cmd,
|
||||||
corner_radius(
|
corner_radius(
|
||||||
id,
|
id,
|
||||||
if rounded {
|
if rounded {
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,8 @@ pub struct Core {
|
||||||
|
|
||||||
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
||||||
pub(crate) sync_window_border_radii_to_theme: bool,
|
pub(crate) sync_window_border_radii_to_theme: bool,
|
||||||
|
|
||||||
|
pub(crate) auto_blur: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Core {
|
impl Default for Core {
|
||||||
|
|
@ -161,6 +163,7 @@ impl Default for Core {
|
||||||
menu_bars: HashMap::new(),
|
menu_bars: HashMap::new(),
|
||||||
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
#[cfg(all(feature = "wayland", target_os = "linux"))]
|
||||||
sync_window_border_radii_to_theme: true,
|
sync_window_border_radii_to_theme: true,
|
||||||
|
auto_blur: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -502,4 +505,8 @@ impl Core {
|
||||||
pub fn sync_window_border_radii_to_theme(&self) -> bool {
|
pub fn sync_window_border_radii_to_theme(&self) -> bool {
|
||||||
self.sync_window_border_radii_to_theme
|
self.sync_window_border_radii_to_theme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_auto_blur(&mut self, auto_blur: bool) {
|
||||||
|
self.auto_blur = auto_blur;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -565,6 +565,9 @@ impl iced_container::Catalog for Theme {
|
||||||
|
|
||||||
Container::ContextDrawer => {
|
Container::ContextDrawer => {
|
||||||
let mut a = Container::primary(cosmic);
|
let mut a = Container::primary(cosmic);
|
||||||
|
if let Some(Background::Color(ref mut color)) = a.background {
|
||||||
|
color.a = 1.;
|
||||||
|
}
|
||||||
|
|
||||||
if cosmic.is_high_contrast {
|
if cosmic.is_high_contrast {
|
||||||
a.border.width = 1.;
|
a.border.width = 1.;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue