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,
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);
self.direct_backend = Some(backend);
result
} else {
return None;
};
let pixels = result.ok()?;
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 {
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 {
+1 -1
View File
@@ -193,7 +193,7 @@ pub(crate) fn capture_window_frame(
return Err("Incomplete window readback".into());
}
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);
let alpha = pixel[3] as u16;
for channel in &mut pixel[..3] {
+4 -6
View File
@@ -534,15 +534,13 @@ pub fn resolve_with_context(
.get("geometry")
.and_then(|value| value.get("shell_radius"))
.is_none()
{
if let Some(radius) = document
&& let Some(radius) = document
.get("appearance.corner_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;
}
}
let mut value = serde_json::to_value(&tokens).map_err(|e| e.to_string())?;
for file in [&policy.file, &selection.file].into_iter().flatten() {
let path = theme_path(directory, file);
@@ -646,11 +644,11 @@ pub fn theme_path(directory: &Path, path: &Path) -> PathBuf {
} else {
directory.join(path)
};
if let (Some(parent), Some(name)) = (path.parent(), path.file_name()) {
if let Ok(parent) = parent.canonicalize() {
if let (Some(parent), Some(name)) = (path.parent(), path.file_name())
&& let Ok(parent) = parent.canonicalize()
{
return parent.join(name);
}
}
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 {
let text = palette.text;
let muted = palette.muted;
@@ -268,6 +296,40 @@ pub fn filled_button(fill: Color, foreground: Color, radius: f32, opacity: f32)
mod tests {
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]
fn switch_thumb_remains_readable_in_every_preset_and_state() {
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) {
return;
}
if matches!(request.action, accesskit::Action::Focus | accesskit::Action::Click) {
if let Some(message) = self
if matches!(request.action, accesskit::Action::Focus | accesskit::Action::Click)
&& let Some(message) = self
.navigate
.as_ref()
.and_then(|navigate| navigate(&keyboard::key::Named::Enter))
@@ -320,7 +320,6 @@ impl<M: Clone> Widget<M, Theme, Renderer> for Radio<'_, M> {
return;
}
}
}
if matches!(event, Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))) {
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),
..
}) = 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.capture_event();
return;
}
}
}
self.content.as_widget_mut().update(
&mut tree.children[0],
event,
+3 -3
View File
@@ -44,12 +44,12 @@ fn stream() -> impl cosmic::iced::futures::Stream<Item = Snapshot> {
});
while receive.changed().await.is_ok() {
let snapshot = receive.borrow_and_update().clone();
if let Some(snapshot) = snapshot {
if output.send(snapshot).await.is_err() {
if let Some(snapshot) = snapshot
&& output.send(snapshot).await.is_err()
{
return;
}
}
}
drop(cancellation);
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) {
continue;
}
if let Some(program) = entry.get("TryExec").filter(|program| !program.is_empty()) {
if !available(program) {
if let Some(program) = entry.get("TryExec").filter(|program| !program.is_empty())
&& !available(program)
{
continue;
}
}
let parent = std::process::id() as libc::pid_t;
let mut command = Command::new("timeout");
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> {
let source = match std::fs::read_to_string(&path) {
let source = match std::fs::read_to_string(path) {
Ok(source) => source,
Err(error) if error.kind() == std::io::ErrorKind::NotFound => String::new(),
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())?;
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())?;
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());
}
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()),
("session-state".into(), Value::from(phase).try_into().unwrap()),
]);
if let Ok(emitter) = SignalEmitter::new(&connection, PATH) {
if Self::state_changed(
if let Ok(emitter) = SignalEmitter::new(&connection, PATH)
&& Self::state_changed(
&emitter,
OwnedObjectPath::try_from(path.clone()).unwrap(),
values,
@@ -160,7 +160,6 @@ impl Inhibit {
break;
}
}
}
*last = Some((locked, phase, revision, token));
}
}
@@ -344,7 +343,7 @@ impl Inhibit {
{
Ok(2)
} else {
let attempt = async {
async {
let bridge = Bridge::connect().map_err(zbus::fdo::Error::Failed)?;
let result = tokio::select! {
biased;
@@ -403,8 +402,7 @@ impl Inhibit {
}
}
}
.await;
attempt
.await
};
drop(monitors);
self.requests.end(connection, &handle).await;
+1 -3
View File
@@ -165,14 +165,12 @@ impl InputCapture {
if let Some(position) = event["cursor_position"]
.as_array()
.filter(|position| position.len() == 2)
{
if let Ok(position) =
&& let Ok(position) =
Value::from((position[0].as_f64().unwrap_or(0.0), position[1].as_f64().unwrap_or(0.0)))
.try_to_owned()
{
options.insert("cursor_position".into(), position);
}
}
Self::activated(&emitter, path.clone(), options).await
}
Some("deactivated") => {
+3 -3
View File
@@ -128,11 +128,11 @@ impl Settings {
}
async fn read(&self, namespace: &str, key: &str) -> zbus::fdo::Result<OwnedValue> {
if namespace == APPEARANCE {
if let Some(value) = self.0.read().await.values().remove(key) {
if namespace == APPEARANCE
&& let Some(value) = self.0.read().await.values().remove(key)
{
return Ok(value);
}
}
Err(zbus::fdo::Error::InvalidArgs("Unknown setting".into()))
}
+1 -1
View File
@@ -55,7 +55,7 @@ impl Appearance {
.unwrap_or(fallback)
.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 background = string("theme.background.path", ferese_config::default_wallpaper());
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))
.class(ferese_theme::accent_button())
.class(ferese_theme::controls::authentication_button(palette.palette()))
.height(Length::Fixed(36.))
.padding([8, 16])
.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() {
let mut group = column([]).spacing(1);
if self.page == Page::Appearance {
if self.auto_details {
if self.page == Page::Appearance && self.auto_details {
group = group.push(self.auto_controls());
}
}
for field in fields {
if self.page == Page::Appearance
&& (field.path == "theme.mode"
+4 -6
View File
@@ -425,10 +425,9 @@ impl cosmic::Application for FereseShell {
}
self.theme_error = snapshot.error;
}
return self.apply_config(config);
self.apply_config(config)
}
Message::ThemeMode(mode) => {
return cosmic::task::future(async move {
Message::ThemeMode(mode) => cosmic::task::future(async move {
let result = tokio::task::spawn_blocking(move || {
let mut connection = ferese_ipc::theme::Connection::connect().map_err(|e| e.to_string())?;
connection
@@ -438,14 +437,13 @@ impl cosmic::Application for FereseShell {
.await
.unwrap_or_else(|e| Err(e.to_string()));
cosmic::Action::App(Message::ThemeModeSet(result))
});
}
}),
Message::ThemeModeSet(result) => {
if let Err(error) = result {
self.notifications
.service_error("Appearance could not be changed", &error);
}
return Task::none();
Task::none()
}
Message::BeginNoteEdit(id) => {
let mut tasks = vec![self.finish_note_edit()];
-1
View File
@@ -547,7 +547,6 @@ impl FereseShell {
surface.regions.clone(),
self.config.theme.material_radius,
)
.into()
} else {
content
};