Unify shell opacity and add native authentication and system controls

This commit is contained in:
Samuel Onoja committed 2026-09-28 09:26:14 +01:00
1 parent 8832a9bf2e
commit c8e89fb758
35 files changed
+1674 -133

No files matched your search

+11 -11
View File
@@ -623,6 +623,17 @@ pub fn fields(page: Page) -> Vec<Field> {
"solid",
&[("solid", "Solid"), ("translucent", "Translucent")],
),
range(
"theme.material.opacity",
"Shell opacity",
"Background opacity for the bar, popovers, menus, notifications and sharing dialog. Text and icons stay opaque.",
ferese_config::DEFAULT_MATERIAL_OPACITY,
0.0,
1.0,
0.01,
"",
false,
),
range(
"theme.material.blur_radius",
"Background blur",
@@ -727,17 +738,6 @@ pub fn fields(page: Page) -> Vec<Field> {
" px",
true,
),
range(
"theme.surface.bar.opacity",
"Opacity",
"Background opacity for translucent bars, with or without blur. Text and icons stay opaque.",
0.78,
0.0,
1.0,
0.01,
"",
false,
),
range(
"theme.geometry.top_bar_window_gap",
"Window clearance",
+14 -1
View File
@@ -151,6 +151,7 @@ fn styled_button(p: Palette, selected: bool, navigation: bool) -> theme::Button
} else {
(background, p.text)
};
button::Style {
background: Some(Background::Color(background)),
text_color: Some(on),
@@ -196,6 +197,7 @@ pub fn native_theme(snapshot: Option<&Snapshot>) -> cosmic::Theme {
.text_tint(cosmic_color(palette.text).color)
.accent(ferese_theme::accent_color(palette.accent, palette.card))
.build();
ferese_theme::apply(&mut theme, palette.text);
cosmic::Theme::custom(std::sync::Arc::new(theme))
}
@@ -204,16 +206,20 @@ pub fn configured_font(snapshot: &Snapshot) -> cosmic::font::Font {
static FONTS: std::sync::OnceLock<
std::sync::Mutex<std::collections::HashMap<String, cosmic::font::Font>>,
> = std::sync::OnceLock::new();
let family = snapshot.string("theme.typography.font_family", "Inter");
let mut fonts = FONTS.get_or_init(Default::default).lock().unwrap();
if let Some(font) = fonts.get(&family) {
return *font;
}
if fonts.len() >= 32 {
return cosmic::font::default();
}
let font = cosmic::font::Font::with_name(Box::leak(family.clone().into_boxed_str()));
fonts.insert(family, font);
font
}
@@ -331,6 +337,7 @@ pub fn preset(index: usize) -> Vec<Edit> {
let Some(preset) = PRESETS.get(index) else {
return Vec::new();
};
vec![
set("theme.colors.accent", preset.accent),
set("theme.colors.surface_base", preset.base),
@@ -351,6 +358,7 @@ pub fn preset_selected(snapshot: &Snapshot, index: usize) -> bool {
let Some(preset) = PRESETS.get(index) else {
return false;
};
[
("theme.colors.accent", preset.accent, "#3D7BE6"),
("theme.colors.surface_base", preset.base, "#111821"),
@@ -442,7 +450,11 @@ pub fn preview(snapshot: &Snapshot) -> Element<'static, Message> {
let bar_margin = snapshot.number("theme.geometry.top_bar_margin_horizontal", 0.) * 0.5 + 14.;
let bar_height = snapshot.number("theme.geometry.top_bar_height", 30.) * 0.65;
let bar_radius = snapshot.number("theme.geometry.shell_radius", 14.) * 0.65;
let opacity = snapshot.number("theme.surface.bar.opacity", 0.78);
let opacity = if snapshot.string("theme.material.style", "solid") == "translucent" {
snapshot.number("theme.material.opacity", ferese_config::DEFAULT_MATERIAL_OPACITY).clamp(0., 1.)
} else {
1.
};
let right = 340. + gap / 2.;
let left_width = 288. - gap / 2.;
let svg = format!(
@@ -465,6 +477,7 @@ pub fn preview(snapshot: &Snapshot) -> Element<'static, Message> {
bar_y + bar_height / 2.,
right + 16.
);
svg_icon::from_svg_bytes(svg.into_bytes())
.symbolic(false)
.icon()
+3
View File
@@ -6,6 +6,7 @@ use std::{path::PathBuf, time::Duration};
pub fn changes(path: &PathBuf) -> impl Stream<Item = Message> + use<> {
let path = path.clone();
cosmic::iced::stream::channel(1, async move |mut output| {
let (send, mut events) = tokio::sync::mpsc::channel(1);
let target = path.clone();
@@ -26,6 +27,7 @@ pub fn changes(path: &PathBuf) -> impl Stream<Item = Message> + use<> {
return;
}
};
if let Err(error) = watcher.watch(
path.parent().unwrap_or(std::path::Path::new(".")),
RecursiveMode::NonRecursive,
@@ -35,6 +37,7 @@ pub fn changes(path: &PathBuf) -> impl Stream<Item = Message> + use<> {
.await;
return;
}
// Read once after installing the watch to cover the startup race.
loop {
let file = path.clone();