fix clippy warnings

This commit is contained in:
Samuel Onoja committed 2026-10-01 13:24:21 +01:00
1 parent 7b88083020
commit bdc3ba435f
39 files changed
+825 -688

No files matched your search

+4 -4
View File
@@ -52,7 +52,7 @@ enum Message {
RefreshDisplays,
DisplaysLoaded(Result<Vec<displays::Display>, String>),
RefreshRate(String, displays::Mode, bool),
ThemeChanged(ferese_config::theme::Snapshot),
ThemeChanged(Box<ferese_config::theme::Snapshot>),
DragWindow,
Page(Page),
Search(String),
@@ -207,7 +207,7 @@ impl cosmic::Application for App {
return self.edit_many(displays::edits(&prefix, mode, automatic));
}
Message::ThemeChanged(snapshot) => {
self.resolved = snapshot;
self.resolved = *snapshot;
self.font = ferese_theme::font(Some(&self.resolved.presented.tokens.typography.font_family));
return self.update_theme();
}
@@ -596,8 +596,8 @@ impl cosmic::Application for App {
fn subscription(&self) -> cosmic::iced::Subscription<Message> {
cosmic::iced::Subscription::batch([
cosmic::iced::Subscription::run_with(self.path.clone(), watch::changes),
ferese_theme::service::subscription().map(Message::ThemeChanged),
cosmic::iced::Subscription::run_with(self.path.clone(), |path| watch::changes(path)),
ferese_theme::service::subscription().map(|snapshot| Message::ThemeChanged(Box::new(snapshot))),
if self.page == Page::Displays {
cosmic::iced::time::every(std::time::Duration::from_secs(2)).map(|_| Message::RefreshDisplays)
} else {
+8 -6
View File
@@ -412,12 +412,14 @@ impl App {
format!("{prefix}.scale"),
"Scale",
"Logical size of text and controls.",
1.,
0.75,
3.,
0.25,
"×",
false,
schema::RangeSpec {
default: 1.,
min: 0.75,
max: 3.,
step: 0.25,
suffix: "×",
integer: false,
},
)));
body = body.push(container(group).padding(8).class(visuals::surface(palette.card, 14.)));
}
+347 -252
View File
@@ -148,17 +148,30 @@ fn toggle(path: &str, label: &str, description: &str, default: bool) -> Field {
Field::new(path, label, description, Kind::Toggle(default))
}
#[derive(Clone, Copy, Debug)]
pub struct RangeSpec {
pub default: f64,
pub min: f64,
pub max: f64,
pub step: f64,
pub suffix: &'static str,
pub integer: bool,
}
pub fn range(
path: impl Into<String>,
label: impl Into<String>,
description: impl Into<String>,
default: f64,
min: f64,
max: f64,
step: f64,
suffix: &'static str,
integer: bool,
spec: RangeSpec,
) -> Field {
let RangeSpec {
default,
min,
max,
step,
suffix,
integer,
} = spec;
Field::new(
path,
label,
@@ -278,100 +291,118 @@ fn clock_fields() -> Vec<Field> {
"desktop_widgets.clock.margin_x",
"Horizontal margin",
"Distance from left/right edge; ignored when horizontally centered.",
64.0,
0.0,
1000.0,
1.0,
" px",
true,
RangeSpec {
default: 64.0,
min: 0.0,
max: 1000.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
"desktop_widgets.clock.margin_y",
"Vertical margin",
"Distance from top/bottom edge; ignored when vertically centered.",
80.0,
0.0,
1000.0,
1.0,
" px",
true,
RangeSpec {
default: 80.0,
min: 0.0,
max: 1000.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
"desktop_widgets.clock.width",
"Widget width",
"Logical pixels; increase for longer formats.",
440.0,
64.0,
1600.0,
1.0,
" px",
true,
RangeSpec {
default: 440.0,
min: 64.0,
max: 1600.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
"desktop_widgets.clock.height",
"Widget height",
"Leave room for both text lines.",
320.0,
32.0,
800.0,
1.0,
" px",
true,
RangeSpec {
default: 320.0,
min: 32.0,
max: 800.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
"desktop_widgets.clock.time_size",
"Time size",
"Logical pixels; scales with your output.",
128.0,
8.0,
240.0,
1.0,
" px",
false,
RangeSpec {
default: 128.0,
min: 8.0,
max: 240.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
"desktop_widgets.clock.date_size",
"Date size",
"Separate size for the date line.",
18.0,
8.0,
96.0,
1.0,
" px",
false,
RangeSpec {
default: 18.0,
min: 8.0,
max: 96.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
"desktop_widgets.clock.opacity",
"Opacity",
"Applies to text and the optional background.",
0.9,
0.0,
1.0,
0.05,
"",
false,
RangeSpec {
default: 0.9,
min: 0.0,
max: 1.0,
step: 0.05,
suffix: "",
integer: false,
},
),
range(
"desktop_widgets.clock.gap",
"Line spacing",
"Space between time and date.",
4.0,
0.0,
64.0,
1.0,
" px",
false,
RangeSpec {
default: 4.0,
min: 0.0,
max: 64.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
"desktop_widgets.clock.padding",
"Inner padding",
"Space around the labels.",
12.0,
0.0,
64.0,
1.0,
" px",
false,
RangeSpec {
default: 12.0,
min: 0.0,
max: 64.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
choice(
"desktop_widgets.clock.alignment",
@@ -422,100 +453,118 @@ pub fn note_fields(index: usize) -> Vec<Field> {
format!("{prefix}.width"),
"Width",
"Logical pixels; centered axes ignore margins.",
320.0,
120.0,
1200.0,
1.0,
" px",
true,
RangeSpec {
default: 320.0,
min: 120.0,
max: 1200.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
format!("{prefix}.height"),
"Height",
"Logical pixels; centered axes ignore margins.",
240.0,
80.0,
1200.0,
1.0,
" px",
true,
RangeSpec {
default: 240.0,
min: 80.0,
max: 1200.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
format!("{prefix}.margin_x"),
"Horizontal margin",
"Logical pixels; centered axes ignore margins.",
48.0,
0.0,
1000.0,
1.0,
" px",
true,
RangeSpec {
default: 48.0,
min: 0.0,
max: 1000.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
format!("{prefix}.margin_y"),
"Vertical margin",
"Logical pixels; centered axes ignore margins.",
80.0,
0.0,
1000.0,
1.0,
" px",
true,
RangeSpec {
default: 80.0,
min: 0.0,
max: 1000.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
format!("{prefix}.text_size"),
"Text size",
"Logical pixels; centered axes ignore margins.",
16.0,
8.0,
96.0,
1.0,
" px",
false,
RangeSpec {
default: 16.0,
min: 8.0,
max: 96.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
format!("{prefix}.title_size"),
"Title size",
"Logical pixels; centered axes ignore margins.",
18.0,
8.0,
96.0,
1.0,
" px",
false,
RangeSpec {
default: 18.0,
min: 8.0,
max: 96.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
format!("{prefix}.opacity"),
"Opacity",
"Logical pixels; centered axes ignore margins.",
0.9,
0.0,
1.0,
0.05,
"",
false,
RangeSpec {
default: 0.9,
min: 0.0,
max: 1.0,
step: 0.05,
suffix: "",
integer: false,
},
),
range(
format!("{prefix}.padding"),
"Padding",
"Logical pixels; centered axes ignore margins.",
20.0,
0.0,
64.0,
1.0,
" px",
false,
RangeSpec {
default: 20.0,
min: 0.0,
max: 64.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
format!("{prefix}.gap"),
"Title spacing",
"Logical pixels; centered axes ignore margins.",
8.0,
0.0,
64.0,
1.0,
" px",
false,
RangeSpec {
default: 8.0,
min: 0.0,
max: 64.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
Field::new(
format!("{prefix}.alignment"),
@@ -536,23 +585,27 @@ pub fn fields(page: Page) -> Vec<Field> {
"lock_screen.dim_after_seconds",
"Dim after",
"Dim the locked display after inactivity. Zero disables dimming.",
30.0,
0.0,
600.0,
5.0,
"s",
true,
RangeSpec {
default: 30.0,
min: 0.0,
max: 600.0,
step: 5.0,
suffix: "s",
integer: true,
},
),
range(
"lock_screen.sleep_after_seconds",
"Display sleep after",
"Turn off locked displays after inactivity. Input wakes them; zero disables display sleep.",
120.0,
0.0,
1800.0,
15.0,
"s",
true,
RangeSpec {
default: 120.0,
min: 0.0,
max: 1800.0,
step: 15.0,
suffix: "s",
integer: true,
},
),
toggle(
"lock_screen.show_clock",
@@ -577,23 +630,27 @@ pub fn fields(page: Page) -> Vec<Field> {
"lock_screen.background_blur",
"Wallpaper softness",
"Blur the lock screen wallpaper. Zero keeps the original image sharp.",
18.0,
0.0,
40.0,
1.0,
"",
false,
RangeSpec {
default: 18.0,
min: 0.0,
max: 40.0,
step: 1.0,
suffix: "",
integer: false,
},
),
range(
"lock_screen.background_dim",
"Wallpaper dimming",
"Darken the wallpaper behind the clock and sign-in card.",
0.48,
0.0,
0.9,
0.02,
"",
false,
RangeSpec {
default: 0.48,
min: 0.0,
max: 0.9,
step: 0.02,
suffix: "",
integer: false,
},
),
],
Page::Accessibility => vec![
@@ -664,12 +721,14 @@ pub fn fields(page: Page) -> Vec<Field> {
"theme.geometry.shell_radius",
"Shell corner radius",
"Rounds the bar, menus, notifications, desktop widgets and hover backgrounds. Window corners are separate.",
14.0,
0.0,
32.0,
1.0,
" px",
false,
RangeSpec {
default: 14.0,
min: 0.0,
max: 32.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
text(
"theme.accent",
@@ -688,23 +747,27 @@ pub fn fields(page: Page) -> Vec<Field> {
"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,
RangeSpec {
default: ferese_config::DEFAULT_MATERIAL_OPACITY,
min: 0.0,
max: 1.0,
step: 0.01,
suffix: "",
integer: false,
},
),
range(
"theme.material.blur_radius",
"Background blur",
"Softness behind translucent surfaces.",
12.0,
0.0,
32.0,
1.0,
" px",
false,
RangeSpec {
default: 12.0,
min: 0.0,
max: 32.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
text(
"theme.typography.font_family",
@@ -716,12 +779,14 @@ pub fn fields(page: Page) -> Vec<Field> {
"theme.geometry.focus_ring_width",
"Focus border",
"A subtle outline around the active window.",
2.0,
0.0,
4.0,
0.5,
" px",
false,
RangeSpec {
default: 2.0,
min: 0.0,
max: 4.0,
step: 0.5,
suffix: " px",
integer: false,
},
),
],
Page::Wallpaper => vec![
@@ -757,12 +822,14 @@ pub fn fields(page: Page) -> Vec<Field> {
"notifications.timeout_ms",
"Popup timeout",
"Default duration; apps can request another timeout. Pauses while hovered.",
6000.0,
1000.0,
30000.0,
1000.0,
" ms",
true,
RangeSpec {
default: 6000.0,
min: 1000.0,
max: 30000.0,
step: 1000.0,
suffix: " ms",
integer: true,
},
),
],
Page::Bar => vec![
@@ -776,45 +843,53 @@ pub fn fields(page: Page) -> Vec<Field> {
"theme.geometry.top_bar_height",
"Height",
"Keeps icon and text sizes unchanged.",
28.0,
24.0,
48.0,
1.0,
" px",
false,
RangeSpec {
default: 28.0,
min: 24.0,
max: 48.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
"theme.geometry.top_bar_margin_top",
"Top margin",
"Set to zero for an edge-to-edge bar.",
0.0,
0.0,
24.0,
1.0,
" px",
true,
RangeSpec {
default: 0.0,
min: 0.0,
max: 24.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
"theme.geometry.top_bar_margin_horizontal",
"Side margins",
"Space between the bar and the display edges.",
0.0,
0.0,
32.0,
1.0,
" px",
true,
RangeSpec {
default: 0.0,
min: 0.0,
max: 32.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
range(
"theme.geometry.top_bar_window_gap",
"Window clearance",
"Space below the menu bar.",
0.0,
0.0,
24.0,
1.0,
" px",
true,
RangeSpec {
default: 0.0,
min: 0.0,
max: 24.0,
step: 1.0,
suffix: " px",
integer: true,
},
),
toggle(
"status.battery_percentage",
@@ -852,45 +927,53 @@ pub fn fields(page: Page) -> Vec<Field> {
"scrolling.default_column_width",
"New window width",
"Fraction of the available workspace.",
0.5,
0.25,
1.0,
0.05,
"",
false,
RangeSpec {
default: 0.5,
min: 0.25,
max: 1.0,
step: 0.05,
suffix: "",
integer: false,
},
),
range(
"layout.inner_gap",
"Between windows",
"Space between neighboring windows.",
10.0,
0.0,
32.0,
1.0,
" px",
false,
RangeSpec {
default: 10.0,
min: 0.0,
max: 32.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
"layout.outer_gap",
"Workspace edges",
"Space around the outside of the layout.",
4.0,
0.0,
32.0,
1.0,
" px",
false,
RangeSpec {
default: 4.0,
min: 0.0,
max: 32.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
range(
"theme.geometry.window_radius",
"Corner radius",
"Rounded corners for application windows.",
14.0,
0.0,
28.0,
1.0,
" px",
false,
RangeSpec {
default: 14.0,
min: 0.0,
max: 28.0,
step: 1.0,
suffix: " px",
integer: false,
},
),
toggle(
"appearance.inactive_dim.enabled",
@@ -902,12 +985,14 @@ pub fn fields(page: Page) -> Vec<Field> {
"appearance.inactive_dim.amount",
"Dimming amount",
"How much inactive windows recede.",
0.15,
0.0,
0.5,
0.01,
"",
false,
RangeSpec {
default: 0.15,
min: 0.0,
max: 0.5,
step: 0.01,
suffix: "",
integer: false,
},
),
],
Page::Motion => vec![
@@ -921,23 +1006,27 @@ pub fn fields(page: Page) -> Vec<Field> {
"animations.speed",
"Animation speed",
"Lower values give transitions more time.",
1.0,
0.25,
2.0,
0.05,
"×",
false,
RangeSpec {
default: 1.0,
min: 0.25,
max: 2.0,
step: 0.05,
suffix: "×",
integer: false,
},
),
range(
"appearance.inactive_dim.duration_ms",
"Focus transition",
"Time taken to dim an inactive window.",
150.0,
0.0,
600.0,
10.0,
" ms",
false,
RangeSpec {
default: 150.0,
min: 0.0,
max: 600.0,
step: 10.0,
suffix: " ms",
integer: false,
},
),
],
Page::Keyboard => vec![
@@ -957,23 +1046,27 @@ pub fn fields(page: Page) -> Vec<Field> {
"input.repeat_rate",
"Key repeat",
"Characters repeated each second while a key is held.",
25.0,
1.0,
70.0,
1.0,
" /s",
true,
RangeSpec {
default: 25.0,
min: 1.0,
max: 70.0,
step: 1.0,
suffix: " /s",
integer: true,
},
),
range(
"input.repeat_delay_ms",
"Delay before repeat",
"How long to hold a key before it starts repeating.",
600.0,
150.0,
1000.0,
25.0,
" ms",
true,
RangeSpec {
default: 600.0,
min: 150.0,
max: 1000.0,
step: 25.0,
suffix: " ms",
integer: true,
},
),
toggle(
"input.focus_follows_mouse",
@@ -1003,12 +1096,14 @@ pub fn fields(page: Page) -> Vec<Field> {
"input.touchpad.swipe_threshold",
"Swipe distance",
"Distance needed to navigate. Larger values reduce accidental swipes.",
80.0,
16.0,
1000.0,
8.0,
" px",
true,
RangeSpec {
default: 80.0,
min: 16.0,
max: 1000.0,
step: 8.0,
suffix: " px",
integer: true,
},
),
],
Page::Shortcuts => vec![toggle(
+8 -6
View File
@@ -199,12 +199,14 @@ impl App {
let tile_id = gallery_id(&id, appearance);
tiles = tiles.push(gallery::tile(
family,
appearance,
active,
selected,
palette,
self.font,
tile_id,
gallery::TileOptions {
variant: appearance,
active,
selected,
palette,
font: self.font,
id: tile_id,
},
Message::Family(id, appearance),
move |key| {
gallery::neighbor(index, ids.len(), key)
+12 -8
View File
@@ -294,9 +294,11 @@ mod tests {
fn presets_are_distinct_and_readable_on_settings_surfaces() {
for (index, preset) in PRESETS.iter().enumerate() {
let tokens = ferese_config::theme::preset(preset.id, preset.appearance).unwrap();
let mut theme = ferese_config::theme::ResolvedTheme::default();
theme.appearance = preset.appearance;
theme.tokens = tokens;
let theme = ferese_config::theme::ResolvedTheme {
appearance: preset.appearance,
tokens,
..Default::default()
};
let palette = Palette::from_resolved(&theme);
for background in [palette.background, palette.sidebar, palette.card] {
assert!(contrast(palette.text, background) >= 4.5, "{} text", preset.name);
@@ -313,10 +315,10 @@ mod tests {
#[test]
fn selection_tracks_all_preset_colors_and_gradient_changes() {
for index in 0..PRESETS.len() {
for (index, preset) in PRESETS.iter().enumerate() {
let mut snapshot = configured_preset(index);
assert!(preset_selected(&snapshot, index));
let kind = if PRESETS[index].appearance == ferese_config::theme::Appearance::Light {
let kind = if preset.appearance == ferese_config::theme::Appearance::Light {
"light"
} else {
"dark"
@@ -343,9 +345,11 @@ mod tests {
for (index, item) in PRESETS.iter().enumerate() {
let _ = index;
let mut resolved = ferese_config::theme::ResolvedTheme::default();
resolved.appearance = item.appearance;
resolved.tokens = ferese_config::theme::preset(item.id, item.appearance).unwrap();
let resolved = ferese_config::theme::ResolvedTheme {
appearance: item.appearance,
tokens: ferese_config::theme::preset(item.id, item.appearance).unwrap(),
..Default::default()
};
assert_eq!(
Palette::from_resolved(&resolved).native_theme().cosmic().is_dark,
item.appearance == ferese_config::theme::Appearance::Dark
+3 -3
View File
@@ -1,5 +1,5 @@
//! Watch the parent directory so atomic editor saves keep working.
use std::path::PathBuf;
use std::path::Path;
use std::time::Duration;
use cosmic::iced::futures::{SinkExt, Stream};
@@ -8,8 +8,8 @@ use notify::{RecursiveMode, Watcher};
use crate::Message;
use crate::store::Snapshot;
pub fn changes(path: &PathBuf) -> impl Stream<Item = Message> + use<> {
let path = path.clone();
pub fn changes(path: &Path) -> impl Stream<Item = Message> + use<> {
let path = path.to_path_buf();
cosmic::iced::stream::channel(1, async move |mut output| {
let (send, mut events) = tokio::sync::mpsc::channel(1);