styling fix and clippy fixes

This commit is contained in:
Samuel Onoja committed 2026-10-01 08:59:00 +01:00
1 parent 1364ff62b8
commit 4137f787bf
17 files changed
+96 -48

No files matched your search

+2 -3
View File
@@ -242,12 +242,11 @@ impl Ferese {
scale, scale,
cursor.map(|rect| (&*self, rect)), cursor.map(|rect| (&*self, rect)),
) )
} else if let Some(mut backend) = self.direct_backend.take() { } else {
let mut backend = self.direct_backend.take()?;
let result = backend.capture_window_frame(self, &window, &output, cursor); let result = backend.capture_window_frame(self, &window, &output, cursor);
self.direct_backend = Some(backend); self.direct_backend = Some(backend);
result result
} else {
return None;
}; };
let pixels = result.ok()?; let pixels = result.ok()?;
if let Some(toplevel) = window.toplevel() { if let Some(toplevel) = window.toplevel() {
+1 -1
View File
@@ -126,7 +126,7 @@ fn crossed(barrier: &Barrier, edge: Edge, from: (f64, f64), to: (f64, f64)) -> O
} else { } else {
from.0 + (to.0 - from.0) * fraction from.0 + (to.0 - from.0) * fraction
}; };
(fraction >= 0.0 && fraction <= 1.0 && along >= start && along < end).then_some(fraction) ((0.0..=1.0).contains(&fraction) && along >= start && along < end).then_some(fraction)
} }
struct Session { struct Session {
+1 -1
View File
@@ -193,7 +193,7 @@ pub(crate) fn capture_window_frame(
return Err("Incomplete window readback".into()); return Err("Incomplete window readback".into());
} }
let mut pixels = source[..bytes].to_vec(); let mut pixels = source[..bytes].to_vec();
for pixel in pixels.chunks_exact_mut(4) { for pixel in pixels.as_chunks_mut::<4>().0 {
pixel.swap(0, 2); pixel.swap(0, 2);
let alpha = pixel[3] as u16; let alpha = pixel[3] as u16;
for channel in &mut pixel[..3] { for channel in &mut pixel[..3] {
+4 -6
View File
@@ -534,15 +534,13 @@ pub fn resolve_with_context(
.get("geometry") .get("geometry")
.and_then(|value| value.get("shell_radius")) .and_then(|value| value.get("shell_radius"))
.is_none() .is_none()
{ && let Some(radius) = document
if let Some(radius) = document
.get("appearance.corner_radius") .get("appearance.corner_radius")
.and_then(Value::as_f64) .and_then(Value::as_f64)
.or_else(|| document.get("theme.geometry.top_bar_radius").and_then(Value::as_f64)) .or_else(|| document.get("theme.geometry.top_bar_radius").and_then(Value::as_f64))
{ {
tokens.geometry.shell_radius = radius; tokens.geometry.shell_radius = radius;
} }
}
let mut value = serde_json::to_value(&tokens).map_err(|e| e.to_string())?; let mut value = serde_json::to_value(&tokens).map_err(|e| e.to_string())?;
for file in [&policy.file, &selection.file].into_iter().flatten() { for file in [&policy.file, &selection.file].into_iter().flatten() {
let path = theme_path(directory, file); let path = theme_path(directory, file);
@@ -646,11 +644,11 @@ pub fn theme_path(directory: &Path, path: &Path) -> PathBuf {
} else { } else {
directory.join(path) directory.join(path)
}; };
if let (Some(parent), Some(name)) = (path.parent(), path.file_name()) { if let (Some(parent), Some(name)) = (path.parent(), path.file_name())
if let Ok(parent) = parent.canonicalize() { && let Ok(parent) = parent.canonicalize()
{
return parent.join(name); return parent.join(name);
} }
}
path path
} }
+62
View File
@@ -130,6 +130,34 @@ fn styled_button(p: Palette, selected: bool, navigation: bool) -> theme::Button
} }
} }
/// Authentication actions use normal text while enabled and muted text while disabled.
/// Keep the disabled fill neutral so contrast correction cannot make it look active.
pub fn authentication_button(palette: Palette) -> theme::Button {
let paint = move |enabled: bool, interaction: f32, focused: bool| {
let (fill, foreground) = if enabled {
let candidate = mix(palette.accent, palette.text, interaction);
crate::accent_pair(crate::composite(candidate, palette.card), palette.text)
} else {
(crate::composite(palette.card, palette.background), palette.muted)
};
button::Style {
background: Some(Background::Color(fill)),
text_color: Some(foreground),
icon_color: Some(foreground),
border_radius: palette.radius.into(),
outline_width: if focused { 1. } else { 0. },
outline_color: foreground,
..Default::default()
}
};
theme::Button::Custom {
active: Box::new(move |focused, _| paint(true, 0., focused)),
hovered: Box::new(move |focused, _| paint(true, 0.06, focused)),
pressed: Box::new(move |focused, _| paint(true, 0.12, focused)),
disabled: Box::new(move |_| paint(false, 0., false)),
}
}
pub fn authentication_input(palette: Palette) -> theme::TextInput { pub fn authentication_input(palette: Palette) -> theme::TextInput {
let text = palette.text; let text = palette.text;
let muted = palette.muted; let muted = palette.muted;
@@ -268,6 +296,40 @@ pub fn filled_button(fill: Color, foreground: Color, radius: f32, opacity: f32)
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn authentication_button_does_not_reverse_enabled_and_disabled_text() {
use cosmic::widget::button::Catalog;
let palette = Palette {
appearance: ferese_config::theme::Appearance::Dark,
background: Color::from_rgb8(17, 24, 33),
sidebar: Color::from_rgb8(17, 24, 33),
card: Color::from_rgb8(17, 24, 33),
accent: Color::from_rgb8(61, 123, 230),
on_accent: Color::from_rgb8(17, 24, 33),
text: Color::from_rgb8(244, 247, 251),
muted: Color::from_rgb8(135, 147, 162),
error: Color::from_rgb8(235, 98, 98),
radius: 10.,
};
let theme = palette.native_theme();
let class = authentication_button(palette);
for style in [
theme.active(false, false, &class),
theme.hovered(false, false, &class),
theme.pressed(false, false, &class),
] {
assert_eq!(style.text_color, Some(palette.text));
let Some(Background::Color(fill)) = style.background else {
panic!("No fill")
};
assert!(crate::contrast(fill, palette.text) >= 4.5);
}
let disabled = theme.disabled(&class);
assert_eq!(disabled.text_color, Some(palette.muted));
assert_eq!(disabled.background, Some(Background::Color(palette.card)));
}
#[test] #[test]
fn switch_thumb_remains_readable_in_every_preset_and_state() { fn switch_thumb_remains_readable_in_every_preset_and_state() {
for preset in crate::PRESETS { for preset in crate::PRESETS {
+3 -5
View File
@@ -309,8 +309,8 @@ impl<M: Clone> Widget<M, Theme, Renderer> for Radio<'_, M> {
if !iced_accessibility::IdEq::eq(&id.0, &self.id.0) { if !iced_accessibility::IdEq::eq(&id.0, &self.id.0) {
return; return;
} }
if matches!(request.action, accesskit::Action::Focus | accesskit::Action::Click) { if matches!(request.action, accesskit::Action::Focus | accesskit::Action::Click)
if let Some(message) = self && let Some(message) = self
.navigate .navigate
.as_ref() .as_ref()
.and_then(|navigate| navigate(&keyboard::key::Named::Enter)) .and_then(|navigate| navigate(&keyboard::key::Named::Enter))
@@ -320,7 +320,6 @@ impl<M: Clone> Widget<M, Theme, Renderer> for Radio<'_, M> {
return; return;
} }
} }
}
if matches!(event, Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))) { if matches!(event, Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))) {
tree.state.downcast_mut::<Focus>().0 = self.selected && cursor.is_over(layout.bounds()); tree.state.downcast_mut::<Focus>().0 = self.selected && cursor.is_over(layout.bounds());
} }
@@ -344,14 +343,13 @@ impl<M: Clone> Widget<M, Theme, Renderer> for Radio<'_, M> {
key: keyboard::Key::Named(key), key: keyboard::Key::Named(key),
.. ..
}) = event }) = event
&& let Some(message) = self.navigate.as_ref().and_then(|navigate| navigate(key))
{ {
if let Some(message) = self.navigate.as_ref().and_then(|navigate| navigate(key)) {
shell.publish(message); shell.publish(message);
shell.capture_event(); shell.capture_event();
return; return;
} }
} }
}
self.content.as_widget_mut().update( self.content.as_widget_mut().update(
&mut tree.children[0], &mut tree.children[0],
event, event,
+3 -3
View File
@@ -44,12 +44,12 @@ fn stream() -> impl cosmic::iced::futures::Stream<Item = Snapshot> {
}); });
while receive.changed().await.is_ok() { while receive.changed().await.is_ok() {
let snapshot = receive.borrow_and_update().clone(); let snapshot = receive.borrow_and_update().clone();
if let Some(snapshot) = snapshot { if let Some(snapshot) = snapshot
if output.send(snapshot).await.is_err() { && output.send(snapshot).await.is_err()
{
return; return;
} }
} }
}
drop(cancellation); drop(cancellation);
tokio::time::sleep(std::time::Duration::from_secs(1)).await; tokio::time::sleep(std::time::Duration::from_secs(1)).await;
} }
+3 -3
View File
@@ -53,11 +53,11 @@ pub(crate) fn run() -> Result<(), Box<dyn std::error::Error>> {
if !enabled(&entry, &desktop) { if !enabled(&entry, &desktop) {
continue; continue;
} }
if let Some(program) = entry.get("TryExec").filter(|program| !program.is_empty()) { if let Some(program) = entry.get("TryExec").filter(|program| !program.is_empty())
if !available(program) { && !available(program)
{
continue; continue;
} }
}
let parent = std::process::id() as libc::pid_t; let parent = std::process::id() as libc::pid_t;
let mut command = Command::new("timeout"); let mut command = Command::new("timeout");
command command
+2 -2
View File
@@ -702,7 +702,7 @@ fn update_wallpaper(image: &Path, target: &str) -> Result<(), String> {
} }
fn edit_wallpaper(path: &Path, image: &Path, target: &str) -> Result<(), String> { fn edit_wallpaper(path: &Path, image: &Path, target: &str) -> Result<(), String> {
let source = match std::fs::read_to_string(&path) { let source = match std::fs::read_to_string(path) {
Ok(source) => source, Ok(source) => source,
Err(error) if error.kind() == std::io::ErrorKind::NotFound => String::new(), Err(error) if error.kind() == std::io::ErrorKind::NotFound => String::new(),
Err(error) => return Err(error.to_string()), Err(error) => return Err(error.to_string()),
@@ -736,7 +736,7 @@ fn edit_wallpaper(path: &Path, image: &Path, target: &str) -> Result<(), String>
let mut temp = tempfile::NamedTempFile::new_in(parent).map_err(|error| error.to_string())?; let mut temp = tempfile::NamedTempFile::new_in(parent).map_err(|error| error.to_string())?;
std::io::Write::write_all(&mut temp, document.to_string().as_bytes()).map_err(|error| error.to_string())?; std::io::Write::write_all(&mut temp, document.to_string().as_bytes()).map_err(|error| error.to_string())?;
temp.as_file().sync_all().map_err(|error| error.to_string())?; temp.as_file().sync_all().map_err(|error| error.to_string())?;
if std::fs::read_to_string(&path).unwrap_or_default() != source { if std::fs::read_to_string(path).unwrap_or_default() != source {
return Err("Configuration changed; please try again".into()); return Err("Configuration changed; please try again".into());
} }
temp.persist(path).map_err(|error| error.to_string())?; temp.persist(path).map_err(|error| error.to_string())?;
+4 -6
View File
@@ -148,8 +148,8 @@ impl Inhibit {
("screensaver-active".into(), Value::from(locked).try_into().unwrap()), ("screensaver-active".into(), Value::from(locked).try_into().unwrap()),
("session-state".into(), Value::from(phase).try_into().unwrap()), ("session-state".into(), Value::from(phase).try_into().unwrap()),
]); ]);
if let Ok(emitter) = SignalEmitter::new(&connection, PATH) { if let Ok(emitter) = SignalEmitter::new(&connection, PATH)
if Self::state_changed( && Self::state_changed(
&emitter, &emitter,
OwnedObjectPath::try_from(path.clone()).unwrap(), OwnedObjectPath::try_from(path.clone()).unwrap(),
values, values,
@@ -160,7 +160,6 @@ impl Inhibit {
break; break;
} }
} }
}
*last = Some((locked, phase, revision, token)); *last = Some((locked, phase, revision, token));
} }
} }
@@ -344,7 +343,7 @@ impl Inhibit {
{ {
Ok(2) Ok(2)
} else { } else {
let attempt = async { async {
let bridge = Bridge::connect().map_err(zbus::fdo::Error::Failed)?; let bridge = Bridge::connect().map_err(zbus::fdo::Error::Failed)?;
let result = tokio::select! { let result = tokio::select! {
biased; biased;
@@ -403,8 +402,7 @@ impl Inhibit {
} }
} }
} }
.await; .await
attempt
}; };
drop(monitors); drop(monitors);
self.requests.end(connection, &handle).await; self.requests.end(connection, &handle).await;
+1 -3
View File
@@ -165,14 +165,12 @@ impl InputCapture {
if let Some(position) = event["cursor_position"] if let Some(position) = event["cursor_position"]
.as_array() .as_array()
.filter(|position| position.len() == 2) .filter(|position| position.len() == 2)
{ && let Ok(position) =
if let Ok(position) =
Value::from((position[0].as_f64().unwrap_or(0.0), position[1].as_f64().unwrap_or(0.0))) Value::from((position[0].as_f64().unwrap_or(0.0), position[1].as_f64().unwrap_or(0.0)))
.try_to_owned() .try_to_owned()
{ {
options.insert("cursor_position".into(), position); options.insert("cursor_position".into(), position);
} }
}
Self::activated(&emitter, path.clone(), options).await Self::activated(&emitter, path.clone(), options).await
} }
Some("deactivated") => { Some("deactivated") => {
+3 -3
View File
@@ -128,11 +128,11 @@ impl Settings {
} }
async fn read(&self, namespace: &str, key: &str) -> zbus::fdo::Result<OwnedValue> { async fn read(&self, namespace: &str, key: &str) -> zbus::fdo::Result<OwnedValue> {
if namespace == APPEARANCE { if namespace == APPEARANCE
if let Some(value) = self.0.read().await.values().remove(key) { && let Some(value) = self.0.read().await.values().remove(key)
{
return Ok(value); return Ok(value);
} }
}
Err(zbus::fdo::Error::InvalidArgs("Unknown setting".into())) Err(zbus::fdo::Error::InvalidArgs("Unknown setting".into()))
} }
+1 -1
View File
@@ -55,7 +55,7 @@ impl Appearance {
.unwrap_or(fallback) .unwrap_or(fallback)
.to_owned() .to_owned()
}; };
let palette = ferese_theme::Palette::from_resolved(&theme); let palette = ferese_theme::Palette::from_resolved(theme);
let font = string("theme.typography.font_family", "Inter"); let font = string("theme.typography.font_family", "Inter");
let background = string("theme.background.path", ferese_config::default_wallpaper()); let background = string("theme.background.path", ferese_config::default_wallpaper());
let path = string("theme.background.lock_path", &background); let path = string("theme.background.lock_path", &background);
+1 -1
View File
@@ -321,7 +321,7 @@ impl cosmic::Application for Prompt {
}); });
} }
let action = button::custom(ferese_theme::text("Authenticate", palette.font).size(13)) let action = button::custom(ferese_theme::text("Authenticate", palette.font).size(13))
.class(ferese_theme::accent_button()) .class(ferese_theme::controls::authentication_button(palette.palette()))
.height(Length::Fixed(36.)) .height(Length::Fixed(36.))
.padding([8, 16]) .padding([8, 16])
.on_press_maybe((!self.waiting && !self.answer.is_empty()).then_some(Message::Submit)); .on_press_maybe((!self.waiting && !self.answer.is_empty()).then_some(Message::Submit));
+1 -3
View File
@@ -793,11 +793,9 @@ impl cosmic::Application for App {
if !fields.is_empty() { if !fields.is_empty() {
let mut group = column([]).spacing(1); let mut group = column([]).spacing(1);
if self.page == Page::Appearance { if self.page == Page::Appearance && self.auto_details {
if self.auto_details {
group = group.push(self.auto_controls()); group = group.push(self.auto_controls());
} }
}
for field in fields { for field in fields {
if self.page == Page::Appearance if self.page == Page::Appearance
&& (field.path == "theme.mode" && (field.path == "theme.mode"
+4 -6
View File
@@ -425,10 +425,9 @@ impl cosmic::Application for FereseShell {
} }
self.theme_error = snapshot.error; self.theme_error = snapshot.error;
} }
return self.apply_config(config); self.apply_config(config)
} }
Message::ThemeMode(mode) => { Message::ThemeMode(mode) => cosmic::task::future(async move {
return cosmic::task::future(async move {
let result = tokio::task::spawn_blocking(move || { let result = tokio::task::spawn_blocking(move || {
let mut connection = ferese_ipc::theme::Connection::connect().map_err(|e| e.to_string())?; let mut connection = ferese_ipc::theme::Connection::connect().map_err(|e| e.to_string())?;
connection connection
@@ -438,14 +437,13 @@ impl cosmic::Application for FereseShell {
.await .await
.unwrap_or_else(|e| Err(e.to_string())); .unwrap_or_else(|e| Err(e.to_string()));
cosmic::Action::App(Message::ThemeModeSet(result)) cosmic::Action::App(Message::ThemeModeSet(result))
}); }),
}
Message::ThemeModeSet(result) => { Message::ThemeModeSet(result) => {
if let Err(error) = result { if let Err(error) = result {
self.notifications self.notifications
.service_error("Appearance could not be changed", &error); .service_error("Appearance could not be changed", &error);
} }
return Task::none(); Task::none()
} }
Message::BeginNoteEdit(id) => { Message::BeginNoteEdit(id) => {
let mut tasks = vec![self.finish_note_edit()]; let mut tasks = vec![self.finish_note_edit()];
-1
View File
@@ -547,7 +547,6 @@ impl FereseShell {
surface.regions.clone(), surface.regions.clone(),
self.config.theme.material_radius, self.config.theme.material_radius,
) )
.into()
} else { } else {
content content
}; };