Unify shell opacity and add native authentication and system controls
This commit is contained in:
1 parent
8832a9bf2e
commit
c8e89fb758
35 files changed
+1674
-133
No files matched your search
+19
-32
@@ -190,7 +190,7 @@ pub struct ThemeSettings {
|
||||
pub focus_ring_gradient: Option<BorderGradient>,
|
||||
pub shadow_color: RgbaColor,
|
||||
pub surface_base_color: RgbaColor,
|
||||
pub panel_opacity: f64,
|
||||
pub shell_opacity: f64,
|
||||
pub inactive_dim: InactiveDimSettings,
|
||||
pub window_radius: f64,
|
||||
pub shadow_offset_y: f64,
|
||||
@@ -253,8 +253,6 @@ struct ThemeConfig {
|
||||
#[serde(default)]
|
||||
background: crate::wallpaper::WallpaperConfig,
|
||||
#[serde(default)]
|
||||
surface: ThemeSurfaceConfig,
|
||||
#[serde(default)]
|
||||
colors: ThemeColorsConfig,
|
||||
#[serde(default)]
|
||||
geometry: ThemeGeometryConfig,
|
||||
@@ -331,19 +329,10 @@ struct OverviewTypographyConfig {
|
||||
font_family: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
struct ThemeSurfaceConfig {
|
||||
#[serde(default)]
|
||||
bar: ThemeBarConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
struct ThemeBarConfig {
|
||||
opacity: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ThemeMaterialConfig {
|
||||
#[serde(default = "default_shell_opacity")]
|
||||
opacity: f64,
|
||||
#[serde(default)]
|
||||
style: MaterialStyle,
|
||||
#[serde(default = "default_backdrop_blur")]
|
||||
@@ -354,11 +343,16 @@ impl Default for ThemeMaterialConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
style: MaterialStyle::Solid,
|
||||
opacity: default_shell_opacity(),
|
||||
blur_radius: default_backdrop_blur(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_shell_opacity() -> f64 {
|
||||
ferese_config::DEFAULT_MATERIAL_OPACITY
|
||||
}
|
||||
|
||||
fn default_backdrop_blur() -> f64 {
|
||||
12.0
|
||||
}
|
||||
@@ -1095,10 +1089,7 @@ impl Config {
|
||||
&self.theme.colors.surface_base,
|
||||
"colors.surface_base",
|
||||
)?,
|
||||
panel_opacity: unit_theme_value(
|
||||
self.theme.surface.bar.opacity.unwrap_or(0.78),
|
||||
"surface.bar.opacity",
|
||||
)?,
|
||||
shell_opacity: unit_theme_value(self.theme.material.opacity, "material.opacity")?,
|
||||
inactive_dim: InactiveDimSettings {
|
||||
enabled: self.appearance.inactive_dim.enabled,
|
||||
amount: unit_theme_value(
|
||||
@@ -2034,7 +2025,7 @@ mod tests {
|
||||
focus_ring_gradient: None,
|
||||
shadow_color: RgbaColor([1.0 / 255.0, 2.0 / 255.0, 3.0 / 255.0, 128.0 / 255.0]),
|
||||
surface_base_color: RgbaColor([17.0 / 255.0, 24.0 / 255.0, 33.0 / 255.0, 1.0,]),
|
||||
panel_opacity: 0.78,
|
||||
shell_opacity: 0.78,
|
||||
inactive_dim: InactiveDimSettings {
|
||||
enabled: false,
|
||||
amount: 0.15,
|
||||
@@ -2125,26 +2116,22 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bar_opacity_uses_config_and_rejects_invalid_values() {
|
||||
assert_eq!(parse("").theme_settings().unwrap().panel_opacity, 0.78);
|
||||
fn shell_opacity_uses_config_and_rejects_invalid_values() {
|
||||
assert_eq!(parse("").theme_settings().unwrap().shell_opacity, 0.78);
|
||||
for opacity in [0.0, 0.65, 1.0] {
|
||||
assert_eq!(
|
||||
parse(&format!(
|
||||
"theme {{ surface {{ bar {{ opacity {opacity}; }} }} }}"
|
||||
))
|
||||
.theme_settings()
|
||||
.unwrap()
|
||||
.panel_opacity,
|
||||
parse(&format!("theme {{ material {{ opacity {opacity}; }} }}"))
|
||||
.theme_settings()
|
||||
.unwrap()
|
||||
.shell_opacity,
|
||||
opacity
|
||||
);
|
||||
}
|
||||
for opacity in ["-0.1", "1.1", "#nan", "#inf"] {
|
||||
assert!(
|
||||
Config::parse_source(&format!(
|
||||
"theme {{ surface {{ bar {{ opacity {opacity}; }} }} }}"
|
||||
))
|
||||
.and_then(|config| config.theme_settings())
|
||||
.is_err()
|
||||
Config::parse_source(&format!("theme {{ material {{ opacity {opacity}; }} }}"))
|
||||
.and_then(|config| config.theme_settings())
|
||||
.is_err()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,11 @@ pub(crate) struct ResolvedMaterial {
|
||||
pub shadow: [f64; 3],
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_material(role: SemanticRole, style: MaterialStyle) -> ResolvedMaterial {
|
||||
pub(crate) fn resolve_material(
|
||||
role: SemanticRole,
|
||||
style: MaterialStyle,
|
||||
opacity: f32,
|
||||
) -> ResolvedMaterial {
|
||||
let shadow = match role {
|
||||
SemanticRole::Panel => [1.0, 5.0, 0.04],
|
||||
SemanticRole::PanelElevated | SemanticRole::Popover | SemanticRole::Menu => {
|
||||
@@ -46,11 +50,9 @@ pub(crate) fn resolve_material(role: SemanticRole, style: MaterialStyle) -> Reso
|
||||
SemanticRole::Hud => [1.0, 4.0, 0.04],
|
||||
SemanticRole::Notification | SemanticRole::Modal => [3.0, 10.0, 0.09],
|
||||
};
|
||||
let opacity = match (style, role) {
|
||||
(MaterialStyle::Solid, _) => 1.0,
|
||||
(_, SemanticRole::Panel) => 0.78,
|
||||
(_, SemanticRole::Hud | SemanticRole::Modal) => 0.88,
|
||||
_ => 0.84,
|
||||
let opacity = match style {
|
||||
MaterialStyle::Solid => 1.0,
|
||||
MaterialStyle::Translucent => opacity.clamp(0.0, 1.0),
|
||||
};
|
||||
ResolvedMaterial {
|
||||
style,
|
||||
@@ -430,10 +432,10 @@ mod tests {
|
||||
SemanticRole::Notification,
|
||||
SemanticRole::Modal,
|
||||
] {
|
||||
let solid = resolve_material(role, MaterialStyle::Solid);
|
||||
let translucent = resolve_material(role, MaterialStyle::Translucent);
|
||||
let solid = resolve_material(role, MaterialStyle::Solid, 0.6);
|
||||
let translucent = resolve_material(role, MaterialStyle::Translucent, 0.6);
|
||||
assert_eq!(solid.opacity, 1.0);
|
||||
assert!(translucent.opacity < 1.0);
|
||||
assert_eq!(translucent.opacity, 0.6);
|
||||
assert_eq!(solid.shadow, translucent.shadow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ pub fn resolve(
|
||||
) -> WindowRuleResult {
|
||||
let app_id = app_id.map(normalize_app_id);
|
||||
let mut result = WindowRuleResult::default();
|
||||
if app_id.as_deref() == Some("dev.ferese.Authentication") {
|
||||
result.floating = Some(true);
|
||||
}
|
||||
|
||||
for rule in rules {
|
||||
let app_id_matches = rule
|
||||
|
||||
+11
-12
@@ -1532,7 +1532,11 @@ fn overview_strip_elements(
|
||||
}
|
||||
}
|
||||
let mut color = state.theme_settings.surface_base_color.0;
|
||||
color[3] = alpha * state.theme_settings.panel_opacity as f32;
|
||||
color[3] = alpha * crate::effects::resolve_material(
|
||||
crate::effects::SemanticRole::Panel,
|
||||
state.theme_settings.material_style,
|
||||
state.theme_settings.shell_opacity as f32,
|
||||
).opacity;
|
||||
if let Some(strip) = overview_chrome_element(
|
||||
state,
|
||||
renderer,
|
||||
@@ -2306,13 +2310,12 @@ fn material_element(
|
||||
capture_geometry: Rectangle<i32, Logical>,
|
||||
) -> Option<(AnimatedWindowRenderElement, AnimatedWindowRenderElement)> {
|
||||
let (role, generation) = crate::effects::surface_role(surface)?;
|
||||
let mut material = crate::effects::resolve_material(role, state.theme_settings.material_style);
|
||||
let material = crate::effects::resolve_material(
|
||||
role,
|
||||
state.theme_settings.material_style,
|
||||
state.theme_settings.shell_opacity as f32,
|
||||
);
|
||||
let presentation_alpha = crate::effects::surface_opacity(surface);
|
||||
if role == crate::effects::SemanticRole::Panel
|
||||
&& material.style == crate::config::MaterialStyle::Translucent
|
||||
{
|
||||
material.opacity = state.theme_settings.panel_opacity as f32;
|
||||
}
|
||||
let mode = output.current_mode()?;
|
||||
let scale = output.current_scale().fractional_scale();
|
||||
let transform = output.current_transform().invert();
|
||||
@@ -2330,11 +2333,7 @@ fn material_element(
|
||||
(geometry.loc.x, geometry.loc.y + offset_y.round() as i32).into(),
|
||||
geometry.size,
|
||||
);
|
||||
let background_opacity = if role == crate::effects::SemanticRole::Panel {
|
||||
material.opacity
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
let background_opacity = material.opacity;
|
||||
let blur = material_blur_radius(
|
||||
material.style,
|
||||
material.opacity,
|
||||
|
||||
Reference in new issue
Block a user