diff --git a/AGENTS.md b/AGENTS.md index d0f32d79f..e2252bc88 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,6 +40,12 @@ - Never reach inside a poisoned lock. Use `expect` when the critical section cannot panic, or a fallback that leaves the data alone. Tests that serialize on process-wide state use `test_env::lock()` or a `test_env::Lease`. - `catch_unwind` is reserved for the reviewed worker-isolation sites that carry an `#[expect]` reason. Tests observe panics through a joined scoped thread. - Getters are `foo()`/`foo_mut()`, a fallible constructor is `try_new`, and type lifetimes have descriptive names. Every `unsafe` block has a `// SAFETY:` comment that says why it is sound. +- Convert numbers losslessly with `From` (`f64::from(width)`) wherever it can be called; `const` initializers keep `as`. Take the middle of two values with `midpoint` (`f64::midpoint(a, b)`), which cannot overflow. +- Inline named format arguments: `format!("{name}: {err}")`. +- Use `map_or`, `map_or_else`, `is_some_and`, or `is_ok_and` instead of `map(..).unwrap_or(..)`. Use `let ... else` for a `match` that only unwraps or leaves, and `if let ... else` for a `match` with one pattern and a fallback. +- In doc comments, put identifiers and protocol names in backticks (`wl_output`). Product names that docs write plainly go in `doc-valid-idents` in `clippy.toml`. +- Take raw pointers with `&raw const`/`&raw mut`, change pointer constness with `cast_const`/`cast_mut`, and write the anonymous lifetime in paths (`Formatter<'_>`). Give every `#[ignore]` a reason: `#[ignore = "needs a running Wayland compositor"]`. +- Clippy pedantic lints are enabled one at a time in `Cargo.toml`, never as the whole group, so a toolchain update does not turn on new ones. ## Coupled Changes - Config changes often require `config.example.toml`, `docs/CONFIG.md`, configurator models/views, schema behavior, and tests. diff --git a/Cargo.toml b/Cargo.toml index e93732de4..86203b4f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,37 @@ undocumented_unsafe_blocks = "warn" unnecessary_safety_comment = "warn" unwrap_used = "warn" wildcard_imports = "warn" +# Pedantic lints, adopted one at a time. Most of them have machine-applicable +# fixes, so `cargo clippy --fix` can apply them. +borrow_as_ptr = "warn" +cast_lossless = "warn" +comparison_chain = "warn" +doc_markdown = "warn" +duration_suboptimal_units = "warn" +elidable_lifetime_names = "warn" +explicit_iter_loop = "warn" +if_not_else = "warn" +ignore_without_reason = "warn" +ignored_unit_patterns = "warn" +implicit_clone = "warn" +manual_is_variant_and = "warn" +manual_let_else = "warn" +manual_midpoint = "warn" +manual_string_new = "warn" +map_unwrap_or = "warn" +needless_raw_string_hashes = "warn" +option_as_ref_cloned = "warn" +ptr_cast_constness = "warn" +redundant_else = "warn" +semicolon_if_nothing_returned = "warn" +single_match_else = "warn" +uninlined_format_args = "warn" +unnecessary_debug_formatting = "warn" +unnested_or_patterns = "warn" + +[workspace.lints.rust] +# Write the anonymous lifetime in paths: `Formatter<'_>`, not `Formatter`. +elided_lifetimes_in_paths = "warn" [lints] workspace = true diff --git a/clippy.toml b/clippy.toml index ffaa221b0..741b6353e 100644 --- a/clippy.toml +++ b/clippy.toml @@ -14,3 +14,7 @@ disallowed-methods = [ { path = "std::sync::Mutex::clear_poison", reason = "a poisoned lock may hold broken invariants" }, { path = "std::sync::RwLock::clear_poison", reason = "a poisoned lock may hold broken invariants" }, ] + +# Product and library names that docs may write without backticks. The `..` +# keeps Clippy's default list. +doc-valid-idents = ["GLib", "HarfBuzz", "HiDPI", "JetBrains", "MSBuild", "StatusNotifierItem", "VSync", ".."] diff --git a/configurator/src/app/component.rs b/configurator/src/app/component.rs index 49c939eac..6f7c95bd8 100644 --- a/configurator/src/app/component.rs +++ b/configurator/src/app/component.rs @@ -40,7 +40,7 @@ fn load_app_stylesheet() { } } -/// GApplication id. A valid dotted id is required by GLib; the window still +/// `GApplication` id. A valid dotted id is required by GLib; the window still /// advertises this as its Wayland app-id, so compositor rules and the /// `.desktop` `StartupWMClass` must match it. const APP_ID: &str = "org.wayscriber.Configurator"; diff --git a/configurator/src/app/component/rebuild.rs b/configurator/src/app/component/rebuild.rs index d0021f413..369252009 100644 --- a/configurator/src/app/component/rebuild.rs +++ b/configurator/src/app/component/rebuild.rs @@ -185,23 +185,19 @@ pub(super) fn restore(widgets: &AppWidgets, state: ViewState) { if let (Some(editable), Some(caret)) = (widget.downcast_ref::(), caret) { - match caret.selection { - // `select_region` puts the caret on its second - // argument, and the bounds come back ordered: a - // selection made backwards keeps its active end - // where the caret was. - Some((start, end)) => { - let (anchor, active) = if caret.position == start { - (end, start) - } else { - (start, end) - }; - editable.select_region(anchor, active); - } - None => { - editable.select_region(caret.position, caret.position); - editable.set_position(caret.position); - } + // `select_region` puts the caret on its second argument, + // and the bounds come back ordered: a selection made + // backwards keeps its active end where the caret was. + if let Some((start, end)) = caret.selection { + let (anchor, active) = if caret.position == start { + (end, start) + } else { + (start, end) + }; + editable.select_region(anchor, active); + } else { + editable.select_region(caret.position, caret.position); + editable.set_position(caret.position); } } } diff --git a/configurator/src/app/daemon_setup/hyprland.rs b/configurator/src/app/daemon_setup/hyprland.rs index e6a6213f2..cc3a6afd4 100644 --- a/configurator/src/app/daemon_setup/hyprland.rs +++ b/configurator/src/app/daemon_setup/hyprland.rs @@ -101,8 +101,7 @@ fn read_light_controls_status_from_config_root(config_root: &Path) -> HyprlandLi let main_config_path = main_config_path(config_root); let source_line = source_line_for_include(&include_path); let source_present = fs::read_to_string(&main_config_path) - .map(|content| has_source_line(&content, &source_line)) - .unwrap_or(false); + .is_ok_and(|content| has_source_line(&content, &source_line)); HyprlandLightControlsStatus { include_exists: include_path.exists(), @@ -327,9 +326,7 @@ fn strip_matching_quotes(value: &str) -> &str { fn normalize_source_target(target: &str) -> PathBuf { let expanded = if let Some(stripped) = target.strip_prefix("~/") { - paths::home_dir() - .map(|home| home.join(stripped)) - .unwrap_or_else(|| PathBuf::from(target)) + paths::home_dir().map_or_else(|| PathBuf::from(target), |home| home.join(stripped)) } else { PathBuf::from(target) }; diff --git a/configurator/src/app/daemon_setup/service.rs b/configurator/src/app/daemon_setup/service.rs index 19973534b..e417e601f 100644 --- a/configurator/src/app/daemon_setup/service.rs +++ b/configurator/src/app/daemon_setup/service.rs @@ -54,9 +54,8 @@ pub(super) fn detect_service_unit_path(systemctl_available: bool) -> Option bool { - let capture = match run_command("systemctl", &["--user", "is-enabled", SERVICE_NAME]) { - Ok(capture) => capture, - Err(_) => return false, + let Ok(capture) = run_command("systemctl", &["--user", "is-enabled", SERVICE_NAME]) else { + return false; }; if !capture.success { return false; @@ -66,9 +65,8 @@ pub(super) fn query_service_enabled() -> bool { } pub(super) fn query_service_active() -> bool { - let capture = match run_command("systemctl", &["--user", "is-active", SERVICE_NAME]) { - Ok(capture) => capture, - Err(_) => return false, + let Ok(capture) = run_command("systemctl", &["--user", "is-active", SERVICE_NAME]) else { + return false; }; capture.success && capture.stdout.trim() == "active" } @@ -135,9 +133,7 @@ pub(super) fn install_or_update_user_service() -> Result { } pub(super) fn detect_managed_daemon_portal_runtime_supported() -> bool { - managed_daemon_runtime_capabilities() - .map(|capabilities| capabilities.portal) - .unwrap_or(false) + managed_daemon_runtime_capabilities().is_ok_and(|capabilities| capabilities.portal) } fn managed_daemon_runtime_capabilities() -> Result { diff --git a/configurator/src/app/daemon_workflow.rs b/configurator/src/app/daemon_workflow.rs index eb77c9f40..199aafe6e 100644 --- a/configurator/src/app/daemon_workflow.rs +++ b/configurator/src/app/daemon_workflow.rs @@ -60,10 +60,10 @@ impl DaemonFeedback { trf("Background setup action failed: {}", &[error]) } Self::Action(ActionFeedback::RefreshFailed { previous, error }) => { - let previous = previous - .as_deref() - .map(DaemonFeedback::text) - .unwrap_or_else(|| tr("Background setup action failed.").to_string()); + let previous = previous.as_deref().map_or_else( + || tr("Background setup action failed.").to_string(), + DaemonFeedback::text, + ); trf("{}\nStatus refresh failed: {}", &[&previous, error]) } } diff --git a/configurator/src/app/pages/daemon/groups.rs b/configurator/src/app/pages/daemon/groups.rs index 570b5f4de..481e11b88 100644 --- a/configurator/src/app/pages/daemon/groups.rs +++ b/configurator/src/app/pages/daemon/groups.rs @@ -233,9 +233,9 @@ pub(super) fn light_controls_group( None => set_visible(&path_label, false), } - let capability = status - .map(|status| status.light_shortcut_apply_capability) - .unwrap_or(LightShortcutApplyCapability::Manual); + let capability = status.map_or(LightShortcutApplyCapability::Manual, |status| { + status.light_shortcut_apply_capability + }); let native = capability == LightShortcutApplyCapability::HyprlandNative; set_visible(&native_body, native); set_visible(&manual_label, !native); diff --git a/configurator/src/app/pages/keybindings/mod.rs b/configurator/src/app/pages/keybindings/mod.rs index 75982658a..f8a1e370a 100644 --- a/configurator/src/app/pages/keybindings/mod.rs +++ b/configurator/src/app/pages/keybindings/mod.rs @@ -186,24 +186,21 @@ fn conflict_banner( let revealer_for_bind = revealer.clone(); bindings.push(Box::new(move |app, _summary| { - match &app.shortcuts.conflict() { - Some(conflict) => { - set_label(&label, &conflict.prompt()); - replace.set_label(conflict.replace_label()); - set_accessible_label(&replace, conflict.replace_label()); - let target = conflict.jump_field(); - jump_field.set(target); - set_sensitive(&jump, target.is_some()); - if !revealer_for_bind.reveals_child() { - revealer_for_bind.set_reveal_child(true); - } - set_visible(&revealer_for_bind, true); + if let Some(conflict) = &app.shortcuts.conflict() { + set_label(&label, &conflict.prompt()); + replace.set_label(conflict.replace_label()); + set_accessible_label(&replace, conflict.replace_label()); + let target = conflict.jump_field(); + jump_field.set(target); + set_sensitive(&jump, target.is_some()); + if !revealer_for_bind.reveals_child() { + revealer_for_bind.set_reveal_child(true); } - None => { - jump_field.set(None); - if revealer_for_bind.reveals_child() { - revealer_for_bind.set_reveal_child(false); - } + set_visible(&revealer_for_bind, true); + } else { + jump_field.set(None); + if revealer_for_bind.reveals_child() { + revealer_for_bind.set_reveal_child(false); } } })); diff --git a/configurator/src/app/pages/keybindings/recorder.rs b/configurator/src/app/pages/keybindings/recorder.rs index 3549e0c43..8cdbdf34f 100644 --- a/configurator/src/app/pages/keybindings/recorder.rs +++ b/configurator/src/app/pages/keybindings/recorder.rs @@ -222,16 +222,13 @@ fn attach_button_controller(popover: >k::Popover, sender: &ComponentSender() else { return Propagation::Proceed; }; - let kind = event - .device() - .map(|device| match device.source() { - InputSource::Mouse | InputSource::Touchpad | InputSource::Trackpoint => { - RecorderDeviceKind::Mouse - } - InputSource::Pen => RecorderDeviceKind::Pen, - _ => RecorderDeviceKind::Other, - }) - .unwrap_or(RecorderDeviceKind::Other); + let kind = match event.device().map(|device| device.source()) { + Some(InputSource::Mouse | InputSource::Touchpad | InputSource::Trackpoint) => { + RecorderDeviceKind::Mouse + } + Some(InputSource::Pen) => RecorderDeviceKind::Pen, + _ => RecorderDeviceKind::Other, + }; let modifiers = event.modifier_state(); let recorded = KeyboardModifiers { ctrl: modifiers.contains(ModifierType::CONTROL_MASK), diff --git a/configurator/src/app/pages/keybindings/row.rs b/configurator/src/app/pages/keybindings/row.rs index 80d39b651..9ac474d74 100644 --- a/configurator/src/app/pages/keybindings/row.rs +++ b/configurator/src/app/pages/keybindings/row.rs @@ -268,7 +268,7 @@ pub(super) fn binding_row( .shortcuts .editor() .filter(|editor| editor.field == field); - let editor_text = editing.map(|editor| editor.text.as_str()).unwrap_or(value); + let editor_text = editing.map_or(value, |editor| editor.text.as_str()); let editor_error = editing.and_then(|editor| editor.parse_error()); text_editor.refresh(editing.is_some(), editor_text, editor_error.as_deref()); diff --git a/configurator/src/app/pages/keybindings/text_editor.rs b/configurator/src/app/pages/keybindings/text_editor.rs index d5135942f..04bbdc059 100644 --- a/configurator/src/app/pages/keybindings/text_editor.rs +++ b/configurator/src/app/pages/keybindings/text_editor.rs @@ -97,15 +97,12 @@ impl TextEditorPopover { pub(super) fn refresh(&self, open: bool, text: &str, parse_error: Option<&str>) { set_text_blocked(&self.entry, &self.entry_handler, text); - match parse_error { - Some(message) => { - set_label(&self.error, message); - self.error.set_visible(true); - } - None => { - set_label(&self.error, ""); - self.error.set_visible(false); - } + if let Some(message) = parse_error { + set_label(&self.error, message); + self.error.set_visible(true); + } else { + set_label(&self.error, ""); + self.error.set_visible(false); } if open { if !self.popover.is_visible() { diff --git a/configurator/src/app/pages/keybindings/widgets.rs b/configurator/src/app/pages/keybindings/widgets.rs index d15af9c07..8d30908ae 100644 --- a/configurator/src/app/pages/keybindings/widgets.rs +++ b/configurator/src/app/pages/keybindings/widgets.rs @@ -77,7 +77,7 @@ pub(super) fn connect_clicked( }); } -/// GtkPopover widgets created with `set_parent` are not ordinary children. +/// `GtkPopover` widgets created with `set_parent` are not ordinary children. /// If they are still attached when the parent is destroyed, GTK warns on /// finalize. Unparent in the destroy handler so shutdown stays quiet. pub(super) fn unparent_on_destroy(parent: &impl IsA, popover: >k::Popover) { diff --git a/configurator/src/app/search/summary.rs b/configurator/src/app/search/summary.rs index 5708772e0..f83cafd0b 100644 --- a/configurator/src/app/search/summary.rs +++ b/configurator/src/app/search/summary.rs @@ -62,7 +62,7 @@ fn tab_summary(app: &ConfiguratorApp, tab: TabId) -> Option { TabId::Keybindings => keybinding_matches(app, query, &mut summary), #[cfg(feature = "tablet-input")] TabId::Tablet => { - add_area_if(query, &mut summary, tab, SearchArea::Tablet, TABLET_TERMS) + add_area_if(query, &mut summary, tab, SearchArea::Tablet, TABLET_TERMS); } } } @@ -392,11 +392,11 @@ fn session_matches(app: &ConfiguratorApp, query: &SearchQuery, summary: &mut Tab ); for item in &app.session_catalog.items { let text = format!( - "session saved recent catalog {} {} {} {:?}", + "session saved recent catalog {} {} {} {}", item.display_name, item.path_label, item.created_label(), - item.path, + item.path.display(), ); if query.matches_text(&text) { summary.add_area(SearchArea::SessionCatalog); diff --git a/configurator/src/app/session_catalog/move_file.rs b/configurator/src/app/session_catalog/move_file.rs index 99776a21d..5728e69da 100644 --- a/configurator/src/app/session_catalog/move_file.rs +++ b/configurator/src/app/session_catalog/move_file.rs @@ -93,7 +93,7 @@ fn rollback_moved_artifacts_after_catalog_failure( reason: &str, ) -> Result { match session::rollback_named_session_non_lock_artifacts_move(outcome) { - Ok(_) => Err(trf( + Ok(()) => Err(trf( "Move Session failed because {}; rolled back moved files for {}.", &[&reason, &item.display_name], )), diff --git a/configurator/src/app/session_catalog/tests.rs b/configurator/src/app/session_catalog/tests.rs index 2846e0216..74a088c84 100644 --- a/configurator/src/app/session_catalog/tests.rs +++ b/configurator/src/app/session_catalog/tests.rs @@ -139,9 +139,8 @@ fn inactive_session_reservation_refuses_a_running_daemon() { let _env = EnvGuard::set(&[(XDG_RUNTIME_DIR_ENV, temp.path().as_os_str())]); let _daemon_lock = acquire_runtime_lock_for_clear(RuntimeLockKind::Daemon).unwrap(); - let error = match reserve_inactive_session_operation(SessionCatalogOperation::Move) { - Ok(_) => panic!("a held daemon lock must refuse the operation"), - Err(error) => error, + let Err(error) = reserve_inactive_session_operation(SessionCatalogOperation::Move) else { + panic!("a held daemon lock must refuse the operation"); }; assert!(error.contains("manually started daemon"), "{error}"); diff --git a/configurator/src/app/update/color_picker.rs b/configurator/src/app/update/color_picker.rs index fafadcd47..747c2c599 100644 --- a/configurator/src/app/update/color_picker.rs +++ b/configurator/src/app/update/color_picker.rs @@ -121,7 +121,7 @@ impl ConfiguratorApp { let values = rgb.map(format_rgb255); for (component, value) in values.iter().enumerate() { if let Some(slot) = self.draft.drawing_color.rgb.get_mut(component) { - *slot = value.to_string(); + *slot = value.clone(); } } } @@ -130,7 +130,7 @@ impl ConfiguratorApp { if let Some(entry) = self.draft.drawing_quick_colors.get_mut(index) { for (component, value) in values.iter().enumerate() { if let Some(slot) = entry.color.rgb.get_mut(component) { - *slot = value.to_string(); + *slot = value.clone(); } } } @@ -139,7 +139,7 @@ impl ConfiguratorApp { if let Some(item) = self.draft.boards.items.get_mut(index) { for (component, value) in values.iter().enumerate() { item.background_color - .set_component(component, value.to_string()); + .set_component(component, value.clone()); } } } @@ -148,7 +148,7 @@ impl ConfiguratorApp { for (component, value) in values.iter().enumerate() { item.default_pen_color .color - .set_component(component, value.to_string()); + .set_component(component, value.clone()); } } } @@ -206,7 +206,7 @@ impl ConfiguratorApp { fn apply_quad_rgb(&mut self, field: QuadField, values: &[String; 3], alpha: Option) { for (component, value) in values.iter().enumerate() { - self.draft.set_quad(field, component, value.to_string()); + self.draft.set_quad(field, component, value.clone()); } if let Some(alpha) = alpha { self.draft.set_quad(field, 3, format_float(alpha)); diff --git a/configurator/src/app/update/config/tests.rs b/configurator/src/app/update/config/tests.rs index 86d69d5af..4c385c3e4 100644 --- a/configurator/src/app/update/config/tests.rs +++ b/configurator/src/app/update/config/tests.rs @@ -1519,7 +1519,7 @@ fn check_leave_dirty_draft(close: bool, save_succeeds: bool) { let clean = app.update_message(request.clone()); assert!(matches!( clean.as_slice(), - [Effect::CloseWindow] | [Effect::LoadConfig] + [Effect::CloseWindow | Effect::LoadConfig] )); if !close { app.update_command(CommandMessage::ConfigLoaded(Err("failed reload".into()))); @@ -1554,7 +1554,7 @@ fn check_leave_dirty_draft(close: bool, save_succeeds: bool) { if save_succeeds { assert!(matches!( effects.as_slice(), - [Effect::CloseWindow] | [Effect::LoadConfig] + [Effect::CloseWindow | Effect::LoadConfig] )); } else { assert!(effects.is_empty()); @@ -1564,7 +1564,7 @@ fn check_leave_dirty_draft(close: bool, save_succeeds: bool) { assert!(matches!( app.update_message(Message::LeaveDiscardRequested) .as_slice(), - [Effect::CloseWindow] | [Effect::LoadConfig] + [Effect::CloseWindow | Effect::LoadConfig] )); } } diff --git a/configurator/src/app/update/shortcuts.rs b/configurator/src/app/update/shortcuts.rs index 3ee84f1d4..eea31338c 100644 --- a/configurator/src/app/update/shortcuts.rs +++ b/configurator/src/app/update/shortcuts.rs @@ -108,12 +108,11 @@ impl ConfiguratorApp { let Some(recorder) = self.shortcuts.take_recorder() else { return Vec::new(); }; - match recorder.finish_sequence() { - Some(shortcut) => self.commit_recorded_binding(recorder.field, shortcut), - None => { - self.shortcuts.set_recorder(Some(recorder)); - Vec::new() - } + if let Some(shortcut) = recorder.finish_sequence() { + self.commit_recorded_binding(recorder.field, shortcut) + } else { + self.shortcuts.set_recorder(Some(recorder)); + Vec::new() } } @@ -413,21 +412,18 @@ impl ConfiguratorApp { } fn arm_next_shortcut_conflict(&mut self) { - match next_review_conflict(&self.draft.keybindings) { - Some((field, binding, claimants)) => { - self.select_keybinding_field(field); - self.shortcuts - .set_conflict(Some(PendingShortcutConflict::Recorded { - target: field, - binding, - claimants, - })); - self.status = StatusMessage::info(tr("Review the next conflicting shortcut.")); - } - None => { - self.shortcuts.review = false; - self.status = StatusMessage::success(tr("No remaining shortcut conflicts.")); - } + if let Some((field, binding, claimants)) = next_review_conflict(&self.draft.keybindings) { + self.select_keybinding_field(field); + self.shortcuts + .set_conflict(Some(PendingShortcutConflict::Recorded { + target: field, + binding, + claimants, + })); + self.status = StatusMessage::info(tr("Review the next conflicting shortcut.")); + } else { + self.shortcuts.review = false; + self.status = StatusMessage::success(tr("No remaining shortcut conflicts.")); } } diff --git a/configurator/src/app/update/shortcuts/tests.rs b/configurator/src/app/update/shortcuts/tests.rs index be5f83fb6..99192a817 100644 --- a/configurator/src/app/update/shortcuts/tests.rs +++ b/configurator/src/app/update/shortcuts/tests.rs @@ -611,7 +611,7 @@ fn reset_visible_does_not_touch_fields_outside_the_filter() { let _ = app.handle_shortcut_manager_filter_changed(ShortcutManagerFilter::Unbound); app.draft .keybindings - .set(KeybindingField::ToggleFloatingBadge, "".to_string()); + .set(KeybindingField::ToggleFloatingBadge, String::new()); let _ = app.handle_shortcut_reset_visible_requested(); let _ = app.handle_shortcut_reset_visible_confirmed(); assert_eq!( diff --git a/configurator/src/main.rs b/configurator/src/main.rs index e784d79a3..69e664b7c 100644 --- a/configurator/src/main.rs +++ b/configurator/src/main.rs @@ -17,5 +17,5 @@ fn main() { return; } - app::run(startup) + app::run(startup); } diff --git a/configurator/src/models/color/convert.rs b/configurator/src/models/color/convert.rs index 6437a2795..5a5ef38aa 100644 --- a/configurator/src/models/color/convert.rs +++ b/configurator/src/models/color/convert.rs @@ -7,7 +7,7 @@ fn clamp01(value: f64) -> f64 { } fn parse_component(value: &str, fallback: f64) -> f64 { - value.trim().parse::().map(clamp01).unwrap_or(fallback) + value.trim().parse::().map_or(fallback, clamp01) } pub fn parse_triplet_values(values: &[String; 3]) -> [f64; 3] { diff --git a/configurator/src/models/config/presets.rs b/configurator/src/models/config/presets.rs index 35b2c7350..9a620919c 100644 --- a/configurator/src/models/config/presets.rs +++ b/configurator/src/models/config/presets.rs @@ -40,8 +40,8 @@ pub struct PresetSlotDraft { impl PresetSlotDraft { pub(super) fn from_config(preset: Option<&ToolPresetConfig>, defaults: &Config) -> Self { - match preset { - Some(preset) => Self { + if let Some(preset) = preset { + Self { enabled: true, name: preset.name.clone().unwrap_or_default(), tool: ToolOption::from_tool(preset.tool), @@ -63,12 +63,11 @@ impl PresetSlotDraft { show_status_bar: OverrideOption::from_option(preset.show_status_bar), drag_tools: preset.drag_tools.clone(), tool_settings: preset.tool_settings.clone(), - }, - None => { - let mut slot = Self::default_from_config(defaults); - slot.enabled = false; - slot } + } else { + let mut slot = Self::default_from_config(defaults); + slot.enabled = false; + slot } } diff --git a/configurator/src/models/config/quick_colors.rs b/configurator/src/models/config/quick_colors.rs index b20fe38f1..7ee5aa3b2 100644 --- a/configurator/src/models/config/quick_colors.rs +++ b/configurator/src/models/config/quick_colors.rs @@ -51,7 +51,7 @@ impl QuickColorsDraft { .to_known_color_spec_with_field(&color_field_name(index)) { Ok(color) => next_entries.push(QuickColorConfig { - label: label.to_string(), + label: label.clone(), color, }), Err(error) => errors.push(error), @@ -64,9 +64,7 @@ impl QuickColorsDraft { return; } - let persist_len = if next_entries.len() != effective_entries.len() { - next_entries.len() - } else { + let persist_len = if next_entries.len() == effective_entries.len() { let source_len = config .configured_entry_count() .unwrap_or(config.entries.len()); @@ -76,6 +74,8 @@ impl QuickColorsDraft { .rposition(|(next, previous)| next != previous) .map_or(0, |index| index + 1); source_len.max(changed_len).min(next_entries.len()) + } else { + next_entries.len() }; next_entries.truncate(persist_len); config.set_entries(next_entries); @@ -134,8 +134,7 @@ fn resolved_label(label: &str, index: usize) -> String { let trimmed = label.trim(); if trimmed.is_empty() { QuickColorSlot::from_index(index) - .map(QuickColorSlot::label) - .unwrap_or("Quick color") + .map_or("Quick color", QuickColorSlot::label) .to_string() } else { trimmed.to_string() diff --git a/configurator/src/models/config/render_profiles.rs b/configurator/src/models/config/render_profiles.rs index c7826f2c2..1d276abd0 100644 --- a/configurator/src/models/config/render_profiles.rs +++ b/configurator/src/models/config/render_profiles.rs @@ -273,11 +273,10 @@ fn normalized_hex( RenderProfileMappingSide::To => "to", } ); - match parse_hex_rgb(value) { - Some(color) => Some(format_hex_rgb(color)), - None => { - errors.push(FormError::new(field, tr("Expected #RRGGBB hex color"))); - None - } + if let Some(color) = parse_hex_rgb(value) { + Some(format_hex_rgb(color)) + } else { + errors.push(FormError::new(field, tr("Expected #RRGGBB hex color"))); + None } } diff --git a/configurator/src/models/config/setters.rs b/configurator/src/models/config/setters.rs index 9cc383ff1..f842ee4b7 100644 --- a/configurator/src/models/config/setters.rs +++ b/configurator/src/models/config/setters.rs @@ -341,7 +341,7 @@ impl ConfigDraft { TextField::DrawingMarkerOpacity => self.drawing_marker_opacity = value, TextField::DrawingPenSmoothing => self.drawing_pen_smoothing = value, TextField::DrawingShapeRecognitionSensitivity => { - self.drawing_shape_recognition_sensitivity = value + self.drawing_shape_recognition_sensitivity = value; } TextField::DrawingFontFamily => self.drawing_font_family = value, TextField::DrawingFontWeight => { @@ -389,7 +389,7 @@ impl ConfigDraft { TextField::HelpPadding => self.help_padding = value, TextField::HelpBorderWidth => self.help_border_width = value, TextField::UiCommandPaletteToastDurationMs => { - self.ui_command_palette_toast_duration_ms = value + self.ui_command_palette_toast_duration_ms = value; } TextField::CaptureSaveDirectory => self.capture.save_directory = value, TextField::CaptureFilename => self.capture.filename_template = value, @@ -397,12 +397,12 @@ impl ConfigDraft { TextField::CaptureOcrLanguages => self.capture.ocr_languages = value, TextField::ExportPdfFilenameTemplate => self.export_pdf_filename_template = value, TextField::ExportPdfAllBoardsFilenameTemplate => { - self.export_pdf_all_boards_filename_template = value + self.export_pdf_all_boards_filename_template = value; } TextField::ExportPdfCustomWidth => self.export_pdf_custom_width = value, TextField::ExportPdfCustomHeight => self.export_pdf_custom_height = value, TextField::ExportPdfContentSourcePadding => { - self.export_pdf_content_source_padding = value + self.export_pdf_content_source_padding = value; } TextField::ExportPdfLabelTemplate => self.export_pdf_label_template = value, TextField::ExportPdfLabelFontFamily => self.export_pdf_label_font_family = value, @@ -417,16 +417,16 @@ impl ConfigDraft { TextField::SessionMaxShapesPerFrame => self.session_max_shapes_per_frame = value, TextField::SessionMaxFileSizeMb => self.session_max_file_size_mb = value, TextField::SessionAutoCompressThresholdKb => { - self.session_auto_compress_threshold_kb = value + self.session_auto_compress_threshold_kb = value; } TextField::SessionMaxPersistedUndoDepth => { - self.session_max_persisted_undo_depth = value + self.session_max_persisted_undo_depth = value; } TextField::SessionBackupRetention => self.session_backup_retention = value, TextField::SessionAutosaveIdleMs => self.session_autosave_idle_ms = value, TextField::SessionAutosaveIntervalMs => self.session_autosave_interval_ms = value, TextField::SessionAutosaveFailureBackoffMs => { - self.session_autosave_failure_backoff_ms = value + self.session_autosave_failure_backoff_ms = value; } #[cfg(feature = "tablet-input")] TextField::TabletMinThickness => self.tablet_min_thickness = value, @@ -434,7 +434,7 @@ impl ConfigDraft { TextField::TabletMaxThickness => self.tablet_max_thickness = value, #[cfg(feature = "tablet-input")] TextField::TabletPressureVariationThreshold => { - self.tablet_pressure_variation_threshold = value + self.tablet_pressure_variation_threshold = value; } #[cfg(feature = "tablet-input")] TextField::TabletPressureScaleStep => self.tablet_pressure_thickness_scale_step = value, @@ -454,7 +454,7 @@ impl ConfigDraft { .set_component(index, value), QuadField::LaserColor => self.laser_color.set_component(index, value), QuadField::ExportPdfLabelText => { - self.export_pdf_label_text_color.set_component(index, value) + self.export_pdf_label_text_color.set_component(index, value); } QuadField::ExportPdfLabelBackground => self .export_pdf_label_background_color diff --git a/configurator/src/models/keybindings/analysis.rs b/configurator/src/models/keybindings/analysis.rs index a565c6944..e3ece986b 100644 --- a/configurator/src/models/keybindings/analysis.rs +++ b/configurator/src/models/keybindings/analysis.rs @@ -24,8 +24,9 @@ impl<'draft> ParsedShortcuts<'draft> { self.entries .iter() .find(|(candidate, _)| *candidate == field) - .map(|(_, parsed)| parsed.as_ref().map(Vec::as_slice).map_err(String::as_str)) - .unwrap_or(Ok(&[])) + .map_or(Ok(&[]), |(_, parsed)| { + parsed.as_ref().map(Vec::as_slice).map_err(String::as_str) + }) } pub(super) fn claimants(&self, binding: &Shortcut) -> Vec { diff --git a/configurator/src/models/keybindings/edit.rs b/configurator/src/models/keybindings/edit.rs index 6306e8118..cad597c5b 100644 --- a/configurator/src/models/keybindings/edit.rs +++ b/configurator/src/models/keybindings/edit.rs @@ -191,7 +191,7 @@ mod tests { "[keybindings]\nclear_canvas = []\nredo = []\ntoggle_floating_badge = []\n", )); draft.set(KeybindingField::ClearCanvas, "X".to_string()); - draft.set(KeybindingField::Redo, "".to_string()); + draft.set(KeybindingField::Redo, String::new()); draft.set(KeybindingField::ToggleFloatingBadge, "F8".to_string()); reset_field(&mut draft, &defaults, KeybindingField::ClearCanvas); @@ -299,7 +299,7 @@ mod tests { #[test] fn mouse_and_stylus_strings_append_as_chips() { let (mut draft, _defaults) = draft(); - draft.set(KeybindingField::Undo, "".to_string()); + draft.set(KeybindingField::Undo, String::new()); let binding = Shortcut::parse("Ctrl+MouseBack").expect("parses"); append_binding(&mut draft, KeybindingField::Undo, &binding).expect("append"); assert_eq!( @@ -311,7 +311,7 @@ mod tests { #[test] fn sequences_append_in_storage_form() { let (mut draft, _defaults) = draft(); - draft.set(KeybindingField::Undo, "".to_string()); + draft.set(KeybindingField::Undo, String::new()); let binding = Shortcut::parse("Ctrl+K > Ctrl+C").expect("parses"); append_binding(&mut draft, KeybindingField::Undo, &binding).expect("append"); assert_eq!( diff --git a/configurator/src/models/keybindings/manager.rs b/configurator/src/models/keybindings/manager.rs index a8bf763ee..bc9725382 100644 --- a/configurator/src/models/keybindings/manager.rs +++ b/configurator/src/models/keybindings/manager.rs @@ -532,7 +532,7 @@ mod tests { #[test] fn unbound_filter_is_empty_parsed_lists_only() { let (mut draft, defaults) = drafts(); - draft.set(KeybindingField::ToggleFloatingBadge, "".to_string()); + draft.set(KeybindingField::ToggleFloatingBadge, String::new()); draft.set(KeybindingField::Exit, "Ctrl+Shift".to_string()); let summary = ShortcutManagerSummary::from_drafts(&draft, &defaults); let visible = summary.visible_fields( @@ -578,8 +578,8 @@ mod tests { #[test] fn category_scope_keeps_the_filtered_identity_set() { let (mut draft, defaults) = drafts(); - draft.set(KeybindingField::Undo, "".to_string()); - draft.set(KeybindingField::ClearCanvas, "".to_string()); + draft.set(KeybindingField::Undo, String::new()); + draft.set(KeybindingField::ClearCanvas, String::new()); let summary = ShortcutManagerSummary::from_drafts(&draft, &defaults); let visible = summary.visible_fields( ShortcutManagerFilter::Unbound, diff --git a/configurator/src/models/session.rs b/configurator/src/models/session.rs index fa4b4a98b..a17755094 100644 --- a/configurator/src/models/session.rs +++ b/configurator/src/models/session.rs @@ -256,9 +256,7 @@ impl SessionCatalogItem { } fn optional_catalog_time(epoch_millis: Option) -> String { - epoch_millis - .map(format_catalog_time) - .unwrap_or_else(|| tr("Never").to_string()) + epoch_millis.map_or_else(|| tr("Never").to_string(), format_catalog_time) } #[derive(Debug, Clone, PartialEq, Eq)] @@ -391,10 +389,10 @@ fn default_sibling_target_path(path: &Path, suffix_word: &str) -> PathBuf { .and_then(|name| name.to_str()) .filter(|name| !name.is_empty()) .unwrap_or("session.wayscriber-session"); - let target_name = file_name - .strip_suffix(SESSION_SUFFIX) - .map(|stem| format!("{stem} {suffix_word}{SESSION_SUFFIX}")) - .unwrap_or_else(|| format!("{file_name} {suffix_word}")); + let target_name = file_name.strip_suffix(SESSION_SUFFIX).map_or_else( + || format!("{file_name} {suffix_word}"), + |stem| format!("{stem} {suffix_word}{SESSION_SUFFIX}"), + ); match path .parent() diff --git a/src/about_window/handlers/seat.rs b/src/about_window/handlers/seat.rs index 39d0f11a9..fa70cc5dd 100644 --- a/src/about_window/handlers/seat.rs +++ b/src/about_window/handlers/seat.rs @@ -32,7 +32,7 @@ impl SeatHandler for AboutWindowState { self.themed_pointer = Some(pointer); } Err(err) => { - warn!("Pointer initialized without theme: {}", err); + warn!("Pointer initialized without theme: {err}"); let _ = self.seat_state.get_pointer(qh, &seat); } } diff --git a/src/about_window/handlers/window.rs b/src/about_window/handlers/window.rs index 434507bbc..fbb09769f 100644 --- a/src/about_window/handlers/window.rs +++ b/src/about_window/handlers/window.rs @@ -20,14 +20,12 @@ impl WindowHandler for AboutWindowState { let width = configure .new_size .0 - .map(|w| w.get()) - .unwrap_or(preferred_width) + .map_or(preferred_width, |w| w.get()) .max(1); let height = configure .new_size .1 - .map(|h| h.get()) - .unwrap_or(preferred_height) + .map_or(preferred_height, |h| h.get()) .max(1); if self.width != width || self.height != height { diff --git a/src/about_window/render/draw.rs b/src/about_window/render/draw.rs index fe6460efe..72103f58d 100644 --- a/src/about_window/render/draw.rs +++ b/src/about_window/render/draw.rs @@ -87,23 +87,22 @@ fn backdrop(ctx: &cairo::Context, plan: &Plan, theme: &Theme) { fn header(engine: &UiTextEngine, ctx: &cairo::Context, frame: &Frame<'_>, theme: &Theme) { let plan = frame.plan; - match frame.icon { - Some(icon) => draw_icon(ctx, icon, plan.icon), - None => { - // A themed monogram beats an empty gap when the PNG cannot be - // decoded. - fill_rounded_rect(ctx, plan.icon, CARD_RADIUS, theme.accent); - let style = style(20.0, cairo::FontWeight::Bold); - let x = plan.icon.0 + (plan.icon.2 - advance(engine, style, "W")) / 2.0; - label( - engine, - ctx, - style, - (x, plan.icon.1 + plan.icon.3 * 0.72), - (1.0, 1.0, 1.0, 1.0), - "W", - ); - } + if let Some(icon) = frame.icon { + draw_icon(ctx, icon, plan.icon); + } else { + // A themed monogram beats an empty gap when the PNG cannot be + // decoded. + fill_rounded_rect(ctx, plan.icon, CARD_RADIUS, theme.accent); + let style = style(20.0, cairo::FontWeight::Bold); + let x = plan.icon.0 + (plan.icon.2 - advance(engine, style, "W")) / 2.0; + label( + engine, + ctx, + style, + (x, plan.icon.1 + plan.icon.3 * 0.72), + (1.0, 1.0, 1.0, 1.0), + "W", + ); } label( diff --git a/src/about_window/render/mod.rs b/src/about_window/render/mod.rs index 7b9531550..b61dd6c11 100644 --- a/src/about_window/render/mod.rs +++ b/src/about_window/render/mod.rs @@ -26,9 +26,8 @@ impl AboutWindowState { self.pool = Some(pool); } - let pool = match self.pool.as_mut() { - Some(pool) => pool, - None => return Ok(()), + let Some(pool) = self.pool.as_mut() else { + return Ok(()); }; let (buffer, canvas) = pool .create_buffer( @@ -58,7 +57,7 @@ impl AboutWindowState { let _ = ctx.paint(); ctx.set_operator(cairo::Operator::Over); if self.scale > 1 { - ctx.scale(self.scale as f64, self.scale as f64); + ctx.scale(f64::from(self.scale), f64::from(self.scale)); } draw::draw_about( diff --git a/src/about_window/render/widgets.rs b/src/about_window/render/widgets.rs index b1264644d..57ad31f49 100644 --- a/src/about_window/render/widgets.rs +++ b/src/about_window/render/widgets.rs @@ -141,7 +141,7 @@ pub(super) fn draw_icon( icon: &cairo::ImageSurface, rect: (f64, f64, f64, f64), ) { - let (width, height) = (icon.width() as f64, icon.height() as f64); + let (width, height) = (f64::from(icon.width()), f64::from(icon.height())); if width <= 0.0 || height <= 0.0 { return; } diff --git a/src/app/mod.rs b/src/app/mod.rs index b01f95189..58e531bb8 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -314,9 +314,8 @@ pub fn run(cli: Cli) -> anyhow::Result<()> { if maybe_detach_active(&cli)? { return Ok(()); } - let _overlay_lock = match acquire_overlay_lock()? { - Some(lock) => lock, - None => return Ok(()), + let Some(_overlay_lock) = acquire_overlay_lock()? else { + return Ok(()); }; protocol_v2::publish_ready_from_environment() .context("failed to publish daemon overlay readiness")?; diff --git a/src/app/session.rs b/src/app/session.rs index 1c5967bfd..783038feb 100644 --- a/src/app/session.rs +++ b/src/app/session.rs @@ -84,7 +84,7 @@ pub(crate) fn run_session_cli_commands(cli: &Cli) -> anyhow::Result<()> { println!(" Persist history : {}", inspection.persist_history); if inspection.persist_history { match inspection.history_limit { - Some(limit) => println!(" Max persisted undo depth: {}", limit), + Some(limit) => println!(" Max persisted undo depth: {limit}"), None => println!(" Max persisted undo depth: follows runtime limit"), } } else { @@ -97,21 +97,21 @@ pub(crate) fn run_session_cli_commands(cli: &Cli) -> anyhow::Result<()> { inspection.session_path.display() ); if let Some(identity) = &inspection.active_identity { - println!(" Output identity: {}", identity); + println!(" Output identity: {identity}"); } if inspection.exists { if let Some(size) = inspection.size_bytes { - println!(" Size : {} bytes", size); + println!(" Size : {size} bytes"); } if let Some(ts) = inspection .modified .and_then(|m| time_utils::format_system_time(m, "%Y-%m-%d %H:%M:%S")) { - println!(" Modified : {}", ts); + println!(" Modified : {ts}"); } println!(" Compressed: {}", inspection.compressed); if let Some(version) = inspection.file_version { - println!(" File version: {}", version); + println!(" File version: {version}"); } if let Some(counts) = inspection.frame_counts { println!( @@ -139,7 +139,7 @@ pub(crate) fn run_session_cli_commands(cli: &Cli) -> anyhow::Result<()> { println!(" Backup file : {}", inspection.backup_path.display()); if inspection.backup_exists { if let Some(size) = inspection.backup_size_bytes { - println!(" Size : {} bytes", size); + println!(" Size : {size} bytes"); } } else { println!(" (not found)"); diff --git a/src/app/usage.rs b/src/app/usage.rs index 3e6020c25..5e0a47f1d 100644 --- a/src/app/usage.rs +++ b/src/app/usage.rs @@ -7,7 +7,7 @@ fn default_action_bindings() -> HashMap> { match KeybindingsConfig::default().build_action_bindings() { Ok(bindings) => bindings, Err(err) => { - log::warn!("Failed to build default keybindings: {}", err); + log::warn!("Failed to build default keybindings: {err}"); HashMap::new() } } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 3c073fa83..d977acad8 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -58,7 +58,7 @@ mod tests { use std::env; #[test] - #[ignore] + #[ignore = "needs a running Wayland compositor"] fn wayland_backend_smoke_test() { if env::var(super::WAYLAND_DISPLAY_ENV).is_err() { eprintln!( diff --git a/src/backend/wayland/backend/event_loop/capture.rs b/src/backend/wayland/backend/event_loop/capture.rs index e23eecc1b..b5081a7c1 100644 --- a/src/backend/wayland/backend/event_loop/capture.rs +++ b/src/backend/wayland/backend/event_loop/capture.rs @@ -176,7 +176,7 @@ pub(super) fn handle_pending_actions( InputEffect::KeybindingEdit(request) => state.handle_keybinding_edit(request), InputEffect::Backend(action) => apply_backend_effect(state, action), InputEffect::ClipboardFallbackSave(request) => { - state.start_clipboard_fallback_save(request) + state.start_clipboard_fallback_save(request); } InputEffect::FrozenPass { user_requested } => { handle_frozen_toggle(state, user_requested); @@ -253,9 +253,7 @@ fn frozen_toggle_pass_decision( frozen_active: bool, frozen_enabled: bool, ) -> FrozenTogglePassDecision { - let user_action = if !user_toggle { - FrozenUserToggleAction::None - } else { + let user_action = if user_toggle { match slot { Some(record) if record.stage == AcquisitionStage::Queued @@ -268,6 +266,8 @@ fn frozen_toggle_pass_decision( None if !frozen_enabled => FrozenUserToggleAction::ReportUnavailable, None => FrozenUserToggleAction::RequestUserFreeze, } + } else { + FrozenUserToggleAction::None }; FrozenTogglePassDecision { user_action, @@ -367,8 +367,10 @@ fn handle_capture_worker_failure( state.capture.finish_capture_lifecycle(); let message = operation .filter(|operation| *operation == ImageOperationKind::Screenshot) - .map(|_| friendly_capture_error(CaptureFailureKind::Other)) - .unwrap_or_else(|| "Capture services stopped unexpectedly.".to_string()); + .map_or_else( + || "Capture services stopped unexpectedly.".to_string(), + |_| friendly_capture_error(CaptureFailureKind::Other), + ); warn!("Board region capture worker failed: {error}"); state .input_state @@ -702,8 +704,7 @@ fn handle_capture_manager_failure( notification::send_notification_async( &state.tokio_handle, operation - .map(ImageOperationKind::failure_title) - .unwrap_or(tr("Capture failed")) + .map_or(tr("Capture failed"), ImageOperationKind::failure_title) .to_string(), message, Some("dialog-error".to_string()), diff --git a/src/backend/wayland/backend/event_loop/dispatch.rs b/src/backend/wayland/backend/event_loop/dispatch.rs index cd1737745..0d85bb315 100644 --- a/src/backend/wayland/backend/event_loop/dispatch.rs +++ b/src/backend/wayland/backend/event_loop/dispatch.rs @@ -59,7 +59,7 @@ pub(super) fn dispatch_events( |state| route_woken_sources(state, signals), animation_timeout, ) - .map_err(|e| anyhow::anyhow!("Wayland event queue error: {}", e)) + .map_err(|e| anyhow::anyhow!("Wayland event queue error: {e}")) } #[cfg(test)] @@ -134,7 +134,7 @@ mod tests { loop { // SAFETY: pollfd and the runtime wake descriptor stay valid for this // bounded test wait. - let ready = unsafe { libc::poll(&mut pollfd, 1, 1_000) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 1_000) }; if ready > 0 { assert_ne!(pollfd.revents & libc::POLLIN, 0); return; diff --git a/src/backend/wayland/backend/event_loop/mod.rs b/src/backend/wayland/backend/event_loop/mod.rs index e92811b4b..d60795199 100644 --- a/src/backend/wayland/backend/event_loop/mod.rs +++ b/src/backend/wayland/backend/event_loop/mod.rs @@ -109,7 +109,7 @@ pub(super) fn run_event_loop( if let Err(e) = dispatch::dispatch_events(event_queue, state, runtime_wake, signal_state, timeout) { - warn!("Event queue error: {}", e); + warn!("Event queue error: {e}"); loop_error = Some(e); break; } @@ -163,7 +163,7 @@ pub(super) fn run_event_loop( state.cancel_region_capture_for_teardown(); state.finish_clipboard_fallback_saves(); if let Err(err) = session_save::persist_session(state) { - warn!("Failed to save session state: {}", err); + warn!("Failed to save session state: {err}"); session_save::notify_session_failure(state, &err); } // Every exit path funnels here, including the post-dispatch break @@ -256,7 +256,7 @@ fn persist_post_dispatch_state(state: &mut WaylandState) { } } if let Err(err) = session_save::autosave_if_due(state, Instant::now()) { - warn!("Failed to autosave session state: {}", err); + warn!("Failed to autosave session state: {err}"); } if !state.input_state.should_exit { state.reconcile_text_input(); diff --git a/src/backend/wayland/backend/event_loop/render.rs b/src/backend/wayland/backend/event_loop/render.rs index e6afdda54..5b19dba97 100644 --- a/src/backend/wayland/backend/event_loop/render.rs +++ b/src/backend/wayland/backend/event_loop/render.rs @@ -11,7 +11,7 @@ fn min_frame_time_from_fps(max_fps: u32) -> Option { if max_fps == 0 { None } else { - Some(Duration::from_micros(1_000_000 / max_fps as u64)) + Some(Duration::from_micros(1_000_000 / u64::from(max_fps))) } } @@ -134,7 +134,7 @@ pub(super) fn maybe_render( let render_end = Instant::now(); let render_duration = render_end.saturating_duration_since(render_start); if render_duration > Duration::from_millis(5) { - debug!("Render took {:?}", render_duration); + debug!("Render took {render_duration:?}"); } // Reset failure counter and record render time. diff --git a/src/backend/wayland/backend/event_loop/session_save/final_save.rs b/src/backend/wayland/backend/event_loop/session_save/final_save.rs index 465b2a615..3e66b490a 100644 --- a/src/backend/wayland/backend/event_loop/session_save/final_save.rs +++ b/src/backend/wayland/backend/event_loop/session_save/final_save.rs @@ -363,8 +363,7 @@ fn refused_drawings_options(options: &session::SessionOptions) -> session::Sessi .unwrap_or_default(); let mut name = path .file_stem() - .map(OsStr::to_os_string) - .unwrap_or_else(|| "session".into()); + .map_or_else(|| "session".into(), OsStr::to_os_string); name.push(format!(".unsaved-{millis}.wayscriber-session")); let parent = path .parent() diff --git a/src/backend/wayland/backend/event_loop/session_save/interaction.rs b/src/backend/wayland/backend/event_loop/session_save/interaction.rs index cbce10f01..b5e194eef 100644 --- a/src/backend/wayland/backend/event_loop/session_save/interaction.rs +++ b/src/backend/wayland/backend/event_loop/session_save/interaction.rs @@ -62,10 +62,7 @@ pub(super) fn defer_pending_autosave_for_interaction( let delay = runtime_session::interaction_defer_interval(); session.defer_autosave(now, delay); - log::debug!( - "Deferring autosave for {:?} while an input interaction is active", - delay - ); + log::debug!("Deferring autosave for {delay:?} while an input interaction is active"); true } diff --git a/src/backend/wayland/backend/event_loop/session_save/notifications.rs b/src/backend/wayland/backend/event_loop/session_save/notifications.rs index 902aaaa29..edea1f6d9 100644 --- a/src/backend/wayland/backend/event_loop/session_save/notifications.rs +++ b/src/backend/wayland/backend/event_loop/session_save/notifications.rs @@ -267,9 +267,10 @@ fn suggested_limit_mb(projected_written_size: u64, current_limit_bytes: u64) -> } fn config_path_display() -> String { - Config::config_path() - .map(|path| path.display().to_string()) - .unwrap_or_else(|_| "~/.config/wayscriber/config.toml".to_string()) + Config::config_path().map_or_else( + |_| "~/.config/wayscriber/config.toml".to_string(), + |path| path.display().to_string(), + ) } #[cfg(test)] diff --git a/src/backend/wayland/backend/helpers.rs b/src/backend/wayland/backend/helpers.rs index 7f24f75b4..1f1da97e8 100644 --- a/src/backend/wayland/backend/helpers.rs +++ b/src/backend/wayland/backend/helpers.rs @@ -312,8 +312,7 @@ pub(super) fn launched_resume_policy() -> Option { "0" | "false" | "no" | "off" | "disable" | "disabled" => Some(false), _ => { warn!( - "Ignoring invalid {} value '{}'; expected on/off/true/false", - RESUME_SESSION_ENV, raw + "Ignoring invalid {RESUME_SESSION_ENV} value '{raw}'; expected on/off/true/false" ); None } diff --git a/src/backend/wayland/backend/runtime_wake.rs b/src/backend/wayland/backend/runtime_wake.rs index 05db280a9..4b1ad2458 100644 --- a/src/backend/wayland/backend/runtime_wake.rs +++ b/src/backend/wayland/backend/runtime_wake.rs @@ -56,11 +56,9 @@ pub(super) fn poll_with_retry( loop { match attempt(timeout_ms) { Err(err) if err.kind() == io::ErrorKind::Interrupted => { - timeout_ms = deadline - .map(|deadline| { - timeout_to_poll_ms(Some(deadline.saturating_duration_since(Instant::now()))) - }) - .unwrap_or(-1); + timeout_ms = deadline.map_or(-1, |deadline| { + timeout_to_poll_ms(Some(deadline.saturating_duration_since(Instant::now()))) + }); } result => return result, } @@ -102,7 +100,7 @@ impl RuntimeWakeSource { let result = unsafe { libc::read( self.fd.as_raw_fd(), - (&mut value as *mut u64).cast(), + (&raw mut value).cast(), size_of::(), ) }; @@ -135,7 +133,7 @@ impl RuntimeWakeSource { }; // SAFETY: pollfd is valid and the Arc-owned descriptor remains open // throughout this bounded or producer-woken wait. - let ready = unsafe { libc::poll(&mut pollfd, 1, timeout_ms) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, timeout_ms) }; if ready == 0 { return Ok(None); } @@ -159,16 +157,14 @@ impl RuntimeWakeSource { } pub(super) fn timeout_to_poll_ms(timeout: Option) -> i32 { - timeout - .map(|duration| { - // poll(2) accepts integer milliseconds. Round positive fractions - // up so an unexpired deadline never becomes a zero-timeout spin. - duration - .as_nanos() - .div_ceil(1_000_000) - .min(i32::MAX as u128) as i32 - }) - .unwrap_or(-1) + timeout.map_or(-1, |duration| { + // poll(2) accepts integer milliseconds. Round positive fractions + // up so an unexpired deadline never becomes a zero-timeout spin. + duration + .as_nanos() + .div_ceil(1_000_000) + .min(i32::MAX as u128) as i32 + }) } impl RuntimeWakeHandle { @@ -180,7 +176,7 @@ impl RuntimeWakeHandle { let result = unsafe { libc::write( self.fd.as_raw_fd(), - (&value as *const u64).cast(), + (&raw const value).cast(), size_of::(), ) }; @@ -220,7 +216,7 @@ mod tests { revents: 0, }; // SAFETY: pollfd is valid for the duration of this call. - let ready = unsafe { libc::poll(&mut pollfd, 1, timeout_ms) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, timeout_ms) }; assert!(ready >= 0, "poll failed: {}", io::Error::last_os_error()); ready > 0 && pollfd.revents & libc::POLLIN != 0 } diff --git a/src/backend/wayland/backend/setup.rs b/src/backend/wayland/backend/setup.rs index 4b617e098..11fd241c8 100644 --- a/src/backend/wayland/backend/setup.rs +++ b/src/backend/wayland/backend/setup.rs @@ -65,8 +65,7 @@ fn bind_shell_globals( let session_env = env::var(XDG_SESSION_DESKTOP_ENV).unwrap_or_else(|_| "unknown".into()); warn!( - "Layer shell not available: {} (desktop='{}', session='{}'); toolbars will be disabled and xdg fallback may not cover docks/panels.", - err, desktop_env, session_env + "Layer shell not available: {err} (desktop='{desktop_env}', session='{session_env}'); toolbars will be disabled and xdg fallback may not cover docks/panels." ); None } @@ -77,7 +76,7 @@ fn bind_shell_globals( Some(shell) } Err(err) => { - warn!("xdg-shell not available: {}", err); + warn!("xdg-shell not available: {err}"); None } }; @@ -87,7 +86,7 @@ fn bind_shell_globals( Some(state) } Err(err) => { - debug!("xdg-activation not available: {}", err); + debug!("xdg-activation not available: {err}"); None } }; @@ -117,8 +116,7 @@ fn bind_capture_globals( } Err(err) => { warn!( - "zwlr_screencopy_manager_v1 not available; frozen mode may use portal fallback: {}", - err + "zwlr_screencopy_manager_v1 not available; frozen mode may use portal fallback: {err}" ); None } @@ -156,10 +154,7 @@ fn bind_text_input_manager( Some(manager) } Err(err) => { - debug!( - "zwp_text_input_manager_v3 not available; IME disabled: {}", - err - ); + debug!("zwp_text_input_manager_v3 not available; IME disabled: {err}"); None } } diff --git a/src/backend/wayland/backend/signals.rs b/src/backend/wayland/backend/signals.rs index 455448d80..637bb00c8 100644 --- a/src/backend/wayland/backend/signals.rs +++ b/src/backend/wayland/backend/signals.rs @@ -126,7 +126,7 @@ mod tests { revents: 0, }; // SAFETY: source retains the descriptor throughout this bounded wait. - let ready = unsafe { libc::poll(&mut pollfd, 1, 1_000) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 1_000) }; assert_eq!(ready, 1); assert_ne!(pollfd.revents & libc::POLLIN, 0); source.drain().unwrap(); diff --git a/src/backend/wayland/backend/state_init/config.rs b/src/backend/wayland/backend/state_init/config.rs index 7f343c01d..ad3ab4b46 100644 --- a/src/backend/wayland/backend/state_init/config.rs +++ b/src/backend/wayland/backend/state_init/config.rs @@ -85,7 +85,7 @@ pub(super) fn load(backend_exit_mode: ExitAfterCaptureMode) -> LoadedConfig { ) } Err(e) => { - warn!("Failed to load config: {}. Using defaults.", e); + warn!("Failed to load config: {e}. Using defaults."); ( Config::default(), ConfigSource::Default, @@ -407,9 +407,10 @@ fn keybinding_notification_body(entries: &[String], closing: &str) -> String { } fn config_path_display() -> String { - Config::config_path() - .map(|path| path.display().to_string()) - .unwrap_or_else(|_| "~/.config/wayscriber/config.toml".to_string()) + Config::config_path().map_or_else( + |_| "~/.config/wayscriber/config.toml".to_string(), + |path| path.display().to_string(), + ) } fn log_config(config: &Config) { diff --git a/src/backend/wayland/backend/state_init/mod.rs b/src/backend/wayland/backend/state_init/mod.rs index 140177cbf..67f59e4f2 100644 --- a/src/backend/wayland/backend/state_init/mod.rs +++ b/src/backend/wayland/backend/state_init/mod.rs @@ -278,10 +278,10 @@ fn apply_initial_mode( // Apply initial board from CLI (if provided). if let Some(initial_id) = backend.initial_mode.clone() { if input_state.boards.has_board(&initial_id) { - info!("Starting on board '{}'", initial_id); + info!("Starting on board '{initial_id}'"); input_state.switch_board_force_with_measurer(measurer, &initial_id); } else if !initial_id.is_empty() { - warn!("Requested board '{}' not found; using default", initial_id); + warn!("Requested board '{initial_id}' not found; using default"); } } } diff --git a/src/backend/wayland/backend/state_init/output.rs b/src/backend/wayland/backend/state_init/output.rs index 5c8c973f5..874125901 100644 --- a/src/backend/wayland/backend/state_init/output.rs +++ b/src/backend/wayland/backend/state_init/output.rs @@ -18,24 +18,21 @@ pub(super) fn resolve(config: &Config) -> OutputPreferences { .ok() .or_else(|| config.ui.preferred_output.clone()); if let Some(ref output) = preferred_output_identity { - info!( - "Preferring xdg fullscreen on output '{}' (env or config override)", - output - ); + info!("Preferring xdg fullscreen on output '{output}' (env or config override)"); } let mut xdg_fullscreen = env::var(XDG_FULLSCREEN_ENV) .ok() - .map(|v| v == "1" || v.eq_ignore_ascii_case("true")) - .unwrap_or(config.ui.xdg_fullscreen); + .map_or(config.ui.xdg_fullscreen, |v| { + v == "1" || v.eq_ignore_ascii_case("true") + }); let desktop_env = env::var(XDG_CURRENT_DESKTOP_ENV).unwrap_or_default(); let session_env = env::var(XDG_SESSION_DESKTOP_ENV).unwrap_or_default(); let desktop_session = env::var(DESKTOP_SESSION_ENV).unwrap_or_default(); let sway_sock = env::var(SWAYSOCK_ENV).unwrap_or_default(); let niri_socket = env::var(NIRI_SOCKET_ENV).unwrap_or_default(); let force_fullscreen = env::var(XDG_FULLSCREEN_FORCE_ENV) - .map(|v| v == "1" || v.eq_ignore_ascii_case("true")) - .unwrap_or(false); + .is_ok_and(|v| v == "1" || v.eq_ignore_ascii_case("true")); if xdg_fullscreen && desktop_env.to_uppercase().contains("GNOME") && !force_fullscreen { warn!( "GNOME fullscreen xdg fallback is opaque; falling back to maximized. Set {XDG_FULLSCREEN_FORCE_ENV}=1 to force fullscreen anyway." diff --git a/src/backend/wayland/backend/state_init/session.rs b/src/backend/wayland/backend/state_init/session.rs index 589512c6c..b546ca28e 100644 --- a/src/backend/wayland/backend/state_init/session.rs +++ b/src/backend/wayland/backend/state_init/session.rs @@ -72,7 +72,7 @@ fn session_options_for( match session::options_from_config(&config.session, config_dir, display_env.as_deref()) { Ok(opts) => Some(opts), Err(err) => { - warn!("Session persistence disabled: {}", err); + warn!("Session persistence disabled: {err}"); None } } @@ -90,8 +90,7 @@ fn session_options_for( if let Some(options) = session_options.as_mut() { options.force_resume_persistence(); info!( - "Session resume forced on via {} (persisting all boards, history, tool state)", - RESUME_SESSION_ENV + "Session resume forced on via {RESUME_SESSION_ENV} (persisting all boards, history, tool state)" ); } } @@ -101,15 +100,14 @@ fn session_options_for( .is_some_and(session::SessionOptions::is_named_file) { info!( - "Ignoring {}=off because a named session file requires persistence for this run", - RESUME_SESSION_ENV + "Ignoring {RESUME_SESSION_ENV}=off because a named session file requires persistence for this run" ); if let Some(options) = session_options.as_mut() { options.force_resume_persistence(); } } else { if session_options.is_some() { - info!("Session resume disabled via {}=off", RESUME_SESSION_ENV); + info!("Session resume disabled via {RESUME_SESSION_ENV}=off"); } session_options = None; } diff --git a/src/backend/wayland/backend/state_init/tablet.rs b/src/backend/wayland/backend/state_init/tablet.rs index 27c7e93e6..568a9c6a6 100644 --- a/src/backend/wayland/backend/state_init/tablet.rs +++ b/src/backend/wayland/backend/state_init/tablet.rs @@ -27,7 +27,7 @@ pub(super) fn bind_tablet_manager( Some(manager) } Err(err) => { - warn!("Tablet protocol not available: {}", err); + warn!("Tablet protocol not available: {err}"); None } } diff --git a/src/backend/wayland/backend/surface.rs b/src/backend/wayland/backend/surface.rs index 41093f8be..8d4938e00 100644 --- a/src/backend/wayland/backend/surface.rs +++ b/src/backend/wayland/backend/surface.rs @@ -19,7 +19,7 @@ pub(super) fn create_overlay_surface( } if let Some(layer_shell) = state.protocol.layer_shell() { let layer = state.surface.placement().layer(); - info!("Creating layer shell surface in {:?} layer", layer); + info!("Creating layer shell surface in {layer:?} layer"); let layer_surface = layer_shell.create_layer_surface( qh, wl_surface, diff --git a/src/backend/wayland/clipboard/file_list.rs b/src/backend/wayland/clipboard/file_list.rs index dd2217504..df30b8a2b 100644 --- a/src/backend/wayland/clipboard/file_list.rs +++ b/src/backend/wayland/clipboard/file_list.rs @@ -31,7 +31,7 @@ pub(super) fn decode_clipboard_uri_list( let path = match file_uri::decode_file_uri(&uri) { Ok(path) => path, Err(err) => { - log::debug!("Ignoring unsupported clipboard file URI '{}': {}", uri, err); + log::debug!("Ignoring unsupported clipboard file URI '{uri}': {err}"); continue; } }; diff --git a/src/backend/wayland/clipboard/image.rs b/src/backend/wayland/clipboard/image.rs index 8eafe9226..9f072fa5b 100644 --- a/src/backend/wayland/clipboard/image.rs +++ b/src/backend/wayland/clipboard/image.rs @@ -28,7 +28,7 @@ pub(super) fn choose_supported_mime(offered: &[String]) -> Option { pub(super) fn decode_clipboard_image(mime_type: &str, bytes: Vec) -> ClipboardPasteResult { let encoded_bytes = bytes.len(); let Some(format) = format_from_mime_or_bytes(mime_type, &bytes) else { - return ClipboardPasteResult::DecodeFailed(format!("unsupported MIME type {}", mime_type)); + return ClipboardPasteResult::DecodeFailed(format!("unsupported MIME type {mime_type}")); }; let dimensions = match image_dimensions(format, &bytes) { Ok(dimensions) => dimensions, diff --git a/src/backend/wayland/clipboard/system.rs b/src/backend/wayland/clipboard/system.rs index ccec8aa28..92ab38c12 100644 --- a/src/backend/wayland/clipboard/system.rs +++ b/src/backend/wayland/clipboard/system.rs @@ -87,7 +87,7 @@ fn list_mime_types_with_runner( runner: &impl ClipboardCommandRunner, ) -> Result, ClipboardReadError> { let output = runner.list_types().map_err(|err| { - ClipboardReadError::Unavailable(format!("Failed to spawn wl-paste: {}", err)) + ClipboardReadError::Unavailable(format!("Failed to spawn wl-paste: {err}")) })?; if !output.timed_out && output.status == 0 { @@ -110,8 +110,7 @@ fn list_mime_types_with_runner( )) } else { Err(ClipboardReadError::Other(format!( - "wl-paste --list-types failed: {}", - stderr + "wl-paste --list-types failed: {stderr}" ))) } } @@ -213,9 +212,9 @@ fn read_limited(mut reader: R, limit: usize) -> Result, Clipboa let mut data = Vec::new(); let mut buffer = [0u8; 8192]; loop { - let read = reader.read(&mut buffer).map_err(|err| { - ClipboardReadError::Other(format!("Failed to read clipboard: {}", err)) - })?; + let read = reader + .read(&mut buffer) + .map_err(|err| ClipboardReadError::Other(format!("Failed to read clipboard: {err}")))?; if read == 0 { break; } @@ -242,9 +241,9 @@ fn read_prefix( }); } - let read = reader.read(&mut buffer).map_err(|err| { - ClipboardReadError::Other(format!("Failed to read clipboard: {}", err)) - })?; + let read = reader + .read(&mut buffer) + .map_err(|err| ClipboardReadError::Other(format!("Failed to read clipboard: {err}")))?; if read == 0 { break; } diff --git a/src/backend/wayland/clipboard/transfer.rs b/src/backend/wayland/clipboard/transfer.rs index d18d5012c..1b10bc96c 100644 --- a/src/backend/wayland/clipboard/transfer.rs +++ b/src/backend/wayland/clipboard/transfer.rs @@ -117,7 +117,7 @@ pub(in crate::backend::wayland) fn resolve_selection_clipboard_publish( let copied = match panic::catch_unwind(|| system::publish_selection_clipboard(payload_json)) { Ok(Ok(())) => true, Ok(Err(err)) => { - log::warn!("Selection clipboard publish failed: {}", err); + log::warn!("Selection clipboard publish failed: {err}"); false } Err(_) => { @@ -152,11 +152,7 @@ pub(in crate::backend::wayland) fn resolve_system_clipboard() -> ClipboardPasteR let Some(mime_type) = image::choose_supported_mime(&offered) else { return ClipboardPasteResult::NoSupportedMime { offered }; }; - log::info!( - "Selected clipboard MIME type '{}' from offered {:?}", - mime_type, - offered - ); + log::info!("Selected clipboard MIME type '{mime_type}' from offered {offered:?}"); let limit = if mime_type == WAYSCRIBER_SELECTION_MIME { MAX_CLIPBOARD_SELECTION_BYTES } else { @@ -176,11 +172,10 @@ pub(in crate::backend::wayland) fn resolve_system_clipboard() -> ClipboardPasteR ); if mime_type == WAYSCRIBER_SELECTION_MIME { - return serde_json::from_slice::(&bytes) - .map(ClipboardPasteResult::PrivateSelection) - .unwrap_or_else(|err| { - ClipboardPasteResult::MalformedPrivateSelection(err.to_string()) - }); + return serde_json::from_slice::(&bytes).map_or_else( + |err| ClipboardPasteResult::MalformedPrivateSelection(err.to_string()), + ClipboardPasteResult::PrivateSelection, + ); } if file_list::is_uri_list_mime(&mime_type) { @@ -282,7 +277,7 @@ pub(in crate::backend::wayland) fn plan_paste_completion( }, ), ClipboardPasteResult::ClipboardUnavailable(err) => { - log::warn!("Clipboard unavailable: {}", err); + log::warn!("Clipboard unavailable: {err}"); TransferPlan::action(PasteAction::TryFreshLocalFallbackOrWarn { request, missing_warning: TransferWarning::ClipboardUnavailable, @@ -290,7 +285,7 @@ pub(in crate::backend::wayland) fn plan_paste_completion( }) } ClipboardPasteResult::NoSupportedMime { offered } => { - log::debug!("Unsupported clipboard MIME types: {:?}", offered); + log::debug!("Unsupported clipboard MIME types: {offered:?}"); TransferPlan::with_effects( supersede_request_generation(&request), PasteAction::ShowWarning { @@ -325,7 +320,7 @@ pub(in crate::backend::wayland) fn plan_paste_completion( }, ), ClipboardPasteResult::DecodeFailed(err) => { - log::warn!("Clipboard image decode failed: {}", err); + log::warn!("Clipboard image decode failed: {err}"); TransferPlan::with_effects( supersede_request_generation(&request), PasteAction::ShowWarning { @@ -343,7 +338,7 @@ pub(in crate::backend::wayland) fn plan_paste_completion( }) } ClipboardPasteResult::ClipboardError(err) => { - log::warn!("Clipboard paste error: {}", err); + log::warn!("Clipboard paste error: {err}"); TransferPlan::action(PasteAction::TryFreshLocalFallbackOrWarn { request, missing_warning: TransferWarning::ClipboardError, @@ -351,7 +346,7 @@ pub(in crate::backend::wayland) fn plan_paste_completion( }) } ClipboardPasteResult::MalformedPrivateSelection(err) => { - log::warn!("Malformed Wayscriber clipboard payload: {}", err); + log::warn!("Malformed Wayscriber clipboard payload: {err}"); TransferPlan::with_effects( supersede_request_generation(&request), PasteAction::ShowWarning { diff --git a/src/backend/wayland/config_edits.rs b/src/backend/wayland/config_edits.rs index 30b5137ff..4d0c6e5c0 100644 --- a/src/backend/wayland/config_edits.rs +++ b/src/backend/wayland/config_edits.rs @@ -421,17 +421,16 @@ impl ConfigEditWorker { if finished.is_some() { self.handed_over.pop_front(); } - let completion = match finished { - Some(completion) => completion, + let completion = if let Some(completion) = finished { + completion + } else { // No worker, or none left: nothing older can still arrive, so the // edits it never took come back as failed writes, oldest first. - None => { - let edit = self.staged.pop_front()?; - let reason = self.stop_reason(); - ConfigEditCompletion { - edit, - result: Err(anyhow!("{reason}")), - } + let edit = self.staged.pop_front()?; + let reason = self.stop_reason(); + ConfigEditCompletion { + edit, + result: Err(anyhow!("{reason}")), } }; self.retire_projection(&completion); diff --git a/src/backend/wayland/frozen/capture.rs b/src/backend/wayland/frozen/capture.rs index 9fd22eb14..fa7465223 100644 --- a/src/backend/wayland/frozen/capture.rs +++ b/src/backend/wayland/frozen/capture.rs @@ -223,11 +223,8 @@ impl FrozenState { self.capture_done = false; - let output = match self.active_output.clone() { - Some(out) => out, - None => { - anyhow::bail!("No active output available for frozen capture"); - } + let Some(output) = self.active_output.clone() else { + anyhow::bail!("No active output available for frozen capture"); }; let (source_geometry, target_output_id) = require_verified_capture_source( self.active_geometry.clone(), @@ -270,7 +267,7 @@ impl FrozenState { stride, } => { if let Err(err) = self.on_buffer(format, width, height, stride) { - warn!("Failed to prepare screencopy buffer: {}", err); + warn!("Failed to prepare screencopy buffer: {err}"); return self.fail_wlr_capture(); } } @@ -280,7 +277,7 @@ impl FrozenState { } FrameEvent::BufferDone => { if let Err(err) = self.on_buffer_done() { - warn!("Failed to issue screencopy copy: {}", err); + warn!("Failed to issue screencopy copy: {err}"); return self.fail_wlr_capture(); } } @@ -293,9 +290,8 @@ impl FrozenState { WEnum::Value(v) => v.bits(), WEnum::Unknown(raw) => raw, }; - capture.y_invert = Flags::from_bits(raw_flags) - .map(|f| f.contains(Flags::YInvert)) - .unwrap_or(false); + capture.y_invert = + Flags::from_bits(raw_flags).is_some_and(|f| f.contains(Flags::YInvert)); } } FrameEvent::Ready { .. } => match self.on_ready() { @@ -305,7 +301,7 @@ impl FrozenState { self.finish_stale_direct_capture(input_state); } Err(err) => { - warn!("Frozen capture ready handling failed: {}", err); + warn!("Frozen capture ready handling failed: {err}"); // `on_ready` owns and destroys the completed WLR attempt, // including error paths, so only the fallback decision // remains here. @@ -344,15 +340,17 @@ impl FrozenState { height: u32, stride: u32, ) -> Result<()> { - let capture = match self.direct_capture.as_mut() { - Some(DirectCaptureAttempt::WlrScreencopy { session, .. }) => session, - _ => anyhow::bail!("No WLR capture session present for buffer event"), + let Some(DirectCaptureAttempt::WlrScreencopy { + session: capture, .. + }) = self.direct_capture.as_mut() + else { + anyhow::bail!("No WLR capture session present for buffer event"); }; let format = match format { WEnum::Value(fmt) => fmt, WEnum::Unknown(raw) => { - anyhow::bail!("Unknown wl_shm format {}", raw); + anyhow::bail!("Unknown wl_shm format {raw}"); } }; @@ -376,9 +374,11 @@ impl FrozenState { } fn on_buffer_done(&mut self) -> Result<()> { - let capture = match self.direct_capture.as_mut() { - Some(DirectCaptureAttempt::WlrScreencopy { session, .. }) => session, - _ => anyhow::bail!("No WLR capture session present for buffer_done"), + let Some(DirectCaptureAttempt::WlrScreencopy { + session: capture, .. + }) = self.direct_capture.as_mut() + else { + anyhow::bail!("No WLR capture session present for buffer_done"); }; capture.request_copy(); Ok(()) diff --git a/src/backend/wayland/frozen/image.rs b/src/backend/wayland/frozen/image.rs index a79e92673..41c13bb72 100644 --- a/src/backend/wayland/frozen/image.rs +++ b/src/backend/wayland/frozen/image.rs @@ -51,7 +51,7 @@ pub(in crate::backend::wayland) fn validate_shm_buffer_layout( } impl FrozenImage { - /// Apply the wl_output transform advertised for the captured output. + /// Apply the `wl_output` transform advertised for the captured output. /// /// WLR screencopy buffers are returned in output framebuffer coordinates. /// Frozen/zoom rendering paints them onto a logical surface, so rotated or diff --git a/src/backend/wayland/frozen/portal.rs b/src/backend/wayland/frozen/portal.rs index dffdb0e2e..8d933150d 100644 --- a/src/backend/wayland/frozen/portal.rs +++ b/src/backend/wayland/frozen/portal.rs @@ -242,10 +242,10 @@ impl FrozenState { } } } else { - if !layout_matches { - warn!("Portal capture discarded after the output layout changed"); - } else { + if layout_matches { warn!("Portal capture for inactive output discarded"); + } else { + warn!("Portal capture discarded after the output layout changed"); } if self.queue_portal_layout_retry(target_output, !layout_matches) { return; diff --git a/src/backend/wayland/frozen/state/activation.rs b/src/backend/wayland/frozen/state/activation.rs index 76aa8b5ea..48c068758 100644 --- a/src/backend/wayland/frozen/state/activation.rs +++ b/src/backend/wayland/frozen/state/activation.rs @@ -151,8 +151,7 @@ impl FrozenState { if let FrozenCaptureSource::Portal { .. } = pending.source { let Some(geometry) = pending .source_geometry - .as_ref() - .cloned() + .clone() .and_then(|geometry| geometry.with_revalidated_output_count(live_output_count)) else { let topology_changed = pending diff --git a/src/backend/wayland/frozen/state/direct.rs b/src/backend/wayland/frozen/state/direct.rs index 734e93005..a60e49d92 100644 --- a/src/backend/wayland/frozen/state/direct.rs +++ b/src/backend/wayland/frozen/state/direct.rs @@ -71,8 +71,9 @@ impl DirectCaptureContext { pub(super) fn timeout(&self, now: Instant) -> Duration { self.started_at .checked_add(DIRECT_CAPTURE_TIMEOUT) - .map(|deadline| deadline.saturating_duration_since(now)) - .unwrap_or(Duration::ZERO) + .map_or(Duration::ZERO, |deadline| { + deadline.saturating_duration_since(now) + }) } } diff --git a/src/backend/wayland/frozen_geometry.rs b/src/backend/wayland/frozen_geometry.rs index 477f0578c..1dd569fdb 100644 --- a/src/backend/wayland/frozen_geometry.rs +++ b/src/backend/wayland/frozen_geometry.rs @@ -547,7 +547,7 @@ impl OutputGeometry { /// Crop origin inside a portal/desktop screenshot of `image_width` × /// `image_height`. /// - /// Prefer the walked layout origin. If optional zxdg_output metadata is + /// Prefer the walked layout origin. If optional `zxdg_output` metadata is /// missing, `(0, 0)` is inferred only when topology proves there is a /// single output and the image is that output's physical size. pub fn portal_crop_origin(&self, image_width: u32, image_height: u32) -> Option<(u32, u32)> { diff --git a/src/backend/wayland/handlers/compositor.rs b/src/backend/wayland/handlers/compositor.rs index 79cbca960..f415d3b61 100644 --- a/src/backend/wayland/handlers/compositor.rs +++ b/src/backend/wayland/handlers/compositor.rs @@ -48,7 +48,7 @@ impl CompositorHandler for WaylandState { } let scale = new_factor.max(1); - debug!("Scale factor changed to {}", scale); + debug!("Scale factor changed to {scale}"); self.surface.set_scale(scale); self.refresh_freeze_zoom_geometry(); self.buffer_damage diff --git a/src/backend/wayland/handlers/pointer/cursor.rs b/src/backend/wayland/handlers/pointer/cursor.rs index 4344191d2..f4fdee44f 100644 --- a/src/backend/wayland/handlers/pointer/cursor.rs +++ b/src/backend/wayland/handlers/pointer/cursor.rs @@ -266,7 +266,11 @@ impl WaylandState { } return Some( layout - .cursor_hint_at(mx as f64, my as f64, self.input_state.recent_colors().len()) + .cursor_hint_at( + f64::from(mx), + f64::from(my), + self.input_state.recent_colors().len(), + ) .icon(), ); } diff --git a/src/backend/wayland/handlers/pointer/enter_leave.rs b/src/backend/wayland/handlers/pointer/enter_leave.rs index 1f7afd102..1f54ab477 100644 --- a/src/backend/wayland/handlers/pointer/enter_leave.rs +++ b/src/backend/wayland/handlers/pointer/enter_leave.rs @@ -99,13 +99,13 @@ impl WaylandState { // Don't clear drag state if we're in a move drag - the user may be // dragging the toolbar and their pointer left the toolbar surface. // The drag will continue on the main surface. - if !self.toolbar_drag.is_moving() { + if self.toolbar_drag.is_moving() { + debug!("Preserving move drag state on toolbar leave"); + } else { debug!("Clearing toolbar drag state on leave"); self.finish_toolbar_item_drag(false); self.toolbar_drag.set_item_dragging(false); self.cancel_toolbar_move_drag(); - } else { - debug!("Preserving move drag state on toolbar leave"); } self.toolbar.mark_dirty(); // Ensure pointer-driven visuals (e.g. eraser hover) update once on leave. diff --git a/src/backend/wayland/handlers/pointer/press.rs b/src/backend/wayland/handlers/pointer/press.rs index bb6baedba..c11aea4a8 100644 --- a/src/backend/wayland/handlers/pointer/press.rs +++ b/src/backend/wayland/handlers/pointer/press.rs @@ -377,8 +377,7 @@ fn input_hud_button_label(button: u32) -> String { BTN_RIGHT => tr("Right Click").to_string(), BTN_MIDDLE => tr("Middle Click").to_string(), other => linux::pointer_button(other) - .map(|button| button.name()) - .unwrap_or_else(|| trf("Button {}", &[&other])), + .map_or_else(|| trf("Button {}", &[&other]), |button| button.name()), } } diff --git a/src/backend/wayland/handlers/pointer/release.rs b/src/backend/wayland/handlers/pointer/release.rs index a0f846ae5..beb8c507f 100644 --- a/src/backend/wayland/handlers/pointer/release.rs +++ b/src/backend/wayland/handlers/pointer/release.rs @@ -109,7 +109,7 @@ impl WaylandState { } } ReleaseRoute::Unowned => { - self.release_by_toolbar_state(event, on_toolbar, inline_active, button) + self.release_by_toolbar_state(event, on_toolbar, inline_active, button); } } } @@ -137,7 +137,7 @@ impl WaylandState { self.finish_main_surface_drag(event); return; } - debug!("Button {} released", button); + debug!("Button {button} released"); if self.zoom.active && button == BTN_MIDDLE { if self.zoom.panning { self.zoom.stop_pan(); diff --git a/src/backend/wayland/handlers/screencopy.rs b/src/backend/wayland/handlers/screencopy.rs index 42f8349fb..01466b6f6 100644 --- a/src/backend/wayland/handlers/screencopy.rs +++ b/src/backend/wayland/handlers/screencopy.rs @@ -20,7 +20,7 @@ impl Dispatch for WaylandState { _conn: &Connection, _qh: &QueueHandle, ) { - debug!("Screencopy manager event ignored: {:?}", event); + debug!("Screencopy manager event ignored: {event:?}"); } } diff --git a/src/backend/wayland/handlers/seat.rs b/src/backend/wayland/handlers/seat.rs index 2faf9f437..d6d2f5b7e 100644 --- a/src/backend/wayland/handlers/seat.rs +++ b/src/backend/wayland/handlers/seat.rs @@ -52,7 +52,7 @@ impl SeatHandler for WaylandState { self.pointer.attach_pointer(pointer); } Err(err) => { - warn!("Pointer initialized without theme: {}", err); + warn!("Pointer initialized without theme: {err}"); if self.protocol.seat_mut().get_pointer(qh, &seat).is_ok() { debug!("Pointer initialized without theme fallback"); } @@ -141,7 +141,7 @@ impl WaylandState { release_keyboard(&replaced); } } - Err(err) => warn!("Keyboard initialization failed: {}", err), + Err(err) => warn!("Keyboard initialization failed: {err}"), } } @@ -161,7 +161,7 @@ impl WaylandState { release_touch(&replaced); } } - Err(err) => warn!("Touch initialization failed: {}", err), + Err(err) => warn!("Touch initialization failed: {err}"), } } diff --git a/src/backend/wayland/handlers/tablet/frame.rs b/src/backend/wayland/handlers/tablet/frame.rs index 08aed2400..5fdd9b3ca 100644 --- a/src/backend/wayland/handlers/tablet/frame.rs +++ b/src/backend/wayland/handlers/tablet/frame.rs @@ -354,11 +354,11 @@ impl WaylandState { /// Dispatch the configured action for a stylus barrel button press. fn dispatch_stylus_button_press(&mut self, button: u32) { if let Some(action) = stylus_barrel_action(&self.input_state, button, &self.config.tablet) { - debug!("Stylus button {}: dispatching {:?}", button, action); + debug!("Stylus button {button}: dispatching {action:?}"); self.input_state.clear_pending_sequence(); self.dispatch_input_action(action); } else if linux::stylus_button(button).is_none() { - debug!("Ignoring unknown stylus button {}", button); + debug!("Ignoring unknown stylus button {button}"); } } diff --git a/src/backend/wayland/handlers/tablet/mod.rs b/src/backend/wayland/handlers/tablet/mod.rs index 64bbe91dd..441302e54 100644 --- a/src/backend/wayland/handlers/tablet/mod.rs +++ b/src/backend/wayland/handlers/tablet/mod.rs @@ -1,4 +1,4 @@ -//! Wayland tablet/stylus protocol handling (zwp_tablet_v2). +//! Wayland tablet/stylus protocol handling (`zwp_tablet_v2`). use std::os::fd::OwnedFd; use std::sync::Arc; diff --git a/src/backend/wayland/handlers/tablet/pad.rs b/src/backend/wayland/handlers/tablet/pad.rs index 31e1d3433..2154b2654 100644 --- a/src/backend/wayland/handlers/tablet/pad.rs +++ b/src/backend/wayland/handlers/tablet/pad.rs @@ -24,10 +24,10 @@ impl Dispatch for WaylandState { state.tablet.pad_groups.push(pad_group); } Event::Path { path } => { - debug!("Tablet pad path: {}", path); + debug!("Tablet pad path: {path}"); } Event::Buttons { buttons } => { - debug!("Tablet pad button count: {}", buttons); + debug!("Tablet pad button count: {buttons}"); } Event::Done => { debug!("Tablet pad description complete"); @@ -37,10 +37,7 @@ impl Dispatch for WaylandState { button, state, } => { - debug!( - "Tablet pad button event: index {} -> {:?} @ {}", - button, state, time - ); + debug!("Tablet pad button event: index {button} -> {state:?} @ {time}"); } Event::Enter { serial, @@ -74,12 +71,11 @@ impl Dispatch for WaylandState { fn event_created_child(opcode: u16, qhandle: &QueueHandle) -> Arc { use wayland_protocols::wp::tablet::zv2::client::zwp_tablet_pad_v2::EVT_GROUP_OPCODE; - match opcode { - EVT_GROUP_OPCODE => qhandle.make_data::(()), - _ => { - warn!("Ignoring unknown tablet pad child opcode {}", opcode); - Arc::new(IgnoredObjectData) - } + if opcode == EVT_GROUP_OPCODE { + qhandle.make_data::(()) + } else { + warn!("Ignoring unknown tablet pad child opcode {opcode}"); + Arc::new(IgnoredObjectData) } } } diff --git a/src/backend/wayland/handlers/tablet/pad_group.rs b/src/backend/wayland/handlers/tablet/pad_group.rs index addfb93b8..8544eb3ac 100644 --- a/src/backend/wayland/handlers/tablet/pad_group.rs +++ b/src/backend/wayland/handlers/tablet/pad_group.rs @@ -21,7 +21,7 @@ impl Dispatch for WaylandState { use wayland_protocols::wp::tablet::zv2::client::zwp_tablet_pad_group_v2::Event; match event { Event::Buttons { buttons } => { - debug!("Tablet pad group buttons: {:?}", buttons); + debug!("Tablet pad group buttons: {buttons:?}"); } Event::Ring { ring } => { debug!("Tablet pad ring announced: {:?}", ring.id()); @@ -32,15 +32,14 @@ impl Dispatch for WaylandState { state.tablet.pad_strips.push(strip); } Event::Modes { modes } => { - debug!("Tablet pad group modes: {}", modes); + debug!("Tablet pad group modes: {modes}"); } Event::Done => { debug!("Tablet pad group description complete"); } Event::ModeSwitch { time, serial, mode } => { debug!( - "Tablet pad group mode switch -> mode {} (serial {}, time {})", - mode, serial, time + "Tablet pad group mode switch -> mode {mode} (serial {serial}, time {time})" ); } _ => {} @@ -55,7 +54,7 @@ impl Dispatch for WaylandState { EVT_RING_OPCODE => qhandle.make_data::(()), EVT_STRIP_OPCODE => qhandle.make_data::(()), _ => { - warn!("Ignoring unknown tablet pad group child opcode {}", opcode); + warn!("Ignoring unknown tablet pad group child opcode {opcode}"); Arc::new(IgnoredObjectData) } } diff --git a/src/backend/wayland/handlers/tablet/pad_ring.rs b/src/backend/wayland/handlers/tablet/pad_ring.rs index eca0269c0..08f5c15ea 100644 --- a/src/backend/wayland/handlers/tablet/pad_ring.rs +++ b/src/backend/wayland/handlers/tablet/pad_ring.rs @@ -16,16 +16,16 @@ impl Dispatch for WaylandState { use wayland_protocols::wp::tablet::zv2::client::zwp_tablet_pad_ring_v2::Event; match event { Event::Source { source } => { - debug!("Tablet pad ring source: {:?}", source); + debug!("Tablet pad ring source: {source:?}"); } Event::Angle { degrees } => { - debug!("Tablet pad ring angle: {:?}", degrees); + debug!("Tablet pad ring angle: {degrees:?}"); } Event::Stop => { debug!("Tablet pad ring interaction stopped"); } Event::Frame { time } => { - debug!("Tablet pad ring frame @ {}", time); + debug!("Tablet pad ring frame @ {time}"); } _ => {} } diff --git a/src/backend/wayland/handlers/tablet/pad_strip.rs b/src/backend/wayland/handlers/tablet/pad_strip.rs index 792174dbb..2af353d7e 100644 --- a/src/backend/wayland/handlers/tablet/pad_strip.rs +++ b/src/backend/wayland/handlers/tablet/pad_strip.rs @@ -16,16 +16,16 @@ impl Dispatch for WaylandState { use wayland_protocols::wp::tablet::zv2::client::zwp_tablet_pad_strip_v2::Event; match event { Event::Source { source } => { - debug!("Tablet pad strip source: {:?}", source); + debug!("Tablet pad strip source: {source:?}"); } Event::Position { position } => { - debug!("Tablet pad strip position: {}", position); + debug!("Tablet pad strip position: {position}"); } Event::Stop => { debug!("Tablet pad strip interaction stopped"); } Event::Frame { time } => { - debug!("Tablet pad strip frame @ {}", time); + debug!("Tablet pad strip frame @ {time}"); } _ => {} } diff --git a/src/backend/wayland/handlers/tablet/seat.rs b/src/backend/wayland/handlers/tablet/seat.rs index 130dade45..c64b0601f 100644 --- a/src/backend/wayland/handlers/tablet/seat.rs +++ b/src/backend/wayland/handlers/tablet/seat.rs @@ -57,7 +57,7 @@ impl Dispatch for WaylandState { EVT_TOOL_ADDED_OPCODE => qhandle.make_data::(()), EVT_PAD_ADDED_OPCODE => qhandle.make_data::(()), _ => { - warn!("Ignoring unknown tablet seat child opcode {}", opcode); + warn!("Ignoring unknown tablet seat child opcode {opcode}"); Arc::new(IgnoredObjectData) } } diff --git a/src/backend/wayland/handlers/tablet/tool.rs b/src/backend/wayland/handlers/tablet/tool.rs index 5cdc3dfd2..f1a9fb410 100644 --- a/src/backend/wayland/handlers/tablet/tool.rs +++ b/src/backend/wayland/handlers/tablet/tool.rs @@ -123,10 +123,7 @@ impl WaylandState { fn handle_stylus_proximity_in(&mut self, proxy: &ZwpTabletToolV2, surface: WlSurface) { let tool_id = proxy.id(); let tool_type = self.tablet.tool_types.get(&tool_id).copied(); - debug!( - "Tablet proximity in: tool {:?}, type: {:?}", - tool_id, tool_type - ); + debug!("Tablet proximity in: tool {tool_id:?}, type: {tool_type:?}"); let routed = self.route_input(&surface, (0.0, 0.0)); let on_overlay = routed.surface == InputSurface::Canvas; let on_toolbar = routed.surface == InputSurface::Toolbar; @@ -171,10 +168,7 @@ impl WaylandState { fn handle_stylus_proximity_out(&mut self, proxy: &ZwpTabletToolV2) { let tool_id = proxy.id(); let tool_type = self.tablet.tool_types.get(&tool_id).copied(); - debug!( - "Tablet proximity out: tool {:?}, type: {:?}", - tool_id, tool_type - ); + debug!("Tablet proximity out: tool {tool_id:?}, type: {tool_type:?}"); self.commit_pending_stylus_frame(); self.cancel_region_selection_from(RegionInputSource::Stylus); self.take_retired_stylus_contact(); @@ -211,10 +205,7 @@ impl WaylandState { .set_tool_override_with(self.render.text_measurer(), restored_tool); self.tablet.auto_switched_to_eraser = false; self.tablet.pre_eraser_tool_override = None; - info!( - "Restored previous tool after eraser proximity out: {:?}", - restored_tool - ); + info!("Restored previous tool after eraser proximity out: {restored_tool:?}"); } fn handle_stylus_down(&mut self, conn: &Connection, qh: &QueueHandle) { @@ -521,7 +512,7 @@ impl Dispatch for WaylandState { use crate::backend::wayland::TabletToolType; let physical_type = TabletToolType::from(tool_type); let tool_id = _proxy.id(); - debug!("Tablet tool type: {:?} -> {:?}", tool_id, physical_type); + debug!("Tablet tool type: {tool_id:?} -> {physical_type:?}"); state.tablet.tool_types.insert(tool_id, physical_type); // Note: We don't switch tools here - this event comes during initial @@ -548,7 +539,7 @@ impl Dispatch for WaylandState { debug!("Tablet frame event"); } other => { - debug!("Unhandled tablet tool event: {:?}", other); + debug!("Unhandled tablet tool event: {other:?}"); } } } diff --git a/src/backend/wayland/handlers/xdg.rs b/src/backend/wayland/handlers/xdg.rs index eb22acaa2..f16a4f906 100644 --- a/src/backend/wayland/handlers/xdg.rs +++ b/src/backend/wayland/handlers/xdg.rs @@ -59,13 +59,11 @@ impl WindowHandler for WaylandState { let width = configure .new_size .0 - .map(|w| w.get()) - .unwrap_or(fallback_dimensions.0); + .map_or(fallback_dimensions.0, |w| w.get()); let height = configure .new_size .1 - .map(|h| h.get()) - .unwrap_or(fallback_dimensions.1); + .map_or(fallback_dimensions.1, |h| h.get()); if self.surface.placement().xdg_frozen().requested() { if let Some(output) = self.preferred_fullscreen_output() { @@ -94,14 +92,11 @@ impl WindowHandler for WaylandState { self.refresh_active_output_label(); if self.surface.update_dimensions(width, height) { - info!("xdg window configured: {}x{}", width, height); + info!("xdg window configured: {width}x{height}"); self.buffer_damage .mark_all_full(FullDamageReason::SurfaceResized); } else { - debug!( - "xdg window configure acknowledged without size change ({}x{})", - width, height - ); + debug!("xdg window configure acknowledged without size change ({width}x{height})"); } self.surface.set_configured(true); diff --git a/src/backend/wayland/input_monitor/monitor/worker/tests.rs b/src/backend/wayland/input_monitor/monitor/worker/tests.rs index 7c0c3dfe7..ffb01a10d 100644 --- a/src/backend/wayland/input_monitor/monitor/worker/tests.rs +++ b/src/backend/wayland/input_monitor/monitor/worker/tests.rs @@ -123,7 +123,7 @@ fn default_keymap() -> Option { xkb::Keymap::new_from_names(&context, "", "", "", "", None, xkb::KEYMAP_COMPILE_NO_FLAGS) } -/// evdev KEY_LEFTCTRL. +/// evdev `KEY_LEFTCTRL`. const CTRL_KEYCODE: u32 = 29; /// A press/release pair is reported to xkb once per *keycode*, not once diff --git a/src/backend/wayland/input_monitor/probe.rs b/src/backend/wayland/input_monitor/probe.rs index e5314ea88..8c4ef7d9a 100644 --- a/src/backend/wayland/input_monitor/probe.rs +++ b/src/backend/wayland/input_monitor/probe.rs @@ -145,12 +145,9 @@ fn classify_event_nodes(dir: &Path) -> EventNodeAccess { }; let mut access = EventNodeAccess::None; for entry in entries { - let entry = match entry { - Ok(entry) => entry, - Err(_) => { - access = access.include(NodePathAccess::Unknown); - continue; - } + let Ok(entry) = entry else { + access = access.include(NodePathAccess::Unknown); + continue; }; if !entry .file_name() diff --git a/src/backend/wayland/portal_task.rs b/src/backend/wayland/portal_task.rs index 60349965c..398018fe3 100644 --- a/src/backend/wayland/portal_task.rs +++ b/src/backend/wayland/portal_task.rs @@ -50,8 +50,7 @@ impl PortalOperation { pub(super) fn poll(&mut self) -> PortalPoll { self.active .as_mut() - .map(PortalTask::poll) - .unwrap_or(PortalPoll::Disconnected) + .map_or(PortalPoll::Disconnected, PortalTask::poll) } pub(super) fn timeout(&self, now: Instant) -> Option { self.active.as_ref().map(|task| task.timeout(now)) @@ -142,8 +141,9 @@ where pub(super) fn timeout(&self, now: Instant) -> Duration { self.started_at .checked_add(PORTAL_CAPTURE_TIMEOUT) - .map(|deadline| deadline.saturating_duration_since(now)) - .unwrap_or(Duration::ZERO) + .map_or(Duration::ZERO, |deadline| { + deadline.saturating_duration_since(now) + }) } pub(super) fn timed_out(&self, now: Instant) -> bool { @@ -231,7 +231,7 @@ mod tests { revents: 0, }; // SAFETY: the descriptor and pollfd remain valid during the bounded wait. - assert_eq!(unsafe { libc::poll(&mut pollfd, 1, 1_000) }, 1); + assert_eq!(unsafe { libc::poll(&raw mut pollfd, 1, 1_000) }, 1); } #[tokio::test(flavor = "multi_thread")] @@ -270,7 +270,7 @@ mod tests { revents: 0, }; // SAFETY: the descriptor and pollfd are valid for this non-blocking poll. - let ready = unsafe { libc::poll(&mut pollfd, 1, 0) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 0) }; assert_eq!(ready, 0); } diff --git a/src/backend/wayland/runtime_operation.rs b/src/backend/wayland/runtime_operation.rs index cfbf486b9..4d4c98cf3 100644 --- a/src/backend/wayland/runtime_operation.rs +++ b/src/backend/wayland/runtime_operation.rs @@ -402,7 +402,7 @@ mod tests { revents: 0, }; // SAFETY: pollfd and the runtime wake descriptor remain valid for the bounded wait. - assert_eq!(unsafe { libc::poll(&mut pollfd, 1, 1_000) }, 1); + assert_eq!(unsafe { libc::poll(&raw mut pollfd, 1, 1_000) }, 1); assert_ne!(pollfd.revents & libc::POLLIN, 0); } @@ -598,7 +598,7 @@ mod tests { revents: 0, }; // SAFETY: pollfd and the runtime wake descriptor are valid for this non-blocking poll. - assert_eq!(unsafe { libc::poll(&mut pollfd, 1, 0) }, 0); + assert_eq!(unsafe { libc::poll(&raw mut pollfd, 1, 0) }, 0); assert_eq!( controller .try_submit(42, "test-after-spawn-failure", || 2) diff --git a/src/backend/wayland/runtime_ui_state/board.rs b/src/backend/wayland/runtime_ui_state/board.rs index 72ac0c52d..451013268 100644 --- a/src/backend/wayland/runtime_ui_state/board.rs +++ b/src/backend/wayland/runtime_ui_state/board.rs @@ -82,7 +82,9 @@ impl ToolbarRuntimeState { match self.update_board_seeds(config) { BoardSeedUpdate::Applied => {} BoardSeedUpdate::Staged => { - if pinned != pin_seed { + if pinned == pin_seed { + input.apply_board_pinned_runtime(&board_id, pin_seed); + } else { self.deferred_board_pin_restores.insert( board_id.clone(), DeferredBoardPinRestore { @@ -93,8 +95,6 @@ impl ToolbarRuntimeState { authority_epoch: self.controller.authority_epoch(), }, ); - } else { - input.apply_board_pinned_runtime(&board_id, pin_seed); } return None; } diff --git a/src/backend/wayland/runtime_ui_state/coordinator.rs b/src/backend/wayland/runtime_ui_state/coordinator.rs index 039090a86..8b961060e 100644 --- a/src/backend/wayland/runtime_ui_state/coordinator.rs +++ b/src/backend/wayland/runtime_ui_state/coordinator.rs @@ -70,8 +70,7 @@ impl ToolbarRuntimeState { let startup_incident = bootstrap.startup_incident; if let Some(incident) = startup_incident { log::warn!( - "Runtime UI state started behind recovery barrier {:?}; runtime preference writes are blocked", - incident + "Runtime UI state started behind recovery barrier {incident:?}; runtime preference writes are blocked" ); } let writer = RuntimeUiStateWriter::spawn_with_completion_notifier(store, move || { @@ -679,7 +678,7 @@ impl ToolbarRuntimeState { recovery_artifacts, .. } => self.note_reset_completed(&recovery_artifacts), SubmitSourceMutationResult::Integrated { recovery_artifacts } => { - self.note_recovery_artifacts(&recovery_artifacts) + self.note_recovery_artifacts(&recovery_artifacts); } SubmitSourceMutationResult::Rejected(error) => { self.note_lifecycle_error(format!( diff --git a/src/backend/wayland/runtime_ui_state/rollback.rs b/src/backend/wayland/runtime_ui_state/rollback.rs index d8022a7d2..4cdb6a3c8 100644 --- a/src/backend/wayland/runtime_ui_state/rollback.rs +++ b/src/backend/wayland/runtime_ui_state/rollback.rs @@ -51,44 +51,44 @@ pub(in crate::backend::wayland) fn apply_toolbar_runtime_rollback( } } Target::StatusBarInteractive => { - set_bool(value, |v| input.ui_visibility.status_bar_interactive = v) + set_bool(value, |v| input.ui_visibility.status_bar_interactive = v); } Target::StatusBarItem(item) => set_bool(value, |v| { input.set_status_bar_item_visible_with_resources(engine, measurer, *item, v); }), Target::StatusBar => set_bool(value, |v| input.ui_visibility.show_status_bar = v), Target::StatusBoardBadge => { - set_bool(value, |v| input.ui_visibility.show_status_board_badge = v) + set_bool(value, |v| input.ui_visibility.show_status_board_badge = v); } Target::StatusPageBadge => { - set_bool(value, |v| input.ui_visibility.show_status_page_badge = v) + set_bool(value, |v| input.ui_visibility.show_status_page_badge = v); } Target::FloatingBadgeAlways => set_bool(value, |v| { - input.ui_visibility.show_floating_badge_always = v + input.ui_visibility.show_floating_badge_always = v; }), Target::FloatingBadge => { - set_bool(value, |v| input.ui_visibility.show_floating_badge = v) + set_bool(value, |v| input.ui_visibility.show_floating_badge = v); } Target::ZoomChip => set_bool(value, |v| input.ui_visibility.show_zoom_chip = v), Target::ToolbarIcons => set_bool(value, |v| input.set_toolbar_use_icons(v)), Target::ToolbarMoreColors => { - set_bool(value, |v| input.ui_visibility.show_more_colors = v) + set_bool(value, |v| input.ui_visibility.show_more_colors = v); } Target::ToolbarContextAwareUi => { - set_bool(value, |v| input.ui_visibility.context_aware_ui = v) + set_bool(value, |v| input.ui_visibility.context_aware_ui = v); } Target::ToolbarPresetToasts => { - set_bool(value, |v| input.ui_visibility.show_preset_toasts = v) + set_bool(value, |v| input.ui_visibility.show_preset_toasts = v); } Target::ToolbarIdleFade => set_bool(value, |v| input.ui_visibility.idle_fade = v), Target::ToolbarToolPreview => { - set_bool(value, |v| input.ui_visibility.show_tool_preview = v) + set_bool(value, |v| input.ui_visibility.show_tool_preview = v); } Target::ToolbarDelaySliders => { - set_bool(value, |v| input.ui_visibility.show_delay_sliders = v) + set_bool(value, |v| input.ui_visibility.show_delay_sliders = v); } Target::HistoryCustomSection => set_bool(value, |v| { - input.history_limits.set_custom_section_enabled(v) + input.history_limits.set_custom_section_enabled(v); }), Target::InputHud => set_bool(value, |v| { input.set_input_hud_enabled(v); diff --git a/src/backend/wayland/runtime_ui_state/tests/board_pins.rs b/src/backend/wayland/runtime_ui_state/tests/board_pins.rs index 5d925d013..e1c89218b 100644 --- a/src/backend/wayland/runtime_ui_state/tests/board_pins.rs +++ b/src/backend/wayland/runtime_ui_state/tests/board_pins.rs @@ -125,12 +125,12 @@ fn session_only_board_pin_survives_startup_until_session_identity_is_known() { let runtime_path = temp.path().join("runtime-ui.toml"); fs::write( &runtime_path, - br#"version = 1 + br"version = 1 [boards.pinned.session-board] seed = false value = true -"#, +", ) .unwrap(); let config = Config::default(); @@ -166,12 +166,12 @@ fn absent_provisional_board_pin_is_pruned_after_session_reconciliation() { let runtime_path = temp.path().join("runtime-ui.toml"); fs::write( &runtime_path, - br#"version = 1 + br"version = 1 [boards.pinned.stale-session-board] seed = false value = true -"#, +", ) .unwrap(); let config = Config::default(); @@ -202,12 +202,12 @@ fn newly_created_board_does_not_adopt_a_provisional_session_pin() { let runtime_path = temp.path().join("runtime-ui.toml"); fs::write( &runtime_path, - br#"version = 1 + br"version = 1 [boards.pinned.board-6] seed = false value = true -"#, +", ) .unwrap(); let config = Config::default(); diff --git a/src/backend/wayland/runtime_ui_state/tests/preference_actions.rs b/src/backend/wayland/runtime_ui_state/tests/preference_actions.rs index b08545f24..eef10b07b 100644 --- a/src/backend/wayland/runtime_ui_state/tests/preference_actions.rs +++ b/src/backend/wayland/runtime_ui_state/tests/preference_actions.rs @@ -180,7 +180,7 @@ fn a_rollback_restores_every_durable_chrome_preference() { |i| i.ui_visibility.show_floating_badge_always, |i| { i.ui_visibility.show_floating_badge_always = - !i.ui_visibility.show_floating_badge_always + !i.ui_visibility.show_floating_badge_always; }, ), ( diff --git a/src/backend/wayland/runtime_ui_state/tests/preferences.rs b/src/backend/wayland/runtime_ui_state/tests/preferences.rs index d2a720091..4097d4c60 100644 --- a/src/backend/wayland/runtime_ui_state/tests/preferences.rs +++ b/src/backend/wayland/runtime_ui_state/tests/preferences.rs @@ -105,7 +105,7 @@ fn toolbar_preference_toggles_survive_restart_without_touching_config() { ( ToolbarRuntimeUiPersistenceTarget::ToolbarDelaySliders, |input| { - input.ui_visibility.show_delay_sliders = !input.ui_visibility.show_delay_sliders + input.ui_visibility.show_delay_sliders = !input.ui_visibility.show_delay_sliders; }, ), ( @@ -119,7 +119,7 @@ fn toolbar_preference_toggles_survive_restart_without_touching_config() { ToolbarRuntimeUiPersistenceTarget::FloatingBadgeAlways, |input| { input.ui_visibility.show_floating_badge_always = - !input.ui_visibility.show_floating_badge_always + !input.ui_visibility.show_floating_badge_always; }, ), ]; diff --git a/src/backend/wayland/runtime_ui_state/wayland.rs b/src/backend/wayland/runtime_ui_state/wayland.rs index d1c371bf4..07bd5ec8d 100644 --- a/src/backend/wayland/runtime_ui_state/wayland.rs +++ b/src/backend/wayland/runtime_ui_state/wayland.rs @@ -292,7 +292,7 @@ impl WaylandState { for entry in self.input_state.take_pending_toolbar_persistence() { match entry { PendingToolbarPersistence::DisplayMode { previous } => { - self.persist_toolbar_display_mode(previous) + self.persist_toolbar_display_mode(previous); } PendingToolbarPersistence::Visibility { previous_top_pinned, diff --git a/src/backend/wayland/session.rs b/src/backend/wayland/session.rs index ec58188b6..a4aa02f10 100644 --- a/src/backend/wayland/session.rs +++ b/src/backend/wayland/session.rs @@ -1,7 +1,7 @@ //! Session persistence bookkeeping for per-output snapshots. //! //! Tracks the current session options and whether a snapshot has been loaded -//! so WaylandState can coordinate persistence without storing extra fields. +//! so `WaylandState` can coordinate persistence without storing extra fields. use std::mem; diff --git a/src/backend/wayland/session/persistence.rs b/src/backend/wayland/session/persistence.rs index 02856965f..f26d2ee91 100644 --- a/src/backend/wayland/session/persistence.rs +++ b/src/backend/wayland/session/persistence.rs @@ -511,7 +511,7 @@ mod tests { loop { // SAFETY: pollfd and the runtime-owned descriptor remain valid for // this bounded test wait. - let ready = unsafe { libc::poll(&mut pollfd, 1, 1_000) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 1_000) }; if ready > 0 { assert_ne!(pollfd.revents & libc::POLLIN, 0); return; diff --git a/src/backend/wayland/session/write_policy.rs b/src/backend/wayland/session/write_policy.rs index c80d05b3e..d599f86a9 100644 --- a/src/backend/wayland/session/write_policy.rs +++ b/src/backend/wayland/session/write_policy.rs @@ -17,7 +17,7 @@ impl SessionState { ) { match result { Err(error) | Ok(PersistenceOutcome::RememberedUnavailable(error)) => { - self.block_unpreserved_corruption(error) + self.block_unpreserved_corruption(error); } _ => {} } @@ -47,10 +47,10 @@ impl SessionState { .as_ref() .is_some_and(|options| self.refuses_source_write(&options.session_file_path())); if (!self.loaded || blocked) && dirty { - let refusal = if !self.loaded { - SourceWriteRefused::NotLoaded - } else { + let refusal = if self.loaded { SourceWriteRefused::NotPreserved + } else { + SourceWriteRefused::NotLoaded }; return Err(refusal.into()); } diff --git a/src/backend/wayland/state/acquisition/transaction/tests.rs b/src/backend/wayland/state/acquisition/transaction/tests.rs index 93219f1dc..1c5462e99 100644 --- a/src/backend/wayland/state/acquisition/transaction/tests.rs +++ b/src/backend/wayland/state/acquisition/transaction/tests.rs @@ -448,7 +448,7 @@ fn ready_activation_rejection_releases_the_modal_owned_freeze_once() { RegionPurposeTag::CaptureDeliver, 1, ScreenCaptureSource::Frozen, - ) + ); } ScreenAcquisitionOwner::UserFreeze => unreachable!(), } diff --git a/src/backend/wayland/state/boards.rs b/src/backend/wayland/state/boards.rs index c1d479958..1fc188d9f 100644 --- a/src/backend/wayland/state/boards.rs +++ b/src/backend/wayland/state/boards.rs @@ -8,7 +8,7 @@ impl WaylandState { (0.0, 0.0) } else { let (x, y) = self.input_state.boards.active_frame().view_offset(); - (x as f64, y as f64) + (f64::from(x), f64::from(y)) } } diff --git a/src/backend/wayland/state/buffer_damage.rs b/src/backend/wayland/state/buffer_damage.rs index 8414094ad..f0f092235 100644 --- a/src/backend/wayland/state/buffer_damage.rs +++ b/src/backend/wayland/state/buffer_damage.rs @@ -5,7 +5,7 @@ //! last displayed - not just regions from the current frame. //! //! This module tracks damage per buffer slot, identified by the canvas memory address. -//! SlotPool reuses the same memory regions for released buffers, so the pointer +//! `SlotPool` reuses the same memory regions for released buffers, so the pointer //! serves as a stable slot identifier across buffer reuse. //! //! A pool generation counter handles pool recreation (due to resize, scale change, @@ -105,7 +105,7 @@ pub(in crate::backend::wayland) struct BufferDamageReport { /// Tracks dirty regions for each buffer slot independently. /// /// Buffers are identified by their canvas memory address, which is stable -/// across SlotPool buffer reuse (the same memory slot gets the same pointer). +/// across `SlotPool` buffer reuse (the same memory slot gets the same pointer). /// Pool identity (generation + size) detects when the pool is recreated or /// grows, which invalidates all previous canvas pointers. /// @@ -141,7 +141,7 @@ impl BufferDamageTracker { /// Checks pool identity and resets tracking if pool was recreated or grew. /// - /// When the SlotPool is recreated (generation changes) or grows (size increases), + /// When the `SlotPool` is recreated (generation changes) or grows (size increases), /// all previous canvas pointers become invalid due to memory remapping. fn check_pool_identity(&mut self, generation: u64, pool_size: usize) { let pool_changed = generation != self.pool_generation; @@ -217,12 +217,12 @@ impl BufferDamageTracker { /// Takes damage regions for the buffer identified by its canvas pointer. /// /// The canvas pointer (memory address of the first byte) serves as a stable - /// slot identifier - SlotPool reuses the same memory for released buffers. + /// slot identifier - `SlotPool` reuses the same memory for released buffers. /// /// Pool identity (generation + size) is checked first - if the pool was /// recreated or grew, all tracking is reset since previous pointers are invalid. /// - /// If this is a new slot (or global_full_damage is set), returns full damage. + /// If this is a new slot (or `global_full_damage` is set), returns full damage. /// Otherwise returns and clears the slot's accumulated damage. pub fn take_buffer_damage_report( &mut self, diff --git a/src/backend/wayland/state/canvas_layer.rs b/src/backend/wayland/state/canvas_layer.rs index 2d4cb1a5d..b66a4a44f 100644 --- a/src/backend/wayland/state/canvas_layer.rs +++ b/src/backend/wayland/state/canvas_layer.rs @@ -85,8 +85,8 @@ impl CanvasLayerCache { return false; }; let _ = ctx.save(); - ctx.translate(self.world_x as f64, self.world_y as f64); - let inv = 1.0 / self.scale.max(1) as f64; + ctx.translate(f64::from(self.world_x), f64::from(self.world_y)); + let inv = 1.0 / f64::from(self.scale.max(1)); ctx.scale(inv, inv); let ok = ctx.set_source_surface(surface, 0.0, 0.0).is_ok(); if ok { @@ -306,23 +306,22 @@ impl CanvasLayerCache { bake_ctx.set_source_rgba(color.r, color.g, color.b, color.a); let _ = bake_ctx.paint(); } - bake_ctx.scale(scale as f64, scale as f64); - bake_ctx.translate(-(world_x as f64), -(world_y as f64)); + bake_ctx.scale(f64::from(scale), f64::from(scale)); + bake_ctx.translate(-f64::from(world_x), -f64::from(world_y)); let paper = match background.filter(|_| grid.kind != BoardGridKind::None) { - Some(color) => match BoardPaper::for_context(color, grid, &bake_ctx) { - Ok(paper) => { + Some(color) => { + if let Ok(paper) = BoardPaper::for_context(color, grid, &bake_ctx) { if paper.paint(&bake_ctx).is_err() { cache.clear(); return false; } Some(paper) - } - Err(_) => { + } else { cache.clear(); return false; } - }, + } None => None, }; @@ -380,10 +379,7 @@ impl CanvasLayerCache { cache.text_halo_enabled = text_halo_enabled; cache.board_key = board_key; cache.valid = true; - debug!( - "canvas layer cache: baked {}x{} logical at ({}, {})", - bake_w, bake_h, world_x, world_y - ); + debug!("canvas layer cache: baked {bake_w}x{bake_h} logical at ({world_x}, {world_y})"); true } } diff --git a/src/backend/wayland/state/capture.rs b/src/backend/wayland/state/capture.rs index 165d85228..ee34d3a13 100644 --- a/src/backend/wayland/state/capture.rs +++ b/src/backend/wayland/state/capture.rs @@ -157,7 +157,7 @@ impl WaylandState { self.exit_overlay_suppression(OverlaySuppression::DesktopBackdrop); } - /// Handles capture actions by delegating to the CaptureManager. + /// Handles capture actions by delegating to the `CaptureManager`. pub(in crate::backend::wayland) fn handle_capture_action(&mut self, action: Action) { if action.is_region_capture() { if let Some(opening_action) = self.capture.active_region_action() { @@ -199,8 +199,7 @@ impl WaylandState { if self.capture.is_in_progress() { log::warn!( - "Capture action {:?} requested while another capture is running; ignoring", - action + "Capture action {action:?} requested while another capture is running; ignoring" ); return; } @@ -270,10 +269,7 @@ impl WaylandState { ) } _ => { - log::error!( - "Non-capture action passed to handle_capture_action: {:?}", - action - ); + log::error!("Non-capture action passed to handle_capture_action: {action:?}"); return; } }; @@ -298,10 +294,7 @@ impl WaylandState { let suppression = overlay_suppression_for_screenshot(capture_type, self.config.capture.include_drawings); if !self.enter_overlay_suppression(suppression) { - log::warn!( - "Capture action {:?} requested while overlay is suppressed; ignoring", - action - ); + log::warn!("Capture action {action:?} requested while overlay is suppressed; ignoring"); self.capture.finish_capture_lifecycle(); self.input_state.push_toast( ToastPriority::Info, @@ -331,8 +324,7 @@ impl WaylandState { pub(in crate::backend::wayland) fn handle_canvas_export_action(&mut self, action: Action) { if self.capture.is_in_progress() { log::warn!( - "Canvas export action {:?} requested while another image operation is running; ignoring", - action + "Canvas export action {action:?} requested while another image operation is running; ignoring" ); return; } @@ -343,8 +335,7 @@ impl WaylandState { Action::ExportCanvasClipboardAndFile => CaptureDestination::ClipboardAndFile, _ => { log::error!( - "Non-canvas-export action passed to handle_canvas_export_action: {:?}", - action + "Non-canvas-export action passed to handle_canvas_export_action: {action:?}" ); return; } diff --git a/src/backend/wayland/state/capture/barrier.rs b/src/backend/wayland/state/capture/barrier.rs index 6f5beca1c..2bdf3291e 100644 --- a/src/backend/wayland/state/capture/barrier.rs +++ b/src/backend/wayland/state/capture/barrier.rs @@ -439,13 +439,13 @@ impl WaylandState { self.cancel_overlay_capture_preflight(reason, None); return; }; - if !self.suppression.capture_suppressed() { + if self.suppression.capture_suppressed() { + self.begin_pending_capture(request); + } else { log::warn!( "Capture preflight completed without capture suppression; cancelling" ); self.cancel_overlay_capture_preflight(reason, None); - } else { - self.begin_pending_capture(request); } } OverlaySuppression::None | OverlaySuppression::ExternalDialog => { diff --git a/src/backend/wayland/state/capture/pdf.rs b/src/backend/wayland/state/capture/pdf.rs index f633a8f19..18d80ad1a 100644 --- a/src/backend/wayland/state/capture/pdf.rs +++ b/src/backend/wayland/state/capture/pdf.rs @@ -22,8 +22,7 @@ impl WaylandState { pub(in crate::backend::wayland) fn handle_board_pdf_export_action(&mut self, action: Action) { if self.capture.is_in_progress() { log::warn!( - "Board PDF export action {:?} requested while another image operation is running; ignoring", - action + "Board PDF export action {action:?} requested while another image operation is running; ignoring" ); return; } @@ -33,8 +32,7 @@ impl WaylandState { Action::ExportBoardPdfFile | Action::ExportAllBoardsPdfFile ) { log::error!( - "Non-board-PDF-export action passed to handle_board_pdf_export_action: {:?}", - action + "Non-board-PDF-export action passed to handle_board_pdf_export_action: {action:?}" ); return; } @@ -64,8 +62,7 @@ impl WaylandState { }; if !self.enter_overlay_suppression(OverlaySuppression::DesktopBackdrop) { log::warn!( - "Board PDF export action {:?} requested while overlay is suppressed; ignoring", - action + "Board PDF export action {action:?} requested while overlay is suppressed; ignoring" ); self.input_state.push_toast( ToastPriority::Info, @@ -85,8 +82,7 @@ impl WaylandState { layout_context, }); log::info!( - "Queued {:?} desktop backdrop capture for PDF export; waiting for suppression frame", - operation + "Queued {operation:?} desktop backdrop capture for PDF export; waiting for suppression frame" ); self.capture .queue_preflight(CapturePreflightRequest::DesktopBackdrop(request)); @@ -97,7 +93,7 @@ impl WaylandState { Ok(snapshot) => snapshot, Err(err) => { let message = operation.format_error(&err); - log::error!("Board PDF export failed: {}", message); + log::error!("Board PDF export failed: {message}"); self.input_state.push_toast( ToastPriority::Critical, "capture.pdf", @@ -163,7 +159,7 @@ impl WaylandState { Ok(snapshot) => snapshot, Err(err) => { let message = pending.operation.format_error(&err); - log::error!("Board PDF export failed after desktop capture: {}", message); + log::error!("Board PDF export failed after desktop capture: {message}"); self.input_state.push_toast( ToastPriority::Critical, "capture.pdf", diff --git a/src/backend/wayland/state/clipboard.rs b/src/backend/wayland/state/clipboard.rs index e21849421..dadc50e85 100644 --- a/src/backend/wayland/state/clipboard.rs +++ b/src/backend/wayland/state/clipboard.rs @@ -259,7 +259,7 @@ impl WaylandState { self.start_system_clipboard_read(request); } PasteAction::StaleCompletion { request_id } => { - log::debug!("Ignoring stale clipboard paste completion {}", request_id); + log::debug!("Ignoring stale clipboard paste completion {request_id}"); } PasteAction::ApplyPrivateSelection { request, shapes } => { let pasted = self.input_state.paste_clipboard_shapes_from_request_with( @@ -631,7 +631,7 @@ fn apply_transfer_effects(input_state: &mut InputState, effects: Vec { - input_state.mark_selection_clipboard_superseded_for_generation(Some(generation)) + input_state.mark_selection_clipboard_superseded_for_generation(Some(generation)); } } } diff --git a/src/backend/wayland/state/clipboard/session_paste.rs b/src/backend/wayland/state/clipboard/session_paste.rs index 113f09dd8..105dc8500 100644 --- a/src/backend/wayland/state/clipboard/session_paste.rs +++ b/src/backend/wayland/state/clipboard/session_paste.rs @@ -430,10 +430,10 @@ fn describe_limit(limit: session::SaveLimitExceeded) -> String { } fn config_path_display() -> String { - Config::config_path() - .as_deref() - .map(compact_path) - .unwrap_or_else(|_| "~/.config/wayscriber/config.toml".to_string()) + Config::config_path().as_deref().map_or_else( + |_| "~/.config/wayscriber/config.toml".to_string(), + compact_path, + ) } fn compact_path(path: &Path) -> String { diff --git a/src/backend/wayland/state/color_picker.rs b/src/backend/wayland/state/color_picker.rs index ec70bff84..7f4cae617 100644 --- a/src/backend/wayland/state/color_picker.rs +++ b/src/backend/wayland/state/color_picker.rs @@ -15,7 +15,7 @@ impl WaylandState { /// Copies the color captured when the request was made as hex. pub(in crate::backend::wayland) fn handle_copy_hex_color(&mut self, color: Color) { let hex = color_to_hex(color); - log::info!("Hex copy requested: {}", hex); + log::info!("Hex copy requested: {hex}"); self.focus .suppress_exit_for(Instant::now(), Duration::from_millis(1500)); @@ -114,7 +114,7 @@ impl WaylandState { return; } Ok(Err(ClipboardTextError::Other(err))) => { - log::warn!("wl-paste failed for hex paste: {}", err); + log::warn!("wl-paste failed for hex paste: {err}"); self.input_state.push_toast( ToastPriority::Info, "color_picker", diff --git a/src/backend/wayland/state/core/accessors.rs b/src/backend/wayland/state/core/accessors.rs index 0785042dd..4a2792da5 100644 --- a/src/backend/wayland/state/core/accessors.rs +++ b/src/backend/wayland/state/core/accessors.rs @@ -125,7 +125,7 @@ impl WaylandState { } Ok(false) => {} Err(err) => { - log::warn!("Frozen pending image activation failed: {}", err); + log::warn!("Frozen pending image activation failed: {err}"); self.restore_xdg_after_frozen(); } } diff --git a/src/backend/wayland/state/core/output/focus.rs b/src/backend/wayland/state/core/output/focus.rs index 32c904d8f..1130712e8 100644 --- a/src/backend/wayland/state/core/output/focus.rs +++ b/src/backend/wayland/state/core/output/focus.rs @@ -90,7 +90,7 @@ impl WaylandState { warn!("Output switch requested in xdg mode, but no xdg window is active"); return; }; - info!("Switching xdg overlay to {}", target_label); + info!("Switching xdg overlay to {target_label}"); window.set_fullscreen(Some(&target_output)); window.commit(); self.surface.request_output(target_output); @@ -106,7 +106,7 @@ impl WaylandState { return; } - info!("Switching layer overlay to {}", target_label); + info!("Switching layer overlay to {target_label}"); self.teardown_keyboard_focus(); self.recreate_layer_surface_for_output(qh, &target_output); self.refresh_surface_output(current_output.as_ref(), None); diff --git a/src/backend/wayland/state/core/output/identity.rs b/src/backend/wayland/state/core/output/identity.rs index 051724395..d41bba53d 100644 --- a/src/backend/wayland/state/core/output/identity.rs +++ b/src/backend/wayland/state/core/output/identity.rs @@ -11,8 +11,7 @@ impl WaylandState { if let Some(preferred) = self.surface.placement().preferred_output_identity() && let Some(output) = self.protocol.output().outputs().find(|output| { self.output_identity_for(output) - .map(|id| id.eq_ignore_ascii_case(preferred)) - .unwrap_or(false) + .is_some_and(|id| id.eq_ignore_ascii_case(preferred)) }) { return Some(output); diff --git a/src/backend/wayland/state/core/output/session_ops.rs b/src/backend/wayland/state/core/output/session_ops.rs index 9ac74be00..0771eb929 100644 --- a/src/backend/wayland/state/core/output/session_ops.rs +++ b/src/backend/wayland/state/core/output/session_ops.rs @@ -41,16 +41,13 @@ impl WaylandState { reason, home, } => { - match home { - Some((options, outcome)) => { - self.commit_output_session(options.clone(), outcome, context)?; - self.input_state - .set_session_preflight_options(Some(options)); - } - None => { - self.session.commit_without_persistence(); - self.input_state.set_session_preflight_options(None); - } + if let Some((options, outcome)) = home { + self.commit_output_session(options.clone(), outcome, context)?; + self.input_state + .set_session_preflight_options(Some(options)); + } else { + self.session.commit_without_persistence(); + self.input_state.set_session_preflight_options(None); } self.notify_remembered_session_abandoned(&remembered, &reason); } diff --git a/src/backend/wayland/state/core/output/transition.rs b/src/backend/wayland/state/core/output/transition.rs index dc165b88b..7631ef16a 100644 --- a/src/backend/wayland/state/core/output/transition.rs +++ b/src/backend/wayland/state/core/output/transition.rs @@ -64,8 +64,7 @@ impl WaylandState { } OutputTransitionStart::KeepPending => { log::debug!( - "Keeping existing pending output transition for physical output {:?}", - physical_output_identity + "Keeping existing pending output transition for physical output {physical_output_identity:?}" ); } OutputTransitionStart::DeferForInteraction => { diff --git a/src/backend/wayland/state/input_actions.rs b/src/backend/wayland/state/input_actions.rs index dfcc1f0ac..45a595a13 100644 --- a/src/backend/wayland/state/input_actions.rs +++ b/src/backend/wayland/state/input_actions.rs @@ -32,19 +32,19 @@ impl InputHudSnapshot { impl WaylandState { pub(in crate::backend::wayland) fn apply_input_key(&mut self, key: Key) { self.apply_input_update(|input_state, resources| { - input_state.on_key_press_with_resources(resources, key) + input_state.on_key_press_with_resources(resources, key); }); } pub(in crate::backend::wayland) fn apply_input_key_repeat(&mut self, key: Key) { self.apply_input_update(|input_state, resources| { - input_state.on_key_repeat_with_resources(resources, key) + input_state.on_key_repeat_with_resources(resources, key); }); } pub(in crate::backend::wayland) fn dispatch_input_action(&mut self, action: Action) { self.apply_input_update(|input_state, resources| { - input_state.handle_action_with_resources(resources, action) + input_state.handle_action_with_resources(resources, action); }); } @@ -56,7 +56,7 @@ impl WaylandState { anchor: ZoomAnchor, ) { self.apply_input_update(|input_state, resources| { - input_state.handle_action_anchored(resources, action, anchor) + input_state.handle_action_anchored(resources, action, anchor); }); } diff --git a/src/backend/wayland/state/input_hud.rs b/src/backend/wayland/state/input_hud.rs index 5fc0d08c3..6dc1c8464 100644 --- a/src/backend/wayland/state/input_hud.rs +++ b/src/backend/wayland/state/input_hud.rs @@ -411,10 +411,10 @@ impl WaylandState { .input_state .note_input_hud_system_key(label, bare_modifier), SystemInputEvent::Mouse { label } => { - self.input_state.note_input_hud_system_mouse(label) + self.input_state.note_input_hud_system_mouse(label); } SystemInputEvent::Scroll { label } => { - self.input_state.note_input_hud_system_scroll(label) + self.input_state.note_input_hud_system_scroll(label); } SystemInputEvent::Failed(reason) => { failure = Some(reason); diff --git a/src/backend/wayland/state/pdf_export.rs b/src/backend/wayland/state/pdf_export.rs index 9fe866f45..8d546b998 100644 --- a/src/backend/wayland/state/pdf_export.rs +++ b/src/backend/wayland/state/pdf_export.rs @@ -277,10 +277,10 @@ fn frame_content_bounds(frame: &Frame, measurer: &TextMeasurer) -> Option bool { env::var(PERF_LOG_ENV) - .map(|value| matches!(value.trim(), "1" | "true" | "TRUE" | "yes" | "on" | "ON")) - .unwrap_or(false) + .is_ok_and(|value| matches!(value.trim(), "1" | "true" | "TRUE" | "yes" | "on" | "ON")) } fn duration_ms(duration: Duration) -> u64 { diff --git a/src/backend/wayland/state/perf_modules/damage_diagnostics.rs b/src/backend/wayland/state/perf_modules/damage_diagnostics.rs index c7ac3b7f3..b170d5712 100644 --- a/src/backend/wayland/state/perf_modules/damage_diagnostics.rs +++ b/src/backend/wayland/state/perf_modules/damage_diagnostics.rs @@ -34,10 +34,10 @@ pub(super) fn effective_full_damage_reason( full_damage: bool, force_full_reason: Option, ) -> Option { - if !full_damage { - None - } else { + if full_damage { Some(force_full_reason.unwrap_or(FullDamageReason::DamageRegionsCoverSurface)) + } else { + None } } diff --git a/src/backend/wayland/state/region_capture/active_state.rs b/src/backend/wayland/state/region_capture/active_state.rs index f39b97ed1..689605622 100644 --- a/src/backend/wayland/state/region_capture/active_state.rs +++ b/src/backend/wayland/state/region_capture/active_state.rs @@ -141,8 +141,10 @@ impl ActiveScreenRegion { pub(super) fn selection_owner(self) -> Option { match self.phase() { - Some(RegionInteractionPhase::Selecting { owner }) - | Some(RegionInteractionPhase::Review { owner: Some(owner) }) => Some(owner), + Some( + RegionInteractionPhase::Selecting { owner } + | RegionInteractionPhase::Review { owner: Some(owner) }, + ) => Some(owner), Some( RegionInteractionPhase::Armed | RegionInteractionPhase::Review { owner: None } diff --git a/src/backend/wayland/state/region_capture/delivery.rs b/src/backend/wayland/state/region_capture/delivery.rs index c2e4d4895..b8064bea8 100644 --- a/src/backend/wayland/state/region_capture/delivery.rs +++ b/src/backend/wayland/state/region_capture/delivery.rs @@ -211,7 +211,7 @@ impl WaylandState { /// Submit the whole displayed image and retire any in-flight drag owner. /// - /// Keeping this transaction on WaylandState leaves the keyboard protocol + /// Keeping this transaction on `WaylandState` leaves the keyboard protocol /// callback responsible only for translating Ctrl+A into one state action. pub(in crate::backend::wayland) fn submit_whole_region_capture(&mut self) { let Some(RegionSelectionFinalize::Selected { purpose, rect }) = diff --git a/src/backend/wayland/state/region_capture/picker.rs b/src/backend/wayland/state/region_capture/picker.rs index b97ba5e6f..613e0a04d 100644 --- a/src/backend/wayland/state/region_capture/picker.rs +++ b/src/backend/wayland/state/region_capture/picker.rs @@ -206,23 +206,20 @@ impl WaylandState { } } RegionPickerEntry::AutoFreeze => { - match self + if let Ok(acquisition) = self .acquisition .request(ScreenAcquisitionOwner::RegionCapture) { - Ok(acquisition) => { - self.set_pending_frozen_screen_region(purpose, generation, acquisition) - } - Err(_) => { - self.cancel_region_capture_ui_and_lifecycle(); - self.input_state.push_toast( - ToastPriority::Info, - TOAST_SOURCE, - Toast::warning(tr( - "Capture is already preparing another overlay operation.", - )), - ); - } + self.set_pending_frozen_screen_region(purpose, generation, acquisition); + } else { + self.cancel_region_capture_ui_and_lifecycle(); + self.input_state.push_toast( + ToastPriority::Info, + TOAST_SOURCE, + Toast::warning(tr( + "Capture is already preparing another overlay operation.", + )), + ); } } RegionPickerEntry::Legacy => self.handoff_region_capture_to_legacy(), diff --git a/src/backend/wayland/state/region_capture/runtime.rs b/src/backend/wayland/state/region_capture/runtime.rs index e7744bb2b..3293f4275 100644 --- a/src/backend/wayland/state/region_capture/runtime.rs +++ b/src/backend/wayland/state/region_capture/runtime.rs @@ -529,9 +529,11 @@ impl WaylandState { ) -> Option { match self.region_capture.active() { Some(ActiveScreenRegion::Ready { source, .. }) => Some(source), - Some(ActiveScreenRegion::Measure { .. }) - | Some(ActiveScreenRegion::PendingFrozen { .. }) - | Some(ActiveScreenRegion::PendingZoom { .. }) + Some( + ActiveScreenRegion::Measure { .. } + | ActiveScreenRegion::PendingFrozen { .. } + | ActiveScreenRegion::PendingZoom { .. }, + ) | None => None, } } diff --git a/src/backend/wayland/state/region_capture/window_snap.rs b/src/backend/wayland/state/region_capture/window_snap.rs index 6b4b1cc57..ff44b4777 100644 --- a/src/backend/wayland/state/region_capture/window_snap.rs +++ b/src/backend/wayland/state/region_capture/window_snap.rs @@ -188,8 +188,7 @@ impl WindowSnapSession { } let origin = self .hovered_target() - .map(|target| rect_center(target.screen_rect)) - .unwrap_or(pointer); + .map_or(pointer, |target| rect_center(target.screen_rect)); let current = self.hovered; let mut best: Option<(usize, f64)> = None; // Reverse provider order makes the visually topmost target win an diff --git a/src/backend/wayland/state/render/canvas/background.rs b/src/backend/wayland/state/render/canvas/background.rs index 8c236734f..ef8eb416d 100644 --- a/src/backend/wayland/state/render/canvas/background.rs +++ b/src/backend/wayland/state/render/canvas/background.rs @@ -200,7 +200,7 @@ impl WaylandState { // no other alias mutates the buffer while Cairo holds it. let surface = unsafe { cairo::ImageSurface::create_for_data_unsafe( - image.data.as_ptr() as *mut u8, + image.data.as_ptr().cast_mut(), cairo::Format::ARgb32, image.width as i32, image.height as i32, @@ -210,23 +210,23 @@ impl WaylandState { .context("Failed to create frozen image surface")?; let scale_x = if image.width > 0 { - phys_width as f64 / image.width as f64 + f64::from(phys_width) / f64::from(image.width) } else { 1.0 }; let scale_y = if image.height > 0 { - phys_height as f64 / image.height as f64 + f64::from(phys_height) / f64::from(image.height) } else { 1.0 }; - logical_to_image_scale_x = (scale as f64) / scale_x.max(f64::MIN_POSITIVE); - logical_to_image_scale_y = (scale as f64) / scale_y.max(f64::MIN_POSITIVE); + logical_to_image_scale_x = f64::from(scale) / scale_x.max(f64::MIN_POSITIVE); + logical_to_image_scale_y = f64::from(scale) / scale_y.max(f64::MIN_POSITIVE); let _ = ctx.save(); if zoom_render_active { let scale_x_safe = scale_x.max(f64::MIN_POSITIVE); let scale_y_safe = scale_y.max(f64::MIN_POSITIVE); - let offset_x = self.zoom.view_offset.0 * (scale as f64) / scale_x_safe; - let offset_y = self.zoom.view_offset.1 * (scale as f64) / scale_y_safe; + let offset_x = self.zoom.view_offset.0 * f64::from(scale) / scale_x_safe; + let offset_y = self.zoom.view_offset.1 * f64::from(scale) / scale_y_safe; ctx.scale(scale_x * self.zoom.scale, scale_y * self.zoom.scale); ctx.translate(-offset_x, -offset_y); } else if (scale_x - 1.0).abs() > f64::EPSILON || (scale_y - 1.0).abs() > f64::EPSILON { @@ -234,17 +234,17 @@ impl WaylandState { } if let Err(err) = ctx.set_source_surface(&surface, 0.0, 0.0) { - warn!("Failed to set frozen background surface: {}", err); + warn!("Failed to set frozen background surface: {err}"); } else if let Err(err) = ctx.paint() { - warn!("Failed to paint frozen background: {}", err); + warn!("Failed to paint frozen background: {err}"); } let _ = ctx.restore(); let pattern = cairo::SurfacePattern::create(&surface); pattern.set_extend(cairo::Extend::Pad); let mut matrix = cairo::Matrix::identity(); - let scale_x_inv = 1.0 / (scale as f64 * scale_x.max(f64::MIN_POSITIVE)); - let scale_y_inv = 1.0 / (scale as f64 * scale_y.max(f64::MIN_POSITIVE)); + let scale_x_inv = 1.0 / (f64::from(scale) * scale_x.max(f64::MIN_POSITIVE)); + let scale_y_inv = 1.0 / (f64::from(scale) * scale_y.max(f64::MIN_POSITIVE)); matrix.scale(scale_x_inv, scale_y_inv); pattern.set_matrix(matrix); eraser_surface = Some(surface); diff --git a/src/backend/wayland/state/render/canvas/mod.rs b/src/backend/wayland/state/render/canvas/mod.rs index e0109a8a5..32a40d1e6 100644 --- a/src/backend/wayland/state/render/canvas/mod.rs +++ b/src/backend/wayland/state/render/canvas/mod.rs @@ -160,7 +160,7 @@ impl WaylandState { // Scale subsequent drawing to logical coordinates let _ = ctx.save(); if scale > 1 { - ctx.scale(scale as f64, scale as f64); + ctx.scale(f64::from(scale), f64::from(scale)); } if canvas_transform_active { @@ -207,7 +207,7 @@ impl WaylandState { // completing it warns through its own action instead. let spotlight_cursor = render_transients.then(|| { let (screen_x, screen_y) = self.pointer.position(); - self.canvas_world_coords(screen_x as f64, screen_y as f64) + self.canvas_world_coords(f64::from(screen_x), f64::from(screen_y)) }); let SpotlightFrameRegions { regions: spotlight_regions, @@ -295,13 +295,12 @@ impl WaylandState { self.render_selection_overlays(ctx); let (mx, my) = self.canvas_world_coords( - self.pointer.position().0 as f64, - self.pointer.position().1 as f64, + f64::from(self.pointer.position().0), + f64::from(self.pointer.position().1), ); let (hover_mx, hover_my) = self .stylus_hover_cursor_position() - .map(|(x, y)| self.canvas_world_coords(x, y)) - .unwrap_or((mx, my)); + .map_or((mx, my), |(x, y)| self.canvas_world_coords(x, y)); self.render_eraser_hover_halos(ctx, hover_mx, hover_my); @@ -404,7 +403,7 @@ fn render_committed_canvas_shapes( shape, &replay_ctx, text_halo_enabled, - ) + ); }; let Some(bounds) = union_damage_bounds(damage_world) else { for shape in shapes { diff --git a/src/backend/wayland/state/render/canvas/overlays.rs b/src/backend/wayland/state/render/canvas/overlays.rs index e5e671d2d..6076a6895 100644 --- a/src/backend/wayland/state/render/canvas/overlays.rs +++ b/src/backend/wayland/state/render/canvas/overlays.rs @@ -48,10 +48,10 @@ impl WaylandState { { let _ = ctx.save(); ctx.rectangle( - handle.x as f64, - handle.y as f64, - handle.width as f64, - handle.height as f64, + f64::from(handle.x), + f64::from(handle.y), + f64::from(handle.width), + f64::from(handle.height), ); ctx.set_source_rgba(1.0, 1.0, 1.0, 0.9); let _ = ctx.fill_preserve(); diff --git a/src/backend/wayland/state/render/canvas/resource_tests.rs b/src/backend/wayland/state/render/canvas/resource_tests.rs index 55b3b7ea2..5aaf4d7fe 100644 --- a/src/backend/wayland/state/render/canvas/resource_tests.rs +++ b/src/backend/wayland/state/render/canvas/resource_tests.rs @@ -93,7 +93,7 @@ fn paint( .unwrap(); { let cairo = cairo::Context::new(&surface).unwrap(); - cairo.scale(inputs.scale as f64, inputs.scale as f64); + cairo.scale(f64::from(inputs.scale), f64::from(inputs.scale)); cairo.translate(-inputs.origin.0, -inputs.origin.1); let frame = CanvasFrame { draw_committed: true, diff --git a/src/backend/wayland/state/render/canvas/text.rs b/src/backend/wayland/state/render/canvas/text.rs index b21c9946b..d73bd6ca3 100644 --- a/src/backend/wayland/state/render/canvas/text.rs +++ b/src/backend/wayland/state/render/canvas/text.rs @@ -127,8 +127,8 @@ impl WaylandState { ) else { return; }; - let caret_x = x as f64 + geom.x; - let top = y as f64 + geom.y_from_baseline; + let caret_x = f64::from(x) + geom.x; + let top = f64::from(y) + geom.y_from_baseline; let bottom = top + geom.height; render_caret_stroke( canvas.cairo, @@ -282,10 +282,10 @@ impl WaylandState { let _ = ctx.save(); let padding = 4.0; - let x = bounds.x as f64 - padding; - let y = bounds.y as f64 - padding; - let width = bounds.width as f64 + padding * 2.0; - let height = bounds.height as f64 + padding * 2.0; + let x = f64::from(bounds.x) - padding; + let y = f64::from(bounds.y) - padding; + let width = f64::from(bounds.width) + padding * 2.0; + let height = f64::from(bounds.height) + padding * 2.0; // Teal color at 50% alpha ctx.set_source_rgba(0.2, 0.55, 0.65, 0.5); @@ -313,8 +313,14 @@ impl WaylandState { let glow_radius = 30.0 + progress * 20.0; // Expands slightly as it fades // Create radial gradient for glow effect - let gradient = - cairo::RadialGradient::new(x as f64, y as f64, 0.0, x as f64, y as f64, glow_radius); + let gradient = cairo::RadialGradient::new( + f64::from(x), + f64::from(y), + 0.0, + f64::from(x), + f64::from(y), + glow_radius, + ); // Teal glow color gradient.add_color_stop_rgba(0.0, 0.2, 0.55, 0.65, alpha); @@ -322,7 +328,13 @@ impl WaylandState { gradient.add_color_stop_rgba(1.0, 0.2, 0.55, 0.65, 0.0); ctx.set_source(&gradient).ok(); - ctx.arc(x as f64, y as f64, glow_radius, 0.0, consts::PI * 2.0); + ctx.arc( + f64::from(x), + f64::from(y), + glow_radius, + 0.0, + consts::PI * 2.0, + ); let _ = ctx.fill(); let _ = ctx.restore(); diff --git a/src/backend/wayland/state/render/canvas/text/ime.rs b/src/backend/wayland/state/render/canvas/text/ime.rs index 738ba9648..3bb14719c 100644 --- a/src/backend/wayland/state/render/canvas/text/ime.rs +++ b/src/backend/wayland/state/render/canvas/text/ime.rs @@ -36,9 +36,9 @@ pub(super) fn paint_preedit_selection( attrs.insert(alpha); layout.set_attributes(Some(&attrs)); - let baseline = layout.baseline() as f64 / pango::SCALE as f64; + let baseline = f64::from(layout.baseline()) / f64::from(pango::SCALE); ctx.save().ok(); - ctx.move_to(x as f64, y as f64 - baseline); + ctx.move_to(f64::from(x), f64::from(y) - baseline); // The transparent source suppresses a second glyph pass; Pango's explicit // background attributes still paint the selected range. ctx.set_source_rgba(0.0, 0.0, 0.0, 0.0); @@ -87,9 +87,9 @@ pub(super) fn paint_preedit_underline( attrs.insert(foreground_alpha); layout.set_attributes(Some(&attrs)); - let baseline = layout.baseline() as f64 / pango::SCALE as f64; + let baseline = f64::from(layout.baseline()) / f64::from(pango::SCALE); ctx.save().ok(); - ctx.move_to(origin.0 as f64, origin.1 as f64 - baseline); + ctx.move_to(f64::from(origin.0), f64::from(origin.1) - baseline); ctx.set_source_rgba(0.0, 0.0, 0.0, color.a.clamp(0.0, 1.0)); functions::show_layout(ctx, &layout); ctx.restore().ok(); diff --git a/src/backend/wayland/state/render/measure_badge.rs b/src/backend/wayland/state/render/measure_badge.rs index 6864542a0..589919e1d 100644 --- a/src/backend/wayland/state/render/measure_badge.rs +++ b/src/backend/wayland/state/render/measure_badge.rs @@ -11,7 +11,7 @@ impl WaylandState { height: u32, ) -> Option { let pointer = self.pointer.position(); - let world = self.canvas_world_coords(pointer.0 as f64, pointer.1 as f64); + let world = self.canvas_world_coords(f64::from(pointer.0), f64::from(pointer.1)); let readout = self .input_state .provisional_shape_readout(world.0, world.1)?; @@ -19,7 +19,7 @@ impl WaylandState { self.render.ui_text(), self.config.ui.show_shape_size_readout, readout, - (pointer.0 as f64, pointer.1 as f64), + (f64::from(pointer.0), f64::from(pointer.1)), width, height, ) diff --git a/src/backend/wayland/state/render/paint.rs b/src/backend/wayland/state/render/paint.rs index a110e1c8c..e3f7f4606 100644 --- a/src/backend/wayland/state/render/paint.rs +++ b/src/backend/wayland/state/render/paint.rs @@ -62,10 +62,10 @@ impl WaylandState { if !damage_screen.is_empty() { for rect in damage_screen { // Scale logical rect to physical pixels - let x = rect.x as f64 * scale as f64; - let y = rect.y as f64 * scale as f64; - let w = rect.width as f64 * scale as f64; - let h = rect.height as f64 * scale as f64; + let x = f64::from(rect.x) * f64::from(scale); + let y = f64::from(rect.y) * f64::from(scale); + let w = f64::from(rect.width) * f64::from(scale); + let h = f64::from(rect.height) * f64::from(scale); ctx.rectangle(x, y, w, h); } ctx.clip(); @@ -160,12 +160,11 @@ impl WaylandState { .is_some_and(|purpose| purpose.is_capture()) { debug!( - "Region picker frame: logical={}x{}, physical={}x{}, scale={}, cairo_draw={:?}", - width, height, phys_width, phys_height, scale, draw_duration + "Region picker frame: logical={width}x{height}, physical={phys_width}x{phys_height}, scale={scale}, cairo_draw={draw_duration:?}" ); } if draw_duration > Duration::from_millis(2) { - debug!("Cairo draw took {:?}", draw_duration); + debug!("Cairo draw took {draw_duration:?}"); } Ok(()) diff --git a/src/backend/wayland/state/render/profile.rs b/src/backend/wayland/state/render/profile.rs index eac887de6..711e9cddf 100644 --- a/src/backend/wayland/state/render/profile.rs +++ b/src/backend/wayland/state/render/profile.rs @@ -9,7 +9,7 @@ pub(super) enum ProfileMode { CanvasAndUi, } -/// The selected profile is a frame value; reusable baseline storage stays in RenderRuntime. +/// The selected profile is a frame value; reusable baseline storage stays in `RenderRuntime`. #[derive(Debug)] pub(super) struct FrameProfile { profile: Option, diff --git a/src/backend/wayland/state/render/tool_preview.rs b/src/backend/wayland/state/render/tool_preview.rs index 2cb8337df..bc71f33c7 100644 --- a/src/backend/wayland/state/render/tool_preview.rs +++ b/src/backend/wayland/state/render/tool_preview.rs @@ -196,7 +196,7 @@ pub(super) fn mouse_tool_preview_damage_rect( width: u32, height: u32, ) -> Option { - let bounds = tool_preview_bubble(thickness, pos.0, pos.1, width as f64, height as f64); + let bounds = tool_preview_bubble(thickness, pos.0, pos.1, f64::from(width), f64::from(height)); effect_rect(bounds, width, height) } @@ -283,7 +283,10 @@ mod tests { overlay::CURSOR_PREVIEW_DOT_MAX, "very thick strokes cap so the bubble stays compact" ); - let mid = (overlay::CURSOR_PREVIEW_DOT_MIN + overlay::CURSOR_PREVIEW_DOT_MAX) / 2.0; + let mid = f64::midpoint( + overlay::CURSOR_PREVIEW_DOT_MIN, + overlay::CURSOR_PREVIEW_DOT_MAX, + ); assert_eq!( tool_preview_dot_diameter(mid), mid, @@ -315,7 +318,7 @@ mod tests { assert!(by + bubble_h <= 600.0, "clamped within bottom edge"); } - /// Little-endian ARgb32 stores premultiplied BGRA in memory. + /// Little-endian `ARgb32` stores premultiplied BGRA in memory. fn has_strong_green_pixel(pixels: &[u8]) -> bool { pixels.as_chunks::<4>().0.iter().any(|px| { let (b, g, r, a) = (px[0], px[1], px[2], px[3]); diff --git a/src/backend/wayland/state/render/ui.rs b/src/backend/wayland/state/render/ui.rs index 17ceb2300..3f5fc90b0 100644 --- a/src/backend/wayland/state/render/ui.rs +++ b/src/backend/wayland/state/render/ui.rs @@ -29,7 +29,7 @@ impl WaylandState { ) { let _ = ctx.save(); if scale > 1 { - ctx.scale(scale as f64, scale as f64); + ctx.scale(f64::from(scale), f64::from(scale)); } self.render_ui_layers(ctx, width, height, render_ui); let _ = ctx.restore(); @@ -69,7 +69,7 @@ impl WaylandState { if !capture_picker && self.mouse_tool_preview_eligible() { let (cursor_x, cursor_y) = self.stylus_hover_cursor_position().unwrap_or_else(|| { let (x, y) = self.pointer.position(); - (x as f64, y as f64) + (f64::from(x), f64::from(y)) }); draw_tool_preview( ctx, @@ -79,8 +79,8 @@ impl WaylandState { self.input_state.thickness_for_active_tool(), cursor_x, cursor_y, - width as f64, - height as f64, + f64::from(width), + f64::from(height), ); } if !capture_picker { @@ -303,7 +303,7 @@ impl WaylandState { let top_offset = self.toolbar_chrome.top_offset(); let anchor = ( self.inline_top_base_x() + top_offset.0, - self.inline_top_base_y() + top_offset.1 + top_h as f64 + 8.0, + self.inline_top_base_y() + top_offset.1 + f64::from(top_h) + 8.0, ); ui::render_precision_entry_popup_with_engine( self.render.ui_text(), @@ -357,9 +357,7 @@ impl WaylandState { ); self.input_state.set_toast_geometry( toast_geometry.map(|geometry| geometry.0), - toast_geometry - .map(|geometry| geometry.1) - .unwrap_or([None, None]), + toast_geometry.map_or([None, None], |geometry| geometry.1), ); ui::render_preset_toast_with_engine( self.render.ui_text(), @@ -690,8 +688,8 @@ impl WaylandState { let redraw = mouse_tool_preview_redraw( self.mouse_tool_preview_eligible(), self.input_state.thickness_for_active_tool(), - (prev.0 as f64, prev.1 as f64), - (next.0 as f64, next.1 as f64), + (f64::from(prev.0), f64::from(prev.1)), + (f64::from(next.0), f64::from(next.1)), self.surface.width(), self.surface.height(), ); diff --git a/src/backend/wayland/state/render/ui_effect_damage.rs b/src/backend/wayland/state/render/ui_effect_damage.rs index ace7da4a0..4f5237e05 100644 --- a/src/backend/wayland/state/render/ui_effect_damage.rs +++ b/src/backend/wayland/state/render/ui_effect_damage.rs @@ -299,7 +299,7 @@ impl WaylandState { let preview_position = self.stylus_hover_cursor_position().unwrap_or_else(|| { let (x, y) = self.pointer.position(); - (x as f64, y as f64) + (f64::from(x), f64::from(y)) }); let preview_rect = flags .active(UiEffect::ToolPreview) @@ -405,9 +405,9 @@ impl WaylandState { // translate to screen space (zoom forces full damage, so only the // pan offset matters here). let (origin_x, origin_y) = self.canvas_view_origin(); - let screen_x = *x as f64 - origin_x; - let screen_y = *y as f64 - origin_y; - let radius = TEXT_EDIT_ENTRY_MAX_RADIUS as f64; + let screen_x = f64::from(*x) - origin_x; + let screen_y = f64::from(*y) - origin_y; + let radius = f64::from(TEXT_EDIT_ENTRY_MAX_RADIUS); effect_rect( ( screen_x - radius, diff --git a/src/backend/wayland/state/tablet_runtime.rs b/src/backend/wayland/state/tablet_runtime.rs index e24f2fc84..c7197a1c6 100644 --- a/src/backend/wayland/state/tablet_runtime.rs +++ b/src/backend/wayland/state/tablet_runtime.rs @@ -83,7 +83,7 @@ impl TabletState { self.pending_frame .motion .or(self.last_pos) - .unwrap_or((fallback.0 as f64, fallback.1 as f64)) + .unwrap_or((f64::from(fallback.0), f64::from(fallback.1))) } pub(in crate::backend::wayland) fn hover_cursor_position(&self) -> Option<(f64, f64)> { diff --git a/src/backend/wayland/state/tablet_runtime/pressure.rs b/src/backend/wayland/state/tablet_runtime/pressure.rs index 541d5d5bf..071786327 100644 --- a/src/backend/wayland/state/tablet_runtime/pressure.rs +++ b/src/backend/wayland/state/tablet_runtime/pressure.rs @@ -67,7 +67,7 @@ impl TabletState { let first_sample = self.pressure_thickness.is_none(); if !try_apply_pressure_to_state_with( measurer, - pressure as f64 / 65535.0, + f64::from(pressure) / 65535.0, input, self.settings, ) { diff --git a/src/backend/wayland/state/toolbar/drag/clamp.rs b/src/backend/wayland/state/toolbar/drag/clamp.rs index 9aaeb0c4d..61aaa2d9c 100644 --- a/src/backend/wayland/state/toolbar/drag/clamp.rs +++ b/src/backend/wayland/state/toolbar/drag/clamp.rs @@ -28,14 +28,11 @@ impl WaylandState { &mut self, snapshot: &ToolbarSnapshot, ) -> bool { - let width = self.surface.width() as f64; - let height = self.surface.height() as f64; + let width = f64::from(self.surface.width()); + let height = f64::from(self.surface.height()); if width == 0.0 || height == 0.0 { drag_log(|| { - format!( - "skip clamp: surface not configured (width={}, height={})", - width, height - ) + format!("skip clamp: surface not configured (width={width}, height={height})") }); return false; } diff --git a/src/backend/wayland/state/toolbar/drag/handoff.rs b/src/backend/wayland/state/toolbar/drag/handoff.rs index 5222b35c6..bf951bb5a 100644 --- a/src/backend/wayland/state/toolbar/drag/handoff.rs +++ b/src/backend/wayland/state/toolbar/drag/handoff.rs @@ -56,8 +56,7 @@ impl WaylandState { let frozen_top_base_x = self.inline_top_base_x(); drag_log(|| { format!( - "begin GTK {:?} drag preview (park transparent input surface, freeze top base at {frozen_top_base_x:.3})", - kind, + "begin GTK {kind:?} drag preview (park transparent input surface, freeze top base at {frozen_top_base_x:.3})", ) }); self.toolbar_drag.begin_gtk_preview(kind, frozen_top_base_x); diff --git a/src/backend/wayland/state/toolbar/events.rs b/src/backend/wayland/state/toolbar/events.rs index a112d88f8..6bd00adcf 100644 --- a/src/backend/wayland/state/toolbar/events.rs +++ b/src/backend/wayland/state/toolbar/events.rs @@ -139,7 +139,7 @@ impl WaylandState { /// the screen. Both inline and layer-shell placement use the pushed top /// base X, so budgeting must subtract that same position. fn top_strip_viewport_max(&self, snapshot: &ToolbarSnapshot) -> Option { - let screen_width = self.surface.width() as f64; + let screen_width = f64::from(self.surface.width()); let scale = if snapshot.toolbar_scale.is_finite() { snapshot.toolbar_scale.clamp(0.5, 3.0) } else { @@ -156,7 +156,7 @@ impl WaylandState { /// the live vertical drag offset, so opening a tall popover does not make /// the toolbar clamp back up the screen. fn top_popover_available_height(&self, snapshot: &ToolbarSnapshot) -> Option { - let screen_height = self.surface.height() as f64; + let screen_height = f64::from(self.surface.height()); let scale = if snapshot.toolbar_scale.is_finite() { snapshot.toolbar_scale.clamp(0.5, 3.0) } else { diff --git a/src/backend/wayland/state/toolbar/events/session.rs b/src/backend/wayland/state/toolbar/events/session.rs index d66ff3308..e68b66627 100644 --- a/src/backend/wayland/state/toolbar/events/session.rs +++ b/src/backend/wayland/state/toolbar/events/session.rs @@ -74,8 +74,7 @@ pub(super) fn session_info_summary(inspection: &SessionInspection) -> String { let size = inspection .size_bytes - .map(format_byte_count) - .unwrap_or_else(|| tr("unknown size").to_string()); + .map_or_else(|| tr("unknown size").to_string(), format_byte_count); let shapes = inspection .frame_counts .map(|counts| { @@ -119,10 +118,7 @@ fn recent_session_snapshots(current_path: Option<&Path>) -> Vec { - self.handle_toolbar_open_session_path(&path) - } - (SessionFileDialogMode::Open, Ok(None)) | (SessionFileDialogMode::SaveAs, Ok(None)) => { + self.handle_toolbar_open_session_path(&path); } + (SessionFileDialogMode::Open | SessionFileDialogMode::SaveAs, Ok(None)) => {} (SessionFileDialogMode::Open, Err(error)) => { self.set_session_toolbar_error(format!("{}: {error}", tr("Open session failed"))); } @@ -499,7 +494,7 @@ impl WaylandState { self.set_session_toolbar_info(clear_tools_message(report.outcome)); } SessionCommandReport::Inspection(inspection) => { - self.set_session_toolbar_info(session_info_summary(&inspection)) + self.set_session_toolbar_info(session_info_summary(&inspection)); } SessionCommandReport::Forgotten(path, forgotten) => { let status = if forgotten { @@ -510,7 +505,7 @@ impl WaylandState { self.set_session_toolbar_error(trf( "Session file missing; {}: {}", &[&status, &session_display_name(&path)], - )) + )); } } } @@ -669,8 +664,10 @@ enum DialogFramePhase { fn dialog_frame_accepted(phase: DialogFramePhase, outcome: RenderOutcome) -> bool { match (phase, outcome) { (DialogFramePhase::Entry, RenderOutcome::Committed { .. }) - | (DialogFramePhase::Restoration, RenderOutcome::Committed { .. }) - | (DialogFramePhase::Restoration, RenderOutcome::BuffersInFlight) => true, + | ( + DialogFramePhase::Restoration, + RenderOutcome::Committed { .. } | RenderOutcome::BuffersInFlight, + ) => true, (DialogFramePhase::Entry, RenderOutcome::BuffersInFlight) => false, } } diff --git a/src/backend/wayland/state/toolbar/events/session/dialog.rs b/src/backend/wayland/state/toolbar/events/session/dialog.rs index 27b41e405..16b89cbb9 100644 --- a/src/backend/wayland/state/toolbar/events/session/dialog.rs +++ b/src/backend/wayland/state/toolbar/events/session/dialog.rs @@ -202,8 +202,7 @@ fn run_kdialog_session_file_dialog( arguments.push( current_path .and_then(Path::parent) - .map(Path::to_path_buf) - .unwrap_or_else(default_session_dir) + .map_or_else(default_session_dir, Path::to_path_buf) .into_os_string(), ); } @@ -306,8 +305,8 @@ pub(in crate::backend::wayland::state::toolbar::events) fn ensure_save_as_extens if path .extension() .and_then(|extension| extension.to_str()) - .filter(|extension| !extension.is_empty()) - .is_some() + .as_ref() + .is_some_and(|extension| !extension.is_empty()) { return path; } diff --git a/src/backend/wayland/state/toolbar/fade.rs b/src/backend/wayland/state/toolbar/fade.rs index 1fa4b0ad3..7dbad5ee0 100644 --- a/src/backend/wayland/state/toolbar/fade.rs +++ b/src/backend/wayland/state/toolbar/fade.rs @@ -132,7 +132,7 @@ impl WaylandState { return None; } let (x, y) = self.pointer.position(); - Some((x as f64, y as f64)) + Some((f64::from(x), f64::from(y))) } /// The top strip's bounds in canvas coordinates. Layer-shell and GTK @@ -148,8 +148,8 @@ impl WaylandState { Some(( self.inline_top_base_x() + offset.0, self.inline_top_base_y() + offset.1, - width as f64, - height as f64, + f64::from(width), + f64::from(height), )) } } diff --git a/src/backend/wayland/state/toolbar/geometry.rs b/src/backend/wayland/state/toolbar/geometry.rs index ae8d1e565..df604f495 100644 --- a/src/backend/wayland/state/toolbar/geometry.rs +++ b/src/backend/wayland/state/toolbar/geometry.rs @@ -70,8 +70,8 @@ pub(super) fn clamp_toolbar_offsets( offsets: ToolbarOffsets, input: ToolbarClampInput, ) -> (ToolbarOffsets, ToolbarClampBounds) { - let top_w = input.top_size.0 as f64; - let top_h = input.top_size.1 as f64; + let top_w = f64::from(input.top_size.0); + let top_h = f64::from(input.top_size.1); let (top_x, min_top_x, max_top_x) = clamp_floating_axis_offset( offsets.top_x, @@ -165,7 +165,7 @@ mod tests { let mut snapshot = ToolbarSnapshot::from_input_with_bindings(&state, ToolbarBindingHints::default()); snapshot.top_viewport_max = Some(budget); - let planned = layout::top_size(&UiTextEngine::default(), &snapshot).0 as f64; + let planned = f64::from(layout::top_size(&UiTextEngine::default(), &snapshot).0); assert!(planned <= budget, "planned={planned}, budget={budget}"); } diff --git a/src/backend/wayland/state/toolbar/gtk_feedback.rs b/src/backend/wayland/state/toolbar/gtk_feedback.rs index 3fea19a38..564d8a2d0 100644 --- a/src/backend/wayland/state/toolbar/gtk_feedback.rs +++ b/src/backend/wayland/state/toolbar/gtk_feedback.rs @@ -33,16 +33,16 @@ fn clamp_gtk_surface_offset( Some(( super::geometry::clamp_floating_axis_offset( offset.0, - viewport.0 as f64, - surface_size.width as f64, + f64::from(viewport.0), + f64::from(surface_size.width), start_margin.0, end_margin.0, ) .0, super::geometry::clamp_floating_axis_offset( offset.1, - viewport.1 as f64, - surface_size.height as f64, + f64::from(viewport.1), + f64::from(surface_size.height), start_margin.1, end_margin.1, ) diff --git a/src/backend/wayland/state/toolbar/inline/render.rs b/src/backend/wayland/state/toolbar/inline/render.rs index b2a62105c..3b730f146 100644 --- a/src/backend/wayland/state/toolbar/inline/render.rs +++ b/src/backend/wayland/state/toolbar/inline/render.rs @@ -32,8 +32,8 @@ impl WaylandState { ); let top_size = top_size(self.render.ui_text(), snapshot); - let top_base_w = top_size.0 as f64 / ui_scale; - let top_base_h = top_size.1 as f64 / ui_scale; + let top_base_w = f64::from(top_size.0) / ui_scale; + let top_base_h = f64::from(top_size.1) / ui_scale; let top_hover_local = self .toolbar_chrome .inline_hover() @@ -56,7 +56,7 @@ impl WaylandState { top_hover_local, self.toolbar_chrome.inline_hover_start(), ) { - log::warn!("Failed to render inline top toolbar: {}", err); + log::warn!("Failed to render inline top toolbar: {err}"); } let _ = ctx.restore(); for hit in &mut hits { @@ -68,8 +68,8 @@ impl WaylandState { let top_rect = ( top_offset.0, top_offset.1, - top_size.0 as f64, - top_size.1 as f64, + f64::from(top_size.0), + f64::from(top_size.1), ); hit::clip_hit_regions_to_bounds(&mut hits, 0, top_rect); self.toolbar_chrome.set_inline_rendered(hits, top_rect); diff --git a/src/backend/wayland/state/toolbar/scroll.rs b/src/backend/wayland/state/toolbar/scroll.rs index b39729374..9de0e7048 100644 --- a/src/backend/wayland/state/toolbar/scroll.rs +++ b/src/backend/wayland/state/toolbar/scroll.rs @@ -55,7 +55,7 @@ impl WaylandState { if max_scroll <= 0.0 { return false; } - let next = (snapshot.top_popover_scroll + scroll_direction as f64 * WHEEL_SCROLL_STEP) + let next = (snapshot.top_popover_scroll + f64::from(scroll_direction) * WHEEL_SCROLL_STEP) .clamp(0.0, max_scroll); if (next - snapshot.top_popover_scroll).abs() < 0.5 { return false; diff --git a/src/backend/wayland/state/toolbar/visibility/pointer.rs b/src/backend/wayland/state/toolbar/visibility/pointer.rs index 51f19f58d..720338144 100644 --- a/src/backend/wayland/state/toolbar/visibility/pointer.rs +++ b/src/backend/wayland/state/toolbar/visibility/pointer.rs @@ -63,7 +63,7 @@ impl WaylandState { }); } Err(err) => { - warn!("Failed to lock pointer for toolbar drag: {}", err); + warn!("Failed to lock pointer for toolbar drag: {err}"); return; } } @@ -90,7 +90,7 @@ impl WaylandState { drag_log(|| "relative pointer bound for drag"); } Err(err) => { - warn!("Failed to obtain relative pointer for drag: {}", err); + warn!("Failed to obtain relative pointer for drag: {err}"); // Abort lock if relative pointer is unavailable; fall back to absolute path. self.unlock_pointer(); } diff --git a/src/backend/wayland/state/toolbar/visibility/sync.rs b/src/backend/wayland/state/toolbar/visibility/sync.rs index 897cd6d43..946c2cc7e 100644 --- a/src/backend/wayland/state/toolbar/visibility/sync.rs +++ b/src/backend/wayland/state/toolbar/visibility/sync.rs @@ -57,9 +57,7 @@ impl WaylandState { let desktop_env = env::var(XDG_CURRENT_DESKTOP_ENV).unwrap_or_else(|_| "unknown".into()); let session_env = env::var(XDG_SESSION_DESKTOP_ENV).unwrap_or_else(|_| "unknown".into()); log::info!( - "Layer-shell protocol unavailable; toolbar surfaces will not appear (desktop='{}', session='{}'). Overlay may be limited to the work area on compositors like GNOME.", - desktop_env, - session_env + "Layer-shell protocol unavailable; toolbar surfaces will not appear (desktop='{desktop_env}', session='{session_env}'). Overlay may be limited to the work area on compositors like GNOME." ); } @@ -69,12 +67,12 @@ impl WaylandState { let current = self.focus.current_keyboard_interactivity(); let updated = if let Some(layer) = self.surface.layer_surface_mut() { - if current != Some(desired) { + if current == Some(desired) { + false + } else { layer.set_keyboard_interactivity(desired); layer.commit(); true - } else { - false } } else { self.focus.set_keyboard_interactivity(None); @@ -169,8 +167,7 @@ impl WaylandState { let misses = self.toolbar_chrome.configure_miss_count(); if debug_toolbar_drag_logging_enabled() && misses.is_multiple_of(60) { debug!( - "Toolbar configure pending: count={}, expected_top={}, configured_top={}", - misses, expected_top, top_configured + "Toolbar configure pending: count={misses}, expected_top={expected_top}, configured_top={top_configured}" ); } } diff --git a/src/backend/wayland/state/ui_animation.rs b/src/backend/wayland/state/ui_animation.rs index 1b2b5de6f..f26a9a655 100644 --- a/src/backend/wayland/state/ui_animation.rs +++ b/src/backend/wayland/state/ui_animation.rs @@ -9,7 +9,7 @@ pub(in crate::backend::wayland) struct UiAnimationClock { impl UiAnimationClock { pub(in crate::backend::wayland) fn from_fps(fps: u32) -> Self { Self { - interval: (fps != 0).then(|| Duration::from_secs_f64(1.0 / fps as f64)), + interval: (fps != 0).then(|| Duration::from_secs_f64(1.0 / f64::from(fps))), next_tick: None, } } diff --git a/src/backend/wayland/state/zoom.rs b/src/backend/wayland/state/zoom.rs index 049e6139e..c735c5ae8 100644 --- a/src/backend/wayland/state/zoom.rs +++ b/src/backend/wayland/state/zoom.rs @@ -42,7 +42,7 @@ impl WaylandState { && !self.zoom.is_in_progress() && let Err(err) = self.start_zoom_capture(false) { - warn!("Zoom capture failed to start: {}", err); + warn!("Zoom capture failed to start: {err}"); self.zoom.deactivate(&mut self.input_state); self.exit_overlay_suppression(OverlaySuppression::Zoom); self.cancel_screen_modals_if_source_changed(); @@ -92,7 +92,7 @@ impl WaylandState { } else if self.zoom.active && let Err(err) = self.start_zoom_capture(true) { - warn!("Zoom capture refresh failed: {}", err); + warn!("Zoom capture refresh failed: {err}"); } } } @@ -192,7 +192,7 @@ impl WaylandState { && !board_zoom && let Err(err) = self.start_zoom_capture(false) { - warn!("Zoom capture failed to start: {}", err); + warn!("Zoom capture failed to start: {err}"); self.zoom.deactivate(&mut self.input_state); self.exit_overlay_suppression(OverlaySuppression::Zoom); self.cancel_screen_modals_if_source_changed(); @@ -261,12 +261,12 @@ fn resolve_zoom_anchor( width: u32, height: u32, ) -> (f64, f64) { - let center = (width as f64 * 0.5, height as f64 * 0.5); + let center = (f64::from(width) * 0.5, f64::from(height) * 0.5); match anchor { - ZoomAnchor::Pointer => pointer.map_or(center, |(x, y)| (x as f64, y as f64)), + ZoomAnchor::Pointer => pointer.map_or(center, |(x, y)| (f64::from(x), f64::from(y))), ZoomAnchor::ScreenCenter => center, - ZoomAnchor::At(x, y) => (x as f64, y as f64), + ZoomAnchor::At(x, y) => (f64::from(x), f64::from(y)), } } diff --git a/src/backend/wayland/surface.rs b/src/backend/wayland/surface.rs index d08038f6e..cfaa1fb82 100644 --- a/src/backend/wayland/surface.rs +++ b/src/backend/wayland/surface.rs @@ -1,7 +1,7 @@ //! Layer-surface management for the Wayland backend. //! -//! This module owns the wl_surface/layer surface handle and the shm slot -//! pool. WaylandState asks SurfaceState for buffers and size information +//! This module owns the `wl_surface`, its layer-surface handle, and the shm slot +//! pool. `WaylandState` asks `SurfaceState` for buffers and size information //! instead of juggling the raw objects directly. use anyhow::{Context, Result}; @@ -152,17 +152,16 @@ impl SurfaceState { self.frame_callbacks.clear(); } - /// Returns the active wl_surface, if initialized. + /// Returns the active `wl_surface`, if initialized. pub fn wl_surface(&self) -> Option<&wl_surface::WlSurface> { self.wl_surface.as_ref() } - /// Returns true if the provided wl_surface belongs to this overlay surface state. + /// Returns true if the provided `wl_surface` belongs to this overlay surface state. pub fn is_surface(&self, surface: &wl_surface::WlSurface) -> bool { self.wl_surface .as_ref() - .map(|current| current.id() == surface.id()) - .unwrap_or(false) + .is_some_and(|current| current.id() == surface.id()) } /// Returns the mutable layer surface, if initialized. diff --git a/src/backend/wayland/surface/placement.rs b/src/backend/wayland/surface/placement.rs index ac9c1c133..c3a7de29c 100644 --- a/src/backend/wayland/surface/placement.rs +++ b/src/backend/wayland/surface/placement.rs @@ -42,8 +42,9 @@ impl XdgFrozenFullscreen { Some( self.requested_at .and_then(|requested_at| requested_at.checked_add(XDG_FROZEN_FULLSCREEN_TIMEOUT)) - .map(|deadline| deadline.saturating_duration_since(now)) - .unwrap_or(Duration::ZERO), + .map_or(Duration::ZERO, |deadline| { + deadline.saturating_duration_since(now) + }), ) } diff --git a/src/backend/wayland/tablet_types.rs b/src/backend/wayland/tablet_types.rs index fea3eef81..008214813 100644 --- a/src/backend/wayland/tablet_types.rs +++ b/src/backend/wayland/tablet_types.rs @@ -1,8 +1,8 @@ use wayland_protocols::wp::tablet::zv2::client::zwp_tablet_tool_v2::Type; -/// Physical tool types as defined by the zwp_tablet_tool_v2 protocol. +/// Physical tool types as defined by the `zwp_tablet_tool_v2` protocol. /// -/// See: https://wayland.app/protocols/tablet-v2#zwp_tablet_tool_v2:enum:type +/// See: #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TabletToolType { /// Pen tool (0x140) @@ -43,7 +43,7 @@ impl TabletToolType { /// Protocol value for lens tool const LENS_VALUE: u32 = 0x147; - /// Converts from the raw u32 protocol value to TabletToolType. + /// Converts from the raw u32 protocol value to `TabletToolType`. pub fn from_raw(value: u32) -> Self { match value { Self::PEN_VALUE => TabletToolType::Pen, diff --git a/src/backend/wayland/toolbar/hit.rs b/src/backend/wayland/toolbar/hit.rs index c736c0511..f72f3d969 100644 --- a/src/backend/wayland/toolbar/hit.rs +++ b/src/backend/wayland/toolbar/hit.rs @@ -27,7 +27,7 @@ pub struct HitRegion { const ROW_HIT_LENGTH: f64 = MIN_HIT_TARGET * 3.0; /// Shared pointer-target predicate: true when (x, y) lands inside `rect` -/// inflated to the minimum target size. Used by both the legacy HitRegion +/// inflated to the minimum target size. Used by both the legacy `HitRegion` /// path and the view-engine tree so the two can never disagree. pub fn rect_contains_with_min_target(rect: (f64, f64, f64, f64), x: f64, y: f64) -> bool { let (rx, ry, rw, rh) = rect_with_min_target(rect); diff --git a/src/backend/wayland/toolbar/layout/mod.rs b/src/backend/wayland/toolbar/layout/mod.rs index 5d2804cdc..616ea6628 100644 --- a/src/backend/wayland/toolbar/layout/mod.rs +++ b/src/backend/wayland/toolbar/layout/mod.rs @@ -15,7 +15,7 @@ pub fn top_size(engine: &UiTextEngine, snapshot: &ToolbarSnapshot) -> (u32, u32) } /// Scroll bounds for the open Canvas/Session/Settings popover on the top strip as -/// (natural_height, viewport_height), both in pre-scale spec units; `None` +/// (`natural_height`, `viewport_height`), both in pre-scale spec units; `None` /// while no menu popover is open. pub fn top_popover_scroll_bounds( engine: &UiTextEngine, @@ -32,7 +32,7 @@ fn scale_size(size: (u32, u32), scale: f64) -> (u32, u32) { 1.0 }; ( - (size.0 as f64 * scale).ceil() as u32, - (size.1 as f64 * scale).ceil() as u32, + (f64::from(size.0) * scale).ceil() as u32, + (f64::from(size.1) * scale).ceil() as u32, ) } diff --git a/src/backend/wayland/toolbar/layout/spec/top.rs b/src/backend/wayland/toolbar/layout/spec/top.rs index e560e7d21..0a50a7478 100644 --- a/src/backend/wayland/toolbar/layout/spec/top.rs +++ b/src/backend/wayland/toolbar/layout/spec/top.rs @@ -107,7 +107,7 @@ impl ToolbarLayoutSpec { } else { Self::TOP_SIZE_TEXT.1 }; - let mut height = base_height as f64; + let mut height = f64::from(base_height); // Popovers (shapes grid + options, overflow) and the contextual // highlight-ring row grow the surface below the bar. height += top::top_extra_height(engine, snapshot); diff --git a/src/backend/wayland/toolbar/layout/tests/mod.rs b/src/backend/wayland/toolbar/layout/tests/mod.rs index e1455f5d8..b29f7e921 100644 --- a/src/backend/wayland/toolbar/layout/tests/mod.rs +++ b/src/backend/wayland/toolbar/layout/tests/mod.rs @@ -62,11 +62,13 @@ fn narrow_viewports_drop_presets_then_overflow_items() { // Slightly narrow: the non-essential presets island yields first, before // any tool or utility is dropped (M7-C2). - snapshot.top_viewport_max = Some(full_width as f64 - 60.0); + snapshot.top_viewport_max = Some(f64::from(full_width) - 60.0); let degraded = top::plan_top_strip(&UiTextEngine::default(), &snapshot); assert!(degraded.drop_presets); assert!(degraded.dropped_tools.is_empty() && degraded.dropped_utilities.is_empty()); - assert!(top_size(&UiTextEngine::default(), &snapshot).0 as f64 <= full_width as f64 - 60.0); + assert!( + f64::from(top_size(&UiTextEngine::default(), &snapshot).0) <= f64::from(full_width) - 60.0 + ); // Very narrow: droppable items move into the overflow menu; the protected // core (Pen, Eraser, Undo/Redo, Clear) stays. Colors and presets have @@ -75,9 +77,14 @@ fn narrow_viewports_drop_presets_then_overflow_items() { let tight = top::plan_top_strip(&UiTextEngine::default(), &snapshot); assert!(tight.drop_presets); assert!(!tight.dropped_utilities.is_empty()); - assert!(top_size(&UiTextEngine::default(), &snapshot).0 as f64 <= 700.0); + assert!(f64::from(top_size(&UiTextEngine::default(), &snapshot).0) <= 700.0); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); for id in [ "top.tool.pen", "top.tool.eraser", @@ -96,7 +103,12 @@ fn narrow_viewports_drop_presets_then_overflow_items() { // Opening the overflow reveals Clear first, then the dropped items. snapshot.top_overflow_open = true; let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let overflow_ids: Vec<&str> = tree .nodes() .iter() @@ -147,7 +159,12 @@ fn overflow_contains_only_visible_items_and_is_structural() { snapshot.top_overflow_open = true; let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); assert!(tree.node_by_id(&"top.chrome.overflow".into()).is_some()); assert!( tree.node_by_id(&"top.overflow.top.utility.screenshot".into()) @@ -197,7 +214,7 @@ fn compact_top_strip_respects_budget_without_the_old_floor() { // The protected core (Pen, Eraser, history, and the never-dropped chrome // island including Exit) bounds how narrow the compact strip can get. for budget in [376, 340, 320] { - snapshot.top_viewport_max = Some(budget as f64); + snapshot.top_viewport_max = Some(f64::from(budget)); assert!( top_size(&UiTextEngine::default(), &snapshot).0 <= budget, "planned width {} exceeds {budget}", @@ -254,7 +271,12 @@ fn shapes_popover_hosts_the_relocated_tool_options() { let (w, h) = top_size(&UiTextEngine::default(), &snapshot); assert!(h > 58, "open popover grows the surface: {h}"); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); // The grid renders inside popover chrome with a caret. let panel = tree @@ -293,7 +315,12 @@ fn shapes_popover_hosts_the_relocated_tool_options() { let snapshot = snapshot_from_state(&state); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); assert_eq!(h, 104); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); assert!(tree.node_by_id(&"top.utility.fill".into()).is_none()); } @@ -312,7 +339,12 @@ fn highlight_ring_row_grows_the_bar_only_while_active() { // The highlight tool has no style properties, so the pill yields and // only the ring lane grows the 58px band. assert!(h > 58, "ring row grows the bar: {h}"); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); assert!( tree.node_by_id(&"top.island.style".into()).is_none(), "no style pill while the highlight tool is active" @@ -337,7 +369,12 @@ fn highlight_ring_and_top_popovers_use_separate_lanes() { ); let snapshot = snapshot_from_state(&state); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let ring = tree .node_by_id(&"top.utility.highlight-ring".into()) .expect("ring row"); @@ -355,7 +392,7 @@ fn highlight_ring_and_top_popovers_use_separate_lanes() { state.test_set_toolbar_items(items); let mut snapshot = snapshot_from_state(&state); snapshot.top_viewport_max = (480..=1120).rev().find_map(|budget| { - snapshot.top_viewport_max = Some(budget as f64); + snapshot.top_viewport_max = Some(f64::from(budget)); let plan = top::plan_top_strip(&UiTextEngine::default(), &snapshot); let has_dropped_items = !plan.dropped_tools.is_empty() || !plan.dropped_utilities.is_empty(); @@ -363,14 +400,19 @@ fn highlight_ring_and_top_popovers_use_separate_lanes() { && !plan .dropped_utilities .contains(&TopUtilityButton::Highlight)) - .then_some(budget as f64) + .then_some(f64::from(budget)) }); assert!( snapshot.top_viewport_max.is_some(), "overflow budget retaining highlight" ); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = top::build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = top::build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let ring = tree .node_by_id(&"top.utility.highlight-ring".into()) .expect("ring row"); @@ -400,12 +442,12 @@ fn top_size_scales_with_toolbar_scale() { let scaled_size = top_size(&UiTextEngine::default(), &snapshot); assert_eq!( scaled_size.0, - (base_size.0 as f64 * 1.5).ceil() as u32, + (f64::from(base_size.0) * 1.5).ceil() as u32, "Width should scale by 1.5x" ); assert_eq!( scaled_size.1, - (base_size.1 as f64 * 1.5).ceil() as u32, + (f64::from(base_size.1) * 1.5).ceil() as u32, "Height should scale by 1.5x" ); @@ -519,7 +561,7 @@ fn advanced_inline_shapes_yield_before_arrow_and_line() { let advanced_shapes = [Tool::Spotlight, Tool::Blur, Tool::Ellipse, Tool::Rect]; let mut saw_arrow_drop = false; for budget in (500..advanced_width).step_by(20) { - advanced.top_viewport_max = Some(budget as f64); + advanced.top_viewport_max = Some(f64::from(budget)); let plan = top::plan_top_strip(&engine, &advanced); if plan.dropped_tools.contains(&Tool::Arrow) { saw_arrow_drop = true; diff --git a/src/backend/wayland/toolbar/main/lifecycle.rs b/src/backend/wayland/toolbar/main/lifecycle.rs index 9d48aa694..6189e0ea7 100644 --- a/src/backend/wayland/toolbar/main/lifecycle.rs +++ b/src/backend/wayland/toolbar/main/lifecycle.rs @@ -29,8 +29,7 @@ impl ToolbarSurfaceManager { if self.is_top_visible() { if self.top.layer_surface.is_none() { info!( - "Ensuring top toolbar surface exists at logical size {:?}, scale {}", - top_size, scale + "Ensuring top toolbar surface exists at logical size {top_size:?}, scale {scale}" ); self.top.set_logical_size(top_size); } else if self.top.logical_size != top_size { diff --git a/src/backend/wayland/toolbar/main/render.rs b/src/backend/wayland/toolbar/main/render.rs index c38ba1a49..ed40e4b1f 100644 --- a/src/backend/wayland/toolbar/main/render.rs +++ b/src/backend/wayland/toolbar/main/render.rs @@ -48,11 +48,7 @@ impl ToolbarSurfaceManager { /// Store the latest snapshot and report whether it differs from the previous one. pub fn update_snapshot(&mut self, snapshot: &ToolbarSnapshot) -> bool { - let changed = self - .last_snapshot - .as_ref() - .map(|prev| prev != snapshot) - .unwrap_or(true); + let changed = self.last_snapshot.as_ref() != Some(snapshot); self.last_snapshot = Some(snapshot.clone()); changed } diff --git a/src/backend/wayland/toolbar/render/paint.rs b/src/backend/wayland/toolbar/render/paint.rs index ebd2405e1..daa457df5 100644 --- a/src/backend/wayland/toolbar/render/paint.rs +++ b/src/backend/wayland/toolbar/render/paint.rs @@ -55,9 +55,9 @@ pub fn paint_tree( } fn hovered(node: &WidgetNode, hover: Option<(f64, f64)>) -> bool { - hover - .map(|(hx, hy)| point_in_rect(hx, hy, node.rect.0, node.rect.1, node.rect.2, node.rect.3)) - .unwrap_or(false) + hover.is_some_and(|(hx, hy)| { + point_in_rect(hx, hy, node.rect.0, node.rect.1, node.rect.2, node.rect.3) + }) } fn label_style(size: f64, bold: bool) -> UiTextStyle<'static> { @@ -375,7 +375,7 @@ fn paint_node( // Translucent colors sit on the checkerboard, so a low-alpha // swatch reads as see-through rather than as the bar behind it. let swatch_path = |ctx: &cairo::Context| { - draw_round_rect(ctx, x + 1.0, y + 1.0, w - 2.0, h - 2.0, 5.0) + draw_round_rect(ctx, x + 1.0, y + 1.0, w - 2.0, h - 2.0, 5.0); }; ui::checkerboard_behind(ctx, color.3, swatch_path); ctx.set_source_rgba(color.0, color.1, color.2, color.3); @@ -714,7 +714,7 @@ mod tests { }); let node = WidgetNode::new( "test.preset", - (0.0, 0.0, SIZE as f64, SIZE as f64), + (0.0, 0.0, f64::from(SIZE), f64::from(SIZE)), WidgetKind::PresetSlot { glyph, color: (1.0, 0.0, 0.0, 1.0), diff --git a/src/backend/wayland/toolbar/render/top_strip/tests.rs b/src/backend/wayland/toolbar/render/top_strip/tests.rs index 6f039891d..2a2607fc3 100644 --- a/src/backend/wayland/toolbar/render/top_strip/tests.rs +++ b/src/backend/wayland/toolbar/render/top_strip/tests.rs @@ -16,7 +16,7 @@ use crate::ui::toolbar::ToolbarBindingHints; fn pixels(density: i32, paint: impl FnOnce(&cairo::Context)) -> Vec { let mut surface = cairo::ImageSurface::create(cairo::Format::ARgb32, 2000 * density, 800 * density).unwrap(); - surface.set_device_scale(density as f64, density as f64); + surface.set_device_scale(f64::from(density), f64::from(density)); let ctx = cairo::Context::new(&surface).unwrap(); paint(&ctx); drop(ctx); @@ -84,10 +84,10 @@ fn retained_widget_text_matches_fresh_targets() { } for density in [1, 2, 1] { let actual = pixels(density, |ctx| { - paint_tree(&engine, ctx, &tree, Some((80.0, 390.0))) + paint_tree(&engine, ctx, &tree, Some((80.0, 390.0))); }); let expected = pixels(density, |ctx| { - paint_tree(&UiTextEngine::default(), ctx, &tree, Some((80.0, 390.0))) + paint_tree(&UiTextEngine::default(), ctx, &tree, Some((80.0, 390.0))); }); assert!(actual == expected, "widget text at density {density}"); assert!(actual.iter().any(|byte| *byte != 0)); @@ -105,7 +105,8 @@ fn retained_top_strip_preserves_fade_hits_and_delayed_tooltips_across_targets() for fade in [1.0, 0.45] { snapshot.top_fade = fade; let (width, height) = toolbar::top_size(&engine, &snapshot); - let tree = view::top::build_top_view(&engine, &snapshot, width as f64, height as f64); + let tree = + view::top::build_top_view(&engine, &snapshot, f64::from(width), f64::from(height)); let planned_hits = tree.to_hit_regions(); let hovered = planned_hits .iter() @@ -122,28 +123,28 @@ fn retained_top_strip_preserves_fade_hits_and_delayed_tooltips_across_targets() render_top_strip( &engine, ctx, - width as f64, - height as f64, + f64::from(width), + f64::from(height), &snapshot, &mut hits, hover, start, ) - .unwrap() + .unwrap(); }); let mut fresh_hits = Vec::new(); let expected = pixels(density, |ctx| { render_top_strip( &UiTextEngine::default(), ctx, - width as f64, - height as f64, + f64::from(width), + f64::from(height), &snapshot, &mut fresh_hits, hover, start, ) - .unwrap() + .unwrap(); }); assert!(actual == expected, "strip density {density}, fade {fade}"); assert_eq!(hits.len(), planned_hits.len()); @@ -162,11 +163,11 @@ fn retained_top_strip_preserves_fade_hits_and_delayed_tooltips_across_targets() ctx, &hits, hover, - width as f64, - height as f64, + f64::from(width), + f64::from(height), false, start, - ) + ); }); assert!(tooltip.iter().any(|byte| *byte != 0)); // A future start deterministically exercises the not-yet-ready path. @@ -176,11 +177,11 @@ fn retained_top_strip_preserves_fade_hits_and_delayed_tooltips_across_targets() ctx, &hits, hover, - width as f64, - height as f64, + f64::from(width), + f64::from(height), false, Some(Instant::now() + Duration::from_secs(60)), - ) + ); }); assert!(hidden.iter().all(|byte| *byte == 0)); } @@ -199,14 +200,14 @@ fn idle_hidden_strip_paints_nothing_but_keeps_its_hits() { render_top_strip( &engine, ctx, - width as f64, - height as f64, + f64::from(width), + f64::from(height), snapshot, hits, None, None, ) - .unwrap() + .unwrap(); }) }; diff --git a/src/backend/wayland/toolbar/render/widgets/buttons.rs b/src/backend/wayland/toolbar/render/widgets/buttons.rs index c53a57a50..c3b4bcaed 100644 --- a/src/backend/wayland/toolbar/render/widgets/buttons.rs +++ b/src/backend/wayland/toolbar/render/widgets/buttons.rs @@ -16,7 +16,7 @@ use crate::ui_text::{UiTextEngine, UiTextStyle}; use std::f64::consts::PI; /// Faint white glow behind a hovered flat button (quieter than -/// COLOR_ICON_HOVER_BG; value-coincides with COLOR_DIVIDER but is a hover +/// `COLOR_ICON_HOVER_BG`; value-coincides with `COLOR_DIVIDER` but is a hover /// affordance, not a separator). const COLOR_BUTTON_HOVER_GLOW: Rgba = (1.0, 1.0, 1.0, 0.08); /// Warning-tinted glow behind a hovered destructive button (destructive diff --git a/src/backend/wayland/toolbar/render/widgets/checkbox.rs b/src/backend/wayland/toolbar/render/widgets/checkbox.rs index 02c99cb9d..1947719da 100644 --- a/src/backend/wayland/toolbar/render/widgets/checkbox.rs +++ b/src/backend/wayland/toolbar/render/widgets/checkbox.rs @@ -94,7 +94,7 @@ pub(in crate::backend::wayland::toolbar::render) fn draw_mini_checkbox( let layout = engine.layout(ctx, label_style, label, None); let ext = layout.ink_extents(); let label_x = x + box_size + SPACING_LG + (w - box_size - 12.0 - ext.width()) / 2.0; - let label_y = y + (h + ext.height()) / 2.0; + let label_y = y + f64::midpoint(h, ext.height()); set_color(ctx, COLOR_TEXT_SECONDARY); layout.show_at_baseline(ctx, label_x, label_y); } diff --git a/src/backend/wayland/toolbar/surfaces/lifecycle.rs b/src/backend/wayland/toolbar/surfaces/lifecycle.rs index 00aa6b658..86bb64462 100644 --- a/src/backend/wayland/toolbar/surfaces/lifecycle.rs +++ b/src/backend/wayland/toolbar/surfaces/lifecycle.rs @@ -56,7 +56,7 @@ impl ToolbarSurface { self.configured = false; } - /// Resize an already-mapped surface in place via layer_surface.set_size + /// Resize an already-mapped surface in place via `layer_surface.set_size` /// instead of destroy/recreate, so size changes (shape picker, drawer, /// contextual sections) don't flicker. Rendering pauses until the /// compositor acks with a new configure. diff --git a/src/backend/wayland/toolbar/surfaces/render.rs b/src/backend/wayland/toolbar/surfaces/render.rs index 041bb3cad..a78aab512 100644 --- a/src/backend/wayland/toolbar/surfaces/render.rs +++ b/src/backend/wayland/toolbar/surfaces/render.rs @@ -64,9 +64,8 @@ impl ToolbarSurface { } } - let pool = match self.pool.as_mut() { - Some(p) => p, - None => return Err(anyhow!("shm pool is missing after creation")), + let Some(pool) = self.pool.as_mut() else { + return Err(anyhow!("shm pool is missing after creation")); }; let (buffer, canvas) = pool .create_buffer( @@ -105,11 +104,13 @@ impl ToolbarSurface { } else { 1.0 }; - let (logical_w, logical_h) = - (self.width as f64 / ui_scale, self.height as f64 / ui_scale); + let (logical_w, logical_h) = ( + f64::from(self.width) / ui_scale, + f64::from(self.height) / ui_scale, + ); let hover_scaled = hover.map(|(x, y)| (x / ui_scale, y / ui_scale)); if self.scale > 1 { - ctx.scale(self.scale as f64, self.scale as f64); + ctx.scale(f64::from(self.scale), f64::from(self.scale)); } if (ui_scale - 1.0).abs() > f64::EPSILON { ctx.scale(ui_scale, ui_scale); diff --git a/src/backend/wayland/toolbar/surfaces/state.rs b/src/backend/wayland/toolbar/surfaces/state.rs index 8c6d5206b..aff057430 100644 --- a/src/backend/wayland/toolbar/surfaces/state.rs +++ b/src/backend/wayland/toolbar/surfaces/state.rs @@ -130,8 +130,8 @@ impl ToolbarSurface { let rects = top::top_input_rects( engine, snapshot, - self.width as f64 / ui_scale, - self.height as f64 / ui_scale, + f64::from(self.width) / ui_scale, + f64::from(self.height) / ui_scale, ) .map(|rects| { rects diff --git a/src/backend/wayland/toolbar/surfaces/structs.rs b/src/backend/wayland/toolbar/surfaces/structs.rs index 1e93bfd86..d1f67afa3 100644 --- a/src/backend/wayland/toolbar/surfaces/structs.rs +++ b/src/backend/wayland/toolbar/surfaces/structs.rs @@ -68,8 +68,7 @@ impl ToolbarSurface { pub fn is_layer(&self, layer: &LayerSurface) -> bool { self.layer_surface .as_ref() - .map(|ls| ls.wl_surface().id() == layer.wl_surface().id()) - .unwrap_or(false) + .is_some_and(|ls| ls.wl_surface().id() == layer.wl_surface().id()) } pub(in crate::backend::wayland) fn wl_surface(&self) -> Option<&wl_surface::WlSurface> { @@ -79,8 +78,7 @@ impl ToolbarSurface { pub fn is_surface(&self, surface: &wl_surface::WlSurface) -> bool { self.wl_surface .as_ref() - .map(|s| s.id() == surface.id()) - .unwrap_or(false) + .is_some_and(|s| s.id() == surface.id()) } /// Get cursor hint for the current hover position. diff --git a/src/backend/wayland/toolbar/view/top.rs b/src/backend/wayland/toolbar/view/top.rs index 61d4e5d34..f493a8d4b 100644 --- a/src/backend/wayland/toolbar/view/top.rs +++ b/src/backend/wayland/toolbar/view/top.rs @@ -261,9 +261,9 @@ fn planned_button_size(snapshot: &ToolbarSnapshot, plan: &TopStripPlan) -> (f64, fn base_bar_height(snapshot: &ToolbarSnapshot) -> f64 { if snapshot.use_icons { - ToolbarLayoutSpec::TOP_SIZE_ICONS.1 as f64 + f64::from(ToolbarLayoutSpec::TOP_SIZE_ICONS.1) } else { - ToolbarLayoutSpec::TOP_SIZE_TEXT.1 as f64 + f64::from(ToolbarLayoutSpec::TOP_SIZE_TEXT.1) } } @@ -357,7 +357,7 @@ pub fn top_extra_height(engine: &UiTextEngine, snapshot: &ToolbarSnapshot) -> f6 } /// Scroll bounds for the open Canvas/Session/Settings popover as -/// (natural_height, viewport_height), both in pre-scale spec units; `None` +/// (`natural_height`, `viewport_height`), both in pre-scale spec units; `None` /// while no menu popover is open. The wheel path and scrollbar drag use these /// same bounds. pub fn top_popover_scroll_bounds( diff --git a/src/backend/wayland/toolbar/view/top/arrow_menu/tests.rs b/src/backend/wayland/toolbar/view/top/arrow_menu/tests.rs index 188a2e40f..998e8d7ff 100644 --- a/src/backend/wayland/toolbar/view/top/arrow_menu/tests.rs +++ b/src/backend/wayland/toolbar/view/top/arrow_menu/tests.rs @@ -26,7 +26,7 @@ fn snapshot_for(style: ArrowStyle, open: bool) -> ToolbarSnapshot { fn tree_for(snapshot: &ToolbarSnapshot) -> WidgetTree { let engine = UiTextEngine::default(); let (w, h) = top_size(&engine, snapshot); - build_top_view(&engine, snapshot, w as f64, h as f64) + build_top_view(&engine, snapshot, f64::from(w), f64::from(h)) } fn menu_ids(tree: &WidgetTree) -> Vec { @@ -163,13 +163,16 @@ fn the_open_menu_grows_height_and_input_but_not_width() { assert!(top_extra_height(&engine, &open) > top_extra_height(&engine, &closed)); let (w, h) = top_size(&engine, &open); - let tree = build_top_view(&engine, &open, w as f64, h as f64); + let tree = build_top_view(&engine, &open, f64::from(w), f64::from(h)); let panel = tree .node_by_id(&"top.arrow-style.panel".into()) .expect("panel") .rect; - assert!(panel.1 + panel.3 <= h as f64, "the menu fits the surface"); - let rects = top_input_rects(&engine, &open, w as f64, h as f64).expect("rects"); + assert!( + panel.1 + panel.3 <= f64::from(h), + "the menu fits the surface" + ); + let rects = top_input_rects(&engine, &open, f64::from(w), f64::from(h)).expect("rects"); assert!( rects.iter().any(|rect| contains(*rect, panel)), "the whole menu accepts input: {panel:?} in {rects:?}" diff --git a/src/backend/wayland/toolbar/view/top/build.rs b/src/backend/wayland/toolbar/view/top/build.rs index 62ab10154..f8bfcd9fc 100644 --- a/src/backend/wayland/toolbar/view/top/build.rs +++ b/src/backend/wayland/toolbar/view/top/build.rs @@ -1133,16 +1133,14 @@ fn preset_slot_node( model::TopToolbarIcon::Tool(model::semantic_icon_for_tool(preset.tool)), )) }); - let color = preset - .map(|preset| { - ( - preset.color.r, - preset.color.g, - preset.color.b, - preset.color.a, - ) - }) - .unwrap_or((0.0, 0.0, 0.0, 0.0)); + let color = preset.map_or((0.0, 0.0, 0.0, 0.0), |preset| { + ( + preset.color.r, + preset.color.g, + preset.color.b, + preset.color.a, + ) + }); WidgetNode::new( control.id().render_id().into_owned(), rect, @@ -1179,13 +1177,13 @@ fn control_button_node_with_tooltip( tooltip: String, ) -> WidgetNode { let enabled = control.enabled(snapshot); - let style = if !enabled { - ButtonStyle::disabled() - } else { + let style = if enabled { match control.role() { model::TopToolbarControlRole::Destructive => ButtonStyle::destructive(), _ => ButtonStyle::active(control.active(snapshot)), } + } else { + ButtonStyle::disabled() }; let kind = if use_icons { let icon_size = if control == model::TopToolbarControl::ShapePicker { diff --git a/src/backend/wayland/toolbar/view/top/layout_menu.rs b/src/backend/wayland/toolbar/view/top/layout_menu.rs index 74e62d5f5..0e752e084 100644 --- a/src/backend/wayland/toolbar/view/top/layout_menu.rs +++ b/src/backend/wayland/toolbar/view/top/layout_menu.rs @@ -144,7 +144,7 @@ mod tests { fn tree_for(snapshot: &ToolbarSnapshot) -> WidgetTree { let engine = UiTextEngine::default(); let (w, h) = top_size(&engine, snapshot); - build_top_view(&engine, snapshot, w as f64, h as f64) + build_top_view(&engine, snapshot, f64::from(w), f64::from(h)) } #[test] @@ -200,13 +200,16 @@ mod tests { assert!(top_extra_height(&engine, &open) >= top_extra_height(&engine, &closed)); let (w, h) = top_size(&engine, &open); - let tree = build_top_view(&engine, &open, w as f64, h as f64); + let tree = build_top_view(&engine, &open, f64::from(w), f64::from(h)); let panel = tree .node_by_id(&"top.layout.panel".into()) .expect("panel") .rect; - assert!(panel.1 + panel.3 <= h as f64, "the panel fits the surface"); - let rects = top_input_rects(&engine, &open, w as f64, h as f64).expect("rects"); + assert!( + panel.1 + panel.3 <= f64::from(h), + "the panel fits the surface" + ); + let rects = top_input_rects(&engine, &open, f64::from(w), f64::from(h)).expect("rects"); assert!( rects.iter().any(|rect| rect.0 <= panel.0 && rect.1 <= panel.1 diff --git a/src/backend/wayland/toolbar/view/top/menus.rs b/src/backend/wayland/toolbar/view/top/menus.rs index 3cc162094..a8581948a 100644 --- a/src/backend/wayland/toolbar/view/top/menus.rs +++ b/src/backend/wayland/toolbar/view/top/menus.rs @@ -125,7 +125,7 @@ fn menu_viewport_cap(snapshot: &ToolbarSnapshot, plan: &super::TopStripPlan) -> } /// Scroll bounds for the open Canvas/Session/Settings popover as -/// (natural_height, viewport_height), both in pre-scale spec units; `None` +/// (`natural_height`, `viewport_height`), both in pre-scale spec units; `None` /// while no menu popover is open. Max scroll = (natural - viewport).max(0). pub(super) fn menu_scroll_bounds_planned( engine: &UiTextEngine, @@ -210,7 +210,7 @@ pub(super) fn push_menu_popover( } if max_scroll > 0.0 { let track = ( - px + pw - (MENU_PAD + MENU_SCROLLBAR_W) / 2.0, + px + pw - f64::midpoint(MENU_PAD, MENU_SCROLLBAR_W), py + MENU_PAD, MENU_SCROLLBAR_W, viewport, @@ -724,8 +724,9 @@ fn settings_notice_height(engine: &UiTextEngine, text: &str, bold: bool) -> f64 }; engine .measure(style, text, Some(MENU_CONTENT_W)) - .map(|extents| extents.height() + MENU_NOTICE_PADDING_Y) - .unwrap_or(MENU_TOGGLE_H) + .map_or(MENU_TOGGLE_H, |extents| { + extents.height() + MENU_NOTICE_PADDING_Y + }) .max(MENU_TOGGLE_H) } diff --git a/src/backend/wayland/toolbar/view/top/pen_feel/tests.rs b/src/backend/wayland/toolbar/view/top/pen_feel/tests.rs index b797bd7cb..a784318ee 100644 --- a/src/backend/wayland/toolbar/view/top/pen_feel/tests.rs +++ b/src/backend/wayland/toolbar/view/top/pen_feel/tests.rs @@ -26,7 +26,7 @@ fn snapshot_for(tool: Tool, style: ToolbarStrokeControls, open: bool) -> Toolbar fn tree_for(snapshot: &ToolbarSnapshot) -> WidgetTree { let engine = UiTextEngine::default(); let (w, h) = top_size(&engine, snapshot); - build_top_view(&engine, snapshot, w as f64, h as f64) + build_top_view(&engine, snapshot, f64::from(w), f64::from(h)) } fn feel_ids(tree: &WidgetTree) -> Vec { @@ -97,7 +97,7 @@ fn the_chip_stands_in_for_both_controls_inside_the_planned_width() { .expect("style pill"); assert!(chip.rect.0 + chip.rect.2 <= pill.rect.0 + pill.rect.2); let (_, h) = top_size(&engine, &snapshot); - assert!(top_natural_width(&engine, &snapshot, h as f64) >= pill.rect.0 + pill.rect.2); + assert!(top_natural_width(&engine, &snapshot, f64::from(h)) >= pill.rect.0 + pill.rect.2); assert!(feel_ids(&tree).is_empty(), "the panel is closed"); } @@ -271,7 +271,7 @@ fn the_open_panel_grows_height_and_input_but_not_width() { assert!(top_extra_height(&engine, &open) > top_extra_height(&engine, &closed)); let (w, h) = top_size(&engine, &open); - let tree = build_top_view(&engine, &open, w as f64, h as f64); + let tree = build_top_view(&engine, &open, f64::from(w), f64::from(h)); let panel = tree .node_by_id(&"top.feel.panel".into()) .expect("panel") @@ -293,7 +293,10 @@ fn the_open_panel_grows_height_and_input_but_not_width() { .rect; assert!(caret_up, "{tool:?} opens below"); assert!(panel.1 >= pill.1 + pill.3, "{tool:?} clears the pill"); - assert!(panel.1 + panel.3 <= h as f64, "{tool:?} fits the surface"); + assert!( + panel.1 + panel.3 <= f64::from(h), + "{tool:?} fits the surface" + ); assert!( caret_x >= chip.0 && caret_x <= chip.0 + chip.2, "{tool:?} caret" @@ -304,7 +307,7 @@ fn the_open_panel_grows_height_and_input_but_not_width() { "{tool:?}" ); - let rects = top_input_rects(&engine, &open, w as f64, h as f64).expect("rects"); + let rects = top_input_rects(&engine, &open, f64::from(w), f64::from(h)).expect("rects"); assert!( rects.iter().any(|rect| rect.0 <= panel.0 && rect.0 + rect.2 >= panel.0 + panel.2 diff --git a/src/backend/wayland/toolbar/view/top/tests.rs b/src/backend/wayland/toolbar/view/top/tests.rs index 8af78f740..aeb29f185 100644 --- a/src/backend/wayland/toolbar/view/top/tests.rs +++ b/src/backend/wayland/toolbar/view/top/tests.rs @@ -34,7 +34,12 @@ fn snapshot() -> ToolbarSnapshot { fn build(snapshot: &ToolbarSnapshot) -> WidgetTree { let (w, h) = top_size(&UiTextEngine::default(), snapshot); - build_top_view(&UiTextEngine::default(), snapshot, w as f64, h as f64) + build_top_view( + &UiTextEngine::default(), + snapshot, + f64::from(w), + f64::from(h), + ) } fn node_id_list(tree: &WidgetTree) -> Vec<&str> { @@ -259,8 +264,13 @@ fn presets_render_as_slot_buttons_in_the_presets_island() { // The presets island joins the surface input region as its own rect. let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let rects = top_input_rects(&UiTextEngine::default(), &snapshot, w as f64, h as f64) - .expect("input rects"); + let rects = top_input_rects( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ) + .expect("input rects"); assert!(rects.contains(&island.rect)); } @@ -269,7 +279,7 @@ fn idle_hidden_strip_keeps_its_size_but_passes_input_through() { let engine = UiTextEngine::default(); let mut snapshot = snapshot(); let shown_size = top_size(&engine, &snapshot); - let (w, h) = (shown_size.0 as f64, shown_size.1 as f64); + let (w, h) = (f64::from(shown_size.0), f64::from(shown_size.1)); let shown_rects = top_input_rects(&engine, &snapshot, w, h).expect("island rects"); assert!(!shown_rects.is_empty()); @@ -491,8 +501,13 @@ fn input_rects_cover_islands_and_open_popovers_only() { let snapshot = ToolbarSnapshot::from_input_with_bindings(&state, ToolbarBindingHints::default()); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let rects = top_input_rects(&UiTextEngine::default(), &snapshot, w as f64, h as f64) - .expect("no popover: the islands still restrict input"); + let rects = top_input_rects( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ) + .expect("no popover: the islands still restrict input"); assert_eq!( rects.len(), 5, @@ -505,7 +520,12 @@ fn input_rects_cover_islands_and_open_popovers_only() { assert!(rects[2].0 + rects[2].2 < rects[3].0); // The style pill is the fifth rect, detached below the band. assert!(rects[4].1 > rects[0].1 + rects[0].3); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let islands: Vec<_> = tree .nodes() .iter() @@ -523,14 +543,19 @@ fn input_rects_cover_islands_and_open_popovers_only() { let snapshot = ToolbarSnapshot::from_input_with_bindings(&state, ToolbarBindingHints::default()); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let rects = top_input_rects(&UiTextEngine::default(), &snapshot, w as f64, h as f64) - .expect("partial input region"); + let rects = top_input_rects( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ) + .expect("partial input region"); assert_eq!(rects.len(), 6, "five islands + shapes panel: {rects:?}"); assert_eq!(rects[0].0, 0.0); assert_eq!(rects[0].1, 0.0); for island in &rects[..5] { assert!( - island.1 + island.3 < h as f64, + island.1 + island.3 < f64::from(h), "islands end above the popover" ); } @@ -539,7 +564,12 @@ fn input_rects_cover_islands_and_open_popovers_only() { assert!(rects[0].0 + rects[0].2 < rects[1].0); assert!(rects[1].0 + rects[1].2 < rects[2].0); assert!(rects[2].0 + rects[2].2 < rects[3].0); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let panel = tree .node_by_id(&"top.shapes.panel".into()) .expect("panel node"); @@ -561,9 +591,19 @@ fn island_backgrounds_stop_at_bar_band_when_popover_is_open() { let snapshot = ToolbarSnapshot::from_input_with_bindings(&state, ToolbarBindingHints::default()); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); - let input_rects = top_input_rects(&UiTextEngine::default(), &snapshot, w as f64, h as f64) - .expect("partial input region"); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); + let input_rects = top_input_rects( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ) + .expect("partial input region"); let islands: Vec<_> = tree .nodes() @@ -574,7 +614,7 @@ fn island_backgrounds_stop_at_bar_band_when_popover_is_open() { for (island, input_rect) in islands.iter().zip(&input_rects[..5]) { assert_eq!(island.rect, *input_rect, "{}", island.id); assert!( - island.rect.1 + island.rect.3 < h as f64, + island.rect.1 + island.rect.3 < f64::from(h), "popover area must stay transparent" ); } @@ -590,7 +630,12 @@ fn minimized_strip_is_a_single_restore_tab() { let (w, h) = top_size(&UiTextEngine::default(), &snapshot); assert_eq!((w, h), (104, 32)); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let interactive: Vec<_> = tree .nodes() .iter() @@ -627,7 +672,12 @@ fn micro_strip_is_a_single_round_chip() { "micro mode is one 44px chip" ); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let interactive: Vec<_> = tree .nodes() .iter() @@ -668,7 +718,15 @@ fn micro_strip_is_a_single_round_chip() { // No popovers, ring rows, or partial input regions in micro mode: the // whole 44px surface takes input. - assert!(top_input_rects(&UiTextEngine::default(), &snapshot, w as f64, h as f64).is_none()); + assert!( + top_input_rects( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h) + ) + .is_none() + ); assert_eq!(top_extra_height(&UiTextEngine::default(), &snapshot), 0.0); // Minimized wins if both states are somehow set. @@ -1095,11 +1153,21 @@ fn style_pill_geometry_holds_per_tool_and_select_hides_the_pill() { // no fourth input rect, no extra height for it. let select = snapshot_for_tool(Tool::Select); let (w, h) = top_size(&UiTextEngine::default(), &select); - let tree = build_top_view(&UiTextEngine::default(), &select, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &select, + f64::from(w), + f64::from(h), + ); assert!(tree.node_by_id(&"top.island.style".into()).is_none()); assert!(style_ids(&tree).is_empty()); - let rects = top_input_rects(&UiTextEngine::default(), &select, w as f64, h as f64) - .expect("island input rects"); + let rects = top_input_rects( + &UiTextEngine::default(), + &select, + f64::from(w), + f64::from(h), + ) + .expect("island input rects"); assert_eq!( rects.len(), 4, @@ -1128,7 +1196,12 @@ fn style_pill_geometry_holds_per_tool_and_select_hides_the_pill() { selection.selection_has_text = true; selection.selected_text_bold = Some(false); let (w, h) = top_size(&UiTextEngine::default(), &selection); - let tree = build_top_view(&UiTextEngine::default(), &selection, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &selection, + f64::from(w), + f64::from(h), + ); let style = tree .node_by_id(&"top.island.style".into()) .expect("selection pill card"); @@ -1147,8 +1220,13 @@ fn style_pill_geometry_holds_per_tool_and_select_hides_the_pill() { "top.style.font-bold", ] ); - let rects = top_input_rects(&UiTextEngine::default(), &selection, w as f64, h as f64) - .expect("island input rects"); + let rects = top_input_rects( + &UiTextEngine::default(), + &selection, + f64::from(w), + f64::from(h), + ) + .expect("island input rects"); assert_eq!(rects.len(), 5, "selection pill rect: {rects:?}"); let pill_rect = rects[4]; assert_eq!( @@ -1167,7 +1245,12 @@ fn style_pill_geometry_holds_per_tool_and_select_hides_the_pill() { ] { let snapshot = snapshot_for_tool(tool); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let tools = tree .node_by_id(&"top.island.tools".into()) .expect("tools island"); @@ -1208,8 +1291,13 @@ fn style_pill_geometry_holds_per_tool_and_select_hides_the_pill() { // The pill joins the surface input region as the fifth rect (after // the tools, presets, history, and chrome band islands). - let rects = top_input_rects(&UiTextEngine::default(), &snapshot, w as f64, h as f64) - .expect("island input rects"); + let rects = top_input_rects( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ) + .expect("island input rects"); assert_eq!(rects.len(), 5, "{tool:?} rects: {rects:?}"); assert_eq!(rects[4], style.rect, "{tool:?} pill input rect"); } @@ -1327,7 +1415,7 @@ fn shape_pen_meters_carry_captions_and_level_bars_inside_the_planned_width() { .node_by_id(&"top.island.style".into()) .expect("style pill"); let (_, h) = top_size(&engine, &snapshot); - assert!(top_natural_width(&engine, &snapshot, h as f64) >= style.rect.0 + style.rect.2); + assert!(top_natural_width(&engine, &snapshot, f64::from(h)) >= style.rect.0 + style.rect.2); } #[test] @@ -1394,7 +1482,7 @@ fn shape_pen_steppers_carry_visible_captions_inside_the_planned_width() { .node_by_id(&"top.island.style".into()) .expect("style pill"); let (_, h) = top_size(&engine, &snapshot); - assert!(top_natural_width(&engine, &snapshot, h as f64) >= style.rect.0 + style.rect.2); + assert!(top_natural_width(&engine, &snapshot, f64::from(h)) >= style.rect.0 + style.rect.2); } #[test] @@ -1477,8 +1565,8 @@ fn runtime_sized_menu_popovers_do_not_reenter_strip_planning() { let tree = build_top_view( &UiTextEngine::default(), &snapshot, - width as f64, - height as f64, + f64::from(width), + f64::from(height), ); assert!( tree.node_by_id(&format!("top.menu.{name}.panel").into()) @@ -1813,8 +1901,13 @@ fn canvas_popover_scrolls_when_all_sections_exceed_the_viewport() { let panel = tree .node_by_id(&"top.menu.canvas.panel".into()) .expect("canvas panel"); - let rects = top_input_rects(&UiTextEngine::default(), &snapshot, w as f64, h as f64) - .expect("input rects"); + let rects = top_input_rects( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ) + .expect("input rects"); assert!( rects .iter() @@ -1841,7 +1934,12 @@ fn session_popover_re_hosts_the_session_pane_content() { .collect(); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let panel = tree .node_by_id(&"top.menu.session.panel".into()) .expect("session popover panel"); @@ -1951,8 +2049,13 @@ fn assert_session_popover_input_rect( .node_by_id(&"top.menu.session.panel".into()) .expect("session popover panel"); // The popover joins the input region as an extra rect below the band. - let rects = top_input_rects(&UiTextEngine::default(), snapshot, w as f64, h as f64) - .expect("input rects"); + let rects = top_input_rects( + &UiTextEngine::default(), + snapshot, + f64::from(w), + f64::from(h), + ) + .expect("input rects"); assert!( rects .iter() @@ -2234,7 +2337,12 @@ fn tall_popover_content_caps_the_panel_and_scrolls_internally() { assert!(natural > viewport, "short output must cap tall content"); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let panel = tree .node_by_id(&"top.menu.settings.panel".into()) .expect("settings popover panel"); @@ -2276,7 +2384,12 @@ fn tall_popover_content_caps_the_panel_and_scrolls_internally() { let unscrolled_first = tree.node_by_id(&"top.menu.settings.button.0".into()); assert!(unscrolled_first.is_some(), "top row visible before scroll"); snapshot.top_popover_scroll = max_scroll + 500.0; // clamps to max - let scrolled = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let scrolled = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let scrolled_panel = scrolled .node_by_id(&"top.menu.settings.panel".into()) .expect("panel"); @@ -2324,7 +2437,12 @@ fn tall_content_fills_a_tall_screen_without_scrolling() { ); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); assert!( tree.node_by_id(&"top.menu.settings.scrollbar".into()) .is_none(), @@ -2360,7 +2478,12 @@ fn tall_content_scrolls_on_a_short_screen() { ); let (w, h) = top_size(&UiTextEngine::default(), &snapshot); - let tree = build_top_view(&UiTextEngine::default(), &snapshot, w as f64, h as f64); + let tree = build_top_view( + &UiTextEngine::default(), + &snapshot, + f64::from(w), + f64::from(h), + ); let scrollbar = tree .node_by_id(&"top.menu.settings.scrollbar".into()) .expect("internal scrollbar on a short screen"); diff --git a/src/backend/wayland/toolbar/view/top/tests/engine.rs b/src/backend/wayland/toolbar/view/top/tests/engine.rs index 8b8e1287d..fff478cc5 100644 --- a/src/backend/wayland/toolbar/view/top/tests/engine.rs +++ b/src/backend/wayland/toolbar/view/top/tests/engine.rs @@ -20,17 +20,19 @@ fn retained_planner_preserves_wrapped_notices_surface_size_and_input_regions() { recovery_artifacts: Vec::new(), }); let size = top_size(&engine, &snapshot); - let tree = build_top_view(&engine, &snapshot, size.0 as f64, size.1 as f64); + let tree = build_top_view(&engine, &snapshot, f64::from(size.0), f64::from(size.1)); let fresh = UiTextEngine::default(); assert_eq!(size, top_size(&fresh, &snapshot)); assert!( - tree.nodes() == build_top_view(&fresh, &snapshot, size.0 as f64, size.1 as f64).nodes(), + tree.nodes() + == build_top_view(&fresh, &snapshot, f64::from(size.0), f64::from(size.1)).nodes(), "retained planner nodes for {path}" ); - let rects = top_input_rects(&engine, &snapshot, size.0 as f64, size.1 as f64).unwrap(); + let rects = + top_input_rects(&engine, &snapshot, f64::from(size.0), f64::from(size.1)).unwrap(); assert_eq!( Some(rects.clone()), - top_input_rects(&fresh, &snapshot, size.0 as f64, size.1 as f64) + top_input_rects(&fresh, &snapshot, f64::from(size.0), f64::from(size.1)) ); assert_eq!( top_popover_scroll_bounds(&engine, &snapshot), @@ -97,8 +99,8 @@ fn retained_planner_matches_fresh_under_width_pressure_and_scroll_bounds() { Some((natural, viewport)), top_popover_scroll_bounds(&fresh, &snapshot) ); - let actual = build_top_view(&engine, &snapshot, size.0 as f64, size.1 as f64); - let expected = build_top_view(&fresh, &snapshot, size.0 as f64, size.1 as f64); + let actual = build_top_view(&engine, &snapshot, f64::from(size.0), f64::from(size.1)); + let expected = build_top_view(&fresh, &snapshot, f64::from(size.0), f64::from(size.1)); assert!(actual.nodes() == expected.nodes(), "width pressure {width}"); assert!(!actual.to_hit_regions().is_empty()); } diff --git a/src/backend/wayland/toolbar_intent.rs b/src/backend/wayland/toolbar_intent.rs index ae54f6d2d..37a0730dc 100644 --- a/src/backend/wayland/toolbar_intent.rs +++ b/src/backend/wayland/toolbar_intent.rs @@ -10,7 +10,7 @@ impl ToolbarIntent { } } -/// Translate a backend intent into the UI-facing ToolbarEvent. Snapshot is +/// Translate a backend intent into the UI-facing `ToolbarEvent`. Snapshot is /// available for future context-sensitive mapping. pub fn intent_to_event(intent: ToolbarIntent, _snapshot: Option<&ToolbarSnapshot>) -> ToolbarEvent { let _ = _snapshot; diff --git a/src/backend/wayland/zoom/capture.rs b/src/backend/wayland/zoom/capture.rs index 44f920d8b..1c629f3b2 100644 --- a/src/backend/wayland/zoom/capture.rs +++ b/src/backend/wayland/zoom/capture.rs @@ -180,11 +180,8 @@ impl ZoomState { self.capture_done = false; - let output = match self.active_output.clone() { - Some(out) => out, - None => { - anyhow::bail!("No active output available for zoom capture"); - } + let Some(output) = self.active_output.clone() else { + anyhow::bail!("No active output available for zoom capture"); }; let (source_geometry, target_output_id) = require_verified_capture_source( self.active_geometry.clone(), @@ -224,7 +221,7 @@ impl ZoomState { "capture.preflight component=zoom phase=screencopy-buffer width={width} height={height} stride={stride} format={format:?}" ); if let Err(err) = self.on_buffer(format, width, height, stride) { - warn!("Failed to prepare zoom buffer: {}", err); + warn!("Failed to prepare zoom buffer: {err}"); self.fail_capture(input_state, false, err.to_string()); } } @@ -233,7 +230,7 @@ impl ZoomState { } FrameEvent::BufferDone => { if let Err(err) = self.on_buffer_done() { - warn!("Failed to issue zoom copy: {}", err); + warn!("Failed to issue zoom copy: {err}"); self.fail_capture(input_state, false, err.to_string()); } } @@ -243,9 +240,8 @@ impl ZoomState { WEnum::Value(v) => v.bits(), WEnum::Unknown(raw) => raw, }; - capture.y_invert = Flags::from_bits(raw_flags) - .map(|f| f.contains(Flags::YInvert)) - .unwrap_or(false); + capture.y_invert = + Flags::from_bits(raw_flags).is_some_and(|f| f.contains(Flags::YInvert)); } } FrameEvent::Ready { .. } => { @@ -257,7 +253,7 @@ impl ZoomState { return; } Err(err) => { - warn!("Zoom capture ready handling failed: {}", err); + warn!("Zoom capture ready handling failed: {err}"); self.fail_capture(input_state, false, err.to_string()); return; } @@ -307,7 +303,7 @@ impl ZoomState { let format = match format { WEnum::Value(fmt) => fmt, WEnum::Unknown(raw) => { - anyhow::bail!("Unknown wl_shm format {}", raw); + anyhow::bail!("Unknown wl_shm format {raw}"); } }; @@ -465,9 +461,8 @@ mod tests { data: vec![0; 3200 * 1800 * 4], }; - let error = match finalize_capture_image(image, &context) { - Err(error) => error, - Ok(_) => panic!("a full output cannot be stretched into a shorter viewport"), + let Err(error) = finalize_capture_image(image, &context) else { + panic!("a full output cannot be stretched into a shorter viewport"); }; assert!(error.to_string().contains("aspect does not match")); } diff --git a/src/backend/wayland/zoom/portal.rs b/src/backend/wayland/zoom/portal.rs index d73243098..8d6f589d8 100644 --- a/src/backend/wayland/zoom/portal.rs +++ b/src/backend/wayland/zoom/portal.rs @@ -123,10 +123,10 @@ impl ZoomState { }; self.install_image(image, provenance); } else { - if !layout_matches { - warn!("Portal zoom capture discarded after the output layout changed"); - } else { + if layout_matches { warn!("Portal zoom capture for inactive output discarded"); + } else { + warn!("Portal zoom capture discarded after the output layout changed"); } if self.queue_portal_layout_retry(target_output, !layout_matches) { return; diff --git a/src/backend/wayland/zoom/view.rs b/src/backend/wayland/zoom/view.rs index 9ebaf63ed..4c159c117 100644 --- a/src/backend/wayland/zoom/view.rs +++ b/src/backend/wayland/zoom/view.rs @@ -36,8 +36,8 @@ impl ZoomState { } pub fn clamp_offsets(&mut self, screen_width: u32, screen_height: u32) { - let width = screen_width as f64; - let height = screen_height as f64; + let width = f64::from(screen_width); + let height = f64::from(screen_height); let visible_w = width / self.scale.max(MIN_ZOOM_SCALE); let visible_h = height / self.scale.max(MIN_ZOOM_SCALE); let max_x = (width - visible_w).max(0.0); diff --git a/src/canvas_export/mod.rs b/src/canvas_export/mod.rs index 97540302b..d90b46b19 100644 --- a/src/canvas_export/mod.rs +++ b/src/canvas_export/mod.rs @@ -731,9 +731,8 @@ mod tests { logical_to_image_scale_y: 1.0, }; - let err = match render_canvas_surface(&export) { - Ok(_) => panic!("short backdrop must fail"), - Err(err) => err, + let Err(err) = render_canvas_surface(&export) else { + panic!("short backdrop must fail"); }; assert!( diff --git a/src/canvas_export/page.rs b/src/canvas_export/page.rs index 1726524c3..f3e602b6e 100644 --- a/src/canvas_export/page.rs +++ b/src/canvas_export/page.rs @@ -123,16 +123,16 @@ pub fn draw_canvas_page_with_measurer( let ctx = render.cairo; let backdrop = ExportBackdrop::try_new(&page.backdrop)?; let source = CanvasExportRect { - x: page.origin_x as f64, - y: page.origin_y as f64, - width: page.viewport_width as f64, - height: page.viewport_height as f64, + x: f64::from(page.origin_x), + y: f64::from(page.origin_y), + width: f64::from(page.viewport_width), + height: f64::from(page.viewport_height), }; let destination = CanvasExportRect { x: 0.0, y: 0.0, - width: page.viewport_width as f64, - height: page.viewport_height as f64, + width: f64::from(page.viewport_width), + height: f64::from(page.viewport_height), }; let _ = ctx.save(); @@ -201,10 +201,10 @@ pub(crate) fn paint_pdf_page_background( width: f64, height: f64, ) { - let color = match page.backdrop { - CanvasExportBackdropSnapshot::Solid(color) - | CanvasExportBackdropSnapshot::BoardPaper { color, .. } => color, - _ => return, + let (CanvasExportBackdropSnapshot::Solid(color) + | CanvasExportBackdropSnapshot::BoardPaper { color, .. }) = page.backdrop + else { + return; }; let _ = ctx.save(); ctx.set_source_rgba(color.r, color.g, color.b, color.a); @@ -275,7 +275,7 @@ impl ExportBackdrop { // The surface is owned by ExportBackdrop and dropped before the snapshot. let surface = unsafe { cairo::ImageSurface::create_for_data_unsafe( - data.as_ptr() as *mut u8, + data.as_ptr().cast_mut(), cairo::Format::ARgb32, *width, *height, @@ -331,7 +331,7 @@ impl ExportBackdrop { // it is used only as a paint/blur/eraser replay source. let surface = unsafe { cairo::ImageSurface::create_for_data_unsafe( - image.data.as_ptr() as *mut u8, + image.data.as_ptr().cast_mut(), cairo::Format::ARgb32, width, height, diff --git a/src/canvas_export/pdf.rs b/src/canvas_export/pdf.rs index 98cecb0c8..257f2bf8c 100644 --- a/src/canvas_export/pdf.rs +++ b/src/canvas_export/pdf.rs @@ -308,16 +308,16 @@ pub fn resolve_pdf_page_layout( } let viewport_source = CanvasExportRect { - x: origin_x as f64, - y: origin_y as f64, - width: viewport_width as f64, - height: viewport_height as f64, + x: f64::from(origin_x), + y: f64::from(origin_y), + width: f64::from(viewport_width), + height: f64::from(viewport_height), }; let source_rect = match config.fit { - PdfFitMode::FitContentToPage => content_bounds - .map(|bounds| pad_source_rect(bounds, config.content_source_padding)) - .unwrap_or(viewport_source), + PdfFitMode::FitContentToPage => content_bounds.map_or(viewport_source, |bounds| { + pad_source_rect(bounds, config.content_source_padding) + }), PdfFitMode::FitViewportToPage | PdfFitMode::Viewport => viewport_source, }; let (page_width, page_height) = @@ -372,7 +372,7 @@ fn resolve_page_size( config: &PdfExportConfig, ) -> (f64, f64) { let (base_width, base_height) = match config.page_size { - PdfPageSize::Viewport => (viewport_width as f64, viewport_height as f64), + PdfPageSize::Viewport => (f64::from(viewport_width), f64::from(viewport_height)), PdfPageSize::A4 => (A4_WIDTH, A4_HEIGHT), PdfPageSize::Letter => (LETTER_WIDTH, LETTER_HEIGHT), PdfPageSize::Custom => (config.custom_width, config.custom_height), diff --git a/src/canvas_export/pdf_labels.rs b/src/canvas_export/pdf_labels.rs index 8c414a2e2..40ac4c925 100644 --- a/src/canvas_export/pdf_labels.rs +++ b/src/canvas_export/pdf_labels.rs @@ -399,7 +399,7 @@ mod tests { 100 * density, ) .unwrap(); - surface.set_device_scale(density as f64, density as f64); + surface.set_device_scale(f64::from(density), f64::from(density)); { let ctx = cairo::Context::new(&surface).unwrap(); render_pdf_label(engine, &ctx, &config, &metadata, 240.0, 100.0); diff --git a/src/canvas_export/png.rs b/src/canvas_export/png.rs index d6b812b69..d341145c6 100644 --- a/src/canvas_export/png.rs +++ b/src/canvas_export/png.rs @@ -105,7 +105,7 @@ pub(crate) fn render_canvas_surface( &measurer, &mut RenderCtx::new(&ctx, &mut caches), &page, - scale as f64, + f64::from(scale), )?; } diff --git a/src/canvas_export/tests/cache_tests.rs b/src/canvas_export/tests/cache_tests.rs index 93cfa69c7..34499cecd 100644 --- a/src/canvas_export/tests/cache_tests.rs +++ b/src/canvas_export/tests/cache_tests.rs @@ -387,7 +387,7 @@ fn mixed_image_and_wrapped_text_pages_reuse_measurement_across_output_scales() { measurer, &mut RenderCtx::new(&ctx, caches), page, - scale as f64, + f64::from(scale), ) .unwrap(); } diff --git a/src/capture/desktop_backdrop.rs b/src/capture/desktop_backdrop.rs index 74cbaa298..0edffecd2 100644 --- a/src/capture/desktop_backdrop.rs +++ b/src/capture/desktop_backdrop.rs @@ -223,7 +223,7 @@ fn desktop_backdrop_result( width: width_i32, height: height_i32, stride, - logical_to_image_scale_x: width as f64 / logical_width as f64, - logical_to_image_scale_y: height as f64 / logical_height as f64, + logical_to_image_scale_x: f64::from(width) / f64::from(logical_width), + logical_to_image_scale_y: f64::from(height) / f64::from(logical_height), }) } diff --git a/src/capture/file.rs b/src/capture/file.rs index cef77159a..d27d6183a 100644 --- a/src/capture/file.rs +++ b/src/capture/file.rs @@ -50,7 +50,7 @@ impl Default for FileSaveConfig { pub fn generate_filename(template: &str, format: &str) -> String { let now = now_local(); let filename = format_with_template(now, template); - format!("{}.{}", filename, format) + format!("{filename}.{format}") } fn sanitize_save_extension(format: &str) -> Option { @@ -219,7 +219,7 @@ pub fn save_screenshot( // Verify the write let written_size = fs::metadata(&file_path)?.len(); - log::debug!("File written: {} bytes", written_size); + log::debug!("File written: {written_size} bytes"); log::info!("Screenshot saved successfully: {}", file_path.display()); diff --git a/src/capture/pipeline.rs b/src/capture/pipeline.rs index 8804a43db..e93be2455 100644 --- a/src/capture/pipeline.rs +++ b/src/capture/pipeline.rs @@ -121,7 +121,7 @@ pub(crate) async fn perform_capture( let image_data = match dependencies.source.capture(request.capture_type).await { Ok(data) => data, Err(CaptureError::Cancelled(reason)) => { - log::info!("Capture cancelled: {}", reason); + log::info!("Capture cancelled: {reason}"); return Err(CaptureError::Cancelled(reason)); } Err(err) => return Err(err), @@ -151,7 +151,9 @@ pub(crate) async fn perform_capture( } CaptureDestination::ClipboardAndFile => { if let Some(save_config) = request.save_config.clone() { - if !save_config.save_directory.as_os_str().is_empty() { + if save_config.save_directory.as_os_str().is_empty() { + None + } else { match save_bytes( Arc::clone(&dependencies.saver), image_data.clone(), @@ -161,13 +163,11 @@ pub(crate) async fn perform_capture( { Ok(path) => Some(path), Err(err) => { - log::warn!("Failed to save screenshot: {}", err); + log::warn!("Failed to save screenshot: {err}"); save_error = Some(err); None } } - } else { - None } } else { None @@ -240,7 +240,7 @@ pub(crate) async fn deliver_image( { Ok(path) => Some(path), Err(err) => { - log::warn!("Failed to save delivered image: {}", err); + log::warn!("Failed to save delivered image: {err}"); save_error = Some(err); None } @@ -329,7 +329,7 @@ pub(crate) async fn render_and_deliver_document( let render = request.render; let document = task::spawn_blocking(render) .await - .map_err(|e| CaptureError::ImageError(format!("Render task failed: {}", e)))??; + .map_err(|e| CaptureError::ImageError(format!("Render task failed: {e}")))??; deliver_document( DocumentDeliveryRequest { document, @@ -410,7 +410,7 @@ async fn save_bytes( ) -> Result { task::spawn_blocking(move || saver.save(&bytes, &config)) .await - .map_err(|e| CaptureError::ImageError(format!("Save task failed: {}", e)))? + .map_err(|e| CaptureError::ImageError(format!("Save task failed: {e}")))? } async fn copy_to_clipboard(clipboard: Arc, image_data: Vec) -> bool { @@ -422,14 +422,14 @@ async fn copy_to_clipboard(clipboard: Arc, image_data: Vec ) }) .await - .map_err(|e| CaptureError::ClipboardError(format!("Clipboard task failed: {}", e))) + .map_err(|e| CaptureError::ClipboardError(format!("Clipboard task failed: {e}"))) { Ok(Ok(())) => { log::info!("Successfully copied to clipboard"); true } Ok(Err(e)) | Err(e) => { - log::error!("Failed to copy to clipboard: {}", e); + log::error!("Failed to copy to clipboard: {e}"); false } } diff --git a/src/capture/portal.rs b/src/capture/portal.rs index 08603844d..3186e6796 100644 --- a/src/capture/portal.rs +++ b/src/capture/portal.rs @@ -96,7 +96,7 @@ const DBUS_ERROR_ACCESS_DENIED: &str = "org.freedesktop.DBus.Error.AccessDenied" /// # Returns /// The URI path to the captured screenshot file pub async fn capture_via_portal(capture_type: CaptureType) -> Result { - log::debug!("Initiating portal screenshot capture: {:?}", capture_type); + log::debug!("Initiating portal screenshot capture: {capture_type:?}"); // Connect to session bus let connection = Connection::session() @@ -165,7 +165,7 @@ async fn capture_once( PORTAL_OPTION_HANDLE_TOKEN_KEY.to_string(), handle_token.into(), ); - log::debug!("Calling portal screenshot with options: {:?}", options); + log::debug!("Calling portal screenshot with options: {options:?}"); // Portal backends may complete non-interactive screenshots before the // Screenshot method reply reaches us. Subscribe at the predicted request @@ -191,7 +191,7 @@ async fn capture_once( .await? .map_err(map_portal_call_error)?; - log::info!("Screenshot request created: {:?}", returned_path); + log::info!("Screenshot request created: {returned_path:?}"); log::debug!("Waiting for Response signal..."); @@ -235,7 +235,7 @@ async fn capture_once( .ok_or_else(|| CaptureError::InvalidResponse("No Response signal received".to_string()))?; let args = response_signal.args().map_err(|e| { - CaptureError::InvalidResponse(format!("Failed to parse response args: {}", e)) + CaptureError::InvalidResponse(format!("Failed to parse response args: {e}")) })?; log::debug!( @@ -268,16 +268,15 @@ async fn within_deadline( step: impl Future, close: impl Future, ) -> Result { - match time::timeout_at(deadline, step).await { - Ok(value) => Ok(value), - Err(_) => { - log::warn!( - "Screenshot portal did not answer within {}s; closing the request", - limit.as_secs() - ); - close.await; - Err(CaptureError::PortalTimeout(limit)) - } + if let Ok(value) = time::timeout_at(deadline, step).await { + Ok(value) + } else { + log::warn!( + "Screenshot portal did not answer within {}s; closing the request", + limit.as_secs() + ); + close.await; + Err(CaptureError::PortalTimeout(limit)) } } @@ -365,9 +364,9 @@ fn parse_response( })?; // Extract string from OwnedValue. - let uri_str: &str = uri_value.downcast_ref().map_err(|e| { - CaptureError::InvalidResponse(format!("URI is not a string: {}", e)) - })?; + let uri_str: &str = uri_value + .downcast_ref() + .map_err(|e| CaptureError::InvalidResponse(format!("URI is not a string: {e}")))?; log::info!("Screenshot captured successfully"); Ok(uri_str.to_string()) @@ -379,7 +378,7 @@ fn parse_response( )) } code => { - log::error!("Screenshot failed with code {}", code); + log::error!("Screenshot failed with code {code}"); Err(CaptureError::PortalResponse(code)) } } @@ -607,7 +606,7 @@ mod tests { let closed = AtomicBool::new(false); let result = within_deadline(Instant::now() + limit, limit, future::ready(7), async { - closed.store(true, Ordering::SeqCst) + closed.store(true, Ordering::SeqCst); }) .await; diff --git a/src/capture/sources/frozen.rs b/src/capture/sources/frozen.rs index c87dec7c5..36867ca68 100644 --- a/src/capture/sources/frozen.rs +++ b/src/capture/sources/frozen.rs @@ -8,7 +8,7 @@ pub fn decode_image_to_argb(data: &[u8]) -> Result<(Vec, u32, u32), CaptureE let decoder = png::Decoder::new(Cursor::new(data)); let mut reader = decoder .read_info() - .map_err(|e| CaptureError::ImageError(format!("Decode error: {}", e)))?; + .map_err(|e| CaptureError::ImageError(format!("Decode error: {e}")))?; let output_size = reader .output_buffer_size() @@ -16,7 +16,7 @@ pub fn decode_image_to_argb(data: &[u8]) -> Result<(Vec, u32, u32), CaptureE let mut buf = vec![0; output_size]; let info = reader .next_frame(&mut buf) - .map_err(|e| CaptureError::ImageError(format!("Decode error: {}", e)))?; + .map_err(|e| CaptureError::ImageError(format!("Decode error: {e}")))?; let mut argb = Vec::with_capacity((info.width * info.height * 4) as usize); let iter: Box> = match info.color_type { @@ -34,17 +34,16 @@ pub fn decode_image_to_argb(data: &[u8]) -> Result<(Vec, u32, u32), CaptureE )), other => { return Err(CaptureError::ImageError(format!( - "Unsupported PNG color type: {:?}", - other + "Unsupported PNG color type: {other:?}" ))); } }; for (r, g, b, a) in iter { - let a_f = a as f32 / 255.0; - let pr = (r as f32 * a_f).round() as u8; - let pg = (g as f32 * a_f).round() as u8; - let pb = (b as f32 * a_f).round() as u8; + let a_f = f32::from(a) / 255.0; + let pr = (f32::from(r) * a_f).round() as u8; + let pg = (f32::from(g) * a_f).round() as u8; + let pb = (f32::from(b) * a_f).round() as u8; // Cairo ARgb32 uses native-endian BGRA layout argb.push(pb); argb.push(pg); diff --git a/src/capture/sources/hyprland.rs b/src/capture/sources/hyprland.rs index 6a725b260..d750dbae6 100644 --- a/src/capture/sources/hyprland.rs +++ b/src/capture/sources/hyprland.rs @@ -81,7 +81,7 @@ pub async fn capture_full_screen_hyprland() -> Result, CaptureError> { }) .await .map_err(|e| { - CaptureError::ImageError(format!("Full screen capture task failed to join: {}", e)) + CaptureError::ImageError(format!("Full screen capture task failed to join: {e}")) })? } @@ -108,11 +108,11 @@ pub async fn capture_active_window_hyprland() -> Result, CaptureError> { } let json: Value = serde_json::from_slice(&output.stdout).map_err(|e| { - CaptureError::InvalidResponse(format!("Failed to parse hyprctl output: {}", e)) + CaptureError::InvalidResponse(format!("Failed to parse hyprctl output: {e}")) })?; let geometry = active_window_geometry(&json)?; - log::debug!("Capturing active window via grim: {}", geometry); + log::debug!("Capturing active window via grim: {geometry}"); let arguments = grim_geometry_arguments(&geometry); let grim_output = run_helper( HelperKind::Grim, @@ -139,7 +139,7 @@ pub async fn capture_active_window_hyprland() -> Result, CaptureError> { Ok(grim_output.stdout) }) .await - .map_err(|e| CaptureError::ImageError(format!("Hyprland capture task failed to join: {}", e)))? + .map_err(|e| CaptureError::ImageError(format!("Hyprland capture task failed to join: {e}")))? } /// Capture a user-selected region using `slurp` + `grim` (Hyprland/wlroots fast path). @@ -167,7 +167,7 @@ pub async fn capture_selection_hyprland() -> Result, CaptureError> { } let geometry_output = String::from_utf8(output.stdout) - .map_err(|e| CaptureError::InvalidResponse(format!("Invalid slurp output: {}", e)))?; + .map_err(|e| CaptureError::InvalidResponse(format!("Invalid slurp output: {e}")))?; let geometry = geometry_output.trim(); if geometry.is_empty() { @@ -176,7 +176,7 @@ pub async fn capture_selection_hyprland() -> Result, CaptureError> { )); } - log::debug!("Capturing region via grim: {}", geometry); + log::debug!("Capturing region via grim: {geometry}"); let arguments = grim_geometry_arguments(geometry); let grim_output = run_helper( HelperKind::Grim, @@ -203,9 +203,7 @@ pub async fn capture_selection_hyprland() -> Result, CaptureError> { Ok(grim_output.stdout) }) .await - .map_err(|e| { - CaptureError::ImageError(format!("Selection capture task failed to join: {}", e)) - })? + .map_err(|e| CaptureError::ImageError(format!("Selection capture task failed to join: {e}")))? } /// Build the `grim -g` region for the window described by `hyprctl activewindow -j`. diff --git a/src/capture/sources/portal.rs b/src/capture/sources/portal.rs index 442f421f1..4d7f34a20 100644 --- a/src/capture/sources/portal.rs +++ b/src/capture/sources/portal.rs @@ -12,5 +12,5 @@ pub async fn capture_via_portal_bytes(capture_type: CaptureType) -> Result panic!("Expected success outcome, got {:?}", other), + other => panic!("Expected success outcome, got {other:?}"), } assert_eq!(*clipboard_calls.lock().unwrap(), 1); } diff --git a/src/capture/tests/perform_capture.rs b/src/capture/tests/perform_capture.rs index 37e3e9be0..f00b70747 100644 --- a/src/capture/tests/perform_capture.rs +++ b/src/capture/tests/perform_capture.rs @@ -553,7 +553,7 @@ async fn test_perform_capture_save_failure() { .unwrap_err(); match err { CaptureError::SaveError(_) => {} - other => panic!("expected SaveError, got {:?}", other), + other => panic!("expected SaveError, got {other:?}"), } assert_eq!(*saver_handle.calls.lock().unwrap(), 1); } diff --git a/src/capture/tests/window_geometry.rs b/src/capture/tests/window_geometry.rs index 34c1e8552..bb586309f 100644 --- a/src/capture/tests/window_geometry.rs +++ b/src/capture/tests/window_geometry.rs @@ -205,7 +205,7 @@ fn hyprland_rejects_invalid_monitor_scale() { assert!( parse_hyprland_targets( monitors, - br#"[]"#, + br"[]", &context("DP-1", Rect::new(0, 0, 1920, 1080).unwrap()), ) .is_err() diff --git a/src/capture/types.rs b/src/capture/types.rs index 7a4267fed..47e2dce04 100644 --- a/src/capture/types.rs +++ b/src/capture/types.rs @@ -332,13 +332,17 @@ fn physical_axis_origin( .iter() .filter(|span| span.logical_start <= start && span.logical_end >= end) .map(|span| { - (end - start) as f64 * span.physical_length as f64 / span.logical_length() as f64 + (end - start) as f64 * f64::from(span.physical_length) + / span.logical_length() as f64 }) .reduce(f64::max)?; physical_origin += segment; } - if !physical_origin.is_finite() || physical_origin < 0.0 || physical_origin > u32::MAX as f64 { + if !physical_origin.is_finite() + || physical_origin < 0.0 + || physical_origin > f64::from(u32::MAX) + { return None; } Some(physical_origin.round() as u32) diff --git a/src/clipboard_text.rs b/src/clipboard_text.rs index 1fc027f99..f55f320c8 100644 --- a/src/clipboard_text.rs +++ b/src/clipboard_text.rs @@ -69,8 +69,7 @@ pub(crate) fn read_clipboard_text_via_command() -> Result Option<&'static ActionMeta> { /// The untranslated label from the metadata table, falling back to a word for /// actions that have no entry. fn source_label(action: Action) -> &'static str { - action_meta(action) - .map(|meta| meta.label) - .unwrap_or("Action") + action_meta(action).map_or("Action", |meta| meta.label) } #[must_use] @@ -200,11 +198,7 @@ pub fn action_label(action: Action) -> &'static str { #[must_use] pub fn action_short_label(action: Action) -> &'static str { - i18n::tr( - action_meta(action) - .map(|meta| meta.short_label()) - .unwrap_or("Action"), - ) + i18n::tr(action_meta(action).map_or("Action", |meta| meta.short_label())) } /// The compact spelling used where a full label is too wide. @@ -232,11 +226,7 @@ pub fn action_display_label(action: Action) -> &'static str { #[allow(dead_code)] #[must_use] pub fn action_description(action: Action) -> &'static str { - i18n::tr( - action_meta(action) - .map(|meta| meta.description) - .unwrap_or(""), - ) + i18n::tr(action_meta(action).map_or("", |meta| meta.description)) } #[cfg(test)] diff --git a/src/config/action_meta/tests.rs b/src/config/action_meta/tests.rs index ca3a142a7..8bbb9a2ce 100644 --- a/src/config/action_meta/tests.rs +++ b/src/config/action_meta/tests.rs @@ -328,8 +328,8 @@ fn assert_actions_have_flag( continue; } let meta = - action_meta(*action).unwrap_or_else(|| panic!("missing ActionMeta for {:?}", action)); - assert!(check(meta), "Action {:?} missing {}", action, flag_name); + action_meta(*action).unwrap_or_else(|| panic!("missing ActionMeta for {action:?}")); + assert!(check(meta), "Action {action:?} missing {flag_name}"); } } @@ -387,9 +387,7 @@ fn command_palette_actions_match_expected_contract() { assert!( unexpected.is_empty() && missing.is_empty(), - "command palette contract changed; unexpected: {:?}; missing: {:?}", - unexpected, - missing + "command palette contract changed; unexpected: {unexpected:?}; missing: {missing:?}" ); } diff --git a/src/config/document/merge.rs b/src/config/document/merge.rs index f9cd21016..d15e48494 100644 --- a/src/config/document/merge.rs +++ b/src/config/document/merge.rs @@ -33,7 +33,10 @@ pub(super) fn merge_config_document( && !merged.contains_key("config_revision") && updated_revision > 0 { - merged.insert("config_revision", toml_edit::value(updated_revision as i64)); + merged.insert( + "config_revision", + toml_edit::value(i64::from(updated_revision)), + ); } merge_table_like( merged.as_table_mut(), diff --git a/src/config/enums.rs b/src/config/enums.rs index 1141a2b25..bda8a6052 100644 --- a/src/config/enums.rs +++ b/src/config/enums.rs @@ -152,26 +152,26 @@ impl ColorSpec { Ok(color) => color, Err(ConfigHexColorError::MissingHash) => { util::name_to_color(name).unwrap_or_else(|| { - warn!("Unknown color '{}', using red", name); + warn!("Unknown color '{name}', using red"); PALETTE_RED }) } Err(err) => { - warn!("Invalid hex color '{}': {:?}; using red", name, err); + warn!("Invalid hex color '{name}': {err:?}; using red"); PALETTE_RED } }, ColorSpec::Rgb([r, g, b]) => Color { - r: *r as f64 / 255.0, - g: *g as f64 / 255.0, - b: *b as f64 / 255.0, + r: f64::from(*r) / 255.0, + g: f64::from(*g) / 255.0, + b: f64::from(*b) / 255.0, a: 1.0, }, ColorSpec::Rgba([r, g, b, a]) => Color { - r: *r as f64 / 255.0, - g: *g as f64 / 255.0, - b: *b as f64 / 255.0, - a: *a as f64 / 255.0, + r: f64::from(*r) / 255.0, + g: f64::from(*g) / 255.0, + b: f64::from(*b) / 255.0, + a: f64::from(*a) / 255.0, }, } } diff --git a/src/config/keybindings/binding.rs b/src/config/keybindings/binding.rs index e07e0c942..be6b76d20 100644 --- a/src/config/keybindings/binding.rs +++ b/src/config/keybindings/binding.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::hash::{Hash, Hasher}; use std::{fmt, iter}; @@ -232,19 +233,19 @@ fn within_one_edit(a: &str, b: &str) -> bool { return false; } edited = true; - if a.len() == b.len() { - // Substitution, or a transposition of this pair. - if ai + 1 < a.len() && a[ai] == b[bi + 1] && a[ai + 1] == b[bi] { - ai += 2; - bi += 2; - continue; + match a.len().cmp(&b.len()) { + Ordering::Equal => { + // Substitution, or a transposition of this pair. + if ai + 1 < a.len() && a[ai] == b[bi + 1] && a[ai + 1] == b[bi] { + ai += 2; + bi += 2; + continue; + } + ai += 1; + bi += 1; } - ai += 1; - bi += 1; - } else if a.len() > b.len() { - ai += 1; - } else { - bi += 1; + Ordering::Greater => ai += 1, + Ordering::Less => bi += 1, } } true diff --git a/src/config/keybindings/config/map/board.rs b/src/config/keybindings/config/map/board.rs index 0f3fd5135..fa88e3537 100644 --- a/src/config/keybindings/config/map/board.rs +++ b/src/config/keybindings/config/map/board.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_board_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all(&self.board.toggle_whiteboard, Action::ToggleWhiteboard)?; inserter.insert_all(&self.board.toggle_blackboard, Action::ToggleBlackboard)?; diff --git a/src/config/keybindings/config/map/capture.rs b/src/config/keybindings/config/map/capture.rs index 5ac36dc38..124cd1025 100644 --- a/src/config/keybindings/config/map/capture.rs +++ b/src/config/keybindings/config/map/capture.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_capture_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all(&self.capture.capture_full_screen, Action::CaptureFullScreen)?; inserter.insert_all( diff --git a/src/config/keybindings/config/map/colors.rs b/src/config/keybindings/config/map/colors.rs index 75a91d516..e22a42fac 100644 --- a/src/config/keybindings/config/map/colors.rs +++ b/src/config/keybindings/config/map/colors.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_color_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all(&self.colors.set_color_red, Action::SetColorRed)?; inserter.insert_all(&self.colors.set_color_green, Action::SetColorGreen)?; diff --git a/src/config/keybindings/config/map/core.rs b/src/config/keybindings/config/map/core.rs index 17429b993..6ce1b39c2 100644 --- a/src/config/keybindings/config/map/core.rs +++ b/src/config/keybindings/config/map/core.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_core_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all(&self.core.exit, Action::Exit)?; inserter.insert_all(&self.core.enter_text_mode, Action::EnterTextMode)?; diff --git a/src/config/keybindings/config/map/mod.rs b/src/config/keybindings/config/map/mod.rs index 3d2ee3392..44779d0a9 100644 --- a/src/config/keybindings/config/map/mod.rs +++ b/src/config/keybindings/config/map/mod.rs @@ -50,24 +50,21 @@ struct ConflictLog { impl ConflictLog { fn record(&mut self, binding: &Shortcut, first: Action, next: Action) { - match self.positions.get(binding) { - Some(&position) => { - let actions = &mut self.entries[position].actions; - if !actions.contains(&next) { - actions.push(next); - } + if let Some(&position) = self.positions.get(binding) { + let actions = &mut self.entries[position].actions; + if !actions.contains(&next) { + actions.push(next); } - None => { - self.positions.insert(binding.clone(), self.entries.len()); - let mut actions = vec![first]; - if next != first { - actions.push(next); - } - self.entries.push(KeybindingConflict { - binding: binding.clone(), - actions, - }); + } else { + self.positions.insert(binding.clone(), self.entries.len()); + let mut actions = vec![first]; + if next != first { + actions.push(next); } + self.entries.push(KeybindingConflict { + binding: binding.clone(), + actions, + }); } } } @@ -175,8 +172,7 @@ impl<'maps> BindingInserter<'maps> { return Ok(()); } Err(format!( - "Duplicate keybinding '{}' assigned to both {:?} and {:?}", - binding_str, existing_action, action + "Duplicate keybinding '{binding_str}' assigned to both {existing_action:?} and {action:?}" )) } diff --git a/src/config/keybindings/config/map/presets.rs b/src/config/keybindings/config/map/presets.rs index 7441ff826..16460327f 100644 --- a/src/config/keybindings/config/map/presets.rs +++ b/src/config/keybindings/config/map/presets.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_preset_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all(&self.presets.apply_preset_1, Action::ApplyPreset1)?; inserter.insert_all(&self.presets.apply_preset_2, Action::ApplyPreset2)?; diff --git a/src/config/keybindings/config/map/selection.rs b/src/config/keybindings/config/map/selection.rs index 97a62514d..faca3a737 100644 --- a/src/config/keybindings/config/map/selection.rs +++ b/src/config/keybindings/config/map/selection.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_selection_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all( &self.selection.duplicate_selection, diff --git a/src/config/keybindings/config/map/tools.rs b/src/config/keybindings/config/map/tools.rs index 979d57828..399d42be2 100644 --- a/src/config/keybindings/config/map/tools.rs +++ b/src/config/keybindings/config/map/tools.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_tool_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all(&self.tools.increase_thickness, Action::IncreaseThickness)?; inserter.insert_all(&self.tools.decrease_thickness, Action::DecreaseThickness)?; diff --git a/src/config/keybindings/config/map/ui.rs b/src/config/keybindings/config/map/ui.rs index c7aa55ab5..9bad16afd 100644 --- a/src/config/keybindings/config/map/ui.rs +++ b/src/config/keybindings/config/map/ui.rs @@ -3,7 +3,10 @@ use super::BindingInserter; use crate::config::Action; impl KeybindingsConfig { - pub(super) fn insert_ui_bindings(&self, inserter: &mut BindingInserter) -> Result<(), String> { + pub(super) fn insert_ui_bindings( + &self, + inserter: &mut BindingInserter<'_>, + ) -> Result<(), String> { inserter.insert_all(&self.ui.toggle_help, Action::ToggleHelp)?; inserter.insert_all(&self.ui.toggle_quick_help, Action::ToggleQuickHelp)?; inserter.insert_all(&self.ui.toggle_status_bar, Action::ToggleStatusBar)?; diff --git a/src/config/keybindings/config/map/zoom.rs b/src/config/keybindings/config/map/zoom.rs index 7d453fe4a..2e274ca12 100644 --- a/src/config/keybindings/config/map/zoom.rs +++ b/src/config/keybindings/config/map/zoom.rs @@ -5,7 +5,7 @@ use crate::config::Action; impl KeybindingsConfig { pub(super) fn insert_zoom_bindings( &self, - inserter: &mut BindingInserter, + inserter: &mut BindingInserter<'_>, ) -> Result<(), String> { inserter.insert_all(&self.zoom.toggle_frozen_mode, Action::ToggleFrozenMode)?; inserter.insert_all(&self.zoom.zoom_in, Action::ZoomIn)?; diff --git a/src/config/tests/document.rs b/src/config/tests/document.rs index e25680bf0..4af129394 100644 --- a/src/config/tests/document.rs +++ b/src/config/tests/document.rs @@ -739,7 +739,7 @@ fn document_save_leaves_the_key_aliases_it_does_not_write_alone() { fn document_save_keeps_unknown_fields_with_stable_id_when_tables_reorder() { let temp = TempConfig::new("stable-id"); temp.write( - r##"[[render_profiles.profiles]] + r#"[[render_profiles.profiles]] id = "a" name = "A" future_owner = "owner-a" @@ -748,7 +748,7 @@ future_owner = "owner-a" id = "b" name = "B" future_owner = "owner-b" -"##, +"#, ); let document = ConfigDocument::load_from_path(&temp.path).expect("load profiles"); let mut updated = document.config().clone(); @@ -2500,17 +2500,17 @@ enabled = true /// The historical `full` alias for the regular mode table must keep its /// authored spelling on an unrelated save, and the retired nested field must -/// classify under the path serde_ignored actually emits. +/// classify under the path `serde_ignored` actually emits. #[test] fn retired_full_alias_show_settings_section_is_diagnosed_and_spelling_preserved() { let temp = TempConfig::new("retired-full-alias"); temp.write( - r#"# alias fixture + r"# alias fixture [ui.toolbar.mode_overrides.full] # regular-mode alias spelling show_settings_section = false show_presets = true -"#, +", ); let document = ConfigDocument::load_from_path(&temp.path).expect("load full alias fixture"); diff --git a/src/config/tests/file_io.rs b/src/config/tests/file_io.rs index 0642e2c75..10c9da48c 100644 --- a/src/config/tests/file_io.rs +++ b/src/config/tests/file_io.rs @@ -779,7 +779,7 @@ fn collect_value_drifts( }; match (example.get(key), defaults.get(key)) { (Some(example), Some(defaults)) => { - collect_value_drifts(&child, example, defaults, drifts) + collect_value_drifts(&child, example, defaults, drifts); } (Some(example), None) => drifts.push(ValueDrift { path: child, diff --git a/src/config/tests/finite.rs b/src/config/tests/finite.rs index a31d9bd19..601581e30 100644 --- a/src/config/tests/finite.rs +++ b/src/config/tests/finite.rs @@ -280,14 +280,14 @@ fn document_load_enforces_finite_policy_for_every_float_and_array_component() { // Board RGB maps normalize to the canonical array representation. let output_path = case.path.replace(".rgb.", "."); let actual = get(&loaded, &output_path).and_then(Value::as_float); - let expected = if !input.is_finite() { - case.fallback - } else { + let expected = if input.is_finite() { Some(match case.bounds { Some((min, _)) if input < min => min, Some((_, max)) if input > max => max, _ => input, }) + } else { + case.fallback }; assert_eq!(actual, expected, "{} input={input}", case.path); assert_eq!( diff --git a/src/config/tests/load.rs b/src/config/tests/load.rs index 158bfe6ac..50f80010b 100644 --- a/src/config/tests/load.rs +++ b/src/config/tests/load.rs @@ -318,7 +318,7 @@ fn status_bar_content_flags_have_documented_defaults_and_round_trip() { "the output item waits for a second output by default" ); - let source = r#" + let source = r" [ui] status_bar_interactive = false active_output_badge = false @@ -332,7 +332,7 @@ show_status_context_indicators = false show_toolbar_hint = false show_status_help = false show_status_about = false -"#; +"; let config: Config = toml::from_str(source).expect("status-bar content flags should parse"); assert!(!config.ui.status_bar_interactive); for item in StatusBarItem::ALL { @@ -352,11 +352,11 @@ show_status_about = false #[test] fn explicit_opt_ins_for_the_about_chip_and_single_output_badge_round_trip() { - let source = r#" + let source = r" [ui] show_status_about = true active_output_badge_always = true -"#; +"; let config: Config = toml::from_str(source).expect("opt-in flags should parse"); assert!(config.ui.status_bar_item_visible(StatusBarItem::About)); assert!(config.ui.active_output_badge_always); @@ -529,8 +529,7 @@ fn explicit_empty_cycle_records_legacy_f2_intent_without_a_startup_notice() { fs::write( primary_dir.join("config.toml"), format!( - "config_revision = {}\n\n[keybindings]\ntoggle_toolbar = ['F2', 'F9']\ncycle_toolbar_display = []\n", - CURRENT_CONFIG_REVISION + "config_revision = {CURRENT_CONFIG_REVISION}\n\n[keybindings]\ntoggle_toolbar = ['F2', 'F9']\ncycle_toolbar_display = []\n" ), ) .unwrap(); diff --git a/src/config/types/drawing.rs b/src/config/types/drawing.rs index 12342465e..148c3047c 100644 --- a/src/config/types/drawing.rs +++ b/src/config/types/drawing.rs @@ -907,8 +907,7 @@ fn quick_color_label(entry: &QuickColorConfig, index: usize) -> String { let trimmed = entry.label.trim(); if trimmed.is_empty() { QuickColorSlot::from_index(index) - .map(QuickColorSlot::label) - .unwrap_or("Quick color") + .map_or("Quick color", QuickColorSlot::label) .to_string() } else { trimmed.to_string() diff --git a/src/config/types/presets.rs b/src/config/types/presets.rs index 6d8cef533..fa2949cf0 100644 --- a/src/config/types/presets.rs +++ b/src/config/types/presets.rs @@ -87,10 +87,10 @@ pub struct ToolPresetConfig { impl ToolPresetConfig { #[must_use] pub fn preview_color_spec(&self) -> ColorSpec { - self.tool_settings - .as_ref() - .map(|settings| settings.color_spec_for_tool(self.tool)) - .unwrap_or_else(|| self.color.clone()) + self.tool_settings.as_ref().map_or_else( + || self.color.clone(), + |settings| settings.color_spec_for_tool(self.tool), + ) } #[must_use] @@ -102,8 +102,7 @@ impl ToolPresetConfig { pub fn preview_size(&self) -> f64 { self.tool_settings .as_ref() - .map(|settings| settings.size_for_tool(self.tool)) - .unwrap_or(self.size) + .map_or(self.size, |settings| settings.size_for_tool(self.tool)) } } diff --git a/src/config/types/tablet.rs b/src/config/types/tablet.rs index 3b15cad7b..ed026c290 100644 --- a/src/config/types/tablet.rs +++ b/src/config/types/tablet.rs @@ -55,11 +55,11 @@ pub struct TabletInputConfig { #[serde(default = "default_pressure_thickness_scale_step")] pub pressure_thickness_scale_step: f64, - /// Binding for the primary barrel button (BTN_STYLUS / button 331). + /// Binding for the primary barrel button (`BTN_STYLUS` / button 331). #[serde(default = "default_stylus_button")] pub stylus_button: StylusButtonBinding, - /// Binding for the secondary barrel button (BTN_STYLUS2 / button 332). + /// Binding for the secondary barrel button (`BTN_STYLUS2` / button 332). #[serde(default = "default_stylus_button2")] pub stylus_button2: StylusButtonBinding, } diff --git a/src/config/types/ui.rs b/src/config/types/ui.rs index 39c4d9209..a08c190da 100644 --- a/src/config/types/ui.rs +++ b/src/config/types/ui.rs @@ -94,7 +94,7 @@ pub struct UiConfig { pub show_floating_badge: bool, /// Show the board/page badge even when the status bar is visible - /// (renamed from show_page_badge_with_status_bar for clarity) + /// (renamed from `show_page_badge_with_status_bar` for clarity) #[serde( default = "default_show_page_badge_with_status_bar", alias = "show_page_badge_with_status_bar" diff --git a/src/config/types/updates.rs b/src/config/types/updates.rs index caca5c023..a83f3252c 100644 --- a/src/config/types/updates.rs +++ b/src/config/types/updates.rs @@ -69,7 +69,7 @@ mod tests { assert!(config.check); assert!(config.notify); - assert_eq!(config.interval(), Duration::from_secs(86_400)); + assert_eq!(config.interval(), Duration::from_hours(24)); } #[test] diff --git a/src/config/validate/boards.rs b/src/config/validate/boards.rs index 68cfc66bf..ff92ddf24 100644 --- a/src/config/validate/boards.rs +++ b/src/config/validate/boards.rs @@ -76,8 +76,7 @@ impl Config { .items .iter() .find(|item| item.background.is_transparent()) - .map(|item| item.id.clone()) - .unwrap_or_else(|| boards.items[0].id.clone()); + .map_or_else(|| boards.items[0].id.clone(), |item| item.id.clone()); warn!( "Default board '{}' not found; falling back to '{}'", boards.default_board, fallback @@ -131,15 +130,12 @@ fn normalize_background(background: &mut BoardBackgroundConfig, id: &str) { match background { BoardBackgroundConfig::Transparent(value) => { if value.to_lowercase() != "transparent" { - warn!( - "Board '{}' background '{}' invalid; using transparent", - id, value - ); + warn!("Board '{id}' background '{value}' invalid; using transparent"); *value = "transparent".to_string(); } } BoardBackgroundConfig::Color(color) => { - clamp_color(color, &format!("boards.items[{}].background", id)); + clamp_color(color, &format!("boards.items[{id}].background")); } } } diff --git a/src/config/validate/drawing.rs b/src/config/validate/drawing.rs index 5a896d8a3..f021c2845 100644 --- a/src/config/validate/drawing.rs +++ b/src/config/validate/drawing.rs @@ -159,8 +159,7 @@ impl Config { fn validate_hit_test_settings(&mut self) { if !self.drawing.hit_test_tolerance.is_finite() { log::warn!( - "Invalid non-finite hit_test_tolerance; resetting to default {:.1}", - DEFAULT_HIT_TEST_TOLERANCE + "Invalid non-finite hit_test_tolerance; resetting to default {DEFAULT_HIT_TEST_TOLERANCE:.1}" ); self.drawing.hit_test_tolerance = DEFAULT_HIT_TEST_TOLERANCE; } else if !(1.0..=20.0).contains(&self.drawing.hit_test_tolerance) { diff --git a/src/config/validate/export.rs b/src/config/validate/export.rs index a0f08aa32..bbfe516a4 100644 --- a/src/config/validate/export.rs +++ b/src/config/validate/export.rs @@ -66,10 +66,7 @@ fn validate_pdf_labels(labels: &mut PdfLabelConfig) { if labels.template.trim().is_empty() { labels.template = PDF_LABEL_DEFAULT_TEMPLATE.to_string(); } else if let Err(err) = validate_pdf_label_template(&labels.template) { - log::warn!( - "Invalid export.pdf.labels.template ({}); resetting to default", - err - ); + log::warn!("Invalid export.pdf.labels.template ({err}); resetting to default"); labels.template = PDF_LABEL_DEFAULT_TEMPLATE.to_string(); } } @@ -123,10 +120,10 @@ fn sanitize_range(value: f64, min: f64, max: f64, fallback: f64, field: &str) -> fn sanitize_color(color: &mut [f64; 4], fallback: [f64; 4]) { for (index, component) in color.iter_mut().enumerate() { - if !component.is_finite() { - *component = fallback[index]; - } else { + if component.is_finite() { *component = component.clamp(0.0, 1.0); + } else { + *component = fallback[index]; } } } diff --git a/src/config/validate/render_profiles.rs b/src/config/validate/render_profiles.rs index a6b1a1a19..585ad44fb 100644 --- a/src/config/validate/render_profiles.rs +++ b/src/config/validate/render_profiles.rs @@ -29,8 +29,7 @@ impl Config { .any(|profile| profile.id == *active) { warn!( - "Active render profile '{}' not found; starting with render profiles off", - active + "Active render profile '{active}' not found; starting with render profiles off" ); self.render_profiles.active = None; } @@ -52,8 +51,7 @@ impl Config { .any(|profile| profile.id == *export_profile) { warn!( - "Export render profile '{}' not found; disabling canvas export remapping", - export_profile + "Export render profile '{export_profile}' not found; disabling canvas export remapping" ); self.render_profiles.export = RenderProfileExportMode::Off; self.render_profiles.export_profile = None; @@ -91,9 +89,9 @@ fn normalize_profile_identity( let mut id = normalize_profile_id(&raw_id); if id.is_empty() { id = format!("profile-{}", index + 1); - warn!("Render profile id was empty; using '{}'", id); + warn!("Render profile id was empty; using '{id}'"); } else if id != raw_id.trim() { - warn!("Render profile id '{}' normalized to '{}'", raw_id, id); + warn!("Render profile id '{raw_id}' normalized to '{id}'"); } let base = id.clone(); @@ -103,7 +101,7 @@ fn normalize_profile_identity( suffix += 1; } if id != base { - warn!("Render profile id '{}' deduplicated to '{}'", base, id); + warn!("Render profile id '{base}' deduplicated to '{id}'"); } seen_ids.insert(id.clone()); profile.id = id; diff --git a/src/config/validate/session.rs b/src/config/validate/session.rs index b4eb099f0..bfa88789f 100644 --- a/src/config/validate/session.rs +++ b/src/config/validate/session.rs @@ -30,27 +30,21 @@ impl Config { if self.session.autosave_idle_ms < MIN_AUTOSAVE_IDLE_MS { log::warn!( - "session.autosave_idle_ms must be at least {} ms; using {} instead", - MIN_AUTOSAVE_IDLE_MS, - MIN_AUTOSAVE_IDLE_MS + "session.autosave_idle_ms must be at least {MIN_AUTOSAVE_IDLE_MS} ms; using {MIN_AUTOSAVE_IDLE_MS} instead" ); self.session.autosave_idle_ms = MIN_AUTOSAVE_IDLE_MS; } if self.session.autosave_interval_ms < MIN_AUTOSAVE_INTERVAL_MS { log::warn!( - "session.autosave_interval_ms must be at least {} ms; using {} instead", - MIN_AUTOSAVE_INTERVAL_MS, - MIN_AUTOSAVE_INTERVAL_MS + "session.autosave_interval_ms must be at least {MIN_AUTOSAVE_INTERVAL_MS} ms; using {MIN_AUTOSAVE_INTERVAL_MS} instead" ); self.session.autosave_interval_ms = MIN_AUTOSAVE_INTERVAL_MS; } if self.session.autosave_failure_backoff_ms < MIN_AUTOSAVE_FAILURE_BACKOFF_MS { log::warn!( - "session.autosave_failure_backoff_ms must be at least {} ms; using {} instead", - MIN_AUTOSAVE_FAILURE_BACKOFF_MS, - MIN_AUTOSAVE_FAILURE_BACKOFF_MS + "session.autosave_failure_backoff_ms must be at least {MIN_AUTOSAVE_FAILURE_BACKOFF_MS} ms; using {MIN_AUTOSAVE_FAILURE_BACKOFF_MS} instead" ); self.session.autosave_failure_backoff_ms = MIN_AUTOSAVE_FAILURE_BACKOFF_MS; } diff --git a/src/config/validate/ui.rs b/src/config/validate/ui.rs index 392643f3a..2953ce161 100644 --- a/src/config/validate/ui.rs +++ b/src/config/validate/ui.rs @@ -39,14 +39,12 @@ impl Config { let resolved_items = self.ui.toolbar.items.resolved(); for unknown in resolved_items.unknown_hidden { log::warn!( - "Unknown toolbar item id {:?} in ui.toolbar.items.hidden; preserving it for forward compatibility", - unknown + "Unknown toolbar item id {unknown:?} in ui.toolbar.items.hidden; preserving it for forward compatibility" ); } for unknown in resolved_items.unknown_shown { log::warn!( - "Unknown toolbar item id {:?} in ui.toolbar.items.shown; preserving it for forward compatibility", - unknown + "Unknown toolbar item id {unknown:?} in ui.toolbar.items.shown; preserving it for forward compatibility" ); } diff --git a/src/daemon/control.rs b/src/daemon/control.rs index 1aff11dfa..1577490b7 100644 --- a/src/daemon/control.rs +++ b/src/daemon/control.rs @@ -175,7 +175,7 @@ fn current_unix_millis() -> Result { Ok(duration .as_secs() .saturating_mul(1000) - .saturating_add(duration.subsec_millis() as u64)) + .saturating_add(u64::from(duration.subsec_millis()))) } pub(crate) fn generate_daemon_instance_token() -> String { diff --git a/src/daemon/control/response.rs b/src/daemon/control/response.rs index 135dced94..d6682e375 100644 --- a/src/daemon/control/response.rs +++ b/src/daemon/control/response.rs @@ -93,7 +93,7 @@ fn cancel_daemon_toggle_command(command: &DaemonToggleCommand) { let payload = match canceled_daemon_toggle_payload(command) { Ok(payload) => payload, Err(err) => { - warn!("Failed to serialize daemon cancellation command: {}", err); + warn!("Failed to serialize daemon cancellation command: {err}"); clear_daemon_toggle_command_files(command); return; } diff --git a/src/daemon/control/runtime.rs b/src/daemon/control/runtime.rs index 611799789..01923084c 100644 --- a/src/daemon/control/runtime.rs +++ b/src/daemon/control/runtime.rs @@ -53,10 +53,10 @@ fn try_acquire_daemon_lock() -> Result> { fn clear_stale_daemon_state() { if let Err(err) = clear_daemon_pid_file() { - warn!("Failed to clear stale daemon pid file: {}", err); + warn!("Failed to clear stale daemon pid file: {err}"); } if let Err(err) = clear_daemon_toggle_request_file() { - warn!("Failed to clear stale daemon command file: {}", err); + warn!("Failed to clear stale daemon command file: {err}"); } } @@ -95,10 +95,7 @@ pub(super) fn clear_stale_daemon_state_if_matches(expected: &DaemonRuntimeInfo) let Some(_lock_file) = (match try_acquire_daemon_lock() { Ok(lock_file) => lock_file, Err(err) => { - warn!( - "Failed to inspect daemon lock before stale cleanup: {}", - err - ); + warn!("Failed to inspect daemon lock before stale cleanup: {err}"); return; } }) else { @@ -108,7 +105,7 @@ pub(super) fn clear_stale_daemon_state_if_matches(expected: &DaemonRuntimeInfo) match read_daemon_runtime_file_if_exists() { Ok(Some(current)) if ¤t == expected => clear_stale_daemon_state(), Ok(_) => {} - Err(err) => warn!("Failed to inspect daemon pid before stale cleanup: {}", err), + Err(err) => warn!("Failed to inspect daemon pid before stale cleanup: {err}"), } } @@ -136,7 +133,7 @@ pub(super) fn signal_daemon_pid(pid: u32) -> Result<()> { { let pid = i32::try_from(pid).context("daemon pid does not fit into i32")?; if pid <= 0 { - return Err(anyhow!("invalid daemon pid {}", pid)); + return Err(anyhow!("invalid daemon pid {pid}")); } // SAFETY: `pid` has been checked to be a positive Unix process id and diff --git a/src/daemon/control/tests.rs b/src/daemon/control/tests.rs index f19319914..85115bc11 100644 --- a/src/daemon/control/tests.rs +++ b/src/daemon/control/tests.rs @@ -505,8 +505,7 @@ fn take_daemon_toggle_request_drains_multiple_payloads_in_order() { assert!( daemon_command_dir() .read_dir() - .map(|mut entries| entries.next().is_none()) - .unwrap_or(true) + .map_or(true, |mut entries| entries.next().is_none()) ); // SAFETY: this test still holds the environment mutex in `_guard`. diff --git a/src/daemon/core.rs b/src/daemon/core.rs index 4425bbafc..2daa4b31e 100644 --- a/src/daemon/core.rs +++ b/src/daemon/core.rs @@ -223,13 +223,10 @@ impl Daemon { fn clear_stale_runtime_files() { if let Err(err) = daemon::clear_daemon_pid_file() { - warn!("Failed to clear stale daemon pid file on startup: {}", err); + warn!("Failed to clear stale daemon pid file on startup: {err}"); } if let Err(err) = daemon::clear_daemon_toggle_request_file() { - warn!( - "Failed to clear stale daemon toggle request on startup: {}", - err - ); + warn!("Failed to clear stale daemon toggle request on startup: {err}"); } if let Err(err) = super::protocol_v2::clear_stale_session_reports() { warn!("Failed to clear stale overlay session reports on startup: {err:#}"); @@ -261,7 +258,7 @@ impl Daemon { ) { Ok(tray_runtime) => self.tray_runtime = Some(tray_runtime), Err(err) => { - warn!("System tray unavailable: {}", err); + warn!("System tray unavailable: {err}"); warn!( "Continuing without system tray; use --no-tray or {NO_TRAY_ENV}=1 to silence this warning" ); @@ -821,7 +818,7 @@ impl Daemon { match self.process_single_toggle(Some(legacy_request), None, false) { Ok(_) => claimed.finalize(FinalEffect::Completed, None)?, Err(error) => { - claimed.finalize(FinalEffect::Indeterminate, Some(&format!("{error:#}")))? + claimed.finalize(FinalEffect::Indeterminate, Some(&format!("{error:#}")))?; } } } @@ -835,7 +832,7 @@ impl Daemon { info!("Daemon shutting down"); // Ensure overlay is stopped before exit if let Err(err) = self.hide_overlay() { - warn!("Failed to hide overlay during shutdown: {}", err); + warn!("Failed to hide overlay during shutdown: {err}"); } self.should_quit.store(true, Ordering::Release); if let Some(listener) = self.global_shortcuts_listener.as_mut() { @@ -848,14 +845,14 @@ impl Daemon { if let Some(listener) = self.global_shortcuts_listener.take() { match listener.join() { Ok(()) => info!("Global shortcuts listener thread joined"), - Err(err) => warn!("Global shortcuts listener thread panicked: {:?}", err), + Err(err) => warn!("Global shortcuts listener thread panicked: {err:?}"), } } if let Err(err) = daemon::clear_daemon_toggle_request_file() { - warn!("Failed to clear daemon toggle request file: {}", err); + warn!("Failed to clear daemon toggle request file: {err}"); } if let Err(err) = daemon::clear_daemon_pid_file() { - warn!("Failed to clear daemon pid file: {}", err); + warn!("Failed to clear daemon pid file: {err}"); } self.stop_signal_listener() } diff --git a/src/daemon/core/toggles.rs b/src/daemon/core/toggles.rs index 763efc142..3d9538ace 100644 --- a/src/daemon/core/toggles.rs +++ b/src/daemon/core/toggles.rs @@ -95,9 +95,9 @@ impl Daemon { if self.overlay.state() == OverlayState::Hidden { self.show_overlay()?.require_shown()?; return Ok(was_hidden); - } else { - self.pending_launch = None; } + + self.pending_launch = None; return Ok(false); } @@ -125,17 +125,14 @@ impl Daemon { Ok(spawned_overlay) => { *suppress_overlay_action_signal |= spawned_overlay; if let Err(err) = write_daemon_toggle_command_success(command) { - warn!("Failed to write daemon toggle response: {}", err); + warn!("Failed to write daemon toggle response: {err}"); } } Err(err) => { let message = format!("{err:#}"); - warn!("Toggle overlay failed: {}", message); + warn!("Toggle overlay failed: {message}"); if let Err(response_err) = write_daemon_toggle_command_error(command, &message) { - warn!( - "Failed to write daemon toggle error response: {}", - response_err - ); + warn!("Failed to write daemon toggle error response: {response_err}"); } } } diff --git a/src/daemon/global_shortcuts.rs b/src/daemon/global_shortcuts.rs index 9f18be8e5..4437079e1 100644 --- a/src/daemon/global_shortcuts.rs +++ b/src/daemon/global_shortcuts.rs @@ -118,8 +118,7 @@ pub(super) fn start_global_shortcuts_listener( Ok(runtime) => runtime, Err(err) => { warn!( - "Global shortcuts portal listener disabled: failed to create Tokio runtime: {}", - err + "Global shortcuts portal listener disabled: failed to create Tokio runtime: {err}" ); return; } @@ -130,12 +129,9 @@ pub(super) fn start_global_shortcuts_listener( run_listener(visibility, preferred_trigger, portal_app_id, shutdown_rx).await { if listener_quit_flag.load(Ordering::Acquire) { - info!( - "Global shortcuts portal listener stopped during shutdown: {}", - err - ); + info!("Global shortcuts portal listener stopped during shutdown: {err}"); } else { - warn!("Global shortcuts portal listener disabled: {}", err); + warn!("Global shortcuts portal listener disabled: {err}"); } } }); @@ -253,8 +249,7 @@ async fn run_listener( .await?; info!( - "Global shortcuts portal listener ready (app_id '{}', shortcut id '{}', preferred trigger '{}')", - portal_app_id, TOGGLE_SHORTCUT_ID, preferred_trigger + "Global shortcuts portal listener ready (app_id '{portal_app_id}', shortcut id '{TOGGLE_SHORTCUT_ID}', preferred trigger '{preferred_trigger}')" ); let mut activated_stream = await_portal_operation( @@ -283,8 +278,7 @@ async fn run_listener( let option_keys: Vec<&str> = args.options.keys().map(|key| key.as_str()).collect(); warn!( - "Global shortcut activated without activation_token; focus may require manual click (options keys: {:?})", - option_keys + "Global shortcut activated without activation_token; focus may require manual click (options keys: {option_keys:?})" ); } visibility @@ -303,19 +297,15 @@ async fn run_listener( fn log_global_shortcuts_version(version: zbus::Result) { match version { Ok(version) => { - debug!("GlobalShortcuts portal interface version {}", version); + debug!("GlobalShortcuts portal interface version {version}"); if version < 2 { warn!( - "GlobalShortcuts portal version {} lacks reliable activation token support; overlay focus may require notification click", - version + "GlobalShortcuts portal version {version} lacks reliable activation token support; overlay focus may require notification click" ); } } Err(err) => { - warn!( - "Failed to read GlobalShortcuts portal interface version: {}", - err - ); + warn!("Failed to read GlobalShortcuts portal interface version: {err}"); } } } @@ -370,7 +360,7 @@ mod tests { let (polled_tx, polled_rx) = oneshot::channel(); let operation = async move { polled_tx.send(()).unwrap(); - future::pending::<()>().await + future::pending::<()>().await; }; let shutdown_task = tokio::spawn(async move { polled_rx.await.unwrap(); @@ -398,8 +388,8 @@ async fn register_host_portal_app_id(connection: &Connection, app_id: &str) -> R registry .register(app_id, HashMap::new()) .await - .with_context(|| format!("host portal app-id registration failed for '{}'", app_id))?; - debug!("Registered host portal app-id '{}'", app_id); + .with_context(|| format!("host portal app-id registration failed for '{app_id}'"))?; + debug!("Registered host portal app-id '{app_id}'"); Ok(()) } @@ -435,8 +425,7 @@ async fn create_global_shortcuts_session( let (response, results) = wait_for_request_response(connection, request_path, shutdown).await?; if response != 0 { return Err(anyhow!( - "GlobalShortcuts.CreateSession denied by portal (response code {})", - response + "GlobalShortcuts.CreateSession denied by portal (response code {response})" )); } @@ -474,7 +463,7 @@ async fn bind_toggle_shortcut( ); let session_path = zbus::zvariant::ObjectPath::try_from(session_handle.as_str()) - .map_err(|err| anyhow!("invalid GlobalShortcuts session path: {}", err))?; + .map_err(|err| anyhow!("invalid GlobalShortcuts session path: {err}"))?; let request_path = await_portal_operation( proxy.bind_shortcuts(session_path, shortcuts, "", bind_options), @@ -487,8 +476,7 @@ async fn bind_toggle_shortcut( let (response, _) = wait_for_request_response(connection, request_path, shutdown).await?; if response != 0 { return Err(anyhow!( - "GlobalShortcuts.BindShortcuts denied by portal (response code {})", - response + "GlobalShortcuts.BindShortcuts denied by portal (response code {response})" )); } @@ -549,9 +537,9 @@ async fn wait_for_request_response( fn parse_object_path(value: &OwnedValue) -> Result { let path: &str = value .downcast_ref() - .map_err(|err| anyhow!("session_handle is not a string/object-path: {}", err))?; + .map_err(|err| anyhow!("session_handle is not a string/object-path: {err}"))?; OwnedObjectPath::try_from(path.to_string()) - .map_err(|err| anyhow!("invalid object path string '{}': {}", path, err)) + .map_err(|err| anyhow!("invalid object path string '{path}': {err}")) } #[cfg(feature = "portal")] @@ -588,7 +576,6 @@ fn owned_value_as_string(value: &OwnedValue) -> Option { fn make_handle_token(prefix: &str) -> String { let nanos = SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|duration| duration.as_nanos()) - .unwrap_or(0); + .map_or(0, |duration| duration.as_nanos()); format!("{}_{}_{}", prefix, process::id(), nanos) } diff --git a/src/daemon/overlay/lifecycle/stop.rs b/src/daemon/overlay/lifecycle/stop.rs index 0cc00c2ec..e703a5c2a 100644 --- a/src/daemon/overlay/lifecycle/stop.rs +++ b/src/daemon/overlay/lifecycle/stop.rs @@ -41,10 +41,7 @@ impl OverlayLifecycle { if let Some(pid) = self.child.display_pid() { let stop_started = Instant::now(); let timeout = Duration::from_secs(2); - info!( - "Stopping overlay process (pid {}, graceful_timeout={:?})", - pid, timeout - ); + info!("Stopping overlay process (pid {pid}, graceful_timeout={timeout:?})"); if let Err(err) = self.child.begin_stop() { warn!("Failed to signal overlay process: {err:#}"); } diff --git a/src/daemon/protocol_v2/action.rs b/src/daemon/protocol_v2/action.rs index 6f42f7df2..ee637e910 100644 --- a/src/daemon/protocol_v2/action.rs +++ b/src/daemon/protocol_v2/action.rs @@ -306,7 +306,7 @@ fn validate_record(record: &ActionRecord) -> Result<()> { match &record.state { JournalState::Claimed { claim_generation } => validate_id(claim_generation)?, JournalState::Abandoned { reason } | JournalState::Indeterminate { reason } => { - validate_reason(reason)? + validate_reason(reason)?; } JournalState::Prepared | JournalState::Eligible | JournalState::Applied => {} } diff --git a/src/daemon/protocol_v2/action/claim.rs b/src/daemon/protocol_v2/action/claim.rs index 2c265d49c..46abc68b2 100644 --- a/src/daemon/protocol_v2/action/claim.rs +++ b/src/daemon/protocol_v2/action/claim.rs @@ -35,19 +35,13 @@ impl ActionJournal { for entry in raw_entries { let path = entry.path(); let identity_on_disk = inode_identity(&path)?; - let name = match entry.file_name().into_string() { - Ok(name) => name, - Err(_) => { - quarantine_action(&self.root, &path, identity_on_disk)?; - continue; - } + let Ok(name) = entry.file_name().into_string() else { + quarantine_action(&self.root, &path, identity_on_disk)?; + continue; }; - let (order, identity) = match parse_action_name(&name) { - Ok(parsed) => parsed, - Err(_) => { - quarantine_action(&self.root, &path, identity_on_disk)?; - continue; - } + let Ok((order, identity)) = parse_action_name(&name) else { + quarantine_action(&self.root, &path, identity_on_disk)?; + continue; }; if duplicate_orders.contains(&order) { quarantine_action(&self.root, &path, identity_on_disk)?; @@ -63,12 +57,11 @@ impl ActionJournal { } } for (order, (identity, path, identity_on_disk)) in entries { - let mut record: ActionRecord = match read_record(&path) { - Ok(record) => record, - Err(_) => { - quarantine_action(&self.root, &path, identity_on_disk)?; - continue; - } + let mut record: ActionRecord = if let Ok(record) = read_record(&path) { + record + } else { + quarantine_action(&self.root, &path, identity_on_disk)?; + continue; }; if validate_record(&record).is_err() { quarantine_action(&self.root, &path, identity_on_disk)?; diff --git a/src/daemon/protocol_v2/child.rs b/src/daemon/protocol_v2/child.rs index 551d581db..092ae2798 100644 --- a/src/daemon/protocol_v2/child.rs +++ b/src/daemon/protocol_v2/child.rs @@ -336,13 +336,14 @@ impl OverlayChildOwner { /// its identity is still held, then clears its proofs and releases it. fn retire(&mut self, status: i32) -> OverlayExit { let session = match (self.generation(), self.owned.as_ref()) { - (Some(generation), Some(owned)) => match owned.process_start_ticks { - Some(ticks) => take_final_session_report(generation, owned.display_pid, ticks), - None => { + (Some(generation), Some(owned)) => { + if let Some(ticks) = owned.process_start_ticks { + take_final_session_report(generation, owned.display_pid, ticks) + } else { discard_session_report(generation); None } - }, + } _ => None, }; if let Some(generation) = self.generation.take() { @@ -557,7 +558,7 @@ pub(crate) fn start_daemon_watchdog_from_environment() -> Result<()> { loop { // SAFETY: pollfd points to one initialized entry and the // descriptor remains owned by this thread. - let result = unsafe { libc::poll(&mut pollfd, 1, -1) }; + let result = unsafe { libc::poll(&raw mut pollfd, 1, -1) }; if result > 0 { // SAFETY: loss of the owning daemon is an irrevocable // fail-stop condition for its internal overlay child. diff --git a/src/daemon/protocol_v2/command/action_link.rs b/src/daemon/protocol_v2/command/action_link.rs index b8dcac968..f91e706f3 100644 --- a/src/daemon/protocol_v2/command/action_link.rs +++ b/src/daemon/protocol_v2/command/action_link.rs @@ -295,17 +295,17 @@ fn finish_command_action_inner( unlock(&decision)?; bail!("command action claim no longer matches"); } - let (effect_id, effect_kind) = match &control.decision { - CommandDecision::Committed { - effect_id, - effect_kind, - effect_status: EffectStatus::Authorized, - .. - } => (effect_id.clone(), *effect_kind), - _ => { - unlock(&decision)?; - bail!("command action effect is not authorized"); - } + let (effect_id, effect_kind) = if let CommandDecision::Committed { + effect_id, + effect_kind, + effect_status: EffectStatus::Authorized, + .. + } = &control.decision + { + (effect_id.clone(), *effect_kind) + } else { + unlock(&decision)?; + bail!("command action effect is not authorized"); }; let reason = bounded_reason( reason.unwrap_or("action handler proved no effect"), diff --git a/src/daemon/protocol_v2/command/layout.rs b/src/daemon/protocol_v2/command/layout.rs index 9f95fca0d..00e956c2f 100644 --- a/src/daemon/protocol_v2/command/layout.rs +++ b/src/daemon/protocol_v2/command/layout.rs @@ -131,7 +131,7 @@ fn check_root_shape(root: &Path, collect_temps: bool) -> Result<()> { Ok(()) => log::warn!("Removed leftover v2 admission temporary {name}"), Err(error) if error.kind() == ErrorKind::NotFound => {} Err(error) => { - log::warn!("Failed to remove leftover v2 admission temporary {name}: {error}") + log::warn!("Failed to remove leftover v2 admission temporary {name}: {error}"); } } } @@ -376,24 +376,21 @@ pub(super) fn allocate_order(root: &Path) -> Result { Err(error) if error.kind() == ErrorKind::NotFound => None, Err(error) => return Err(error.into()), }; - let last_order = match previous { - Some(previous) => { - if previous.protocol_version != DAEMON_COMMAND_PROTOCOL_VERSION - || previous.boot_id != boot_id - || previous.time_namespace != namespace - { - bail!("v2 command admission identity changed"); - } - previous.last_order + let last_order = if let Some(previous) = previous { + if previous.protocol_version != DAEMON_COMMAND_PROTOCOL_VERSION + || previous.boot_id != boot_id + || previous.time_namespace != namespace + { + bail!("v2 command admission identity changed"); } - None => { - if !read_dir_bounded(&controls_dir(root), 1)?.is_empty() - || !read_dir_bounded(&queue_dir(root), 1)?.is_empty() - { - bail!("missing admission high-water record for nonempty v2 tree"); - } - 0 + previous.last_order + } else { + if !read_dir_bounded(&controls_dir(root), 1)?.is_empty() + || !read_dir_bounded(&queue_dir(root), 1)?.is_empty() + { + bail!("missing admission high-water record for nonempty v2 tree"); } + 0 }; let next = now.max( last_order diff --git a/src/daemon/protocol_v2/command/owner.rs b/src/daemon/protocol_v2/command/owner.rs index 9542492e1..62b0771ae 100644 --- a/src/daemon/protocol_v2/command/owner.rs +++ b/src/daemon/protocol_v2/command/owner.rs @@ -100,30 +100,23 @@ impl CommandOwner { let mut references = BTreeMap::new(); let mut duplicate_orders = BTreeSet::new(); for entry in read_dir_bounded(&queue_dir(&self.root), MAX_DIRECTORY_ENTRIES_PER_SCAN)? { - let name = match entry.file_name().into_string() { - Ok(name) => name, - Err(_) => { - quarantine_entry(&self.root, &entry.path(), QuarantineKind::Queue)?; - continue; - } + let Ok(name) = entry.file_name().into_string() else { + quarantine_entry(&self.root, &entry.path(), QuarantineKind::Queue)?; + continue; }; if name.starts_with('.') { continue; } - let (order, identity) = match parse_queue_name(&name) { - Ok(parsed) => parsed, - Err(_) => { - quarantine_entry(&self.root, &entry.path(), QuarantineKind::Queue)?; - continue; - } + let Ok((order, identity)) = parse_queue_name(&name) else { + quarantine_entry(&self.root, &entry.path(), QuarantineKind::Queue)?; + continue; }; let reference: QueueReference = - match read_record(&entry.path(), MAX_QUEUE_REFERENCE_BYTES) { - Ok(reference) => reference, - Err(_) => { - quarantine_entry(&self.root, &entry.path(), QuarantineKind::Queue)?; - continue; - } + if let Ok(reference) = read_record(&entry.path(), MAX_QUEUE_REFERENCE_BYTES) { + reference + } else { + quarantine_entry(&self.root, &entry.path(), QuarantineKind::Queue)?; + continue; }; if validate_reference(&reference, order, &identity, &self.daemon_token).is_err() { if reference.command_identity == identity { @@ -166,7 +159,7 @@ impl CommandOwner { let claimed = self.earliest_ref_less_control(&referenced_controls)?; let use_claimed = match (&reference, &claimed) { (None, Some(_)) => true, - (Some(_), None) | (None, None) => false, + (Some(_) | None, None) => false, ( Some((reference_order, (reference_identity, _, _))), Some((claim_order, claim_identity, _)), @@ -201,14 +194,11 @@ impl CommandOwner { if !try_lock_until(&decision_lock, libc::LOCK_EX, retry_deadline)? { return Ok(None); } - let mut control = match read_control(&path) { - Ok(control) => control, - Err(_) => { - unlock(&decision_lock)?; - quarantine_entry(&self.root, &reference_path, QuarantineKind::Queue)?; - quarantine_entry(&self.root, &path, QuarantineKind::Control)?; - return Ok(None); - } + let Ok(mut control) = read_control(&path) else { + unlock(&decision_lock)?; + quarantine_entry(&self.root, &reference_path, QuarantineKind::Queue)?; + quarantine_entry(&self.root, &path, QuarantineKind::Control)?; + return Ok(None); }; if control.identity != reference.command_identity || control.queue_order != reference.queue_order diff --git a/src/daemon/protocol_v2/command/recovery.rs b/src/daemon/protocol_v2/command/recovery.rs index 69ce34906..d56395405 100644 --- a/src/daemon/protocol_v2/command/recovery.rs +++ b/src/daemon/protocol_v2/command/recovery.rs @@ -22,28 +22,21 @@ pub(super) fn recover_previous_generation(root: &Path, daemon_token: &str) -> Re let identity_valid = entry .file_name() .into_string() - .ok() - .is_some_and(|identity| validate_id(&identity).is_ok()); + .is_ok_and(|identity| validate_id(&identity).is_ok()); if !identity_valid { quarantine_entry(root, &path, QuarantineKind::Control)?; continue; } - let decision_lock = match open_lock(&path.join("decision.lock"), false) { - Ok(lock) => lock, - Err(_) => { - quarantine_entry(root, &path, QuarantineKind::Control)?; - continue; - } + let Ok(decision_lock) = open_lock(&path.join("decision.lock"), false) else { + quarantine_entry(root, &path, QuarantineKind::Control)?; + continue; }; let deadline = BootClock::now()?.checked_add(Duration::from_millis(200))?; lock_until(&decision_lock, libc::LOCK_EX, deadline)?; - let mut control = match read_control(&path) { - Ok(control) => control, - Err(_) => { - unlock(&decision_lock)?; - quarantine_entry(root, &path, QuarantineKind::Control)?; - continue; - } + let Ok(mut control) = read_control(&path) else { + unlock(&decision_lock)?; + quarantine_entry(root, &path, QuarantineKind::Control)?; + continue; }; if control.target_daemon_token == daemon_token || control.response.is_some() { unlock(&decision_lock)?; @@ -123,31 +116,24 @@ pub(super) fn recover_previous_generation(root: &Path, daemon_token: &str) -> Re } for entry in read_dir_bounded(&queue_dir(root), MAX_DIRECTORY_ENTRIES_PER_SCAN)? { - let name = match entry.file_name().into_string() { - Ok(name) => name, - Err(_) => { - quarantine_entry(root, &entry.path(), QuarantineKind::Queue)?; - continue; - } + let Ok(name) = entry.file_name().into_string() else { + quarantine_entry(root, &entry.path(), QuarantineKind::Queue)?; + continue; }; if name.starts_with('.') { continue; } - let (_order, identity) = match parse_queue_name(&name) { - Ok(parsed) => parsed, - Err(_) => { - quarantine_entry(root, &entry.path(), QuarantineKind::Queue)?; - continue; - } + let Ok((_order, identity)) = parse_queue_name(&name) else { + quarantine_entry(root, &entry.path(), QuarantineKind::Queue)?; + continue; }; - let reference: QueueReference = match read_record(&entry.path(), MAX_QUEUE_REFERENCE_BYTES) - { - Ok(reference) => reference, - Err(_) => { + let reference: QueueReference = + if let Ok(reference) = read_record(&entry.path(), MAX_QUEUE_REFERENCE_BYTES) { + reference + } else { quarantine_entry(root, &entry.path(), QuarantineKind::Queue)?; continue; - } - }; + }; if reference.command_identity != identity { quarantine_entry(root, &entry.path(), QuarantineKind::Queue)?; continue; diff --git a/src/daemon/protocol_v2/linux.rs b/src/daemon/protocol_v2/linux.rs index 0cf68e51c..58790f1d1 100644 --- a/src/daemon/protocol_v2/linux.rs +++ b/src/daemon/protocol_v2/linux.rs @@ -296,9 +296,7 @@ pub(crate) fn gc_quarantine_tail(dir: &Path, retain: usize) -> io::Result let excess = entries.len() - retain; let mut removed = 0; for (_, _, path) in entries.into_iter().take(excess) { - let is_dir = fs::symlink_metadata(&path) - .map(|metadata| metadata.is_dir()) - .unwrap_or(false); + let is_dir = fs::symlink_metadata(&path).is_ok_and(|metadata| metadata.is_dir()); let result = if is_dir { fs::remove_dir_all(&path) } else { @@ -423,7 +421,7 @@ pub(crate) fn wait_for_pidfd_exit(fd: BorrowedFd<'_>, timeout: Duration) -> io:: let millis = i32::try_from(remaining.as_millis()).unwrap_or(i32::MAX); // SAFETY: one owned pollfd, valid for the call; the descriptor is // borrowed for at least this long. - let ready = unsafe { libc::poll(&mut poll_fd, 1, millis) }; + let ready = unsafe { libc::poll(&raw mut poll_fd, 1, millis) }; if ready < 0 { let error = io::Error::last_os_error(); // A signal arriving mid-wait is expected on this thread. @@ -467,7 +465,7 @@ impl BootClock { }; // SAFETY: value is a valid writable timespec and CLOCK_BOOTTIME has no // additional preconditions. - if unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut value) } != 0 { + if unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &raw mut value) } != 0 { return Err(io::Error::last_os_error()); } if value.tv_sec < 0 || !(0..1_000_000_000).contains(&value.tv_nsec) { @@ -549,7 +547,7 @@ impl BootDeadlineSource { libc::timerfd_settime( self.fd.as_raw_fd(), libc::TFD_TIMER_ABSTIME, - &value, + &raw const value, ptr::null_mut(), ) } != 0 @@ -571,7 +569,10 @@ impl BootDeadlineSource { }, }; // SAFETY: value is initialized and fd owns a timerfd. - if unsafe { libc::timerfd_settime(self.fd.as_raw_fd(), 0, &value, ptr::null_mut()) } != 0 { + if unsafe { + libc::timerfd_settime(self.fd.as_raw_fd(), 0, &raw const value, ptr::null_mut()) + } != 0 + { return Err(io::Error::last_os_error()); } Ok(()) @@ -584,7 +585,7 @@ impl BootDeadlineSource { let result = unsafe { libc::read( self.fd.as_raw_fd(), - (&mut expirations as *mut u64).cast(), + (&raw mut expirations).cast(), size_of::(), ) }; diff --git a/src/daemon/protocol_v2/tests.rs b/src/daemon/protocol_v2/tests.rs index 06f237c30..4598d6f9a 100644 --- a/src/daemon/protocol_v2/tests.rs +++ b/src/daemon/protocol_v2/tests.rs @@ -77,7 +77,7 @@ fn boottime_deadline_source_arms_absolutely_and_drains_once() { revents: 0, }; // SAFETY: poll_fd remains valid for this bounded poll. - let ready = unsafe { libc::poll(&mut poll_fd, 1, 500) }; + let ready = unsafe { libc::poll(&raw mut poll_fd, 1, 500) }; assert_eq!(ready, 1); assert_ne!(poll_fd.revents & libc::POLLIN, 0); assert!(source.drain().unwrap()); @@ -134,7 +134,7 @@ fn self_pidfd_is_not_readable_while_process_is_alive() { revents: 0, }; // SAFETY: poll_fd remains valid for the zero-timeout observation. - let ready = unsafe { libc::poll(&mut poll_fd, 1, 0) }; + let ready = unsafe { libc::poll(&raw mut poll_fd, 1, 0) }; assert_eq!(ready, 0); } @@ -195,7 +195,7 @@ fn command_queue_watch_reports_atomic_publication_and_rejects_replacement() { revents: 0, }; // SAFETY: watcher owns the descriptor throughout the bounded poll. - assert_eq!(unsafe { libc::poll(&mut poll_fd, 1, 500) }, 1); + assert_eq!(unsafe { libc::poll(&raw mut poll_fd, 1, 500) }, 1); assert!(watcher.drain().unwrap().scan_pending); fs::rename(&queue, temp.path().join("old-queue")).unwrap(); diff --git a/src/daemon/protocol_v2/wire.rs b/src/daemon/protocol_v2/wire.rs index b28eab43b..fad471892 100644 --- a/src/daemon/protocol_v2/wire.rs +++ b/src/daemon/protocol_v2/wire.rs @@ -770,7 +770,7 @@ fn validate_reason_fields(control: &CommandControl) -> Result<()> { CommandDecision::Rejected { reason } => validate_reason(reason)?, CommandDecision::Committed { effect_status, .. } => match effect_status { EffectStatus::FailedNoEffect(reason) | EffectStatus::Indeterminate(reason) => { - validate_reason(reason)? + validate_reason(reason)?; } EffectStatus::Authorized | EffectStatus::Completed => {} }, diff --git a/src/daemon/tray/helpers.rs b/src/daemon/tray/helpers.rs index 8027d61aa..84d7c7fe4 100644 --- a/src/daemon/tray/helpers.rs +++ b/src/daemon/tray/helpers.rs @@ -124,10 +124,7 @@ impl WayscriberTray { let exe = match env::current_exe() { Ok(path) => path, Err(err) => { - warn!( - "Failed to resolve current executable for About window: {}", - err - ); + warn!("Failed to resolve current executable for About window: {err}"); return; } }; @@ -141,7 +138,7 @@ impl WayscriberTray { info!("Launched About window (pid {})", child.id()); } Err(err) => { - warn!("Failed to launch About window: {}", err); + warn!("Failed to launch About window: {err}"); } } } @@ -169,10 +166,7 @@ impl WayscriberTray { match self.control.action.publish(action) { Ok(()) => {} Err(super::super::types::OverlayActionPublishError::QueueFull) => { - warn!( - "Failed to queue tray action {}: daemon intent queue is full", - action_str - ); + warn!("Failed to queue tray action {action_str}: daemon intent queue is full"); } Err(super::super::types::OverlayActionPublishError::Wake(error)) => { warn!("Queued tray action {action_str}, but failed to wake daemon: {error}"); @@ -186,21 +180,21 @@ impl WayscriberTray { let config_dir = match Config::config_directory_from_source(&loaded.source) { Ok(dir) => dir, Err(err) => { - warn!("Failed to resolve config directory: {}", err); + warn!("Failed to resolve config directory: {err}"); return; } }; match options_from_config(&loaded.config.session, &config_dir, None) { Ok(opts) => match clear_session(&opts) { Ok(outcome) => { - info!("Cleared session files: {:?}", outcome); + info!("Cleared session files: {outcome:?}"); } - Err(err) => warn!("Failed to clear session files: {}", err), + Err(err) => warn!("Failed to clear session files: {err}"), }, - Err(err) => warn!("Failed to build session options: {}", err), + Err(err) => warn!("Failed to build session options: {err}"), } } - Err(err) => warn!("Failed to load config for clearing session: {}", err), + Err(err) => warn!("Failed to load config for clearing session: {err}"), } } @@ -222,7 +216,7 @@ impl WayscriberTray { let path = match Config::config_path() { Ok(p) => p, Err(err) => { - warn!("Unable to resolve config path: {}", err); + warn!("Unable to resolve config path: {err}"); return false; } }; diff --git a/src/daemon/tray/ksni.rs b/src/daemon/tray/ksni.rs index dd7791d39..e0aa09b90 100644 --- a/src/daemon/tray/ksni.rs +++ b/src/daemon/tray/ksni.rs @@ -377,7 +377,7 @@ impl ksni::Tray for WayscriberTray { fn watcher_offline(&self, reason: ksni::OfflineReason) -> bool { let reason_text = format!("{reason:?}"); if self.tray_status.set_watcher_offline(reason_text.clone()) { - warn!("StatusNotifierWatcher is offline: {}", reason_text); + warn!("StatusNotifierWatcher is offline: {reason_text}"); } true } diff --git a/src/daemon/tray/runtime.rs b/src/daemon/tray/runtime.rs index 448295721..e00ba281f 100644 --- a/src/daemon/tray/runtime.rs +++ b/src/daemon/tray/runtime.rs @@ -46,10 +46,7 @@ fn load_tray_settings_from_config() -> TrayIconStyle { match Config::load() { Ok(loaded) => loaded.config.tray.icon_style, Err(err) => { - warn!( - "Failed to read config for tray settings; using safe defaults: {}", - err - ); + warn!("Failed to read config for tray settings; using safe defaults: {err}"); TrayIconStyle::Auto } } @@ -88,7 +85,7 @@ pub(crate) fn start_system_tray( let rt = match Runtime::new() { Ok(runtime) => runtime, Err(e) => { - warn!("Failed to create Tokio runtime for system tray: {}", e); + warn!("Failed to create Tokio runtime for system tray: {e}"); worker.report_readiness(Err(anyhow!( "Failed to create Tokio runtime for system tray: {e}" ))); @@ -103,7 +100,7 @@ pub(crate) fn start_system_tray( result = &mut spawn => match result { Ok(handle) => handle, Err(e) => { - warn!("System tray error: {}", e); + warn!("System tray error: {e}"); worker.report_readiness(Err(anyhow!("System tray error: {e}"))); return; } @@ -124,7 +121,7 @@ pub(crate) fn start_system_tray( tokio::select! { () = worker.cancelled() => { info!("Tray-local stop requested - shutting down system tray"); - let _ = handle.shutdown().await; + handle.shutdown().await; break; } () = time::sleep(time::Duration::from_millis(100)) => { @@ -138,7 +135,7 @@ pub(crate) fn start_system_tray( } if tray_quit.is_raised() { info!("Quit signal received - shutting down system tray"); - let _ = handle.shutdown().await; + handle.shutdown().await; break; } } @@ -185,8 +182,7 @@ impl TrayWorker { fn report_readiness(&self, result: Result<()>) { if let Err(err) = self.readiness.send(result) { debug!( - "System tray readiness receiver dropped before signal could be delivered: {}", - err + "System tray readiness receiver dropped before signal could be delivered: {err}" ); } } @@ -280,8 +276,7 @@ impl TrayRuntime { } TrayShutdownOutcome::TimedOut => { warn!( - "System tray thread did not stop within {:?} after startup failure; detaching it", - timeout + "System tray thread did not stop within {timeout:?} after startup failure; detaching it" ); } } @@ -318,10 +313,9 @@ impl TrayRuntime { match self.stop_within(TRAY_STOP_TIMEOUT) { TrayShutdownOutcome::Joined => info!("System tray thread joined"), TrayShutdownOutcome::Panicked => warn!("System tray thread panicked"), - TrayShutdownOutcome::TimedOut => warn!( - "System tray thread did not stop within {:?}; detaching it", - TRAY_STOP_TIMEOUT - ), + TrayShutdownOutcome::TimedOut => { + warn!("System tray thread did not stop within {TRAY_STOP_TIMEOUT:?}; detaching it"); + } } } } @@ -342,10 +336,7 @@ async fn log_status_notifier_state() { let conn = match Connection::session().await { Ok(conn) => conn, Err(err) => { - warn!( - "Failed to connect to session D-Bus for tray diagnostics: {}", - err - ); + warn!("Failed to connect to session D-Bus for tray diagnostics: {err}"); return; } }; @@ -360,7 +351,7 @@ async fn log_status_notifier_state() { { Ok(proxy) => proxy, Err(err) => { - warn!("StatusNotifierWatcher unavailable (no tray host?): {}", err); + warn!("StatusNotifierWatcher unavailable (no tray host?): {err}"); return; } }; @@ -368,7 +359,7 @@ async fn log_status_notifier_state() { let host_registered: bool = match proxy.get_property("IsStatusNotifierHostRegistered").await { Ok(value) => value, Err(err) => { - warn!("Failed to query tray host registration: {}", err); + warn!("Failed to query tray host registration: {err}"); return; } }; @@ -376,7 +367,7 @@ async fn log_status_notifier_state() { let items: Vec = match proxy.get_property("RegisteredStatusNotifierItems").await { Ok(value) => value, Err(err) => { - warn!("Failed to query registered tray items: {}", err); + warn!("Failed to query registered tray items: {err}"); return; } }; diff --git a/src/daemon/update_watch.rs b/src/daemon/update_watch.rs index 260d6fbf7..5255b1064 100644 --- a/src/daemon/update_watch.rs +++ b/src/daemon/update_watch.rs @@ -25,7 +25,7 @@ use super::types::{AvailableUpdateNotice, TrayStatusShared}; /// How often the watcher wakes to ask whether a check is due. The gap between /// actual requests comes from `[updates] interval_hours`. -const POLL_INTERVAL: Duration = Duration::from_secs(30 * 60); +const POLL_INTERVAL: Duration = Duration::from_mins(30); /// Grace period before the first check, so a daemon started with the session is /// not racing the network stack. diff --git a/src/desktop_open.rs b/src/desktop_open.rs index 68fef7419..1957f837f 100644 --- a/src/desktop_open.rs +++ b/src/desktop_open.rs @@ -75,7 +75,7 @@ pub(crate) fn open(invocation: &DesktopOpenInvocation) -> Result<()> { } /// Spawn a desktop opener without blocking the Wayland or tray callback that -/// requested it. The broker still authorizes the argv; DetachedAfterExec keeps +/// requested it. The broker still authorizes the argv; `DetachedAfterExec` keeps /// the launched application alive after this process exits. /// /// Callers that own the process broker must join the returned worker before diff --git a/src/draw/frame/core.rs b/src/draw/frame/core.rs index 1ac8691e5..cbad6ffa5 100644 --- a/src/draw/frame/core.rs +++ b/src/draw/frame/core.rs @@ -85,7 +85,7 @@ impl Frame { frame } - /// Copy exactly the newest undo/redo entries retained by clamp_history_depth, + /// Copy exactly the newest undo/redo entries retained by `clamp_history_depth`, /// without first allocating copies of discarded actions or their payloads. #[must_use] pub fn clone_with_history_limit(&self, limit: usize) -> Self { diff --git a/src/draw/frame/tests/history/prune.rs b/src/draw/frame/tests/history/prune.rs index b895f95e2..e8a4b6e4f 100644 --- a/src/draw/frame/tests/history/prune.rs +++ b/src/draw/frame/tests/history/prune.rs @@ -54,7 +54,7 @@ fn prune_history_for_removed_ids_prunes_shapes_and_actions() { assert_eq!(shapes.len(), 1); assert_eq!(shapes[0].1.id, 1); } - other => panic!("expected create action, got {:?}", other), + other => panic!("expected create action, got {other:?}"), } } @@ -118,6 +118,6 @@ fn prune_history_against_shapes_drops_actions_for_missing_ids() { UndoAction::Modify { shape_id, .. } => { assert_eq!(*shape_id, id_existing); } - other => panic!("expected modify action, got {:?}", other), + other => panic!("expected modify action, got {other:?}"), } } diff --git a/src/draw/frame/tests/history/validate.rs b/src/draw/frame/tests/history/validate.rs index 8b0f2710a..0f053d892 100644 --- a/src/draw/frame/tests/history/validate.rs +++ b/src/draw/frame/tests/history/validate.rs @@ -42,6 +42,6 @@ fn validate_history_drops_actions_exceeding_compound_depth() { UndoAction::Compound { actions } => { assert_eq!(actions.len(), 1, "shallow compound should be preserved"); } - other => panic!("expected compound action, got {:?}", other), + other => panic!("expected compound action, got {other:?}"), } } diff --git a/src/draw/frame/types.rs b/src/draw/frame/types.rs index abecfd1ec..237021c5a 100644 --- a/src/draw/frame/types.rs +++ b/src/draw/frame/types.rs @@ -236,8 +236,7 @@ impl HistoryTrimStats { pub(super) fn current_timestamp_ms() -> u64 { SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|dur| dur.as_millis() as u64) - .unwrap_or(0) + .map_or(0, |dur| dur.as_millis() as u64) } #[cfg(test)] diff --git a/src/draw/render/background.rs b/src/draw/render/background.rs index a1dc11ee7..f21473606 100644 --- a/src/draw/render/background.rs +++ b/src/draw/render/background.rs @@ -35,7 +35,7 @@ pub fn fill_transparent(ctx: &cairo::Context, width: i32, height: i32) { // 0.05 alpha = barely visible, just enough to confirm it's working ctx.set_source_rgba(0.1, 0.1, 0.1, 0.05); ctx.set_operator(cairo::Operator::Source); - ctx.rectangle(0.0, 0.0, width as f64, height as f64); + ctx.rectangle(0.0, 0.0, f64::from(width), f64::from(height)); let _ = ctx.fill(); } diff --git a/src/draw/render/blur.rs b/src/draw/render/blur.rs index 3d8e29ad7..72fdfa42d 100644 --- a/src/draw/render/blur.rs +++ b/src/draw/render/blur.rs @@ -276,12 +276,17 @@ pub(super) fn render_blur_placeholder( let _ = ctx.stroke(); let band_count = 4; - let band_h = (height / band_count as f64).max(1.0); + let band_h = (height / f64::from(band_count)).max(1.0); for idx in 0..band_count { if idx % 2 == 0 { continue; } - ctx.rectangle(left, top + idx as f64 * band_h, width, band_h.min(height)); + ctx.rectangle( + left, + top + f64::from(idx) * band_h, + width, + band_h.min(height), + ); ctx.set_source_rgba(1.0, 1.0, 1.0, 0.06); let _ = ctx.fill(); } @@ -297,15 +302,15 @@ fn copy_surface_region( ) -> Option { let region = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height).ok()?; let ctx = cairo::Context::new(®ion).ok()?; - let _ = ctx.set_source_surface(surface, -(x as f64), -(y as f64)); + let _ = ctx.set_source_surface(surface, -f64::from(x), -f64::from(y)); let _ = ctx.paint(); Some(region) } fn resample_dimensions(width: i32, height: i32, factor: f64) -> (i32, i32) { ( - ((width as f64) / factor).round().max(1.0) as i32, - ((height as f64) / factor).round().max(1.0) as i32, + (f64::from(width) / factor).round().max(1.0) as i32, + (f64::from(height) / factor).round().max(1.0) as i32, ) } @@ -317,8 +322,8 @@ fn resample_surface( ) -> Option { let resampled = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height).ok()?; let ctx = cairo::Context::new(&resampled).ok()?; - let scale_x = width as f64 / source.width() as f64; - let scale_y = height as f64 / source.height() as f64; + let scale_x = f64::from(width) / f64::from(source.width()); + let scale_y = f64::from(height) / f64::from(source.height()); ctx.scale( scale_x.max(f64::MIN_POSITIVE), scale_y.max(f64::MIN_POSITIVE), @@ -352,14 +357,14 @@ fn average_surface_stats(surface: &mut cairo::ImageSurface) -> Option() -> EraserReplayContext<'a> { } } -fn with_backdrop<'a>(surface: &'a ImageSurface) -> EraserReplayContext<'a> { +fn with_backdrop(surface: &ImageSurface) -> EraserReplayContext<'_> { EraserReplayContext { surface: Some(surface), ..no_backdrop() diff --git a/src/draw/render/board_grid/performance.rs b/src/draw/render/board_grid/performance.rs index 4d250ed5e..850e5f609 100644 --- a/src/draw/render/board_grid/performance.rs +++ b/src/draw/render/board_grid/performance.rs @@ -24,7 +24,7 @@ fn render_case( ) -> (u128, usize) { let start = Instant::now(); let target: cairo::Surface = if pdf { - cairo::PdfSurface::for_stream(size.0 as f64, size.1 as f64, Vec::::new()) + cairo::PdfSurface::for_stream(f64::from(size.0), f64::from(size.1), Vec::::new()) .unwrap() .as_ref() .clone() @@ -45,7 +45,12 @@ fn render_case( .pattern, ), Source::Viewport => { - let bounds = Rectangle::new(-1_000_021.0, -2_000_003.0, size.0 as f64, size.1 as f64); + let bounds = Rectangle::new( + -1_000_021.0, + -2_000_003.0, + f64::from(size.0), + f64::from(size.1), + ); let record = RecordingSurface::create(cairo::Content::ColorAlpha, Some(bounds)).unwrap(); paint_geometry( diff --git a/src/draw/render/context/text_tests.rs b/src/draw/render/context/text_tests.rs index f15e3e905..65faffbf4 100644 --- a/src/draw/render/context/text_tests.rs +++ b/src/draw/render/context/text_tests.rs @@ -69,7 +69,7 @@ fn pixels( ) -> Vec { let mut surface = cairo::ImageSurface::create(cairo::Format::ARgb32, 400 * density, 380 * density).unwrap(); - surface.set_device_scale(density as f64, density as f64); + surface.set_device_scale(f64::from(density), f64::from(density)); { let ctx = cairo::Context::new(&surface).unwrap(); ctx.set_source_rgb(1.0, 1.0, 1.0); diff --git a/src/draw/render/image.rs b/src/draw/render/image.rs index 2f0dc9169..69ed8be60 100644 --- a/src/draw/render/image.rs +++ b/src/draw/render/image.rs @@ -156,18 +156,18 @@ pub(super) fn render_image_shape( return; }; - let width = w.saturating_abs().max(1) as f64; - let height = h.saturating_abs().max(1) as f64; + let width = f64::from(w.saturating_abs().max(1)); + let height = f64::from(h.saturating_abs().max(1)); let draw_x = if w < 0 { x + w } else { x }; let draw_y = if h < 0 { y + h } else { y }; let _ = ctx.save(); - ctx.rectangle(draw_x as f64, draw_y as f64, width, height); + ctx.rectangle(f64::from(draw_x), f64::from(draw_y), width, height); ctx.clip(); - ctx.translate(draw_x as f64, draw_y as f64); + ctx.translate(f64::from(draw_x), f64::from(draw_y)); ctx.scale( - width / surface.width().max(1) as f64, - height / surface.height().max(1) as f64, + width / f64::from(surface.width().max(1)), + height / f64::from(surface.height().max(1)), ); let _ = ctx.set_source_surface(surface.as_ref(), 0.0, 0.0); let _ = ctx.paint(); @@ -216,8 +216,9 @@ fn decode_surface(data: &EmbeddedImage) -> Option<(ImageSurface, usize)> { .zip(row_bytes.as_chunks_mut::<4>().0.iter_mut()) { let [r, g, b, a] = [pixel[0], pixel[1], pixel[2], pixel[3]]; - let premul = - |channel: u8| -> u8 { ((channel as u16 * a as u16 + 127) / 255).min(255) as u8 }; + let premul = |channel: u8| -> u8 { + ((u16::from(channel) * u16::from(a) + 127) / 255).min(255) as u8 + }; let r = premul(r); let g = premul(g); let b = premul(b); @@ -242,10 +243,10 @@ fn decode_surface(data: &EmbeddedImage) -> Option<(ImageSurface, usize)> { } fn render_missing_image_placeholder(ctx: &cairo::Context, x: i32, y: i32, w: i32, h: i32) { - let width = w.saturating_abs().max(1) as f64; - let height = h.saturating_abs().max(1) as f64; - let draw_x = if w < 0 { x + w } else { x } as f64; - let draw_y = if h < 0 { y + h } else { y } as f64; + let width = f64::from(w.saturating_abs().max(1)); + let height = f64::from(h.saturating_abs().max(1)); + let draw_x = f64::from(if w < 0 { x + w } else { x }); + let draw_y = f64::from(if h < 0 { y + h } else { y }); let _ = ctx.save(); ctx.rectangle(draw_x, draw_y, width, height); diff --git a/src/draw/render/pressure_strokes.rs b/src/draw/render/pressure_strokes.rs index 3ac4854e0..95b3f23a3 100644 --- a/src/draw/render/pressure_strokes.rs +++ b/src/draw/render/pressure_strokes.rs @@ -189,7 +189,7 @@ fn pressure_stroke_preview_samples( for i in 0..len { let (x, y) = points[i]; - let width = (thicknesses[i] as f64).max(PRESSURE_STROKE_MIN_WIDTH); + let width = f64::from(thicknesses[i]).max(PRESSURE_STROKE_MIN_WIDTH); samples.push(PressureStrokeSample { x, y, @@ -416,7 +416,7 @@ mod tests { ); drop(ctx); - let alpha = alpha_at(&mut surface, 100, 80) as i32; + let alpha = i32::from(alpha_at(&mut surface, 100, 80)); assert!( (expected_alpha - 8..=expected_alpha + 8).contains(&alpha), "expected preview overlap alpha near {expected_alpha}, got {alpha}" @@ -449,7 +449,7 @@ mod tests { let (x0, y0) = window[0]; let (x1, y1) = window[1]; for step in 1..20 { - let t = step as f64 / 20.0; + let t = f64::from(step) / 20.0; let x = x0 + (x1 - x0) * t; let y = y0 + (y1 - y0) * t; assert!( @@ -480,7 +480,7 @@ mod tests { ); drop(ctx); - let alpha = alpha_at(&mut surface, 100, 80) as i32; + let alpha = i32::from(alpha_at(&mut surface, 100, 80)); assert!( (expected_alpha - 8..=expected_alpha + 8).contains(&alpha), "expected overlap alpha near {expected_alpha}, got {alpha}" diff --git a/src/draw/render/primitives.rs b/src/draw/render/primitives.rs index acc8b61c3..a202233ce 100644 --- a/src/draw/render/primitives.rs +++ b/src/draw/render/primitives.rs @@ -17,8 +17,8 @@ pub(super) fn render_line( ctx.set_line_width(thick); ctx.set_line_cap(cairo::LineCap::Round); - ctx.move_to(x1 as f64, y1 as f64); - ctx.line_to(x2 as f64, y2 as f64); + ctx.move_to(f64::from(x1), f64::from(y1)); + ctx.line_to(f64::from(x2), f64::from(y2)); let _ = ctx.stroke(); } @@ -78,8 +78,8 @@ pub(super) fn render_ellipse( ctx.set_line_width(thick); ctx.save().ok(); - ctx.translate(cx as f64, cy as f64); - ctx.scale(rx as f64, ry as f64); + ctx.translate(f64::from(cx), f64::from(cy)); + ctx.scale(f64::from(rx), f64::from(ry)); ctx.new_sub_path(); ctx.arc(0.0, 0.0, 1.0, 0.0, 2.0 * consts::PI); fill_path(ctx, fill); @@ -107,9 +107,9 @@ pub(super) fn render_polygon( ctx.set_line_width(thick); ctx.set_line_cap(cairo::LineCap::Round); ctx.set_line_join(cairo::LineJoin::Round); - ctx.move_to(points[0].0 as f64, points[0].1 as f64); + ctx.move_to(f64::from(points[0].0), f64::from(points[0].1)); for &(x, y) in &points[1..] { - ctx.line_to(x as f64, y as f64); + ctx.line_to(f64::from(x), f64::from(y)); } ctx.close_path(); fill_path(ctx, fill); @@ -136,9 +136,9 @@ pub(crate) fn render_polygon_preview( ctx.set_line_width(thick); ctx.set_line_cap(cairo::LineCap::Butt); ctx.set_line_join(cairo::LineJoin::Round); - ctx.move_to(points[0].0 as f64, points[0].1 as f64); + ctx.move_to(f64::from(points[0].0), f64::from(points[0].1)); for &(x, y) in &points[1..] { - ctx.line_to(x as f64, y as f64); + ctx.line_to(f64::from(x), f64::from(y)); } if shape::has_minimum_distinct_points(points) { ctx.close_path(); diff --git a/src/draw/render/selection.rs b/src/draw/render/selection.rs index bd81ba3a0..fe6786dec 100644 --- a/src/draw/render/selection.rs +++ b/src/draw/render/selection.rs @@ -155,10 +155,10 @@ pub fn render_selection_halo_with_measurer( Shape::BlurRect { .. } => { if let Some(bounds) = drawn.bounding_box_with(measurer) { let padding = 3.0; - let x = bounds.x as f64 - padding; - let y = bounds.y as f64 - padding; - let w = bounds.width as f64 + padding * 2.0; - let h = bounds.height as f64 + padding * 2.0; + let x = f64::from(bounds.x) - padding; + let y = f64::from(bounds.y) - padding; + let w = f64::from(bounds.width) + padding * 2.0; + let h = f64::from(bounds.height) + padding * 2.0; ctx.set_source_rgba(glow.r, glow.g, glow.b, glow.a * 0.5); ctx.rectangle(x, y, w, h); let _ = ctx.fill(); @@ -182,8 +182,8 @@ pub fn render_selection_halo_with_measurer( }; render_click_highlight( ctx, - *x as f64, - *y as f64, + f64::from(*x), + f64::from(*y), halo_radius, outline + outline_width, fill, @@ -198,10 +198,10 @@ pub fn render_selection_halo_with_measurer( Shape::Text { .. } | Shape::Image { .. } => { if let Some(bounds) = drawn.bounding_box_with(measurer) { let padding = 4.0; - let x = bounds.x as f64 - padding; - let y = bounds.y as f64 - padding; - let w = bounds.width as f64 + padding * 2.0; - let h = bounds.height as f64 + padding * 2.0; + let x = f64::from(bounds.x) - padding; + let y = f64::from(bounds.y) - padding; + let w = f64::from(bounds.width) + padding * 2.0; + let h = f64::from(bounds.height) + padding * 2.0; ctx.set_source_rgba(glow.r, glow.g, glow.b, glow.a * 0.6); ctx.rectangle(x, y, w, h); let _ = ctx.fill(); @@ -214,10 +214,10 @@ pub fn render_selection_halo_with_measurer( Shape::StickyNote { .. } => { if let Some(bounds) = drawn.bounding_box_with(measurer) { let padding = 4.0; - let x = bounds.x as f64 - padding; - let y = bounds.y as f64 - padding; - let w = bounds.width as f64 + padding * 2.0; - let h = bounds.height as f64 + padding * 2.0; + let x = f64::from(bounds.x) - padding; + let y = f64::from(bounds.y) - padding; + let w = f64::from(bounds.width) + padding * 2.0; + let h = f64::from(bounds.height) + padding * 2.0; ctx.set_source_rgba(glow.r, glow.g, glow.b, glow.a * 0.6); ctx.rectangle(x, y, w, h); let _ = ctx.fill(); @@ -235,10 +235,10 @@ pub fn render_selection_halo_with_measurer( pub fn render_selection_handles(ctx: &cairo::Context, bounds: &Rect) { let _ = ctx.save(); - let x = bounds.x as f64; - let y = bounds.y as f64; - let w = bounds.width as f64; - let h = bounds.height as f64; + let x = f64::from(bounds.x); + let y = f64::from(bounds.y); + let w = f64::from(bounds.width); + let h = f64::from(bounds.height); // Draw dashed bounding box ctx.set_source_rgba(SELECTION_COLOR.r, SELECTION_COLOR.g, SELECTION_COLOR.b, 0.6); diff --git a/src/draw/render/strokes.rs b/src/draw/render/strokes.rs index f5422c59e..b8a697b08 100644 --- a/src/draw/render/strokes.rs +++ b/src/draw/render/strokes.rs @@ -39,7 +39,7 @@ pub(crate) fn render_eraser_stroke( ctx: &cairo::Context, points: &[(i32, i32)], brush: &EraserBrush, - eraser_ctx: &EraserReplayContext, + eraser_ctx: &EraserReplayContext<'_>, ) { if points.is_empty() { return; @@ -53,7 +53,7 @@ pub(crate) fn render_eraser_stroke( let build_path = |ctx: &cairo::Context| { if points.len() == 1 { - let (x, y) = (points[0].0 as f64, points[0].1 as f64); + let (x, y) = (f64::from(points[0].0), f64::from(points[0].1)); let half = stroke_width / 2.0; match brush.kind { EraserKind::Circle => ctx.arc(x, y, half, 0.0, consts::PI * 2.0), @@ -63,9 +63,9 @@ pub(crate) fn render_eraser_stroke( } let (x0, y0) = points[0]; - ctx.move_to(x0 as f64, y0 as f64); + ctx.move_to(f64::from(x0), f64::from(y0)); for &(x, y) in &points[1..] { - ctx.line_to(x as f64, y as f64); + ctx.line_to(f64::from(x), f64::from(y)); } }; diff --git a/src/draw/render/text.rs b/src/draw/render/text.rs index c5a7c1462..a0c66218d 100644 --- a/src/draw/render/text.rs +++ b/src/draw/render/text.rs @@ -276,7 +276,8 @@ pub fn render_text_over_with_halo_with_measurer( layout.set_text(text); if let Some(width) = wrap_width { let width = width.max(1); - let width_pango = (width as i64 * pango::SCALE as i64).min(i32::MAX as i64) as i32; + let width_pango = + (i64::from(width) * i64::from(pango::SCALE)).min(i64::from(i32::MAX)) as i32; layout.set_width(width_pango); layout.set_wrap(pango::WrapMode::WordChar); } @@ -287,23 +288,23 @@ pub fn render_text_over_with_halo_with_measurer( .unwrap_or_else(|| { // Fallback: measure directly. let (ink_rect, logical_rect) = layout.extents(); - let scale = pango::SCALE as f64; + let scale = f64::from(pango::SCALE); TextMeasurement { - ink_x: ink_rect.x() as f64 / scale, - ink_y: ink_rect.y() as f64 / scale, - ink_width: ink_rect.width() as f64 / scale, - ink_height: ink_rect.height() as f64 / scale, - logical_x: logical_rect.x() as f64 / scale, - logical_y: logical_rect.y() as f64 / scale, - logical_width: logical_rect.width() as f64 / scale, - logical_height: logical_rect.height() as f64 / scale, - baseline: layout.baseline() as f64 / scale, + ink_x: f64::from(ink_rect.x()) / scale, + ink_y: f64::from(ink_rect.y()) / scale, + ink_width: f64::from(ink_rect.width()) / scale, + ink_height: f64::from(ink_rect.height()) / scale, + logical_x: f64::from(logical_rect.x()) / scale, + logical_y: f64::from(logical_rect.y()) / scale, + logical_width: f64::from(logical_rect.width()) / scale, + logical_height: f64::from(logical_rect.height()) / scale, + baseline: f64::from(layout.baseline()) / scale, } }); let content = measurement.content_extents(wrap_width); // Adjust y position (Pango measures from top-left, we want baseline) - let adjusted_y = y as f64 - measurement.baseline; + let adjusted_y = f64::from(y) - measurement.baseline; // Read the background before anything is painted over it. The halo has to // contrast with what the label sits on, and this is the last moment at @@ -312,7 +313,7 @@ pub fn render_text_over_with_halo_with_measurer( let background_luminance = backdrop_probe::painted_luminance( ctx, ( - x as f64 + content.x, + f64::from(x) + content.x, adjusted_y + content.y, content.width, content.height, @@ -332,7 +333,7 @@ pub fn render_text_over_with_halo_with_measurer( // Union ink and logical extents: ink preserves italic overhangs while // logical cells retain leading/trailing whitespace advances. ctx.rectangle( - x as f64 + content.x - padding, + f64::from(x) + content.x - padding, adjusted_y + content.y - padding, content.width + padding * 2.0, content.height + padding * 2.0, @@ -343,12 +344,12 @@ pub fn render_text_over_with_halo_with_measurer( // Second pass: draw drop shadow for depth let shadow_offset = size * 0.04; - ctx.move_to(x as f64 + shadow_offset, adjusted_y + shadow_offset); + ctx.move_to(f64::from(x) + shadow_offset, adjusted_y + shadow_offset); ctx.set_source_rgba(0.0, 0.0, 0.0, 0.4); functions::show_layout(ctx, &layout); // Third pass: render text with contrasting stroke outline - ctx.move_to(x as f64, adjusted_y); + ctx.move_to(f64::from(x), adjusted_y); // Create path from layout for stroking functions::layout_path(ctx, &layout); @@ -514,8 +515,8 @@ fn render_sticky_note_layout( font_descriptor, wrap_width, ); - let base_x = x as f64; - let base_y = y as f64 - text_layout.baseline; + let base_x = f64::from(x); + let base_y = f64::from(y) - text_layout.baseline; let note_layout = sticky_note_layout( base_x, base_y, diff --git a/src/draw/shape/arrow_label.rs b/src/draw/shape/arrow_label.rs index 6446f0b92..8a795c06d 100644 --- a/src/draw/shape/arrow_label.rs +++ b/src/draw/shape/arrow_label.rs @@ -92,8 +92,8 @@ pub(crate) fn arrow_label_layout_with( let (base_x, base_y, nx, ny) = if bend == 0.0 { // Straight shaft: the historical placement, one side of the chord. ( - tail_x as f64 + ux * along, - tail_y as f64 + uy * along, + f64::from(tail_x) + ux * along, + f64::from(tail_y) + uy * along, -uy, ux, ) @@ -102,8 +102,8 @@ pub(crate) fn arrow_label_layout_with( let bulge = bend * len / 2.0; let side = bend.signum(); ( - tail_x as f64 + ux * along + left_x * bulge, - tail_y as f64 + uy * along + left_y * bulge, + f64::from(tail_x) + ux * along + left_x * bulge, + f64::from(tail_y) + uy * along + left_y * bulge, left_x * side, left_y * side, ) diff --git a/src/draw/shape/bounds.rs b/src/draw/shape/bounds.rs index 19a302a9f..7ae0d515c 100644 --- a/src/draw/shape/bounds.rs +++ b/src/draw/shape/bounds.rs @@ -157,10 +157,10 @@ pub(crate) fn bounding_box_for_arrow_with( let (label_tip_x, label_tip_y, label_tail_x, label_tail_y) = arrow_label_ends(x1, y1, x2, y2, head_at_end, style); - let mut min_x = tip_x.min(tail_x) as f64; - let mut max_x = tip_x.max(tail_x) as f64; - let mut min_y = tip_y.min(tail_y) as f64; - let mut max_y = tip_y.max(tail_y) as f64; + let mut min_x = f64::from(tip_x.min(tail_x)); + let mut max_x = f64::from(tip_x.max(tail_x)); + let mut min_y = f64::from(tip_y.min(tail_y)); + let mut max_y = f64::from(tip_y.max(tail_y)); if let Some(skeleton) = util::calculate_arrow_skeleton( tip_x, @@ -203,8 +203,8 @@ pub(crate) fn bounding_box_for_arrow_with( label.size, &label.font_descriptor, ) { - min_x = min_x.min(layout.bounds.x as f64); - min_y = min_y.min(layout.bounds.y as f64); + min_x = min_x.min(f64::from(layout.bounds.x)); + min_y = min_y.min(f64::from(layout.bounds.y)); max_x = max_x.max((i64::from(layout.bounds.x) + i64::from(layout.bounds.width)) as f64); max_y = max_y.max((i64::from(layout.bounds.y) + i64::from(layout.bounds.height)) as f64); diff --git a/src/draw/shape/polygon.rs b/src/draw/shape/polygon.rs index 71528f30a..512067fc2 100644 --- a/src/draw/shape/polygon.rs +++ b/src/draw/shape/polygon.rs @@ -149,8 +149,8 @@ fn rhombus_points(start: (i32, i32), end: (i32, i32)) -> Vec<(i32, i32)> { fn regular_polygon_points(start: (i32, i32), end: (i32, i32), sides: u8) -> Vec<(i32, i32)> { let sides = clamp_regular_sides(sides); - let center_x = (start.0 as f64 + end.0 as f64) / 2.0; - let center_y = (start.1 as f64 + end.1 as f64) / 2.0; + let center_x = f64::midpoint(f64::from(start.0), f64::from(end.0)); + let center_y = f64::midpoint(f64::from(start.1), f64::from(end.1)); let radius_x = f64::from(end.0.abs_diff(start.0)) / 2.0; let radius_y = f64::from(end.1.abs_diff(start.1)) / 2.0; let radius = radius_x.min(radius_y); @@ -172,7 +172,7 @@ const fn sorted_pair(a: i32, b: i32) -> (i32, i32) { } fn midpoint_i32(a: i32, b: i32) -> i32 { - ((i64::from(a) + i64::from(b)) / 2) as i32 + i64::midpoint(i64::from(a), i64::from(b)) as i32 } #[cfg(test)] diff --git a/src/draw/shape/step_marker.rs b/src/draw/shape/step_marker.rs index 03de9e698..8648c0024 100644 --- a/src/draw/shape/step_marker.rs +++ b/src/draw/shape/step_marker.rs @@ -18,8 +18,7 @@ pub(crate) fn step_marker_radius_with( let font_desc_str = font_descriptor.to_pango_string(size); let max_dim = measurer .measure(&text, &font_desc_str, size, None) - .map(|m| m.ink_width.max(m.ink_height)) - .unwrap_or(size * 0.6); + .map_or(size * 0.6, |m| m.ink_width.max(m.ink_height)); let padding = (size * STEP_MARKER_PADDING_RATIO).max(STEP_MARKER_PADDING_MIN); (max_dim / 2.0 + padding).max(STEP_MARKER_MIN_RADIUS) } @@ -40,10 +39,10 @@ pub(crate) fn step_marker_bounds_with( let outline = step_marker_outline_thickness(size); let total = radius + (outline / 2.0); ensure_positive_rect_f64( - x as f64 - total, - y as f64 - total, - x as f64 + total, - y as f64 + total, + f64::from(x) - total, + f64::from(y) - total, + f64::from(x) + total, + f64::from(y) + total, ) } diff --git a/src/draw/shape/stroke_points.rs b/src/draw/shape/stroke_points.rs index 0e09da80e..d92b09ac3 100644 --- a/src/draw/shape/stroke_points.rs +++ b/src/draw/shape/stroke_points.rs @@ -82,10 +82,10 @@ mod tests { let expected = [(18.375, 8.25), (23.625, 9.0625)]; match &transformed { Shape::Freehand { points, .. } | Shape::MarkerStroke { points, .. } => { - assert_eq!(points, &expected) + assert_eq!(points, &expected); } Shape::FreehandPressure { points, .. } => { - assert_eq!(points, &[(18.375, 8.25, 2.0), (23.625, 9.0625, 4.0)]) + assert_eq!(points, &[(18.375, 8.25, 2.0), (23.625, 9.0625, 4.0)]); } _ => unreachable!(), } diff --git a/src/draw/shape/tests.rs b/src/draw/shape/tests.rs index 45c57ee9a..a63c51d90 100644 --- a/src/draw/shape/tests.rs +++ b/src/draw/shape/tests.rs @@ -82,8 +82,8 @@ fn arrow_bounding_box_includes_head() { ) .expect("arrow geometry should exist"); for (px, py) in [skeleton.head.left, skeleton.head.right] { - assert!(px >= x_min as f64 && px <= x_max as f64); - assert!(py >= y_min as f64 && py <= y_max as f64); + assert!(px >= f64::from(x_min) && px <= f64::from(x_max)); + assert!(py >= f64::from(y_min) && py <= f64::from(y_max)); } } @@ -624,7 +624,7 @@ fn image_serialization_uses_base64_bytes() { assert_eq!(data.mime_type, "image/jpeg"); assert_eq!(data.bytes.as_ref(), [1, 2, 3, 4]); } - other => panic!("expected image shape, got {:?}", other), + other => panic!("expected image shape, got {other:?}"), } } diff --git a/src/draw/shape/text.rs b/src/draw/shape/text.rs index 405b1c344..678b1a9a3 100644 --- a/src/draw/shape/text.rs +++ b/src/draw/shape/text.rs @@ -37,7 +37,7 @@ pub(super) fn text_bounds_from_metrics( let base_y = y - metrics.baseline; let ink_max = metrics.ink_x + metrics.ink_width; let effective_max = if let Some(width) = wrap_width { - ink_max.max(width.max(1) as f64) + ink_max.max(f64::from(width.max(1))) } else { ink_max }; @@ -90,8 +90,8 @@ pub(crate) fn bounding_box_for_text_with( ) -> Option { let metrics = text_layout_metrics(measurer, text, size, font_descriptor, wrap_width)?; text_bounds_from_metrics( - x as f64, - y as f64, + f64::from(x), + f64::from(y), &metrics, size, background_enabled, @@ -175,7 +175,8 @@ pub(crate) fn sticky_note_text_layout_with_measurer( layout.set_text(text); if let Some(width) = wrap_width { let width = width.max(1); - let width_pango = (width as i64 * pango::SCALE as i64).min(i32::MAX as i64) as i32; + let width_pango = + (i64::from(width) * i64::from(pango::SCALE)).min(i64::from(i32::MAX)) as i32; layout.set_width(width_pango); layout.set_wrap(pango::WrapMode::WordChar); } @@ -190,17 +191,17 @@ pub(crate) fn sticky_note_text_layout_with_measurer( } else { // Fallback: measure directly (shouldn't happen for non-empty text) let (ink_rect, logical_rect) = layout.extents(); - let scale = pango::SCALE as f64; - let baseline = layout.baseline() as f64 / scale; + let scale = f64::from(pango::SCALE); + let baseline = f64::from(layout.baseline()) / scale; let measurement = TextMeasurement { - ink_x: ink_rect.x() as f64 / scale, - ink_y: ink_rect.y() as f64 / scale, - ink_width: ink_rect.width() as f64 / scale, - ink_height: ink_rect.height() as f64 / scale, - logical_x: logical_rect.x() as f64 / scale, - logical_y: logical_rect.y() as f64 / scale, - logical_width: logical_rect.width() as f64 / scale, - logical_height: logical_rect.height() as f64 / scale, + ink_x: f64::from(ink_rect.x()) / scale, + ink_y: f64::from(ink_rect.y()) / scale, + ink_width: f64::from(ink_rect.width()) / scale, + ink_height: f64::from(ink_rect.height()) / scale, + logical_x: f64::from(logical_rect.x()) / scale, + logical_y: f64::from(logical_rect.y()) / scale, + logical_width: f64::from(logical_rect.width()) / scale, + logical_height: f64::from(logical_rect.height()) / scale, baseline, }; @@ -260,8 +261,8 @@ fn bounding_box_for_sticky_note_layout( let font_desc_str = font_descriptor.to_pango_string(size); let measurement = measurer.measure(text, &font_desc_str, size, wrap_width)?; - let base_x = x as f64; - let base_y = y as f64 - measurement.baseline; + let base_x = f64::from(x); + let base_y = f64::from(y) - measurement.baseline; let content = measurement.content_extents(wrap_width); let layout = sticky_note_layout( base_x, diff --git a/src/draw/shape/text_cache.rs b/src/draw/shape/text_cache.rs index 253e9315b..311b72958 100644 --- a/src/draw/shape/text_cache.rs +++ b/src/draw/shape/text_cache.rs @@ -36,7 +36,7 @@ impl TextMeasurement { let min_y = self.ink_y.min(self.logical_y); let mut max_x = (self.ink_x + self.ink_width).max(self.logical_x + self.logical_width); if let Some(width) = wrap_width { - max_x = max_x.max(width.max(1) as f64); + max_x = max_x.max(f64::from(width.max(1))); } let max_y = (self.ink_y + self.ink_height).max(self.logical_y + self.logical_height); TextContentExtents { @@ -164,27 +164,27 @@ pub(crate) struct TextPreviewGeometry { } fn caret_geometry_in(layout: &pango::Layout, text: &str, byte_index: usize) -> CaretGeometry { - let scale = pango::SCALE as f64; + let scale = f64::from(pango::SCALE); let index = snap_char_boundary(text, byte_index); let index_i32 = i32::try_from(index).unwrap_or(i32::MAX); let (strong, _weak) = layout.cursor_pos(index_i32); - let baseline = layout.baseline() as f64 / scale; + let baseline = f64::from(layout.baseline()) / scale; CaretGeometry { - x: strong.x() as f64 / scale, - y_from_baseline: strong.y() as f64 / scale - baseline, - height: strong.height() as f64 / scale, + x: f64::from(strong.x()) / scale, + y_from_baseline: f64::from(strong.y()) / scale - baseline, + height: f64::from(strong.height()) / scale, } } fn logical_bounds_in(layout: &pango::Layout) -> LogicalBounds { - let scale = pango::SCALE as f64; + let scale = f64::from(pango::SCALE); let (_ink, logical) = layout.extents(); - let baseline = layout.baseline() as f64 / scale; + let baseline = f64::from(layout.baseline()) / scale; LogicalBounds { - x: logical.x() as f64 / scale, - y_from_baseline: logical.y() as f64 / scale - baseline, - width: logical.width() as f64 / scale, - height: logical.height() as f64 / scale, + x: f64::from(logical.x()) / scale, + y_from_baseline: f64::from(logical.y()) / scale - baseline, + width: f64::from(logical.width()) / scale, + height: f64::from(logical.height()) / scale, } } diff --git a/src/draw/shape/text_cache/cursor.rs b/src/draw/shape/text_cache/cursor.rs index 21157b939..ad1ddd4a9 100644 --- a/src/draw/shape/text_cache/cursor.rs +++ b/src/draw/shape/text_cache/cursor.rs @@ -27,15 +27,15 @@ impl TextMeasurer { self.with_measurement_context(|ctx| { let layout = configured_layout(ctx, text, font_desc_str, wrap_width); - let scale = pango::SCALE as f64; + let scale = f64::from(pango::SCALE); // Convert the baseline-relative y into the layout's top-left frame. - let local_y = local_y_from_baseline + layout.baseline() as f64 / scale; + let local_y = local_y_from_baseline + f64::from(layout.baseline()) / scale; let x_pu = (local_x * scale) .round() - .clamp(i32::MIN as f64, i32::MAX as f64) as i32; + .clamp(f64::from(i32::MIN), f64::from(i32::MAX)) as i32; let y_pu = (local_y * scale) .round() - .clamp(i32::MIN as f64, i32::MAX as f64) as i32; + .clamp(f64::from(i32::MIN), f64::from(i32::MAX)) as i32; let (_inside, index, trailing) = layout.xy_to_index(x_pu, y_pu); // Advance past `trailing` characters so a click on a glyph's right half diff --git a/src/draw/shape/text_cache/owner.rs b/src/draw/shape/text_cache/owner.rs index 8f0d367a2..affbae1b8 100644 --- a/src/draw/shape/text_cache/owner.rs +++ b/src/draw/shape/text_cache/owner.rs @@ -66,18 +66,18 @@ impl TextMeasurer { let layout = configured_layout(ctx, text, font_desc_str, wrap_width); let (ink_rect, logical_rect) = layout.extents(); - let scale = pango::SCALE as f64; + let scale = f64::from(pango::SCALE); TextMeasurement { - ink_x: ink_rect.x() as f64 / scale, - ink_y: ink_rect.y() as f64 / scale, - ink_width: ink_rect.width() as f64 / scale, - ink_height: ink_rect.height() as f64 / scale, - logical_x: logical_rect.x() as f64 / scale, - logical_y: logical_rect.y() as f64 / scale, - logical_width: logical_rect.width() as f64 / scale, - logical_height: logical_rect.height() as f64 / scale, - baseline: layout.baseline() as f64 / scale, + ink_x: f64::from(ink_rect.x()) / scale, + ink_y: f64::from(ink_rect.y()) / scale, + ink_width: f64::from(ink_rect.width()) / scale, + ink_height: f64::from(ink_rect.height()) / scale, + logical_x: f64::from(logical_rect.x()) / scale, + logical_y: f64::from(logical_rect.y()) / scale, + logical_width: f64::from(logical_rect.width()) / scale, + logical_height: f64::from(logical_rect.height()) / scale, + baseline: f64::from(layout.baseline()) / scale, } })?; diff --git a/src/draw/shape/text_cache/owner/tests.rs b/src/draw/shape/text_cache/owner/tests.rs index 29e0ecc4c..c5278d826 100644 --- a/src/draw/shape/text_cache/owner/tests.rs +++ b/src/draw/shape/text_cache/owner/tests.rs @@ -143,7 +143,7 @@ fn initialization_borrow_is_released_before_nested_measurement() { assert!(measured.logical_width > 0.0); owner .with_measurement_context(|inner| { - assert_eq!(outer.to_raw_none(), inner.to_raw_none()) + assert_eq!(outer.to_raw_none(), inner.to_raw_none()); }) .unwrap(); }) diff --git a/src/draw/shape/text_cache/owner/tests/bounds.rs b/src/draw/shape/text_cache/owner/tests/bounds.rs index e81b55d89..aee1aea2e 100644 --- a/src/draw/shape/text_cache/owner/tests/bounds.rs +++ b/src/draw/shape/text_cache/owner/tests/bounds.rs @@ -106,7 +106,7 @@ fn text_mutations_invalidate_memo_and_select_new_measurement_keys() { let before = drawn.bounding_box_with(&owner).unwrap(); match &mut drawn.shape { Shape::Text { wrap_width, .. } | Shape::StickyNote { wrap_width, .. } => { - *wrap_width = Some(45) + *wrap_width = Some(45); } _ => unreachable!(), } diff --git a/src/draw/shape/transform.rs b/src/draw/shape/transform.rs index a54a3b538..a745f37e9 100644 --- a/src/draw/shape/transform.rs +++ b/src/draw/shape/transform.rs @@ -238,10 +238,10 @@ impl Shape { // scale the arc itself, or the bulge (the only part of a // flat curved arrow with any height) ignores the drag. bend: util::scaled_arrow_bend( - (*x1 as f64, *y1 as f64), - (*x2 as f64, *y2 as f64), - (nx1 as f64, ny1 as f64), - (nx2 as f64, ny2 as f64), + (f64::from(*x1), f64::from(*y1)), + (f64::from(*x2), f64::from(*y2)), + (f64::from(nx1), f64::from(ny1)), + (f64::from(nx2), f64::from(ny2)), *bend, scale_x, scale_y, @@ -417,12 +417,19 @@ fn scale_point_i32( scale_x: f64, scale_y: f64, ) -> (i32, i32) { - let (sx, sy) = scale_point(x as f64, y as f64, anchor_x, anchor_y, scale_x, scale_y); + let (sx, sy) = scale_point( + f64::from(x), + f64::from(y), + anchor_x, + anchor_y, + scale_x, + scale_y, + ); (sx.round() as i32, sy.round() as i32) } fn scale_size(size: i32, factor: f64) -> i32 { - (size as f64 * factor).round() as i32 + (f64::from(size) * factor).round() as i32 } fn scale_points( diff --git a/src/i18n.rs b/src/i18n.rs index 3cf213ea4..fad93cf26 100644 --- a/src/i18n.rs +++ b/src/i18n.rs @@ -250,7 +250,7 @@ pub(crate) fn lookup(language: Language, source: &str) -> &str { return source; }; - catalog.get(source).map(String::as_str).unwrap_or(source) + catalog.get(source).map_or(source, String::as_str) } /// Translates `source` and substitutes each `{}` with the next argument. diff --git a/src/input/boards/mapping.rs b/src/input/boards/mapping.rs index 0a1b4964e..2638748a7 100644 --- a/src/input/boards/mapping.rs +++ b/src/input/boards/mapping.rs @@ -204,22 +204,24 @@ fn pick_template(boards: &[BoardState]) -> BoardSpec { let mut template = boards .iter() .find(|board| !board.spec.background.is_transparent()) - .map(|board| board.spec.clone()) - .unwrap_or_else(|| BoardSpec { - id: BOARD_ID_WHITEBOARD.to_string(), - name: "Whiteboard".to_string(), - background: BoardBackground::Solid(Color { - r: 0.992, - g: 0.992, - b: 0.992, - a: 1.0, - }), - grid: Default::default(), - default_pen_color: Some(PALETTE_BLACK), - auto_adjust_pen: true, - persist: true, - pinned: false, - }); + .map_or_else( + || BoardSpec { + id: BOARD_ID_WHITEBOARD.to_string(), + name: "Whiteboard".to_string(), + background: BoardBackground::Solid(Color { + r: 0.992, + g: 0.992, + b: 0.992, + a: 1.0, + }), + grid: Default::default(), + default_pen_color: Some(PALETTE_BLACK), + auto_adjust_pen: true, + persist: true, + pinned: false, + }, + |board| board.spec.clone(), + ); template.pinned = false; template } diff --git a/src/input/hit_test/geometry.rs b/src/input/hit_test/geometry.rs index d1f0cf6ac..ea319bdb4 100644 --- a/src/input/hit_test/geometry.rs +++ b/src/input/hit_test/geometry.rs @@ -5,7 +5,7 @@ pub(super) fn distance_point_to_segment>( start: (T, T), end: (T, T), ) -> f64 { - let (px, py) = (point.0 as f64, point.1 as f64); + let (px, py) = (f64::from(point.0), f64::from(point.1)); let (x1, y1) = (start.0.into(), start.1.into()); let (x2, y2) = (end.0.into(), end.1.into()); let vx = x2 - x1; @@ -69,8 +69,8 @@ pub(super) fn point_in_polygon(point: (f64, f64), points: &[(i32, i32)]) -> bool let mut inside = false; let mut previous = points[points.len() - 1]; for ¤t in points { - let (x1, y1) = (previous.0 as f64, previous.1 as f64); - let (x2, y2) = (current.0 as f64, current.1 as f64); + let (x1, y1) = (f64::from(previous.0), f64::from(previous.1)); + let (x2, y2) = (f64::from(current.0), f64::from(current.1)); if (y1 > py) != (y2 > py) { let intersection_x = (x2 - x1) * (py - y1) / (y2 - y1) + x1; if px < intersection_x { diff --git a/src/input/hit_test/shapes.rs b/src/input/hit_test/shapes.rs index 9ae5bde00..0edd38610 100644 --- a/src/input/hit_test/shapes.rs +++ b/src/input/hit_test/shapes.rs @@ -39,7 +39,7 @@ pub(super) fn freehand_pressure_hit( } for &(x, y, thick) in points { - let padded = tolerance.max(thick as f64 / 2.0); + let padded = tolerance.max(f64::from(thick) / 2.0); if distance_point_to_point((x, y), point) <= padded { return true; } @@ -81,7 +81,7 @@ pub(super) fn rect_outline_hit( tolerance: f64, ) -> bool { let tolerance = tolerance.max(thickness / 2.0); - let (px, py) = (point.0 as f64, point.1 as f64); + let (px, py) = (f64::from(point.0), f64::from(point.1)); // Normalized like `render_rect` and `rect_fill_hit`: a stored rectangle // can carry negative extents, and it paints normalized — hit testing it // as a bare point instead made such a shape visible but unselectable. @@ -150,7 +150,7 @@ pub(super) fn polygon_fill_hit(points: &[(i32, i32)], point: (i32, i32)) -> bool return false; } - point_in_polygon((point.0 as f64, point.1 as f64), points) + point_in_polygon((f64::from(point.0), f64::from(point.1)), points) } pub(super) fn ellipse_outline_hit( @@ -162,10 +162,10 @@ pub(super) fn ellipse_outline_hit( point: (i32, i32), tolerance: f64, ) -> bool { - let (px, py) = (point.0 as f64, point.1 as f64); - let (cx, cy) = (cx as f64, cy as f64); - let rx = rx.max(0) as f64; - let ry = ry.max(0) as f64; + let (px, py) = (f64::from(point.0), f64::from(point.1)); + let (cx, cy) = (f64::from(cx), f64::from(cy)); + let rx = f64::from(rx.max(0)); + let ry = f64::from(ry.max(0)); if rx.abs() < EPS && ry.abs() < EPS { return distance_point_to_point((cx as i32, cy as i32), point) <= tolerance.max(thickness / 2.0); @@ -201,16 +201,16 @@ pub(crate) fn ellipse_fill_hit(cx: i32, cy: i32, rx: i32, ry: i32, point: (i32, return false; } - let dx = point.0 as f64 - cx as f64; - let dy = point.1 as f64 - cy as f64; - let rx = rx as f64; - let ry = ry as f64; + let dx = f64::from(point.0) - f64::from(cx); + let dy = f64::from(point.1) - f64::from(cy); + let rx = f64::from(rx); + let ry = f64::from(ry); (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry) <= 1.0 + EPS } pub(super) fn circle_hit(cx: i32, cy: i32, radius: f64, point: (i32, i32), tolerance: f64) -> bool { - let dx = point.0 as f64 - cx as f64; - let dy = point.1 as f64 - cy as f64; + let dx = f64::from(point.0) - f64::from(cx); + let dy = f64::from(point.1) - f64::from(cy); let r = radius + tolerance.max(0.5); (dx * dx + dy * dy) <= r * r } @@ -229,7 +229,7 @@ pub(super) fn arrowhead_triangle_hit( let tip = geometry.tip; let (left_x, left_y) = geometry.left; let (right_x, right_y) = geometry.right; - let p = (point.0 as f64, point.1 as f64); + let p = (f64::from(point.0), f64::from(point.1)); if point_in_triangle(p, tip, (left_x, left_y), (right_x, right_y)) { return true; } diff --git a/src/input/state/actions/action_capture_zoom.rs b/src/input/state/actions/action_capture_zoom.rs index 43adcc65b..fc20d65e4 100644 --- a/src/input/state/actions/action_capture_zoom.rs +++ b/src/input/state/actions/action_capture_zoom.rs @@ -30,7 +30,7 @@ impl InputState { // Capture actions are handled externally by WaylandState // since they require access to CaptureManager // Store the action for later retrieval - log::debug!("Capture action {:?} pending for backend", action); + log::debug!("Capture action {action:?} pending for backend"); self.set_pending_backend_action(PendingBackendAction::Screenshot(action)); // Native region selection needs the compositor-synced Shift @@ -44,7 +44,7 @@ impl InputState { Action::ExportCanvasFile | Action::ExportCanvasClipboard | Action::ExportCanvasClipboardAndFile => { - log::debug!("Canvas export action {:?} pending for backend", action); + log::debug!("Canvas export action {action:?} pending for backend"); self.set_pending_backend_action(PendingBackendAction::CanvasExport(action)); // Clear modifiers to prevent them from being "stuck" after capture @@ -53,7 +53,7 @@ impl InputState { true } Action::ExportBoardPdfFile | Action::ExportAllBoardsPdfFile => { - log::debug!("Board PDF export action {:?} pending for backend", action); + log::debug!("Board PDF export action {action:?} pending for backend"); self.set_pending_backend_action(PendingBackendAction::BoardPdfExport(action)); // Clear modifiers to prevent them from being "stuck" after capture diff --git a/src/input/state/actions/action_selection.rs b/src/input/state/actions/action_selection.rs index ee0d33790..0638f6f83 100644 --- a/src/input/state/actions/action_selection.rs +++ b/src/input/state/actions/action_selection.rs @@ -93,7 +93,7 @@ impl InputState { Action::CopySelection => { let copied = self.copy_selection(); if copied > 0 { - info!("Copied selection ({} shape(s))", copied); + info!("Copied selection ({copied} shape(s))"); } else if self.has_selection() { self.push_toast( ToastPriority::Info, @@ -192,7 +192,7 @@ impl InputState { }; if self.translate_selection_with_undo_with(measurer, dx, dy) { self.selection_interaction.note_axis(axis); - info!("Moved selection {} by {} px", direction, step); + info!("Moved selection {direction} by {step} px"); } else if self.has_selection() { self.selection_interaction.note_axis(axis); } diff --git a/src/input/state/actions/action_tools.rs b/src/input/state/actions/action_tools.rs index 126b0d803..ce38cf44e 100644 --- a/src/input/state/actions/action_tools.rs +++ b/src/input/state/actions/action_tools.rs @@ -163,7 +163,7 @@ impl InputState { } else { "Highlight pen disabled" }; - info!("{}", message); + info!("{message}"); } _ => return false, } diff --git a/src/input/state/actions/action_ui.rs b/src/input/state/actions/action_ui.rs index ee2fff2fc..496b20d92 100644 --- a/src/input/state/actions/action_ui.rs +++ b/src/input/state/actions/action_ui.rs @@ -88,8 +88,7 @@ impl InputState { info!( "Render profile {}", self.active_render_profile() - .map(|profile| profile.name()) - .unwrap_or("off") + .map_or("off", |profile| profile.name()) ); } true @@ -100,8 +99,7 @@ impl InputState { info!( "Render profile {}", self.active_render_profile() - .map(|profile| profile.name()) - .unwrap_or("off") + .map_or("off", |profile| profile.name()) ); } true @@ -282,7 +280,7 @@ impl InputState { } else { let message = tr("Input HUD disabled"); self.push_toast(ToastPriority::Info, "ui", Toast::info(message)); - info!("{}", message); + info!("{message}"); } } @@ -357,7 +355,7 @@ impl InputState { self.close_radial_menu(); } else if !self.zoom_active() && matches!(self.state, DrawingState::Idle) { let (x, y) = self.pointer_position(); - self.open_radial_menu(x as f64, y as f64); + self.open_radial_menu(f64::from(x), f64::from(y)); } } diff --git a/src/input/state/actions/key_press/caret_edit.rs b/src/input/state/actions/key_press/caret_edit.rs index b42003cf2..87daaecb1 100644 --- a/src/input/state/actions/key_press/caret_edit.rs +++ b/src/input/state/actions/key_press/caret_edit.rs @@ -128,13 +128,13 @@ fn next_word_end(s: &str, caret: usize) -> usize { /// Byte offset of the start of the logical line containing `caret`. fn line_start(s: &str, caret: usize) -> usize { - s[..caret].rfind('\n').map(|i| i + 1).unwrap_or(0) + s[..caret].rfind('\n').map_or(0, |i| i + 1) } /// Byte offset of the end of the logical line containing `caret` (the position /// of the next newline, or the buffer end). fn line_end(s: &str, caret: usize) -> usize { - s[caret..].find('\n').map(|i| caret + i).unwrap_or(s.len()) + s[caret..].find('\n').map_or(s.len(), |i| caret + i) } /// Grapheme count of `s` (used as the column metric for vertical movement). @@ -146,8 +146,7 @@ fn grapheme_len(s: &str) -> usize { fn grapheme_col_to_byte(s: &str, col: usize) -> usize { s.grapheme_indices(true) .nth(col) - .map(|(i, _)| i) - .unwrap_or(s.len()) + .map_or(s.len(), |(i, _)| i) } /// Clamp `caret` and `anchor` to valid char boundaries within `buffer` (used @@ -193,9 +192,7 @@ pub(in crate::input::state) fn insert_str( text: &str, max_len: usize, ) -> bool { - let selected_len = selection_range(*caret, *anchor) - .map(|range| range.len()) - .unwrap_or(0); + let selected_len = selection_range(*caret, *anchor).map_or(0, |range| range.len()); let remaining = max_len.saturating_sub(buffer.len().saturating_sub(selected_len)); let mut fit = text.len().min(remaining); while fit > 0 && !text.is_char_boundary(fit) { @@ -557,52 +554,48 @@ impl TextEditing { ctrl, VisualCaretDirection::Right, ), - Key::Up => navigation - .measurer - .caret_on_adjacent_visual_line( - buffer, - navigation.font, - navigation.wrap_width, - *caret, - VisualLineDirection::Up, - ) - .map(|new| move_to_offset(caret, anchor, shift, new)) - .unwrap_or_else(|| move_up(buffer, caret, anchor, shift)), - Key::Down => navigation - .measurer - .caret_on_adjacent_visual_line( - buffer, - navigation.font, - navigation.wrap_width, - *caret, - VisualLineDirection::Down, - ) - .map(|new| move_to_offset(caret, anchor, shift, new)) - .unwrap_or_else(|| move_down(buffer, caret, anchor, shift)), + Key::Up => match navigation.measurer.caret_on_adjacent_visual_line( + buffer, + navigation.font, + navigation.wrap_width, + *caret, + VisualLineDirection::Up, + ) { + Some(new) => move_to_offset(caret, anchor, shift, new), + None => move_up(buffer, caret, anchor, shift), + }, + Key::Down => match navigation.measurer.caret_on_adjacent_visual_line( + buffer, + navigation.font, + navigation.wrap_width, + *caret, + VisualLineDirection::Down, + ) { + Some(new) => move_to_offset(caret, anchor, shift, new), + None => move_down(buffer, caret, anchor, shift), + }, Key::Home if ctrl => move_document_start(caret, anchor, shift), - Key::Home => navigation - .measurer - .caret_on_visual_line_edge( - buffer, - navigation.font, - navigation.wrap_width, - *caret, - VisualLineEdge::Start, - ) - .map(|new| move_to_offset(caret, anchor, shift, new)) - .unwrap_or_else(|| move_line_home(buffer, caret, anchor, shift)), + Key::Home => match navigation.measurer.caret_on_visual_line_edge( + buffer, + navigation.font, + navigation.wrap_width, + *caret, + VisualLineEdge::Start, + ) { + Some(new) => move_to_offset(caret, anchor, shift, new), + None => move_line_home(buffer, caret, anchor, shift), + }, Key::End if ctrl => move_document_end(buffer, caret, anchor, shift), - Key::End => navigation - .measurer - .caret_on_visual_line_edge( - buffer, - navigation.font, - navigation.wrap_width, - *caret, - VisualLineEdge::End, - ) - .map(|new| move_to_offset(caret, anchor, shift, new)) - .unwrap_or_else(|| move_line_end(buffer, caret, anchor, shift)), + Key::End => match navigation.measurer.caret_on_visual_line_edge( + buffer, + navigation.font, + navigation.wrap_width, + *caret, + VisualLineEdge::End, + ) { + Some(new) => move_to_offset(caret, anchor, shift, new), + None => move_line_end(buffer, caret, anchor, shift), + }, _ => return None, }; diff --git a/src/input/state/actions/key_press/mod.rs b/src/input/state/actions/key_press/mod.rs index bb9b000c1..80ce088da 100644 --- a/src/input/state/actions/key_press/mod.rs +++ b/src/input/state/actions/key_press/mod.rs @@ -40,7 +40,7 @@ impl InputState { /// Handles all keyboard input including: /// - Drawing color selection (configurable keybindings) /// - Tool actions (text mode, clear, undo - configurable) - /// - Text input (when in TextInput state) + /// - Text input (when in `TextInput` state) /// - Exit commands (configurable) /// - Thickness adjustment (configurable) /// - Help toggle (configurable) diff --git a/src/input/state/actions/key_press/panels.rs b/src/input/state/actions/key_press/panels.rs index 1b96c7e52..e322ff08e 100644 --- a/src/input/state/actions/key_press/panels.rs +++ b/src/input/state/actions/key_press/panels.rs @@ -149,10 +149,10 @@ impl InputState { if self.board_picker_is_quick() { match key { Key::Delete | Key::F2 => return true, - Key::Char('n') | Key::Char('N') if self.modifiers.ctrl => return true, - Key::Char('r') | Key::Char('R') if self.modifiers.ctrl => return true, - Key::Char('c') | Key::Char('C') if self.modifiers.ctrl => return true, - Key::Char('p') | Key::Char('P') if self.modifiers.ctrl => return true, + Key::Char('n' | 'N') if self.modifiers.ctrl => return true, + Key::Char('r' | 'R') if self.modifiers.ctrl => return true, + Key::Char('c' | 'C') if self.modifiers.ctrl => return true, + Key::Char('p' | 'P') if self.modifiers.ctrl => return true, _ => {} } } @@ -220,19 +220,19 @@ impl InputState { } true } - Key::Char('n') | Key::Char('N') if self.modifiers.ctrl => { + Key::Char('n' | 'N') if self.modifiers.ctrl => { self.board_picker_create_new_with_measurer(measurer); true } - Key::Char('r') | Key::Char('R') if self.modifiers.ctrl => { + Key::Char('r' | 'R') if self.modifiers.ctrl => { self.board_picker_rename_selected_with_measurer(measurer); true } - Key::Char('c') | Key::Char('C') if self.modifiers.ctrl => { + Key::Char('c' | 'C') if self.modifiers.ctrl => { self.board_picker_edit_color_selected_with_measurer(measurer); true } - Key::Char('p') | Key::Char('P') if self.modifiers.ctrl => { + Key::Char('p' | 'P') if self.modifiers.ctrl => { self.board_picker_toggle_pin_selected(); true } @@ -293,8 +293,7 @@ impl InputState { let remaining = self .board_picker_page_panel_board_index() .and_then(|bi| self.boards.board_states().get(bi)) - .map(|b| b.pages.page_count()) - .unwrap_or(0); + .map_or(0, |b| b.pages.page_count()); if remaining == 0 { self.board_picker_set_focus(BoardPickerFocus::BoardList); } else { @@ -312,15 +311,15 @@ impl InputState { } true } - Key::Char('n') | Key::Char('N') if self.modifiers.ctrl => { + Key::Char('n' | 'N') if self.modifiers.ctrl => { self.board_picker_add_page_with_measurer(measurer); true } - Key::Char('g') | Key::Char('G') if self.modifiers.ctrl => { + Key::Char('g' | 'G') if self.modifiers.ctrl => { self.board_picker_begin_page_jump(); true } - Key::Char('f') | Key::Char('F') if self.modifiers.ctrl => { + Key::Char('f' | 'F') if self.modifiers.ctrl => { self.board_picker_begin_page_search(); true } @@ -347,8 +346,7 @@ impl InputState { let page_count = self .board_picker_page_panel_board_index() .and_then(|bi| self.boards.board_states().get(bi)) - .map(|b| b.pages.page_count()) - .unwrap_or(0); + .map_or(0, |b| b.pages.page_count()); let current = self .board_picker_page_focus_page_index() .unwrap_or_else(|| { @@ -362,7 +360,7 @@ impl InputState { fn navigate_board_picker_page_panel(&mut self, key: Key, page_count: usize, current: usize) { let layout = self.board_picker.layout; - let page_cols = layout.map(|l| l.page_cols.max(1)).unwrap_or(1); + let page_cols = layout.map_or(1, |l| l.page_cols.max(1)); match key { Key::Left if current == 0 => { @@ -389,15 +387,11 @@ impl InputState { self.board_picker_set_page_focus_page_index(page_count.saturating_sub(1)); } Key::PageUp if page_count > 0 => { - let step = layout - .map(|l| l.page_visible_slots.max(page_cols)) - .unwrap_or(page_cols); + let step = layout.map_or(page_cols, |l| l.page_visible_slots.max(page_cols)); self.board_picker_set_page_focus_page_index(current.saturating_sub(step)); } Key::PageDown if page_count > 0 => { - let step = layout - .map(|l| l.page_visible_slots.max(page_cols)) - .unwrap_or(page_cols); + let step = layout.map_or(page_cols, |l| l.page_visible_slots.max(page_cols)); let next = current .saturating_add(step) .min(page_count.saturating_sub(1)); @@ -434,12 +428,8 @@ impl InputState { Key::Return | Key::Space => self.activate_properties_panel_entry_with(measurer), Key::Left => self.adjust_properties_panel_entry_with(measurer, -adjust_step), Key::Right => self.adjust_properties_panel_entry_with(measurer, adjust_step), - Key::Char('+') | Key::Char('=') => { - self.adjust_properties_panel_entry_with(measurer, adjust_step) - } - Key::Char('-') | Key::Char('_') => { - self.adjust_properties_panel_entry_with(measurer, -adjust_step) - } + Key::Char('+' | '=') => self.adjust_properties_panel_entry_with(measurer, adjust_step), + Key::Char('-' | '_') => self.adjust_properties_panel_entry_with(measurer, -adjust_step), _ => false, } } diff --git a/src/input/state/actions/key_press/text_input.rs b/src/input/state/actions/key_press/text_input.rs index ff5a64a12..da14eb583 100644 --- a/src/input/state/actions/key_press/text_input.rs +++ b/src/input/state/actions/key_press/text_input.rs @@ -194,7 +194,7 @@ impl InputState { .font_descriptor .to_pango_string(self.style.current_font_size) }); - let changed = match self.text_editing.apply_key_edit( + let Some(changed) = self.text_editing.apply_key_edit( &mut self.state, key, ctrl, @@ -204,9 +204,8 @@ impl InputState { font: font_for_navigation.as_deref().unwrap_or_default(), wrap_width: self.style.text_wrap_width, }, - ) { - Some(changed) => changed, - None => return false, + ) else { + return false; }; if changed { self.needs_redraw = true; diff --git a/src/input/state/core/base/types.rs b/src/input/state/core/base/types.rs index facb169b0..1ecdd8246 100644 --- a/src/input/state/core/base/types.rs +++ b/src/input/state/core/base/types.rs @@ -444,7 +444,7 @@ impl ToastPress { } pub(crate) fn matches_target(self, target: Option) -> bool { - self.target == target.map(ToastTarget::Action).unwrap_or(ToastTarget::Body) + self.target == target.map_or(ToastTarget::Body, ToastTarget::Action) } pub(crate) fn action_index(self) -> Option { diff --git a/src/input/state/core/board/delete_restore.rs b/src/input/state/core/board/delete_restore.rs index 443ffd70f..bedb11a3c 100644 --- a/src/input/state/core/board/delete_restore.rs +++ b/src/input/state/core/board/delete_restore.rs @@ -103,8 +103,8 @@ impl InputState { return false; } match action { - Some(Action::BoardDelete) | Some(Action::PageDelete) => true, - Some(Action::BoardRestoreDeleted) | Some(Action::PageRestoreDeleted) => { + Some(Action::BoardDelete | Action::PageDelete) => true, + Some(Action::BoardRestoreDeleted | Action::PageRestoreDeleted) => { include_restore_actions } _ => false, @@ -126,11 +126,10 @@ impl InputState { measurer: &TextMeasurer, now: Instant, ) { - let request = self - .board_transitions - .confirm_board_delete(now) - .map(|pending| BoardDeleteRequest::Confirm(pending.confirmation().clone())) - .unwrap_or(BoardDeleteRequest::Request(BoardDeleteTarget::Active)); + let request = self.board_transitions.confirm_board_delete(now).map_or( + BoardDeleteRequest::Request(BoardDeleteTarget::Active), + |pending| BoardDeleteRequest::Confirm(pending.confirmation().clone()), + ); let active_id_before = self.boards.active_board_id().to_string(); let current_spec = self.boards.active_board().spec.clone(); @@ -199,10 +198,10 @@ impl InputState { .action(tr("Undo"), Action::BoardRestoreDeleted), ); - if self.boards.active_board_id() != active_id_before { - self.finish_board_transition_from(¤t_spec, &active_id_before, false); - } else { + if self.boards.active_board_id() == active_id_before { self.mark_board_surface_changed(); + } else { + self.finish_board_transition_from(¤t_spec, &active_id_before, false); } } BoardDeleteOutcome::Rejected(rejection) => { diff --git a/src/input/state/core/board/delete_restore/page.rs b/src/input/state/core/board/delete_restore/page.rs index 0a832ae98..de8ff6aa9 100644 --- a/src/input/state/core/board/delete_restore/page.rs +++ b/src/input/state/core/board/delete_restore/page.rs @@ -48,13 +48,15 @@ impl InputState { let request = self .board_transitions .confirm_page_delete_for(now, &board_id, page_index) - .map(|pending| PageDeleteRequest::Confirm(pending.confirmation().clone())) - .unwrap_or_else(|| { - PageDeleteRequest::Request(PageDeleteTarget { - board: PageDeleteBoardTarget::BoardIndex(board_index), - page_index, - }) - }); + .map_or_else( + || { + PageDeleteRequest::Request(PageDeleteTarget { + board: PageDeleteBoardTarget::BoardIndex(board_index), + page_index, + }) + }, + |pending| PageDeleteRequest::Confirm(pending.confirmation().clone()), + ); let confirmation_is_current = matches!(&request, PageDeleteRequest::Confirm(confirmation) if self.page_delete_confirmation_is_current(confirmation)); let should_prepare_active = is_active_board && ((matches!(&request, PageDeleteRequest::Request(_)) && page_count <= 1) @@ -137,16 +139,15 @@ impl InputState { let page_count = self.boards.page_count(); let page_index = self.boards.active_page_index(); - let request = self - .board_transitions - .confirm_page_delete(now) - .map(|pending| PageDeleteRequest::Confirm(pending.confirmation().clone())) - .unwrap_or_else(|| { + let request = self.board_transitions.confirm_page_delete(now).map_or_else( + || { PageDeleteRequest::Request(PageDeleteTarget { board: PageDeleteBoardTarget::ActiveBoard, page_index, }) - }); + }, + |pending| PageDeleteRequest::Confirm(pending.confirmation().clone()), + ); let active_target = match &request { PageDeleteRequest::Confirm(confirmation) => { confirmation.board_id == self.boards.active_board_id() diff --git a/src/input/state/core/board/switch.rs b/src/input/state/core/board/switch.rs index cb525f44d..cbce15073 100644 --- a/src/input/state/core/board/switch.rs +++ b/src/input/state/core/board/switch.rs @@ -246,7 +246,7 @@ impl InputState { self.finish_active_board_transition(); - log::info!("Duplicated board '{}' to '{}'", current_id, new_id); + log::info!("Duplicated board '{current_id}' to '{new_id}'"); } else { self.push_toast( ToastPriority::Info, diff --git a/src/input/state/core/board_picker/appearance.rs b/src/input/state/core/board_picker/appearance.rs index 2684e6d54..647842d0d 100644 --- a/src/input/state/core/board_picker/appearance.rs +++ b/src/input/state/core/board_picker/appearance.rs @@ -485,7 +485,7 @@ impl InputState { let picker_right = layout.origin_x + layout.width; let center_x = if layout.page_panel_enabled { - (layout.page_panel_x + picker_right) / 2.0 + f64::midpoint(layout.page_panel_x, picker_right) } else { layout.origin_x + layout.width / 2.0 }; diff --git a/src/input/state/core/board_picker/layout/compute/content_metrics.rs b/src/input/state/core/board_picker/layout/compute/content_metrics.rs index ec2ab1426..1392dff45 100644 --- a/src/input/state/core/board_picker/layout/compute/content_metrics.rs +++ b/src/input/state/core/board_picker/layout/compute/content_metrics.rs @@ -82,9 +82,8 @@ impl InputState { ctx.select_font_face("Sans", cairo::FontSlant::Normal, cairo::FontWeight::Normal); ctx.set_font_size(config.footer_font_size); let footer_width = text_width(ctx, footer, config.footer_font_size); - let recent_width = recent - .map(|label| text_width(ctx, label, config.footer_font_size)) - .unwrap_or(0.0); + let recent_width = + recent.map_or(0.0, |label| text_width(ctx, label, config.footer_font_size)); (title_width, footer_width, recent_width) } diff --git a/src/input/state/core/board_picker/layout/compute/layout_geometry.rs b/src/input/state/core/board_picker/layout/compute/layout_geometry.rs index d3f0e68f7..abf13ff93 100644 --- a/src/input/state/core/board_picker/layout/compute/layout_geometry.rs +++ b/src/input/state/core/board_picker/layout/compute/layout_geometry.rs @@ -16,7 +16,7 @@ impl InputState { } else { list_width }; - let max_width = (screen_width as f64 - 40.0).max(220.0); + let max_width = (f64::from(screen_width) - 40.0).max(220.0); let mut final_total_width = total_width.min(max_width); let mut final_list_width = list_width; @@ -34,8 +34,8 @@ impl InputState { final_list_width }; - let origin_x = (screen_width as f64 - final_total_width) * 0.5; - let origin_y = (screen_height as f64 - panel_height) * 0.5; + let origin_x = (f64::from(screen_width) - final_total_width) * 0.5; + let origin_y = (f64::from(screen_height) - panel_height) * 0.5; let page_panel_x = if page_panel.enabled { origin_x + final_list_width + PAGE_PANEL_GAP } else { @@ -49,8 +49,8 @@ impl InputState { list_width: final_list_width, page_panel_x, page_panel_y: origin_y, - screen_width: screen_width as f64, - screen_height: screen_height as f64, + screen_width: f64::from(screen_width), + screen_height: f64::from(screen_height), } } } diff --git a/src/input/state/core/board_picker/layout/compute/page_panel.rs b/src/input/state/core/board_picker/layout/compute/page_panel.rs index ac5f8eeb2..1efde1171 100644 --- a/src/input/state/core/board_picker/layout/compute/page_panel.rs +++ b/src/input/state/core/board_picker/layout/compute/page_panel.rs @@ -50,13 +50,13 @@ impl InputState { let aspect = if screen_height == 0 { 1.0 } else { - screen_width as f64 / screen_height as f64 + f64::from(screen_width) / f64::from(screen_height) }; let base_thumb_width = (PAGE_THUMB_HEIGHT * aspect).clamp(PAGE_THUMB_MIN_WIDTH, PAGE_THUMB_MAX_WIDTH); let available_right = - (screen_width as f64 - (PAGE_PANEL_GAP + 32.0)).max(base_thumb_width + 32.0); + (f64::from(screen_width) - (PAGE_PANEL_GAP + 32.0)).max(base_thumb_width + 32.0); let mut candidate_cols = PAGE_PANEL_MAX_COLS.max(1); loop { let candidate_width = PAGE_PANEL_PADDING_X * 2.0 diff --git a/src/input/state/core/board_picker/layout/compute/palette_metrics.rs b/src/input/state/core/board_picker/layout/compute/palette_metrics.rs index cf70f2463..725c00fed 100644 --- a/src/input/state/core/board_picker/layout/compute/palette_metrics.rs +++ b/src/input/state/core/board_picker/layout/compute/palette_metrics.rs @@ -20,8 +20,7 @@ impl InputState { && self .board_picker_board_index_for_row(edit_index) .and_then(|board_index| self.boards.board_states().get(board_index)) - .map(|board| !board.spec.background.is_transparent()) - .unwrap_or(false) + .is_some_and(|board| !board.spec.background.is_transparent()) { let colors = board_palette_colors(); if !colors.is_empty() { diff --git a/src/input/state/core/board_picker/layout/hit_test.rs b/src/input/state/core/board_picker/layout/hit_test.rs index 238c82fb9..915beb1b9 100644 --- a/src/input/state/core/board_picker/layout/hit_test.rs +++ b/src/input/state/core/board_picker/layout/hit_test.rs @@ -44,7 +44,10 @@ impl InputState { x: i32, y: i32, ) -> (f64, f64) { - (x as f64 - layout.origin_x, y as f64 - layout.origin_y) + ( + f64::from(x) - layout.origin_x, + f64::from(y) - layout.origin_y, + ) } // Coordinates are in picker-local space (origin at layout.origin_x/origin_y). @@ -89,8 +92,8 @@ impl InputState { pub(crate) fn board_picker_index_at(&self, x: i32, y: i32) -> Option { let layout = self.board_picker.layout.as_ref()?; - let local_x = x as f64 - layout.origin_x; - let local_y = y as f64 - layout.origin_y; + let local_x = f64::from(x) - layout.origin_x; + let local_y = f64::from(y) - layout.origin_y; let row_top = layout.padding_y + layout.header_height; let row_bottom = row_top + layout.row_height * layout.row_count as f64; if local_x < 0.0 || local_y < 0.0 || local_x > layout.list_width { @@ -115,7 +118,7 @@ impl InputState { w: layout.width, h: layout.height, }; - rect.contains(x as f64, y as f64) + rect.contains(f64::from(x), f64::from(y)) } else { false } @@ -151,8 +154,8 @@ impl InputState { } let origin_x = layout.origin_x + layout.padding_x; let origin_y = layout.palette_top; - let local_x = x as f64 - origin_x; - let local_y = y as f64 - origin_y; + let local_x = f64::from(x) - origin_x; + let local_y = f64::from(y) - origin_y; if local_x < 0.0 || local_y < 0.0 { return None; } @@ -176,8 +179,8 @@ impl InputState { pub(crate) fn board_picker_page_index_at(&self, x: i32, y: i32) -> Option { self.with_visible_page_context(|context| { self.board_picker_find_page_thumb_index( - x as f64, - y as f64, + f64::from(x), + f64::from(y), context, |thumb_x, thumb_y| FloatRect { x: thumb_x, @@ -192,8 +195,8 @@ impl InputState { pub(crate) fn board_picker_page_name_index_at(&self, x: i32, y: i32) -> Option { self.with_visible_page_context(|context| { self.board_picker_find_page_thumb_index( - x as f64, - y as f64, + f64::from(x), + f64::from(y), context, |thumb_x, thumb_y| FloatRect { x: thumb_x, @@ -221,7 +224,7 @@ impl InputState { w: context.layout.page_add_button_width, h: context.layout.page_add_button_height, }; - if sticky_rect.contains(x as f64, y as f64) { + if sticky_rect.contains(f64::from(x), f64::from(y)) { return true; } @@ -241,7 +244,7 @@ impl InputState { w: context.layout.page_thumb_width, h: context.layout.page_thumb_height, }; - thumb_rect.contains(x as f64, y as f64) + thumb_rect.contains(f64::from(x), f64::from(y)) } fn board_picker_end_of_pages_visible( @@ -269,14 +272,14 @@ impl InputState { w: context.layout.page_add_button_width, h: context.layout.footer_font_size + 8.0, }; - hint_rect.contains(x as f64, y as f64) + hint_rect.contains(f64::from(x), f64::from(y)) } pub(crate) fn board_picker_page_delete_index_at(&self, x: i32, y: i32) -> Option { self.with_visible_page_context(|context| { self.board_picker_find_page_thumb_index( - x as f64, - y as f64, + f64::from(x), + f64::from(y), context, |thumb_x, thumb_y| FloatRect { x: thumb_x + context.layout.page_thumb_width @@ -302,14 +305,14 @@ impl InputState { w: context.layout.page_panel_width, h: context.layout.page_panel_height, } - .contains(x as f64, y as f64) + .contains(f64::from(x), f64::from(y)) } pub(crate) fn board_picker_page_duplicate_index_at(&self, x: i32, y: i32) -> Option { self.with_visible_page_context(|context| { self.board_picker_find_page_thumb_index( - x as f64, - y as f64, + f64::from(x), + f64::from(y), context, |thumb_x, thumb_y| FloatRect { x: thumb_x + context.layout.page_thumb_width * 0.5 @@ -327,8 +330,8 @@ impl InputState { pub(crate) fn board_picker_page_rename_index_at(&self, x: i32, y: i32) -> Option { self.with_visible_page_context(|context| { self.board_picker_find_page_thumb_index( - x as f64, - y as f64, + f64::from(x), + f64::from(y), context, |thumb_x, thumb_y| FloatRect { x: thumb_x + PAGE_DELETE_ICON_MARGIN, @@ -345,8 +348,8 @@ impl InputState { pub(crate) fn board_picker_page_handle_index_at(&self, x: i32, y: i32) -> Option { self.with_visible_page_context(|context| { self.board_picker_find_page_thumb_index( - x as f64, - y as f64, + f64::from(x), + f64::from(y), context, |thumb_x, thumb_y| { let handle_size = (context.layout.page_thumb_height * 0.22).clamp(8.0, 12.0); diff --git a/src/input/state/core/board_picker/search.rs b/src/input/state/core/board_picker/search.rs index fafe25843..af381df73 100644 --- a/src/input/state/core/board_picker/search.rs +++ b/src/input/state/core/board_picker/search.rs @@ -68,10 +68,7 @@ impl InputState { } else if name.contains(&lower) || id.contains(&lower) { score += 500; } - if best - .map(|(_, best_score)| score > best_score) - .unwrap_or(true) - { + if best.is_none_or(|(_, best_score)| score > best_score) { best = Some((idx, score)); } } @@ -138,7 +135,7 @@ fn fuzzy_score_with_single_swap(needle: &str, haystack: &str) -> Option { let swapped: String = chars.iter().collect(); if let Some(score) = fuzzy_score(&swapped, haystack) { let score = score - 25; - if best.map(|best| score > best).unwrap_or(true) { + if best.is_none_or(|best| score > best) { best = Some(score); } } diff --git a/src/input/state/core/board_picker/state/drag.rs b/src/input/state/core/board_picker/state/drag.rs index d91b8a3d2..63cde7cc6 100644 --- a/src/input/state/core/board_picker/state/drag.rs +++ b/src/input/state/core/board_picker/state/drag.rs @@ -63,7 +63,7 @@ impl InputState { return; } let rows_top = layout.origin_y + layout.padding_y + layout.header_height; - let row = ((y as f64 - rows_top) / layout.row_height).floor() as isize; + let row = ((f64::from(y) - rows_top) / layout.row_height).floor() as isize; let max_row = board_count.saturating_sub(1) as isize; let clamped = row.clamp(0, max_row) as usize; let target_row = self.board_picker_clamp_drag_row(clamped, source_board); diff --git a/src/input/state/core/color_picker_popup/mod.rs b/src/input/state/core/color_picker_popup/mod.rs index a2c6460df..9e0059820 100644 --- a/src/input/state/core/color_picker_popup/mod.rs +++ b/src/input/state/core/color_picker_popup/mod.rs @@ -302,8 +302,8 @@ impl ColorPickerPopupLayout { let height = POPUP_HEIGHT - (ALPHA_HEIGHT + SLIDER_GAP - alpha_room); // Center the popup on screen - let origin_x = (screen_width as f64 - width) / 2.0; - let origin_y = (screen_height as f64 - height) / 2.0; + let origin_x = (f64::from(screen_width) - width) / 2.0; + let origin_y = (f64::from(screen_height) - height) / 2.0; // Content starts after padding and title let content_x = origin_x + PADDING; @@ -693,9 +693,9 @@ pub fn parse_hex_color(value: &str) -> Option { u8::MAX }; Some(Color { - r: r as f64 / 255.0, - g: g as f64 / 255.0, - b: b as f64 / 255.0, - a: a as f64 / 255.0, + r: f64::from(r) / 255.0, + g: f64::from(g) / 255.0, + b: f64::from(b) / 255.0, + a: f64::from(a) / 255.0, }) } diff --git a/src/input/state/core/color_picker_popup/state.rs b/src/input/state/core/color_picker_popup/state.rs index c99a8dc57..5d6472daa 100644 --- a/src/input/state/core/color_picker_popup/state.rs +++ b/src/input/state/core/color_picker_popup/state.rs @@ -1,4 +1,4 @@ -//! Color picker popup state methods for InputState. +//! Color picker popup state methods for `InputState`. use crate::draw::TextMeasurer; use std::borrow::Cow; @@ -442,7 +442,7 @@ impl InputState { y: i32, ) -> bool { self.color_picker_popup - .note_action_press(x as f64, y as f64) + .note_action_press(f64::from(x), f64::from(y)) } pub(in crate::input::state) fn color_picker_popup_clear_action_press(&mut self) { diff --git a/src/input/state/core/command_palette/layout.rs b/src/input/state/core/command_palette/layout.rs index 6829ee9dc..e67a86f84 100644 --- a/src/input/state/core/command_palette/layout.rs +++ b/src/input/state/core/command_palette/layout.rs @@ -85,7 +85,7 @@ impl CommandPaletteRowAction { impl CommandPaletteGeometry { pub(crate) fn local_point(self, x: i32, y: i32) -> (f64, f64) { - (x as f64 - self.x, y as f64 - self.y) + (f64::from(x) - self.x, f64::from(y) - self.y) } pub(crate) fn contains_local(self, local_x: f64, local_y: f64) -> bool { @@ -149,7 +149,7 @@ impl CommandPaletteGeometry { } pub(crate) fn command_palette_visible_count(total_items: usize, screen_height: u32) -> usize { - let available = (screen_height as f64 + let available = (f64::from(screen_height) - 2.0 * COMMAND_PALETTE_HORIZONTAL_MARGIN - command_palette_height(0)) .max(0.0); @@ -234,7 +234,7 @@ impl InputState { let requested_width = required_inner_width + COMMAND_PALETTE_PADDING * 2.0; let max_available = - (screen_width as f64 - COMMAND_PALETTE_HORIZONTAL_MARGIN * 2.0).max(0.0); + (f64::from(screen_width) - COMMAND_PALETTE_HORIZONTAL_MARGIN * 2.0).max(0.0); requested_width.clamp( COMMAND_PALETTE_MIN_WIDTH.min(max_available), COMMAND_PALETTE_MAX_WIDTH.min(max_available), @@ -286,17 +286,19 @@ fn command_palette_geometry_for_width( screen_height: u32, total_items: usize, ) -> CommandPaletteGeometry { - let x = (screen_width as f64 - width) / 2.0; + let x = (f64::from(screen_width) - width) / 2.0; let visible_count = command_palette_visible_count(total_items, screen_height); let content_rows = if total_items == 0 { command_palette_visible_count(2, screen_height) } else { visible_count }; - let height = command_palette_height(content_rows).min(screen_height as f64); - let margin = COMMAND_PALETTE_HORIZONTAL_MARGIN.min((screen_height as f64 - height) / 2.0); - let y = (screen_height as f64 * COMMAND_PALETTE_TOP_RATIO) - .clamp(margin, (screen_height as f64 - height - margin).max(margin)); + let height = command_palette_height(content_rows).min(f64::from(screen_height)); + let margin = COMMAND_PALETTE_HORIZONTAL_MARGIN.min((f64::from(screen_height) - height) / 2.0); + let y = (f64::from(screen_height) * COMMAND_PALETTE_TOP_RATIO).clamp( + margin, + (f64::from(screen_height) - height - margin).max(margin), + ); let input_top = COMMAND_PALETTE_PADDING; let input_bottom = input_top + COMMAND_PALETTE_INPUT_HEIGHT; @@ -341,14 +343,14 @@ mod tests { fn viewport_bounds_include_every_row_and_its_hit_target() { for (width, height) in [(800, 480), (1024, 600), (1280, 720), (240, 320), (80, 80)] { let geometry = command_palette_geometry_for_width( - (width as f64 - 24.0).max(0.0), + (f64::from(width) - 24.0).max(0.0), width, height, 100, ); assert!(geometry.x >= 0.0 && geometry.y >= 0.0); - assert!(geometry.x + geometry.width <= width as f64); - assert!(geometry.y + geometry.height <= height as f64); + assert!(geometry.x + geometry.width <= f64::from(width)); + assert!(geometry.y + geometry.height <= f64::from(height)); for row in 0..geometry.visible_count { let bottom = geometry.items_top + (row + 1) as f64 * COMMAND_PALETTE_ITEM_HEIGHT; assert!(bottom <= geometry.height - COMMAND_PALETTE_PADDING_BOTTOM); diff --git a/src/input/state/core/dirty.rs b/src/input/state/core/dirty.rs index 60c773f47..6cc97a9f5 100644 --- a/src/input/state/core/dirty.rs +++ b/src/input/state/core/dirty.rs @@ -152,7 +152,7 @@ impl InputState { let start = point_thicknesses.len().saturating_sub(2); point_thicknesses[start..] .iter() - .fold(1.0f64, |max, &thickness| max.max(thickness as f64)) + .fold(1.0f64, |max, &thickness| max.max(f64::from(thickness))) } else { self.thickness_for_tool(*tool) } diff --git a/src/input/state/core/editing.rs b/src/input/state/core/editing.rs index d2b41d30a..223ecc9b3 100644 --- a/src/input/state/core/editing.rs +++ b/src/input/state/core/editing.rs @@ -1,4 +1,4 @@ -//! Canvas mutation transactions. InputState applies UI and persistence effects. +//! Canvas mutation transactions. `InputState` applies UI and persistence effects. use std::collections::HashSet; use crate::draw::frame::{Frame, ShapeSnapshot, UndoAction}; diff --git a/src/input/state/core/feedback.rs b/src/input/state/core/feedback.rs index b8dbc8ead..476e675e2 100644 --- a/src/input/state/core/feedback.rs +++ b/src/input/state/core/feedback.rs @@ -219,8 +219,8 @@ impl Feedback { fn contains(bounds: Option, x: i32, y: i32) -> bool { bounds.is_some_and(|(bx, by, bw, bh)| { - let xf = x as f64; - let yf = y as f64; + let xf = f64::from(x); + let yf = f64::from(y); xf >= bx && xf <= bx + bw && yf >= by && yf <= by + bh }) } diff --git a/src/input/state/core/highlight_controls.rs b/src/input/state/core/highlight_controls.rs index ecaf583fd..03bda635a 100644 --- a/src/input/state/core/highlight_controls.rs +++ b/src/input/state/core/highlight_controls.rs @@ -134,7 +134,7 @@ impl InputState { /// Sets highlight-only tool mode on/off and keeps click highlight in sync. pub fn set_highlight_tool(&mut self, enable: bool) { let measurer = TextMeasurer::default(); - self.set_highlight_tool_with_measurer(&measurer, enable) + self.set_highlight_tool_with_measurer(&measurer, enable); } pub fn set_highlight_tool_with_measurer(&mut self, measurer: &TextMeasurer, enable: bool) { diff --git a/src/input/state/core/ime.rs b/src/input/state/core/ime.rs index c502ba2c7..b0078906d 100644 --- a/src/input/state/core/ime.rs +++ b/src/input/state/core/ime.rs @@ -152,9 +152,7 @@ impl TextEditing { return None; }; let caret = clamp_char_boundary(buffer, *caret); - let anchor = selection_anchor - .map(|anchor| clamp_char_boundary(buffer, anchor)) - .unwrap_or(caret); + let anchor = selection_anchor.map_or(caret, |anchor| clamp_char_boundary(buffer, anchor)); surrounding_text_window(buffer, caret, anchor) } @@ -171,9 +169,7 @@ impl TextEditing { return false; }; let caret = clamp_char_boundary(buffer, *caret); - let anchor = selection_anchor - .map(|anchor| clamp_char_boundary(buffer, anchor)) - .unwrap_or(caret); + let anchor = selection_anchor.map_or(caret, |anchor| clamp_char_boundary(buffer, anchor)); caret.abs_diff(anchor) <= MAX_SURROUNDING_TEXT_BYTES } @@ -270,12 +266,8 @@ impl TextEditing { let selection = caret_edit::selection_range(original_caret, original_anchor); let before_edge = selection .as_ref() - .map(|range| range.start) - .unwrap_or(original_caret); - let after_edge = selection - .as_ref() - .map(|range| range.end) - .unwrap_or(original_caret); + .map_or(original_caret, |range| range.start); + let after_edge = selection.as_ref().map_or(original_caret, |range| range.end); let mut start = before_edge.saturating_sub(pending.delete_before as usize); while start > 0 && !buffer.is_char_boundary(start) { start -= 1; diff --git a/src/input/state/core/index/grid.rs b/src/input/state/core/index/grid.rs index 5816a5cac..8ab6238e9 100644 --- a/src/input/state/core/index/grid.rs +++ b/src/input/state/core/index/grid.rs @@ -32,16 +32,16 @@ enum CellCoverage { Global, } -/// Spatial grid for efficient hit-testing using ShapeId instead of indices. +/// Spatial grid for efficient hit-testing using `ShapeId` instead of indices. /// /// This allows incremental updates when shapes are added, removed, or modified /// without needing to rebuild the entire grid. #[derive(Debug, Clone)] pub(in crate::input::state::core) struct SpatialGrid { cell_size: i32, - /// Maps cell coordinates to the ShapeIds contained in that cell. + /// Maps cell coordinates to the `ShapeIds` contained in that cell. cells: HashMap<(i32, i32), Vec>, - /// Reverse mapping from ShapeId to the cells it occupies for efficient removal. + /// Reverse mapping from `ShapeId` to the cells it occupies for efficient removal. shape_cells: HashMap>, /// Shapes kept as global candidates because their coverage is unsafe or /// oversized, or because the aggregate membership budget is exhausted. @@ -199,7 +199,7 @@ impl SpatialGrid { } } - /// Queries for all ShapeIds in cells near the given point with tolerance-aware radius. + /// Queries for all `ShapeIds` in cells near the given point with tolerance-aware radius. /// /// The search radius is expanded based on tolerance to ensure shapes that could /// be hit within the tolerance distance are not missed. diff --git a/src/input/state/core/menus/entries/shape.rs b/src/input/state/core/menus/entries/shape.rs index 85ac92c99..259ae04f7 100644 --- a/src/input/state/core/menus/entries/shape.rs +++ b/src/input/state/core/menus/entries/shape.rs @@ -14,11 +14,11 @@ impl InputState { let frame = self.boards.active_frame(); let locked = ids .iter() - .any(|id| frame.shape(*id).map(|shape| shape.locked).unwrap_or(false)); + .any(|id| frame.shape(*id).is_some_and(|shape| shape.locked)); let all_locked = !ids.is_empty() && ids .iter() - .all(|id| frame.shape(*id).map(|shape| shape.locked).unwrap_or(false)); + .all(|id| frame.shape(*id).is_some_and(|shape| shape.locked)); // What a right-click on a shape is usually for comes first: its own // editor, then its properties. diff --git a/src/input/state/core/menus/lifecycle.rs b/src/input/state/core/menus/lifecycle.rs index 482a3c405..6c202cbff 100644 --- a/src/input/state/core/menus/lifecycle.rs +++ b/src/input/state/core/menus/lifecycle.rs @@ -106,10 +106,9 @@ impl InputState { .boards .active_frame() .shape(selection[0]) - .map(|shape| { + .is_some_and(|shape| { matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. }) - }) - .unwrap_or(false); + }); let anchor = self.keyboard_shape_menu_anchor(measurer, &selection); self.update_pointer_position_synthetic(anchor.0, anchor.1); self.open_context_menu(anchor, selection, ContextMenuKind::Shape, None); @@ -128,7 +127,7 @@ impl InputState { let padding = 16; let x = padding; let y = match &self.context_menu.layout { - Some(layout) => (layout.origin_y + layout.height + padding as f64) as i32, + Some(layout) => (layout.origin_y + layout.height + f64::from(padding)) as i32, None => padding, }; (x, y) diff --git a/src/input/state/core/properties/apply_selection/actions/arrow.rs b/src/input/state/core/properties/apply_selection/actions/arrow.rs index 687ce3262..f228ea4dc 100644 --- a/src/input/state/core/properties/apply_selection/actions/arrow.rs +++ b/src/input/state/core/properties/apply_selection/actions/arrow.rs @@ -175,7 +175,7 @@ impl InputState { measurer: &TextMeasurer, direction: i32, ) -> bool { - let delta = SELECTION_ARROW_LENGTH_STEP * direction as f64; + let delta = SELECTION_ARROW_LENGTH_STEP * f64::from(direction); let result = self.apply_selection_change_with( measurer, |shape| matches!(shape, Shape::Arrow { .. }), @@ -201,7 +201,7 @@ impl InputState { measurer: &TextMeasurer, direction: i32, ) -> bool { - let delta = SELECTION_ARROW_ANGLE_STEP * direction as f64; + let delta = SELECTION_ARROW_ANGLE_STEP * f64::from(direction); let result = self.apply_selection_change_with( measurer, |shape| matches!(shape, Shape::Arrow { .. }), diff --git a/src/input/state/core/properties/apply_selection/actions/stroke.rs b/src/input/state/core/properties/apply_selection/actions/stroke.rs index 5f492735f..da019e10b 100644 --- a/src/input/state/core/properties/apply_selection/actions/stroke.rs +++ b/src/input/state/core/properties/apply_selection/actions/stroke.rs @@ -11,13 +11,14 @@ impl InputState { measurer: &TextMeasurer, direction: i32, ) -> bool { - let delta = SELECTION_THICKNESS_STEP * direction as f64; + let delta = SELECTION_THICKNESS_STEP * f64::from(direction); let pressure_edit_mode = self.style.pressure_thickness_edit_mode; let pressure_editable = matches!( pressure_edit_mode, PressureThicknessEditMode::Add | PressureThicknessEditMode::Scale ); - let pressure_scale = 1.0 + (self.style.pressure_thickness_scale_step * direction as f64); + let pressure_scale = + 1.0 + (self.style.pressure_thickness_scale_step * f64::from(direction)); let result = self.apply_selection_change_with( measurer, |shape| { @@ -57,7 +58,7 @@ impl InputState { PressureThicknessEditMode::Add => { let mut changed = false; for (_, _, thickness) in points.iter_mut() { - let next = (*thickness as f64 + delta) + let next = (f64::from(*thickness) + delta) .clamp(MIN_STROKE_THICKNESS, MAX_STROKE_THICKNESS) as f32; if (next - *thickness).abs() > f32::EPSILON { @@ -73,7 +74,7 @@ impl InputState { } let mut changed = false; for (_, _, thickness) in points.iter_mut() { - let next = (*thickness as f64 * pressure_scale) + let next = (f64::from(*thickness) * pressure_scale) .clamp(MIN_STROKE_THICKNESS, MAX_STROKE_THICKNESS) as f32; if (next - *thickness).abs() > f32::EPSILON { diff --git a/src/input/state/core/properties/apply_selection/actions/text.rs b/src/input/state/core/properties/apply_selection/actions/text.rs index 1c3e81104..297f2dda4 100644 --- a/src/input/state/core/properties/apply_selection/actions/text.rs +++ b/src/input/state/core/properties/apply_selection/actions/text.rs @@ -12,7 +12,7 @@ impl InputState { measurer: &TextMeasurer, direction: i32, ) -> bool { - let delta = SELECTION_FONT_SIZE_STEP * direction as f64; + let delta = SELECTION_FONT_SIZE_STEP * f64::from(direction); let result = self.apply_selection_change_with( measurer, |shape| matches!(shape, Shape::Text { .. }), diff --git a/src/input/state/core/properties/entries.rs b/src/input/state/core/properties/entries.rs index af24f964c..6b2744471 100644 --- a/src/input/state/core/properties/entries.rs +++ b/src/input/state/core/properties/entries.rs @@ -32,8 +32,7 @@ fn summary_value( summary .value .clone() - .map(format) - .unwrap_or_else(|| tr("Mixed").to_string()) + .map_or_else(|| tr("Mixed").to_string(), format) } /// The summary's single editable value, or `None` when it is mixed or locked: diff --git a/src/input/state/core/properties/panel_layout/focus.rs b/src/input/state/core/properties/panel_layout/focus.rs index 9136185a2..8c15411af 100644 --- a/src/input/state/core/properties/panel_layout/focus.rs +++ b/src/input/state/core/properties/panel_layout/focus.rs @@ -77,15 +77,12 @@ impl InputState { return false; } - let index = match self.current_properties_focus_or_hover() { - Some(index) => index, - None => { - return if forward { - self.select_properties_edge_entry(true) - } else { - self.select_properties_edge_entry(false) - }; - } + let Some(index) = self.current_properties_focus_or_hover() else { + return if forward { + self.select_properties_edge_entry(true) + } else { + self.select_properties_edge_entry(false) + }; }; let mut next = if forward { diff --git a/src/input/state/core/properties/panel_layout/geometry.rs b/src/input/state/core/properties/panel_layout/geometry.rs index 2f1289dfa..4e4985b10 100644 --- a/src/input/state/core/properties/panel_layout/geometry.rs +++ b/src/input/state/core/properties/panel_layout/geometry.rs @@ -117,7 +117,7 @@ pub(in crate::input::state::core::properties) fn balanced_column_budget( let mut low = heights.iter().copied().fold(0.0, f64::max); let mut high = max_budget.max(low); for _ in 0..32 { - let middle = (low + high) / 2.0; + let middle = f64::midpoint(low, high); if columns(middle) <= target { high = middle; } else { diff --git a/src/input/state/core/properties/panel_layout/interaction.rs b/src/input/state/core/properties/panel_layout/interaction.rs index d9b041a58..f98b79634 100644 --- a/src/input/state/core/properties/panel_layout/interaction.rs +++ b/src/input/state/core/properties/panel_layout/interaction.rs @@ -10,7 +10,7 @@ impl InputState { pub fn properties_panel_hit_at(&self, x: i32, y: i32) -> Option { let layout = self.properties.layout.as_ref()?; let panel = self.properties.panel.as_ref()?; - layout.hit_at(panel, x as f64, y as f64) + layout.hit_at(panel, f64::from(x), f64::from(y)) } /// The part under `(x, y)` that responds to the pointer. A locked row is @@ -43,7 +43,7 @@ impl InputState { self.properties .layout .as_ref() - .is_some_and(|layout| layout.contains(x as f64, y as f64)) + .is_some_and(|layout| layout.contains(f64::from(x), f64::from(y))) } pub(super) fn update_properties_panel_hover_from_pointer_internal( diff --git a/src/input/state/core/properties/panel_layout/layout.rs b/src/input/state/core/properties/panel_layout/layout.rs index 7893ebee1..bed135139 100644 --- a/src/input/state/core/properties/panel_layout/layout.rs +++ b/src/input/state/core/properties/panel_layout/layout.rs @@ -202,8 +202,8 @@ impl InputState { &heights, rows_top, column_width, - screen_width as f64, - screen_height as f64, + f64::from(screen_width), + f64::from(screen_height), ); let scroll = fit.scrolled_content.map(|content| { let max_offset = (content - fit.height).max(0.0); @@ -232,8 +232,8 @@ impl InputState { }; let panel_height = (rows_top + fit.height + ACTIONS_HEIGHT + tail + PADDING_BOTTOM).ceil(); - let screen_w = screen_width as f64; - let screen_h = screen_height as f64; + let screen_w = f64::from(screen_width); + let screen_h = f64::from(screen_height); let (origin_x, origin_y) = place_panel( panel.anchor, panel.anchor_rect, @@ -478,10 +478,10 @@ fn place_panel( ) -> (f64, f64) { let (mut origin_x, mut origin_y) = if screen_w > 0.0 && screen_h > 0.0 { if let Some(bounds) = anchor_rect { - let rect_x = bounds.x as f64; - let rect_y = bounds.y as f64; - let rect_w = bounds.width.max(1) as f64; - let rect_h = bounds.height.max(1) as f64; + let rect_x = f64::from(bounds.x); + let rect_y = f64::from(bounds.y); + let rect_w = f64::from(bounds.width.max(1)); + let rect_h = f64::from(bounds.height.max(1)); let center_x = rect_x + rect_w / 2.0; let center_y = rect_y + rect_h / 2.0; diff --git a/src/input/state/core/properties/panel_layout/mod.rs b/src/input/state/core/properties/panel_layout/mod.rs index 9fe92971d..f45be9468 100644 --- a/src/input/state/core/properties/panel_layout/mod.rs +++ b/src/input/state/core/properties/panel_layout/mod.rs @@ -12,18 +12,19 @@ mod layout; mod tests; pub(super) fn selection_panel_anchor(bounds: Option, pointer: (i32, i32)) -> (f64, f64) { - bounds - .map(|rect| { + bounds.map_or_else( + || { + let (px, py) = pointer; ( - rect.x as f64 + rect.width as f64 + PANEL_ANCHOR_GAP, - (rect.y as f64 - PANEL_ANCHOR_GAP).max(PANEL_MARGIN), + f64::from(px) + PANEL_POINTER_OFFSET, + f64::from(py) - PANEL_POINTER_OFFSET, ) - }) - .unwrap_or_else(|| { - let (px, py) = pointer; + }, + |rect| { ( - px as f64 + PANEL_POINTER_OFFSET, - py as f64 - PANEL_POINTER_OFFSET, + f64::from(rect.x) + f64::from(rect.width) + PANEL_ANCHOR_GAP, + (f64::from(rect.y) - PANEL_ANCHOR_GAP).max(PANEL_MARGIN), ) - }) + }, + ) } diff --git a/src/input/state/core/properties/panel_layout/tests.rs b/src/input/state/core/properties/panel_layout/tests.rs index d86260f46..998579dab 100644 --- a/src/input/state/core/properties/panel_layout/tests.rs +++ b/src/input/state/core/properties/panel_layout/tests.rs @@ -267,7 +267,7 @@ fn hovering_a_swatch_shows_its_name_in_a_tooltip_on_screen() { tooltip.y >= swatch.bottom(), "the tooltip hangs below the swatch" ); - assert!(tooltip.x >= 0.0 && tooltip.right() <= SCREEN.0 as f64); + assert!(tooltip.x >= 0.0 && tooltip.right() <= f64::from(SCREEN.0)); } #[test] diff --git a/src/input/state/core/properties/utils.rs b/src/input/state/core/properties/utils.rs index 17c4d2d73..4440987a7 100644 --- a/src/input/state/core/properties/utils.rs +++ b/src/input/state/core/properties/utils.rs @@ -59,9 +59,10 @@ pub(super) fn palette_position( /// The palette's name for `color`, or "Custom" for a color it does not hold. pub(super) fn color_label(palette: &[QuickColorPaletteEntry], color: Color) -> String { - color_palette_index(palette, color) - .map(|index| palette[index].label.clone()) - .unwrap_or_else(|| "Custom".to_string()) + color_palette_index(palette, color).map_or_else( + || "Custom".to_string(), + |index| palette[index].label.clone(), + ) } pub(super) fn color_eq(a: &Color, b: &Color) -> bool { diff --git a/src/input/state/core/radial_menu/compass.rs b/src/input/state/core/radial_menu/compass.rs index 2c32576e4..fd15cedaa 100644 --- a/src/input/state/core/radial_menu/compass.rs +++ b/src/input/state/core/radial_menu/compass.rs @@ -181,10 +181,12 @@ pub fn slice_parent(idx: u8) -> Option { } /// Sub-ring children for a segment index (empty for non-parent slices). +#[must_use] pub fn sub_ring_children(parent_idx: u8) -> &'static [Action] { - slice_parent(parent_idx) - .map(RadialParent::children) - .unwrap_or(&[]) + match slice_parent(parent_idx) { + Some(parent) => parent.children(), + None => &[], + } } /// Number of sub-ring children for a segment index, or 0 if none. diff --git a/src/input/state/core/radial_menu/hit_test.rs b/src/input/state/core/radial_menu/hit_test.rs index ca3ea3e62..d4d629460 100644 --- a/src/input/state/core/radial_menu/hit_test.rs +++ b/src/input/state/core/radial_menu/hit_test.rs @@ -32,7 +32,7 @@ pub fn hit_test_radial( let child_count = sub_ring_child_count(parent_idx); if child_count > 0 { let segment_angle = 2.0 * PI / TOOL_SEGMENT_COUNT as f64; - let parent_start = segment_angle * parent_idx as f64; + let parent_start = segment_angle * f64::from(parent_idx); let parent_end = parent_start + segment_angle; if tool_angle >= parent_start && tool_angle < parent_end { let child_angle = segment_angle / child_count as f64; diff --git a/src/input/state/core/radial_menu/layout.rs b/src/input/state/core/radial_menu/layout.rs index 657756925..92d3bc3d0 100644 --- a/src/input/state/core/radial_menu/layout.rs +++ b/src/input/state/core/radial_menu/layout.rs @@ -31,8 +31,8 @@ impl InputState { // Track the outermost band so the whole menu (size ring included) // still fits the screen edges. let margin = SIZE_OUTER + 4.0; - let cx = clamp_center_coordinate(*center_x, width as f64, margin); - let cy = clamp_center_coordinate(*center_y, height as f64, margin); + let cx = clamp_center_coordinate(*center_x, f64::from(width), margin); + let cy = clamp_center_coordinate(*center_y, f64::from(height), margin); self.radial_menu.layout = Some(RadialMenuLayout { center_x: cx, diff --git a/src/input/state/core/radial_menu/mod.rs b/src/input/state/core/radial_menu/mod.rs index cce7760a8..d3bb80648 100644 --- a/src/input/state/core/radial_menu/mod.rs +++ b/src/input/state/core/radial_menu/mod.rs @@ -60,7 +60,7 @@ pub enum RadialMenuState { /// Identifies a segment in the radial menu for hit-testing. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RadialSegmentId { - /// Primary compass-ring segment (index 0..TOOL_SEGMENT_COUNT, N = 0, + /// Primary compass-ring segment (index `0..TOOL_SEGMENT_COUNT`, N = 0, /// clockwise). Tool(u8), /// Sub-ring child segment (parent index, child index). diff --git a/src/input/state/core/radial_menu/state.rs b/src/input/state/core/radial_menu/state.rs index adf009833..79f29c19f 100644 --- a/src/input/state/core/radial_menu/state.rs +++ b/src/input/state/core/radial_menu/state.rs @@ -126,10 +126,12 @@ impl InputState { } } // Collapse when hovering a different tool, color, or outer segment - Some(RadialSegmentId::Tool(_)) - | Some(RadialSegmentId::Color(_)) - | Some(RadialSegmentId::SizeRing) - | Some(RadialSegmentId::Center) => { + Some( + RadialSegmentId::Tool(_) + | RadialSegmentId::Color(_) + | RadialSegmentId::SizeRing + | RadialSegmentId::Center, + ) => { *expanded_sub_ring = None; } None => {} @@ -289,7 +291,7 @@ impl InputState { } // The gauge is a drag/scroll surface, never a commit target. Some(RadialSegmentId::SizeRing) => return true, - Some(RadialSegmentId::Tool(_)) | Some(RadialSegmentId::Center) | None => {} + Some(RadialSegmentId::Tool(_) | RadialSegmentId::Center) | None => {} } } diff --git a/src/input/state/core/region_select.rs b/src/input/state/core/region_select.rs index d951f310c..3230c6e73 100644 --- a/src/input/state/core/region_select.rs +++ b/src/input/state/core/region_select.rs @@ -321,22 +321,22 @@ impl InputState { owner: RegionInputSource, point: (f64, f64), ) -> bool { - let (purpose, generation) = match self.region_select_ui_state { - RegionSelectUiState::Armed { - purpose, - generation, - } - | RegionSelectUiState::Review { - purpose, - generation, - .. - } - | RegionSelectUiState::Measured { - purpose, - generation, - .. - } => (purpose, generation), - _ => return false, + let (RegionSelectUiState::Armed { + purpose, + generation, + } + | RegionSelectUiState::Review { + purpose, + generation, + .. + } + | RegionSelectUiState::Measured { + purpose, + generation, + .. + }) = self.region_select_ui_state + else { + return false; }; self.sync_region_projection(RegionSelectUiState::Selecting { purpose, diff --git a/src/input/state/core/selection.rs b/src/input/state/core/selection.rs index 4d792802b..ddef539ea 100644 --- a/src/input/state/core/selection.rs +++ b/src/input/state/core/selection.rs @@ -25,7 +25,7 @@ enum SelectionState { None, Active { shape_ids: Vec, - /// Cached HashSet for O(1) membership tests during rendering. + /// Cached `HashSet` for O(1) membership tests during rendering. shape_ids_set: HashSet, }, } @@ -130,7 +130,7 @@ impl SelectionInteraction { return false; }; has_minimum_points - && now.duration_since(last.at).as_millis() <= max_elapsed_ms as u128 + && now.duration_since(last.at).as_millis() <= u128::from(max_elapsed_ms) && (x - last.x).abs() <= max_distance && (y - last.y).abs() <= max_distance } @@ -156,8 +156,8 @@ impl InputState { self.selection_interaction.selected_shape_ids() } - /// Returns a reference to the cached HashSet of selected shape IDs. - /// Use this for O(1) membership tests instead of creating a new HashSet. + /// Returns a reference to the cached `HashSet` of selected shape IDs. + /// Use this for O(1) membership tests instead of creating a new `HashSet`. pub fn selected_shape_ids_set(&self) -> Option<&HashSet> { self.selection_interaction.selected_shape_ids_set() } diff --git a/src/input/state/core/selection/clipboard.rs b/src/input/state/core/selection/clipboard.rs index 6786a943a..cc0f3056d 100644 --- a/src/input/state/core/selection/clipboard.rs +++ b/src/input/state/core/selection/clipboard.rs @@ -386,8 +386,7 @@ fn non_empty_shapes(shapes: Vec) -> Option> { fn new_clipboard_app_instance_id() -> String { let millis = SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|duration| duration.as_millis()) - .unwrap_or(0); + .map_or(0, |duration| duration.as_millis()); format!("{}-{millis}", process::id()) } diff --git a/src/input/state/core/selection_actions/arrow_bend.rs b/src/input/state/core/selection_actions/arrow_bend.rs index 390930296..6fba15169 100644 --- a/src/input/state/core/selection_actions/arrow_bend.rs +++ b/src/input/state/core/selection_actions/arrow_bend.rs @@ -243,8 +243,8 @@ fn arrow_ends(p1: (i32, i32), p2: (i32, i32), head_at_end: bool) -> ((i32, i32), /// point's offset, and always on the curve rather than off it. fn arc_midpoint(tip: (i32, i32), tail: (i32, i32), bend: f64) -> Option<(f64, f64)> { let (perp, chord_len) = chord_frame(tip, tail)?; - let mid_x = (tip.0 as f64 + tail.0 as f64) / 2.0; - let mid_y = (tip.1 as f64 + tail.1 as f64) / 2.0; + let mid_x = f64::midpoint(f64::from(tip.0), f64::from(tail.0)); + let mid_y = f64::midpoint(f64::from(tip.1), f64::from(tail.1)); let offset = util::clamp_arrow_bend(bend) * chord_len / 2.0; Some((mid_x + perp.0 * offset, mid_y + perp.1 * offset)) } @@ -257,9 +257,9 @@ fn arc_midpoint(tip: (i32, i32), tail: (i32, i32), bend: f64) -> Option<(f64, f6 /// the arc symmetric no matter where along it the user grabs. fn bend_for_pointer(tip: (i32, i32), tail: (i32, i32), pointer: (i32, i32)) -> Option { let (perp, chord_len) = chord_frame(tip, tail)?; - let mid_x = (tip.0 as f64 + tail.0 as f64) / 2.0; - let mid_y = (tip.1 as f64 + tail.1 as f64) / 2.0; - let offset = (pointer.0 as f64 - mid_x) * perp.0 + (pointer.1 as f64 - mid_y) * perp.1; + let mid_x = f64::midpoint(f64::from(tip.0), f64::from(tail.0)); + let mid_y = f64::midpoint(f64::from(tip.1), f64::from(tail.1)); + let offset = (f64::from(pointer.0) - mid_x) * perp.0 + (f64::from(pointer.1) - mid_y) * perp.1; Some(2.0 * offset / chord_len) } @@ -269,7 +269,10 @@ fn bend_for_pointer(tip: (i32, i32), tail: (i32, i32), pointer: (i32, i32)) -> O /// the arc it edits cannot disagree about which way a positive bend bulges and /// leave the arrow curving away from the drag. fn chord_frame(tip: (i32, i32), tail: (i32, i32)) -> Option<((f64, f64), f64)> { - util::chord_normal((tail.0 as f64, tail.1 as f64), (tip.0 as f64, tip.1 as f64)) + util::chord_normal( + (f64::from(tail.0), f64::from(tail.1)), + (f64::from(tip.0), f64::from(tip.1)), + ) } #[cfg(test)] diff --git a/src/input/state/core/selection_actions/clipboard/image_paste.rs b/src/input/state/core/selection_actions/clipboard/image_paste.rs index 5cd5f134c..ac87a3b37 100644 --- a/src/input/state/core/selection_actions/clipboard/image_paste.rs +++ b/src/input/state/core/selection_actions/clipboard/image_paste.rs @@ -133,10 +133,10 @@ fn image_display_bounds( natural_width: u32, natural_height: u32, ) -> (i32, i32, i32, i32) { - let natural_width = natural_width.max(1) as f64; - let natural_height = natural_height.max(1) as f64; - let max_width = (request.visible_canvas_rect.width.max(1) as f64 * 0.7).max(1.0); - let max_height = (request.visible_canvas_rect.height.max(1) as f64 * 0.7).max(1.0); + let natural_width = f64::from(natural_width.max(1)); + let natural_height = f64::from(natural_height.max(1)); + let max_width = (f64::from(request.visible_canvas_rect.width.max(1)) * 0.7).max(1.0); + let max_height = (f64::from(request.visible_canvas_rect.height.max(1)) * 0.7).max(1.0); let scale = (max_width / natural_width) .min(max_height / natural_height) .min(1.0); diff --git a/src/input/state/core/selection_actions/delete.rs b/src/input/state/core/selection_actions/delete.rs index 53ac91952..10cc47e85 100644 --- a/src/input/state/core/selection_actions/delete.rs +++ b/src/input/state/core/selection_actions/delete.rs @@ -79,8 +79,8 @@ impl InputState { // Check if any segment needs densification let needs_sampling = points.windows(2).any(|w| { - let dx = (w[1].0 - w[0].0) as f64; - let dy = (w[1].1 - w[0].1) as f64; + let dx = f64::from(w[1].0 - w[0].0); + let dy = f64::from(w[1].1 - w[0].1); (dx * dx + dy * dy).sqrt() > step }); @@ -94,15 +94,15 @@ impl InputState { for window in points.windows(2) { let (x0, y0) = window[0]; let (x1, y1) = window[1]; - let dx = (x1 - x0) as f64; - let dy = (y1 - y0) as f64; + let dx = f64::from(x1 - x0); + let dy = f64::from(y1 - y0); let dist = (dx * dx + dy * dy).sqrt(); let steps = ((dist / step).ceil() as i32).max(1); for i in 1..=steps { - let t = i as f64 / steps as f64; + let t = f64::from(i) / f64::from(steps); let point = ( - (x0 as f64 + dx * t).round() as i32, - (y0 as f64 + dy * t).round() as i32, + (f64::from(x0) + dx * t).round() as i32, + (f64::from(y0) + dy * t).round() as i32, ); if sampled.last().copied() != Some(point) { sampled.push(point); diff --git a/src/input/state/core/selection_actions/resize/resize_helpers.rs b/src/input/state/core/selection_actions/resize/resize_helpers.rs index 3f3ecced2..26e21520e 100644 --- a/src/input/state/core/selection_actions/resize/resize_helpers.rs +++ b/src/input/state/core/selection_actions/resize/resize_helpers.rs @@ -63,9 +63,10 @@ impl InputState { dx: i32, dy: i32, ) -> (f64, f64, f64, f64) { - let w = bounds.width as f64; - let h = bounds.height as f64; - let (new_w, new_h) = Self::compute_resized_dimensions(handle, w, h, dx as f64, dy as f64); + let w = f64::from(bounds.width); + let h = f64::from(bounds.height); + let (new_w, new_h) = + Self::compute_resized_dimensions(handle, w, h, f64::from(dx), f64::from(dy)); let (anchor_x, anchor_y) = Self::anchor_for_handle(handle, bounds); (new_w / w, new_h / h, anchor_x, anchor_y) } @@ -111,10 +112,10 @@ impl InputState { } fn anchor_for_handle(handle: SelectionHandle, bounds: &Rect) -> (f64, f64) { - let x = bounds.x as f64; - let y = bounds.y as f64; - let w = bounds.width as f64; - let h = bounds.height as f64; + let x = f64::from(bounds.x); + let y = f64::from(bounds.y); + let w = f64::from(bounds.width); + let h = f64::from(bounds.height); match handle { SelectionHandle::TopLeft => (x + w, y + h), SelectionHandle::TopRight => (x, y + h), diff --git a/src/input/state/core/selection_actions/text/wrap.rs b/src/input/state/core/selection_actions/text/wrap.rs index 4e551b521..c9851e573 100644 --- a/src/input/state/core/selection_actions/text/wrap.rs +++ b/src/input/state/core/selection_actions/text/wrap.rs @@ -5,7 +5,7 @@ const TEXT_WRAP_MIN_WIDTH: i32 = 40; impl InputState { pub(crate) fn clamp_text_wrap_width(&self, base_x: i32, cursor_x: i32, size: f64) -> i32 { - let min_width = (size * 2.0).round().max(TEXT_WRAP_MIN_WIDTH as f64) as i32; + let min_width = (size * 2.0).round().max(f64::from(TEXT_WRAP_MIN_WIDTH)) as i32; let raw = cursor_x - base_x; let mut width = raw.max(1); let screen_width = self.view.screen_width().min(i32::MAX as u32) as i32; diff --git a/src/input/state/core/selection_actions/translation/mod.rs b/src/input/state/core/selection_actions/translation/mod.rs index cf312539d..a6e83d4b0 100644 --- a/src/input/state/core/selection_actions/translation/mod.rs +++ b/src/input/state/core/selection_actions/translation/mod.rs @@ -31,9 +31,8 @@ impl InputState { if dx == 0 && dy == 0 { return false; } - let (dx, dy) = match self.clamp_selection_translation(measurer, dx, dy) { - Some((dx, dy)) => (dx, dy), - None => return false, + let Some((dx, dy)) = self.clamp_selection_translation(measurer, dx, dy) else { + return false; }; if dx == 0 && dy == 0 { return false; diff --git a/src/input/state/core/session_preflight.rs b/src/input/state/core/session_preflight.rs index 1363c48de..07d7e7d9f 100644 --- a/src/input/state/core/session_preflight.rs +++ b/src/input/state/core/session_preflight.rs @@ -107,8 +107,8 @@ impl CloneStorageEstimate { if written == 0 { return false; } - let threshold = ((options.max_file_size_bytes as u128) * 90).div_ceil(100); - (written as u128) >= threshold + let threshold = (u128::from(options.max_file_size_bytes) * 90).div_ceil(100); + u128::from(written) >= threshold } } diff --git a/src/input/state/core/status_hud.rs b/src/input/state/core/status_hud.rs index 3e3fe7c2f..e44ed41e1 100644 --- a/src/input/state/core/status_hud.rs +++ b/src/input/state/core/status_hud.rs @@ -82,7 +82,7 @@ impl InputState { StatusBarItem::Tool => self.ui_visibility.show_status_tool = visible, StatusBarItem::Size => self.ui_visibility.show_status_size = visible, StatusBarItem::ContextIndicators => { - self.ui_visibility.show_status_context_indicators = visible + self.ui_visibility.show_status_context_indicators = visible; } StatusBarItem::ToolbarHint => self.ui_visibility.show_toolbar_hint = visible, StatusBarItem::Help => self.ui_visibility.show_status_help = visible, @@ -251,7 +251,7 @@ impl InputState { self.status_hud .layout .as_ref() - .and_then(|layout| layout.segment_at(x as f64, y as f64)) + .and_then(|layout| layout.segment_at(f64::from(x), f64::from(y))) } else { None }; @@ -298,7 +298,7 @@ impl InputState { .status_hud .layout .as_ref() - .is_some_and(|layout| layout.pill_contains(x as f64, y as f64)) + .is_some_and(|layout| layout.pill_contains(f64::from(x), f64::from(y))) } /// Marks a HUD press consumed by the internal routing chain (tablet and @@ -345,7 +345,7 @@ impl InputState { .status_hud .layout .as_ref() - .and_then(|layout| layout.segment_at(x as f64, y as f64)) + .and_then(|layout| layout.segment_at(f64::from(x), f64::from(y))) else { // Inside the pill but between segments: consume without action. return (true, None); @@ -370,7 +370,7 @@ impl InputState { (true, None) } StatusHudSegmentKind::Tool | StatusHudSegmentKind::Size => { - self.toggle_radial_menu(x as f64, y as f64); + self.toggle_radial_menu(f64::from(x), f64::from(y)); (true, None) } StatusHudSegmentKind::Help => (true, Some(Action::ToggleHelp)), diff --git a/src/input/state/core/test_support.rs b/src/input/state/core/test_support.rs index 89abb0f9d..80c427835 100644 --- a/src/input/state/core/test_support.rs +++ b/src/input/state/core/test_support.rs @@ -10,7 +10,7 @@ use crate::input::boards::PendingBoardRuntimeUiAction; impl InputState { /// Test convenience for inspecting shortcut edits. Production drains the - /// ordered InputEffect stream and forwards edits to the config worker. + /// ordered `InputEffect` stream and forwards edits to the config worker. pub(crate) fn take_pending_keybinding_edits(&mut self) -> Vec { self.input_effects .drain_all(InputEffectKind::KeybindingEdit) @@ -22,7 +22,7 @@ impl InputState { .collect() } - /// Test convenience for inspecting board actions in the InputEffect stream. + /// Test convenience for inspecting board actions in the `InputEffect` stream. pub(crate) fn take_pending_board_runtime_ui_actions( &mut self, ) -> Vec { diff --git a/src/input/state/core/toolbar/apply/layout.rs b/src/input/state/core/toolbar/apply/layout.rs index fd480221c..7e849360d 100644 --- a/src/input/state/core/toolbar/apply/layout.rs +++ b/src/input/state/core/toolbar/apply/layout.rs @@ -24,20 +24,20 @@ impl InputState { } pub(super) fn apply_toolbar_toggle_custom_section(&mut self, enable: bool) -> bool { - if self.history_limits.custom_section_enabled() != enable { + if self.history_limits.custom_section_enabled() == enable { + false + } else { self.history_limits.set_custom_section_enabled(enable); true - } else { - false } } pub(super) fn apply_toolbar_toggle_delay_sliders(&mut self, show: bool) -> bool { - if self.ui_visibility.show_delay_sliders != show { + if self.ui_visibility.show_delay_sliders == show { + false + } else { self.ui_visibility.show_delay_sliders = show; true - } else { - false } } @@ -119,11 +119,11 @@ impl InputState { } pub(super) fn apply_toolbar_toggle_more_colors(&mut self, show: bool) -> bool { - if self.ui_visibility.show_more_colors != show { + if self.ui_visibility.show_more_colors == show { + false + } else { self.ui_visibility.show_more_colors = show; true - } else { - false } } @@ -186,29 +186,29 @@ impl InputState { } pub(super) fn apply_toolbar_toggle_context_aware_ui(&mut self, enabled: bool) -> bool { - if self.ui_visibility.context_aware_ui != enabled { + if self.ui_visibility.context_aware_ui == enabled { + false + } else { self.ui_visibility.context_aware_ui = enabled; true - } else { - false } } pub(super) fn apply_toolbar_toggle_preset_toasts(&mut self, show: bool) -> bool { - if self.ui_visibility.show_preset_toasts != show { + if self.ui_visibility.show_preset_toasts == show { + false + } else { self.ui_visibility.show_preset_toasts = show; true - } else { - false } } pub(super) fn apply_toolbar_toggle_idle_fade(&mut self, enable: bool) -> bool { - if self.ui_visibility.idle_fade != enable { + if self.ui_visibility.idle_fade == enable { + false + } else { self.ui_visibility.idle_fade = enable; true - } else { - false } } @@ -216,12 +216,12 @@ impl InputState { if self.presenter_mode_active() && self.presenter_mode_config().hide_tool_preview { return false; } - if self.ui_visibility.show_tool_preview != show { + if self.ui_visibility.show_tool_preview == show { + false + } else { self.ui_visibility.show_tool_preview = show; self.needs_redraw = true; true - } else { - false } } @@ -236,13 +236,13 @@ impl InputState { // This is an explicit chrome control, so it takes ownership from // Focus Mode just like the keyboard/palette toggle does. self.break_focus_mode(); - if self.ui_visibility.show_status_bar != show { + if self.ui_visibility.show_status_bar == show { + false + } else { self.ui_visibility.show_status_bar = show; self.refresh_status_hud_layout_with_resources(resources.ui_engine, resources.measurer); self.needs_redraw = true; true - } else { - false } } @@ -297,13 +297,13 @@ impl InputState { } pub(super) fn apply_toolbar_toggle_floating_badge_always(&mut self, show: bool) -> bool { - if self.ui_visibility.show_floating_badge_always != show { + if self.ui_visibility.show_floating_badge_always == show { + false + } else { self.ui_visibility.show_floating_badge_always = show; self.dirty_tracker.mark_full(); self.needs_redraw = true; true - } else { - false } } diff --git a/src/input/state/core/utility/help_overlay.rs b/src/input/state/core/utility/help_overlay.rs index 5bb893e61..e5121c92e 100644 --- a/src/input/state/core/utility/help_overlay.rs +++ b/src/input/state/core/utility/help_overlay.rs @@ -116,7 +116,7 @@ impl InputState { /// Resolve a left-click at `(x, y)` (screen space) against the real rendered /// help layout: a clickable row/footer action, inside chrome, or a dismiss. pub fn help_overlay_click_at(&self, x: i32, y: i32) -> HelpOverlayClick { - match self.help_overlay.region_at(x as f64, y as f64) { + match self.help_overlay.region_at(f64::from(x), f64::from(y)) { Some(HelpOverlayRegion::Row(action)) => HelpOverlayClick::Run(action), Some(HelpOverlayRegion::ToggleUnbound) => HelpOverlayClick::ToggleUnbound, Some(_) => HelpOverlayClick::Inside, @@ -174,7 +174,7 @@ impl InputState { return None; } - match self.help_overlay.region_at(x as f64, y as f64)? { + match self.help_overlay.region_at(f64::from(x), f64::from(y))? { HelpOverlayRegion::Search => Some(HelpOverlayCursorHint::Text), HelpOverlayRegion::Row(_) | HelpOverlayRegion::ToggleUnbound => { Some(HelpOverlayCursorHint::Pointer) diff --git a/src/input/state/core/utility/interaction.rs b/src/input/state/core/utility/interaction.rs index d8a3a5b38..e72395504 100644 --- a/src/input/state/core/utility/interaction.rs +++ b/src/input/state/core/utility/interaction.rs @@ -9,7 +9,7 @@ impl InputState { (0.0, 0.0) } else { let (x, y) = self.boards.active_frame().view_offset(); - (x as f64, y as f64) + (f64::from(x), f64::from(y)) } } diff --git a/src/input/state/core/utility/launcher.rs b/src/input/state/core/utility/launcher.rs index da82a725b..fa1f99da7 100644 --- a/src/input/state/core/utility/launcher.rs +++ b/src/input/state/core/utility/launcher.rs @@ -57,7 +57,7 @@ impl InputState { let path = match Config::config_path() { Ok(p) => p, Err(err) => { - log::error!("Unable to resolve config path: {}", err); + log::error!("Unable to resolve config path: {err}"); self.push_toast( ToastPriority::Critical, "launcher", diff --git a/src/input/state/core/utility/sequence.rs b/src/input/state/core/utility/sequence.rs index e5632c62d..4bf7fb41a 100644 --- a/src/input/state/core/utility/sequence.rs +++ b/src/input/state/core/utility/sequence.rs @@ -153,8 +153,7 @@ impl SequenceTrie { return SequenceMatch::None; }; node.action - .map(SequenceMatch::Dispatched) - .unwrap_or(SequenceMatch::None) + .map_or(SequenceMatch::None, SequenceMatch::Dispatched) } } diff --git a/src/input/state/core/view.rs b/src/input/state/core/view.rs index 553db54fb..fb840d8c3 100644 --- a/src/input/state/core/view.rs +++ b/src/input/state/core/view.rs @@ -148,8 +148,8 @@ impl ViewState { let scale = self.canvas_scale(); let (origin_x, origin_y) = self.canvas_origin(board_offset); ( - (origin_x + screen_x as f64 / scale).round() as i32, - (origin_y + screen_y as f64 / scale).round() as i32, + (origin_x + f64::from(screen_x) / scale).round() as i32, + (origin_y + f64::from(screen_y) / scale).round() as i32, ) } @@ -162,8 +162,8 @@ impl ViewState { let scale = self.canvas_scale(); let (origin_x, origin_y) = self.canvas_origin(board_offset); ( - ((canvas_x as f64 - origin_x) * scale).round() as i32, - ((canvas_y as f64 - origin_y) * scale).round() as i32, + ((f64::from(canvas_x) - origin_x) * scale).round() as i32, + ((f64::from(canvas_y) - origin_y) * scale).round() as i32, ) } @@ -174,10 +174,10 @@ impl ViewState { ) -> Option { let scale = self.canvas_scale(); let (origin_x, origin_y) = self.canvas_origin(board_offset); - let min_x = ((rect.x as f64 - origin_x) * scale).floor() as i32; - let min_y = ((rect.y as f64 - origin_y) * scale).floor() as i32; - let max_x = (((rect.x + rect.width) as f64 - origin_x) * scale).ceil() as i32; - let max_y = (((rect.y + rect.height) as f64 - origin_y) * scale).ceil() as i32; + let min_x = ((f64::from(rect.x) - origin_x) * scale).floor() as i32; + let min_y = ((f64::from(rect.y) - origin_y) * scale).floor() as i32; + let max_x = ((f64::from(rect.x + rect.width) - origin_x) * scale).ceil() as i32; + let max_y = ((f64::from(rect.y + rect.height) - origin_y) * scale).ceil() as i32; Rect::from_min_max(min_x, min_y, max_x, max_y) } diff --git a/src/input/state/core/zoom_chip/state.rs b/src/input/state/core/zoom_chip/state.rs index e42003a9d..e0aebb42a 100644 --- a/src/input/state/core/zoom_chip/state.rs +++ b/src/input/state/core/zoom_chip/state.rs @@ -58,13 +58,13 @@ impl ZoomChipState { && self .layout .as_ref() - .is_some_and(|layout| layout.chip_contains(x as f64, y as f64)) + .is_some_and(|layout| layout.chip_contains(f64::from(x), f64::from(y))) } pub(crate) fn button_at(&self, x: i32, y: i32) -> Option { self.layout .as_ref() - .and_then(|layout| layout.button_at(x as f64, y as f64)) + .and_then(|layout| layout.button_at(f64::from(x), f64::from(y))) } pub(in crate::input::state) fn set_press_pending(&mut self, pressed: ZoomChipPress) { diff --git a/src/input/state/highlight/state/mod.rs b/src/input/state/highlight/state/mod.rs index c0addce04..5bcd32f05 100644 --- a/src/input/state/highlight/state/mod.rs +++ b/src/input/state/highlight/state/mod.rs @@ -195,8 +195,8 @@ impl ClickHighlightState { draw::render_click_highlight( ctx, - highlight.x as f64, - highlight.y as f64, + f64::from(highlight.x), + f64::from(highlight.y), self.settings.radius, self.settings.outline_thickness, self.settings.fill_color, @@ -213,8 +213,8 @@ impl ClickHighlightState { draw::render_click_highlight( ctx, - x as f64, - y as f64, + f64::from(x), + f64::from(y), self.settings.radius, self.settings.outline_thickness, self.settings.fill_color, diff --git a/src/input/state/interaction/adapters/pointer.rs b/src/input/state/interaction/adapters/pointer.rs index 4168e5a31..4ebbe4e63 100644 --- a/src/input/state/interaction/adapters/pointer.rs +++ b/src/input/state/interaction/adapters/pointer.rs @@ -271,7 +271,7 @@ pub(crate) fn handle_right_press( let screen = points.screen(); let canvas = points.canvas(); if state.should_toggle_radial_menu_from_mouse(MouseButton::Right) { - state.toggle_radial_menu(screen.x() as f64, screen.y() as f64); + state.toggle_radial_menu(f64::from(screen.x()), f64::from(screen.y())); return RoutingOutcome::Consumed(ConsumedBy::RadialMenuToggle); } @@ -302,7 +302,7 @@ pub(crate) fn handle_right_press( pub(crate) fn handle_middle_press(state: &mut InputState, points: PointerPoints) -> RoutingOutcome { let screen = points.screen(); if state.should_toggle_radial_menu_from_mouse(MouseButton::Middle) { - state.toggle_radial_menu(screen.x() as f64, screen.y() as f64); + state.toggle_radial_menu(f64::from(screen.x()), f64::from(screen.y())); RoutingOutcome::Consumed(ConsumedBy::RadialMenuToggle) } else { RoutingOutcome::NoRoute(NoRouteReason::NoPointerBinding) @@ -331,8 +331,9 @@ fn open_context_menu_from_right_click( .boards .active_frame() .shape(selection[0]) - .map(|shape| matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. })) - .unwrap_or(false); + .is_some_and(|shape| { + matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. }) + }); state.open_context_menu( (screen_x, screen_y), selection, @@ -368,8 +369,8 @@ pub(crate) fn handle_radial_menu_motion( return None; } let screen = points.screen(); - let x = screen.x() as f64; - let y = screen.y() as f64; + let x = f64::from(screen.x()); + let y = f64::from(screen.y()); if state.radial_menu_is_size_dragging() { // Drag capture: while the size gauge is held, every motion adjusts // thickness, even outside the band. @@ -392,10 +393,10 @@ pub(crate) fn handle_color_picker_motion( if let Some(target) = state.color_picker_popup_drag_target() { // The drag keeps steering the area it started on, even once the // pointer leaves that area's bounds. - state.color_picker_popup_apply_drag(target, screen.x() as f64, screen.y() as f64); + state.color_picker_popup_apply_drag(target, f64::from(screen.x()), f64::from(screen.y())); state.color_picker_popup_set_hover(None); } else { - state.color_picker_popup_set_hover(Some((screen.x() as f64, screen.y() as f64))); + state.color_picker_popup_set_hover(Some((f64::from(screen.x()), f64::from(screen.y())))); } Some(RoutingOutcome::Consumed(ConsumedBy::ColorPickerPopup)) } @@ -526,8 +527,8 @@ pub(crate) fn handle_radial_menu_release( .radial_menu_handle_release_with_resources( resources, button, - screen.x() as f64, - screen.y() as f64, + f64::from(screen.x()), + f64::from(screen.y()), ) .then_some(RoutingOutcome::Consumed(ConsumedBy::RadialMenu)) } diff --git a/src/input/state/mouse/press.rs b/src/input/state/mouse/press.rs index ceecd92ff..8f4791109 100644 --- a/src/input/state/mouse/press.rs +++ b/src/input/state/mouse/press.rs @@ -76,10 +76,9 @@ impl InputState { .boards .active_frame() .shape(selection[0]) - .map(|shape| { + .is_some_and(|shape| { matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. }) - }) - .unwrap_or(false); + }); self.open_context_menu( (screen_x, screen_y), selection, @@ -115,7 +114,7 @@ impl InputState { /// /// # Behavior /// - Left click while Idle: Starts drawing with the current tool (based on modifiers) - /// - Left click during TextInput: Updates text position + /// - Left click during `TextInput`: Updates text position /// - Right click: Cancels current action #[allow(dead_code)] // Retained for older callers that only have canvas coordinates. pub fn on_mouse_press(&mut self, button: MouseButton, x: i32, y: i32) { @@ -346,8 +345,8 @@ impl InputState { &preview.text, &font, self.style.text_wrap_width, - (canvas_x - *x) as f64, - (canvas_y - *y) as f64, + f64::from(canvas_x - *x), + f64::from(canvas_y - *y), ) else { return; }; @@ -515,11 +514,10 @@ impl InputState { .boards .active_frame() .shape(hit_id) - .map(|shape| { + .is_some_and(|shape| { !shape.locked && matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. }) - }) - .unwrap_or(false); + }); if is_text { self.begin_pointer_drag(button, color); self.state = DrawingState::PendingTextClick { @@ -557,19 +555,19 @@ impl InputState { moved: false, }; return; - } else { - self.text_editing.set_last_click(None); - self.begin_pointer_drag(button, color); - self.state = DrawingState::Selecting { - start_x: x, - start_y: y, - additive: self.modifiers.shift, - }; - self.pointer.replace_provisional_bounds(None); - self.update_provisional_dirty_with(measurer, x, y); - self.needs_redraw = true; - return; } + + self.text_editing.set_last_click(None); + self.begin_pointer_drag(button, color); + self.state = DrawingState::Selecting { + start_x: x, + start_y: y, + additive: self.modifiers.shift, + }; + self.pointer.replace_provisional_bounds(None); + self.update_provisional_dirty_with(measurer, x, y); + self.needs_redraw = true; + return; } self.text_editing.set_last_click(None); diff --git a/src/input/state/mouse/press/panels.rs b/src/input/state/mouse/press/panels.rs index d5a0661a9..758bc4d75 100644 --- a/src/input/state/mouse/press/panels.rs +++ b/src/input/state/mouse/press/panels.rs @@ -45,14 +45,14 @@ impl InputState { match button { MouseButton::Left => { // Update hover at exact click position before selecting - self.update_radial_menu_hover(screen_x as f64, screen_y as f64); + self.update_radial_menu_hover(f64::from(screen_x), f64::from(screen_y)); if self.radial_menu_hover_is_size_ring() { // Pressing the size gauge starts a drag-capture along the // arc instead of selecting. self.radial_menu_begin_size_drag_with_measurer( resources.measurer, - screen_x as f64, - screen_y as f64, + f64::from(screen_x), + f64::from(screen_y), ); } else { self.radial_menu_select_hovered_with_resources(resources); @@ -93,8 +93,8 @@ impl InputState { MouseButton::Left => { let action_pressed = self.color_picker_popup_note_action_press(x, y); if !action_pressed && let Some(layout) = self.color_picker_popup_layout() { - let fx = x as f64; - let fy = y as f64; + let fx = f64::from(x); + let fy = f64::from(y); let target = if layout.point_in_sv(fx, fy) { Some(PickerDrag::SatVal) } else if layout.point_in_hue(fx, fy) { diff --git a/src/input/state/mouse/release/drawing.rs b/src/input/state/mouse/release/drawing.rs index 7f70c037a..873f5b48d 100644 --- a/src/input/state/mouse/release/drawing.rs +++ b/src/input/state/mouse/release/drawing.rs @@ -140,48 +140,45 @@ pub(super) fn finish_drawing( // A recognized stroke enters history as its ink, then turns into the // shape as a second step, so the first undo gives the ink back. let created = ink.clone().unwrap_or_else(|| shape.clone()); - match frame.try_add_shape_with_id(created, max_shapes) { - Some(new_id) => { - if let Some(index) = frame.find_index(new_id) { - if let Some(new_shape) = frame.shape(new_id) { - let snapshot = new_shape.clone(); + if let Some(new_id) = frame.try_add_shape_with_id(created, max_shapes) { + if let Some(index) = frame.find_index(new_id) { + if let Some(new_shape) = frame.shape(new_id) { + let snapshot = new_shape.clone(); + frame.push_undo_action( + UndoAction::Create { + shapes: vec![(index, snapshot.clone())], + }, + undo_limit, + ); + if let Some(ink) = ink + && let Some(target) = frame.shape_mut(new_id) + { + target.set_shape(shape.clone()); frame.push_undo_action( - UndoAction::Create { - shapes: vec![(index, snapshot.clone())], + UndoAction::Modify { + shape_id: new_id, + before: ShapeSnapshot { + shape: ink, + locked: snapshot.locked, + }, + after: ShapeSnapshot { + shape: shape.clone(), + locked: snapshot.locked, + }, }, undo_limit, ); - if let Some(ink) = ink - && let Some(target) = frame.shape_mut(new_id) - { - target.set_shape(shape.clone()); - frame.push_undo_action( - UndoAction::Modify { - shape_id: new_id, - before: ShapeSnapshot { - shape: ink, - locked: snapshot.locked, - }, - after: ShapeSnapshot { - shape: shape.clone(), - locked: snapshot.locked, - }, - }, - undo_limit, - ); - } - Some((new_id, snapshot)) - } else { - None } + Some((new_id, snapshot)) } else { None } - } - None => { - limit_reached = true; + } else { None } + } else { + limit_reached = true; + None } }; @@ -290,9 +287,9 @@ fn finished_path_damage_regions(shape: &Shape, fallback: Option) -> Option Some(split_path_damage_regions(points, *thick, fallback?)) } Shape::FreehandPressure { points, .. } => { - let max_thick = points - .iter() - .fold(1.0f64, |max, &(_, _, thickness)| max.max(thickness as f64)); + let max_thick = points.iter().fold(1.0f64, |max, &(_, _, thickness)| { + max.max(f64::from(thickness)) + }); let points = points.iter().map(|&(x, y, _)| (x, y)).collect::>(); Some(split_path_damage_regions(&points, max_thick, fallback?)) } diff --git a/src/input/state/mouse/release/panels.rs b/src/input/state/mouse/release/panels.rs index 64ce29af5..cdf4972a5 100644 --- a/src/input/state/mouse/release/panels.rs +++ b/src/input/state/mouse/release/panels.rs @@ -17,21 +17,18 @@ pub(super) fn handle_color_picker_popup_release(state: &mut InputState, x: i32, // read by that control too. Hit-testing the release point instead would // let a saturation drag released over the hue bar, the alpha bar, or a // recent swatch apply there as a fresh click. - let fx = x as f64; - let fy = y as f64; + let fx = f64::from(x); + let fy = f64::from(y); if let Some(target) = state.color_picker_popup_take_drag_target() { state.color_picker_popup_apply_drag(target, fx, fy); state.color_picker_popup_set_hex_editing(false); return true; } - let layout = match state.color_picker_popup_layout() { - Some(layout) => layout, - None => { - // No layout, close popup - state.close_color_picker_popup(true); - return true; - } + let Some(layout) = state.color_picker_popup_layout() else { + // No layout, close popup + state.close_color_picker_popup(true); + return true; }; // Popup actions use a same-button press/release contract. A press that @@ -196,17 +193,13 @@ pub(super) fn handle_board_picker_release( return true; } let now = Instant::now(); - let is_double = state - .board_picker - .last_click - .map(|last| { - last.row == index - && now.duration_since(last.at).as_millis() - <= BOARD_PICKER_DOUBLE_CLICK_MS as u128 - && (x - last.x).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE - && (y - last.y).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE - }) - .unwrap_or(false); + let is_double = state.board_picker.last_click.is_some_and(|last| { + last.row == index + && now.duration_since(last.at).as_millis() + <= u128::from(BOARD_PICKER_DOUBLE_CLICK_MS) + && (x - last.x).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE + && (y - last.y).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE + }); if is_double { state.board_picker.last_click = None; state.board_picker_activate_row_with_measurer(resources.measurer, index); diff --git a/src/input/state/render.rs b/src/input/state/render.rs index daee0d974..fd1863a64 100644 --- a/src/input/state/render.rs +++ b/src/input/state/render.rs @@ -37,10 +37,10 @@ impl InputState { Tool::LiveShape => true, _ => return None, }; - let shape = match self.provisional_tool_stroke(current_x, current_y) { - ProvisionalToolStroke::Shape(shape) - | ProvisionalToolStroke::Recognized { shape, .. } => shape, - _ => return None, + let (ProvisionalToolStroke::Shape(shape) | ProvisionalToolStroke::Recognized { shape, .. }) = + self.provisional_tool_stroke(current_x, current_y) + else { + return None; }; let extent = match &shape { @@ -251,7 +251,7 @@ impl InputState { } => { let max_thick = point_thicknesses .iter() - .fold(1.0f64, |max, &thickness| max.max(thickness as f64)); + .fold(1.0f64, |max, &thickness| max.max(f64::from(thickness))); let ranges = path_damage_ranges(points, damage_regions, max_thick); if ranges.is_empty() { return false; @@ -374,10 +374,10 @@ impl InputState { }; let _ = ctx.save(); ctx.rectangle( - rect.x as f64, - rect.y as f64, - rect.width as f64, - rect.height as f64, + f64::from(rect.x), + f64::from(rect.y), + f64::from(rect.width), + f64::from(rect.height), ); ctx.set_source_rgba(0.2, 0.45, 1.0, 0.12); let _ = ctx.fill_preserve(); diff --git a/src/input/state/tests/erase.rs b/src/input/state/tests/erase.rs index 69eb9990e..91aaafa9d 100644 --- a/src/input/state/tests/erase.rs +++ b/src/input/state/tests/erase.rs @@ -110,8 +110,8 @@ fn erase_stroke_samples_randomized_crossings() { fn next_unit(seed: &mut u64) -> f64 { *seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1); - let value = ((*seed >> 33) as u32) as f64; - value / (u32::MAX as f64) + let value = f64::from((*seed >> 33) as u32); + value / f64::from(u32::MAX) } let mut seed = 0x1234_5678_9abc_def0u64; @@ -152,11 +152,7 @@ fn erase_stroke_samples_randomized_crossings() { ], ); - assert!( - erased, - "stroke eraser should remove line at angle {}", - angle - ); + assert!(erased, "stroke eraser should remove line at angle {angle}"); assert!(state.boards.active_frame().shape(line_id).is_none()); } } diff --git a/src/input/state/tests/menus/context_menu.rs b/src/input/state/tests/menus/context_menu.rs index bfc844b64..c5bed7316 100644 --- a/src/input/state/tests/menus/context_menu.rs +++ b/src/input/state/tests/menus/context_menu.rs @@ -266,12 +266,12 @@ fn keyboard_context_menu_focuses_edit_for_selected_text() { state.set_selection(vec![shape_id]); state.toggle_context_menu_via_keyboard(); - let focus_index = match &state.context_menu.state { - ContextMenuState::Open { - keyboard_focus: Some(index), - .. - } => index, - _ => panic!("Context menu should be open with focus"), + let ContextMenuState::Open { + keyboard_focus: Some(focus_index), + .. + } = &state.context_menu.state + else { + panic!("Context menu should be open with focus"); }; let entries = state.context_menu_entries(); assert_eq!(entries[*focus_index].command, Some(MenuCommand::EditText)); diff --git a/src/input/state/tests/modal.rs b/src/input/state/tests/modal.rs index a4ec02812..315681868 100644 --- a/src/input/state/tests/modal.rs +++ b/src/input/state/tests/modal.rs @@ -65,22 +65,22 @@ fn openers_leave_no_excluded_surface_behind() { let openers: &[Opener] = &[ ("palette", ModalSurface::CommandPalette, |state| { - state.toggle_command_palette() + state.toggle_command_palette(); }), ("help", ModalSurface::HelpOverlay, |state| { - state.toggle_help_overlay() + state.toggle_help_overlay(); }), ("radial", ModalSurface::RadialMenu, |state| { - state.toggle_radial_menu(100.0, 100.0) + state.toggle_radial_menu(100.0, 100.0); }), ("color picker", ModalSurface::ColorPicker, |state| { - state.open_color_picker_popup() + state.open_color_picker_popup(); }), ("context menu", ModalSurface::ContextMenu, |state| { - state.open_page_context_menu((10, 10), 0, 0) + state.open_page_context_menu((10, 10), 0, 0); }), ("board picker", ModalSurface::BoardPicker, |state| { - state.open_board_picker_with_measurer(&TextMeasurer::default()) + state.open_board_picker_with_measurer(&TextMeasurer::default()); }), ]; diff --git a/src/input/state/tests/pen_sampling.rs b/src/input/state/tests/pen_sampling.rs index 193a13942..3f165139a 100644 --- a/src/input/state/tests/pen_sampling.rs +++ b/src/input/state/tests/pen_sampling.rs @@ -93,7 +93,7 @@ fn slow_and_fast_subpixel_strokes_keep_similar_spatial_smoothing() { } let max_difference = (0..=720) .map(|i| { - let x = 300.2 + i as f64 / 4.0; + let x = 300.2 + f64::from(i) / 4.0; (interpolated_y(a, x) - interpolated_y(b, x)).abs() * 5.0 / 3.0 }) .fold(0.0, f64::max); diff --git a/src/input/state/tests/pressure_modes.rs b/src/input/state/tests/pressure_modes.rs index f1ba924b9..dd3c68997 100644 --- a/src/input/state/tests/pressure_modes.rs +++ b/src/input/state/tests/pressure_modes.rs @@ -51,7 +51,7 @@ fn pressure_points(state: &InputState, id: ShapeId) -> Vec { let frame = state.boards.active_frame(); match frame.shape(id).map(|drawn| &drawn.shape) { Some(Shape::FreehandPressure { points, .. }) => points.iter().map(|(_, _, t)| *t).collect(), - other => panic!("expected FreehandPressure shape, got: {:?}", other), + other => panic!("expected FreehandPressure shape, got: {other:?}"), } } @@ -89,7 +89,7 @@ fn text_snapshot( *background_enabled, *wrap_width, ), - other => panic!("expected Text shape, got: {:?}", other), + other => panic!("expected Text shape, got: {other:?}"), } } diff --git a/src/input/state/tests/radial_menu.rs b/src/input/state/tests/radial_menu.rs index 5f6ab8294..7e448a879 100644 --- a/src/input/state/tests/radial_menu.rs +++ b/src/input/state/tests/radial_menu.rs @@ -30,7 +30,7 @@ fn compass_angle_degrees(dir: CompassDir) -> f64 { } fn point_in_compass_wedge(layout: &RadialMenuLayout, dir: CompassDir) -> (f64, f64) { - let radius = (layout.tool_inner + layout.tool_outer) / 2.0; + let radius = f64::midpoint(layout.tool_inner, layout.tool_outer); point_at( layout.center_x, layout.center_y, @@ -50,10 +50,10 @@ fn point_in_sub_tool_segment( let child_angle = seg_angle / child_count as f64; // Compute the desired tool_angle in hit-test space (0 at top, with half-seg offset). let tool_angle = - parent_idx as f64 * seg_angle + child_idx as f64 * child_angle + child_angle / 2.0; + f64::from(parent_idx) * seg_angle + f64::from(child_idx) * child_angle + child_angle / 2.0; // Convert back to raw atan2 angle (undo the +PI/2 and +half_seg transforms). let raw_angle = tool_angle - PI / 2.0 - half_seg; - let radius = (layout.sub_inner + layout.sub_outer) / 2.0; + let radius = f64::midpoint(layout.sub_inner, layout.sub_outer); ( layout.center_x + radius * raw_angle.cos(), layout.center_y + radius * raw_angle.sin(), @@ -169,7 +169,7 @@ fn compass_wedges_dispatch_fixed_tools_via_handle_action() { fn north_wedge_spans_22_5_degrees_around_straight_up() { let mut state = create_test_input_state(); let layout = open_with_layout(&mut state); - let radius = (layout.tool_inner + layout.tool_outer) / 2.0; + let radius = f64::midpoint(layout.tool_inner, layout.tool_outer); for (degrees, expected_dir) in [ (-90.0 + 21.0, CompassDir::N), @@ -277,7 +277,7 @@ fn notes_sub_ring_is_step_marker_then_sticky_note() { #[test] fn non_parent_wedges_have_no_sub_ring_children() { - for slice in RADIAL_COMPASS_SLICES.iter() { + for slice in &RADIAL_COMPASS_SLICES { let expected = matches!(slice.kind, RadialSliceKind::Parent(_)); assert_eq!( sub_ring_child_count(slice.dir.index()) > 0, @@ -339,7 +339,7 @@ fn notes_sub_ring_child_dispatches_sticky_note_mode() { #[test] fn compass_ring_offers_no_history_or_clear_actions() { let mut ring_actions: Vec = Vec::new(); - for slice in RADIAL_COMPASS_SLICES.iter() { + for slice in &RADIAL_COMPASS_SLICES { match slice.kind { RadialSliceKind::Action(action) => ring_actions.push(action), RadialSliceKind::Parent(parent) => ring_actions.extend(parent.children()), @@ -524,7 +524,7 @@ fn color_hit_test_uses_color_ring_alignment_when_tool_count_differs() { // Just inside color segment 1 (Green), close to the segment boundary. let seg = 2.0 * PI / state.style.quick_colors.radial_rendered_len() as f64; let probe_angle = -PI / 2.0 + seg + 0.04; - let probe_radius = (layout.color_inner + layout.color_outer) / 2.0; + let probe_radius = f64::midpoint(layout.color_inner, layout.color_outer); let probe_x = layout.center_x + probe_radius * probe_angle.cos(); let probe_y = layout.center_y + probe_radius * probe_angle.sin(); @@ -563,7 +563,7 @@ fn color_ring_selection_uses_configured_quick_palette() { let seg = 2.0 * PI / state.style.quick_colors.radial_rendered_len() as f64; let probe_angle = -PI / 2.0 + seg + 0.04; - let probe_radius = (layout.color_inner + layout.color_outer) / 2.0; + let probe_radius = f64::midpoint(layout.color_inner, layout.color_outer); let probe_x = layout.center_x + probe_radius * probe_angle.cos(); let probe_y = layout.center_y + probe_radius * probe_angle.sin(); @@ -759,7 +759,7 @@ fn blind_flick_into_sub_band_never_commits_a_sub_child() { // sub-ring band, all before the menu ever painted. let (px, py) = point_in_compass_wedge(&layout, CompassDir::E); state.on_mouse_motion(px as i32, py as i32); - let sub_r = (layout.sub_inner + layout.sub_outer) / 2.0; + let sub_r = f64::midpoint(layout.sub_inner, layout.sub_outer); let (sx, sy) = point_at(layout.center_x, layout.center_y, sub_r, 0.0); state.on_mouse_motion(sx as i32, sy as i32); state.on_mouse_release(MouseButton::Right, sx as i32, sy as i32); @@ -836,7 +836,7 @@ fn open_via_right_press_at_edge(state: &mut InputState, x: i32, y: i32) -> Radia .layout .expect("layout should exist for open radial menu"); assert!( - layout.center_x - x as f64 > layout.center_radius, + layout.center_x - f64::from(x) > layout.center_radius, "edge press must clamp the layout center beyond a deadzone from the press point" ); layout @@ -954,7 +954,7 @@ fn size_ring_angle_value_mapping_roundtrips_and_snaps_the_gap() { fn size_ring_hit_test_covers_arc_but_not_gap() { let mut state = create_test_input_state(); let layout = open_with_layout(&mut state); - let band_r = (layout.size_inner + layout.size_outer) / 2.0; + let band_r = f64::midpoint(layout.size_inner, layout.size_outer); // West is inside the gauge arc. let (wx, wy) = point_at(layout.center_x, layout.center_y, band_r, 180.0); @@ -974,7 +974,7 @@ fn size_ring_drag_adjusts_thickness_live_and_keeps_menu_open() { state.on_mouse_press(MouseButton::Right, 400, 300); state.update_radial_menu_layout(800, 600); let layout = state.radial_menu.layout.expect("layout"); - let band_r = (layout.size_inner + layout.size_outer) / 2.0; + let band_r = f64::midpoint(layout.size_inner, layout.size_outer); // Press on the gauge at west starts a drag and applies the value. let (px, py) = point_at(layout.center_x, layout.center_y, band_r, 180.0); @@ -983,7 +983,7 @@ fn size_ring_drag_adjusts_thickness_live_and_keeps_menu_open() { state.on_mouse_press(MouseButton::Left, pxi, pyi); assert!(state.radial_menu_is_size_dragging()); let expected = size_ring_value_for_angle( - (pyi as f64 - layout.center_y).atan2(pxi as f64 - layout.center_x), + (f64::from(pyi) - layout.center_y).atan2(f64::from(pxi) - layout.center_x), ); assert!((state.size_for_active_tool() - expected).abs() < 1e-9); @@ -992,7 +992,7 @@ fn size_ring_drag_adjusts_thickness_live_and_keeps_menu_open() { let (txi, tyi) = (tx.round() as i32, ty.round() as i32); state.on_mouse_motion(txi, tyi); let expected_top = size_ring_value_for_angle( - (tyi as f64 - layout.center_y).atan2(txi as f64 - layout.center_x), + (f64::from(tyi) - layout.center_y).atan2(f64::from(txi) - layout.center_x), ); assert!((state.size_for_active_tool() - expected_top).abs() < 1e-9); @@ -1019,7 +1019,10 @@ fn recent_colors_are_deduped_most_recent_first_and_capped() { }; // Steps of 0.125 are exact binary fractions, so equality is exact. for i in 0..8 { - state.apply_color_from_ui_with_measurer(&TextMeasurer::default(), color(i as f64 * 0.125)); + state.apply_color_from_ui_with_measurer( + &TextMeasurer::default(), + color(f64::from(i) * 0.125), + ); } assert_eq!(state.style.recent_colors.len(), 6, "recents are capped"); assert_eq!( @@ -1093,7 +1096,7 @@ fn recent_color_segment_applies_through_the_color_path() { assert_eq!(total, quick_len + 1); let seg = 2.0 * PI / total as f64; let probe_angle = -PI / 2.0 + quick_len as f64 * seg; - let probe_radius = (layout.color_inner + layout.color_outer) / 2.0; + let probe_radius = f64::midpoint(layout.color_inner, layout.color_outer); let probe_x = layout.center_x + probe_radius * probe_angle.cos(); let probe_y = layout.center_y + probe_radius * probe_angle.sin(); diff --git a/src/input/state/tests/selection/deletion.rs b/src/input/state/tests/selection/deletion.rs index d1e95d817..45dad06db 100644 --- a/src/input/state/tests/selection/deletion.rs +++ b/src/input/state/tests/selection/deletion.rs @@ -100,10 +100,7 @@ fn clear_all_skips_locked_shapes() { let frame = state.boards.active_frame(); assert!(frame.shape(unlocked_id).is_none()); assert!( - frame - .shape(locked_id) - .map(|shape| shape.locked) - .unwrap_or(false), + frame.shape(locked_id).is_some_and(|shape| shape.locked), "locked shape should remain after clear_all" ); } diff --git a/src/input/state/tests/selection/movement.rs b/src/input/state/tests/selection/movement.rs index 39f46a88c..469a563de 100644 --- a/src/input/state/tests/selection/movement.rs +++ b/src/input/state/tests/selection/movement.rs @@ -1056,7 +1056,7 @@ fn text_moved_to_the_coordinate_limit_survives_deselect_and_undo() { match shape(&state, id) { Shape::Text { x, y, .. } => { - assert_eq!((x, y), (i32::MAX - 1000, 100), "undo must restore the text") + assert_eq!((x, y), (i32::MAX - 1000, 100), "undo must restore the text"); } other => panic!("expected text, got {other:?}"), } diff --git a/src/input/state/tests/status_hud.rs b/src/input/state/tests/status_hud.rs index 8024c1212..355b5e830 100644 --- a/src/input/state/tests/status_hud.rs +++ b/src/input/state/tests/status_hud.rs @@ -98,7 +98,7 @@ fn status_hud_reclassifies_hover_after_toolbar_hint_relayouts_segments() { let segment_now_under_pointer = input .status_hud .layout() - .and_then(|layout| layout.segment_at(x as f64, y as f64)); + .and_then(|layout| layout.segment_at(f64::from(x), f64::from(y))); assert_eq!( segment_now_under_pointer, Some(StatusHudSegmentKind::Toolbar) @@ -529,7 +529,7 @@ fn status_hud_ignored_while_radial_menu_overlays_it() { // Open the radial menu over the HUD (as the Tool chip does): its rings // render above the pill, so the HUD must stop consuming presses there. - input.open_radial_menu(x as f64, y as f64); + input.open_radial_menu(f64::from(x), f64::from(y)); assert!(input.is_radial_menu_open()); // The press side reports no hit while the menu is open. diff --git a/src/input/state/tests/text_input/ime.rs b/src/input/state/tests/text_input/ime.rs index 0def3ce45..a29d11ea5 100644 --- a/src/input/state/tests/text_input/ime.rs +++ b/src/input/state/tests/text_input/ime.rs @@ -1,4 +1,4 @@ -//! IME (zwp_text_input_v3) composition state-machine tests. These queue +//! IME (`zwp_text_input_v3`) composition state-machine tests. These queue //! composition events on `TextEditing`, apply each batch through the root //! `ime_apply_done` coordinator, and assert the caret-aware editor buffer and //! transient preedit follow the protocol's batch-then-done model. diff --git a/src/input/state/tests/tool_controls.rs b/src/input/state/tests/tool_controls.rs index b0840f245..9eb79cff4 100644 --- a/src/input/state/tests/tool_controls.rs +++ b/src/input/state/tests/tool_controls.rs @@ -1679,7 +1679,10 @@ fn color_picker_motion_tracks_action_hover_for_tooltips() { state.on_mouse_motion_with_canvas(x, y, x, y); - assert_eq!(state.color_picker_popup_hover(), Some((x as f64, y as f64))); + assert_eq!( + state.color_picker_popup_hover(), + Some((f64::from(x), f64::from(y))) + ); assert!(state.needs_redraw); } @@ -1698,7 +1701,7 @@ fn color_picker_motion_within_one_action_does_not_redraw_every_pixel() { assert_eq!( state.color_picker_popup_hover(), - Some(((x + 1) as f64, (y + 1) as f64)) + Some((f64::from(x + 1), f64::from(y + 1))) ); assert!(!state.needs_redraw); } diff --git a/src/input/state/tests/zoom_chip.rs b/src/input/state/tests/zoom_chip.rs index f402728c1..51c64315b 100644 --- a/src/input/state/tests/zoom_chip.rs +++ b/src/input/state/tests/zoom_chip.rs @@ -380,7 +380,7 @@ fn zoom_chip_click_percent_readout_consumes_without_action() { input .zoom_chip_layout() .unwrap() - .button_at(x as f64, y as f64), + .button_at(f64::from(x), f64::from(y)), None ); diff --git a/src/input/tool/drawing.rs b/src/input/tool/drawing.rs index 7e8b4df3f..89c9a5267 100644 --- a/src/input/tool/drawing.rs +++ b/src/input/tool/drawing.rs @@ -349,10 +349,10 @@ impl Tool { } } - pub(crate) fn provisional_stroke<'a>( + pub(crate) fn provisional_stroke( self, - snapshot: ProvisionalToolSnapshot<'a>, - ) -> ProvisionalToolStroke<'a> { + snapshot: ProvisionalToolSnapshot<'_>, + ) -> ProvisionalToolStroke<'_> { debug_assert_eq!( self, snapshot.tool, "preview a stroke with the tool that captured its snapshot" @@ -542,7 +542,7 @@ impl Tool { } } -impl<'stroke> ProvisionalToolStroke<'stroke> { +impl ProvisionalToolStroke<'_> { pub(crate) fn bounds_with(&self, measurer: &TextMeasurer) -> Option { match self { Self::BorrowedFreehand { points, size, .. } => bounding_box_for_points(points, *size), @@ -551,7 +551,7 @@ impl<'stroke> ProvisionalToolStroke<'stroke> { point_thicknesses, .. } => { - let max_thick = point_thicknesses.iter().fold(0.0f32, |a, &b| a.max(b)) as f64; + let max_thick = f64::from(point_thicknesses.iter().fold(0.0f32, |a, &b| a.max(b))); bounding_box_for_points(points, max_thick) } Self::BorrowedMarker { points, size, .. } => { diff --git a/src/input/tool/live_shape.rs b/src/input/tool/live_shape.rs index 697300a94..edfa458c5 100644 --- a/src/input/tool/live_shape.rs +++ b/src/input/tool/live_shape.rs @@ -183,8 +183,8 @@ impl Bounds { fn center(self) -> (f64, f64) { ( - (f64::from(self.min_x) + f64::from(self.max_x)) / 2.0, - (f64::from(self.min_y) + f64::from(self.max_y)) / 2.0, + f64::midpoint(f64::from(self.min_x), f64::from(self.max_x)), + f64::midpoint(f64::from(self.min_y), f64::from(self.max_y)), ) } } diff --git a/src/input/tool/live_shape/tests.rs b/src/input/tool/live_shape/tests.rs index f391077f8..b609f6133 100644 --- a/src/input/tool/live_shape/tests.rs +++ b/src/input/tool/live_shape/tests.rs @@ -115,7 +115,7 @@ fn overlapping_rectangles_do_not_become_ellipses() { (120.0, 120.0, 180.0), ] { for step in 0..=12 { - let angle = (start + 90.0 * step as f64 / 12.0).to_radians(); + let angle = (start + 90.0 * f64::from(step) / 12.0).to_radians(); rounded.push((cx + 20.0 * angle.cos(), cy + 20.0 * angle.sin())); } } @@ -181,7 +181,7 @@ fn overlap_rejects_inward_curls() { for inward in [0.2, 0.3] { let path: Vec<_> = (0..=468) .map(|step| { - let fraction = step as f64 / 360.0; + let fraction = f64::from(step) / 360.0; let angle = consts::TAU * fraction; let radius = 60.0 * (1.0 - inward * ((fraction - 1.1) / 0.2).clamp(0.0, 1.0)); ( diff --git a/src/input/tool/live_shape/triangle.rs b/src/input/tool/live_shape/triangle.rs index 2ff0f8374..5064432b9 100644 --- a/src/input/tool/live_shape/triangle.rs +++ b/src/input/tool/live_shape/triangle.rs @@ -104,12 +104,12 @@ fn level_edges(mut vertices: [Point; 3]) -> [Point; 3] { let vertical = flattest(|delta| delta.0); if let Some((a, b)) = horizontal { - let y = (vertices[a].1 + vertices[b].1) / 2.0; + let y = f64::midpoint(vertices[a].1, vertices[b].1); vertices[a].1 = y; vertices[b].1 = y; } if let Some((a, b)) = vertical { - let x = (vertices[a].0 + vertices[b].0) / 2.0; + let x = f64::midpoint(vertices[a].0, vertices[b].0); vertices[a].0 = x; vertices[b].0 = x; } diff --git a/src/logger.rs b/src/logger.rs index e36ad17c1..db8aa733e 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -167,8 +167,7 @@ impl Drop for WritingRecord { fn timestamp_millis() -> u128 { SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|duration| duration.as_millis()) - .unwrap_or(0) + .map_or(0, |duration| duration.as_millis()) } struct LogSink { @@ -448,7 +447,7 @@ mod tests { .spawn(|| { logger.log( &Record::builder() - .args(format_args!("{}", PanicsWhileFormatting)) + .args(format_args!("{PanicsWhileFormatting}")) .level(Level::Warn) .target("wayscriber::daemon") .build(), diff --git a/src/logger/file.rs b/src/logger/file.rs index 62eddc779..fc4d27e93 100644 --- a/src/logger/file.rs +++ b/src/logger/file.rs @@ -44,8 +44,9 @@ fn resolve_log_max_bytes() -> u64 { .ok() .and_then(|value| value.trim().parse::().ok()) .filter(|value| *value > 0) - .map(|value| value.saturating_mul(BYTES_PER_MB)) - .unwrap_or(DEFAULT_LOG_MAX_BYTES) + .map_or(DEFAULT_LOG_MAX_BYTES, |value| { + value.saturating_mul(BYTES_PER_MB) + }) } fn current_log_date() -> String { @@ -61,7 +62,7 @@ pub(super) struct LogFileTarget { impl LogFileTarget { fn path_for_date(&self, date: &str) -> PathBuf { if self.treat_as_dir { - return self.base.join(format!("wayscriber-{}.log", date)); + return self.base.join(format!("wayscriber-{date}.log")); } if !self.append_date { return self.base.clone(); @@ -155,7 +156,7 @@ impl DailyFileWriter { let (path, size) = match self.select_log_path(&date) { Ok(result) => result, Err(err) => { - eprintln!("Failed to resolve log file for {}: {}", date, err); + eprintln!("Failed to resolve log file for {date}: {err}"); self.error_date = Some(date); return; } diff --git a/src/notification.rs b/src/notification.rs index 0c577afdc..477318155 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -119,7 +119,7 @@ mod real { runtime_handle.spawn(async move { let icon_ref = icon.as_deref(); if let Err(e) = send_notification(&summary, &body, icon_ref).await { - log::warn!("Failed to send notification: {}", e); + log::warn!("Failed to send notification: {e}"); } }); } @@ -136,7 +136,7 @@ mod real { if let Err(e) = send_notification_with_timeout(&summary, &body, icon_ref, expire_timeout_ms).await { - log::warn!("Failed to send notification: {}", e); + log::warn!("Failed to send notification: {e}"); } }); } diff --git a/src/ocr/tesseract.rs b/src/ocr/tesseract.rs index a17dbbead..d41a047b8 100644 --- a/src/ocr/tesseract.rs +++ b/src/ocr/tesseract.rs @@ -238,8 +238,7 @@ fn program_in_search_path(program: &str, search_path: &OsStr) -> bool { return false; } fs::metadata(directory.join(program)) - .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0) - .unwrap_or(false) + .is_ok_and(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0) }) } diff --git a/src/palette_recents.rs b/src/palette_recents.rs index ef9a0cce5..d526d9ed8 100644 --- a/src/palette_recents.rs +++ b/src/palette_recents.rs @@ -148,7 +148,7 @@ impl PaletteRecentsStore { let contents = match toml::to_string_pretty(&file) { Ok(contents) => contents, Err(err) => { - warn!("Failed to serialize palette recents: {}", err); + warn!("Failed to serialize palette recents: {err}"); return false; } }; @@ -182,7 +182,7 @@ fn parse_recents(raw: &str) -> Vec { let file: PaletteRecentsFile = match toml::from_str(raw) { Ok(file) => file, Err(err) => { - warn!("Failed to parse palette recents: {}", err); + warn!("Failed to parse palette recents: {err}"); return Vec::new(); } }; diff --git a/src/process_broker/bootstrap.rs b/src/process_broker/bootstrap.rs index 72b23df73..0368352f1 100644 --- a/src/process_broker/bootstrap.rs +++ b/src/process_broker/bootstrap.rs @@ -207,7 +207,7 @@ pub(super) fn broker_exits_within(child_pid: libc::pid_t, grace: Duration) -> bo let mut status = 0; loop { // SAFETY: child_pid names the raw-clone broker child owned by its guard. - let result = unsafe { libc::waitpid(child_pid, &mut status, libc::WNOHANG) }; + let result = unsafe { libc::waitpid(child_pid, &raw mut status, libc::WNOHANG) }; if result == child_pid { return true; } @@ -232,7 +232,7 @@ pub(super) fn wait_for_broker_process(child_pid: libc::pid_t) { let mut status = 0; loop { // SAFETY: child_pid names the raw-clone broker child owned by its guard. - let result = unsafe { libc::waitpid(child_pid, &mut status, 0) }; + let result = unsafe { libc::waitpid(child_pid, &raw mut status, 0) }; if result == child_pid { break; } diff --git a/src/process_broker/execution.rs b/src/process_broker/execution.rs index 2a7c3029e..7700d2168 100644 --- a/src/process_broker/execution.rs +++ b/src/process_broker/execution.rs @@ -441,7 +441,7 @@ impl AbandonablePipe

{ } // SAFETY: pollfd points to one initialized entry, and the pipe // stays open for as long as `self` owns it. - let result = unsafe { libc::poll(&mut pollfd, 1, PIPE_POLL_INTERVAL_MS) }; + let result = unsafe { libc::poll(&raw mut pollfd, 1, PIPE_POLL_INTERVAL_MS) }; if result > 0 { return Ok(()); } diff --git a/src/process_broker/server.rs b/src/process_broker/server.rs index bde855b12..a9ab880e1 100644 --- a/src/process_broker/server.rs +++ b/src/process_broker/server.rs @@ -69,8 +69,8 @@ fn validate_broker_socket(fd: RawFd) -> io::Result<()> { fd, libc::SOL_SOCKET, libc::SO_TYPE, - (&mut socket_type as *mut i32).cast(), - &mut length, + (&raw mut socket_type).cast(), + &raw mut length, ) } != 0 { @@ -583,10 +583,9 @@ mod tests { let (shutdown_writer, shutdown_reader) = test_socket_pair(); drop(shutdown_writer); - let error = match wait_for_request(control_reader.as_raw_fd(), shutdown_reader.as_raw_fd()) - { - Ok(_) => panic!("hangup must unwind through destructive broker cleanup"), - Err(error) => error, + let Err(error) = wait_for_request(control_reader.as_raw_fd(), shutdown_reader.as_raw_fd()) + else { + panic!("hangup must unwind through destructive broker cleanup"); }; assert_eq!(error.kind(), io::ErrorKind::BrokenPipe); @@ -635,10 +634,9 @@ mod tests { 1 ); - let error = match wait_for_request(control_reader.as_raw_fd(), shutdown_reader.as_raw_fd()) - { - Ok(_) => panic!("invalid packet must not authorize ownership release"), - Err(error) => error, + let Err(error) = wait_for_request(control_reader.as_raw_fd(), shutdown_reader.as_raw_fd()) + else { + panic!("invalid packet must not authorize ownership release"); }; assert_eq!(error.kind(), io::ErrorKind::InvalidData); @@ -662,10 +660,9 @@ mod tests { 2 ); - let error = match wait_for_request(control_reader.as_raw_fd(), shutdown_reader.as_raw_fd()) - { - Ok(_) => panic!("oversized packet must not authorize ownership release"), - Err(error) => error, + let Err(error) = wait_for_request(control_reader.as_raw_fd(), shutdown_reader.as_raw_fd()) + else { + panic!("oversized packet must not authorize ownership release"); }; assert_eq!(error.kind(), io::ErrorKind::InvalidData); diff --git a/src/process_broker/transport.rs b/src/process_broker/transport.rs index 9298e1cd8..d3dca23bd 100644 --- a/src/process_broker/transport.rs +++ b/src/process_broker/transport.rs @@ -27,7 +27,7 @@ pub(super) fn set_socket_timeout(fd: RawFd, timeout: Duration) -> io::Result<()> fd, libc::SOL_SOCKET, option, - (&value as *const libc::timeval).cast(), + (&raw const value).cast(), mem::size_of::() as libc::socklen_t, ) } != 0 @@ -45,7 +45,7 @@ pub(super) fn shutdown_requested(descriptor: RawFd) -> io::Result { revents: 0, }; // SAFETY: pollfd points to one initialized entry. - let result = unsafe { libc::poll(&mut pollfd, 1, 0) }; + let result = unsafe { libc::poll(&raw mut pollfd, 1, 0) }; if result < 0 { return Err(io::Error::last_os_error()); } @@ -66,7 +66,7 @@ pub(super) fn take_graceful_shutdown_signal(descriptor: RawFd) -> io::Result io::Result { let received = unsafe { libc::recv( descriptor, - (&mut byte as *mut u8).cast(), + (&raw mut byte).cast(), 1, libc::MSG_DONTWAIT | libc::MSG_TRUNC, ) @@ -281,14 +281,14 @@ pub(super) fn send_packet(fd: RawFd, packet: &[u8], descriptors: &[RawFd]) -> io let mut control = vec![0_usize; control_len.div_ceil(mem::size_of::())]; // SAFETY: zero is a valid initial state for msghdr. let mut message: libc::msghdr = unsafe { mem::zeroed() }; - message.msg_iov = &mut iovec; + message.msg_iov = &raw mut iovec; message.msg_iovlen = 1; if !descriptors.is_empty() { message.msg_control = control.as_mut_ptr().cast(); message.msg_controllen = control_len; // SAFETY: the control buffer has CMSG_SPACE bytes. unsafe { - let header = libc::CMSG_FIRSTHDR(&message); + let header = libc::CMSG_FIRSTHDR(&raw const message); (*header).cmsg_level = libc::SOL_SOCKET; (*header).cmsg_type = libc::SCM_RIGHTS; (*header).cmsg_len = @@ -301,7 +301,7 @@ pub(super) fn send_packet(fd: RawFd, packet: &[u8], descriptors: &[RawFd]) -> io } } // SAFETY: message references live packet/control buffers. - let sent = unsafe { libc::sendmsg(fd, &message, libc::MSG_NOSIGNAL) }; + let sent = unsafe { libc::sendmsg(fd, &raw const message, libc::MSG_NOSIGNAL) }; if sent == packet.len() as isize { return Ok(()); } @@ -331,18 +331,18 @@ pub(super) fn recv_packet(fd: RawFd) -> io::Result<(Vec, Vec)> { let mut control = vec![0_usize; control_len.div_ceil(mem::size_of::())]; // SAFETY: zero is a valid initial state for msghdr. let mut message: libc::msghdr = unsafe { mem::zeroed() }; - message.msg_iov = &mut iovec; + message.msg_iov = &raw mut iovec; message.msg_iovlen = 1; message.msg_control = control.as_mut_ptr().cast(); message.msg_controllen = control_len; // SAFETY: message references writable packet/control buffers. - let read = unsafe { libc::recvmsg(fd, &mut message, libc::MSG_CMSG_CLOEXEC) }; + let read = unsafe { libc::recvmsg(fd, &raw mut message, libc::MSG_CMSG_CLOEXEC) }; if read > 0 { let read = read as usize; let mut descriptors = Vec::new(); // SAFETY: recvmsg initialized ancillary headers in the buffer. unsafe { - let mut header = libc::CMSG_FIRSTHDR(&message); + let mut header = libc::CMSG_FIRSTHDR(&raw const message); while !header.is_null() { if (*header).cmsg_level != libc::SOL_SOCKET || (*header).cmsg_type != libc::SCM_RIGHTS @@ -371,7 +371,7 @@ pub(super) fn recv_packet(fd: RawFd) -> io::Result<(Vec, Vec)> { for index in 0..count { descriptors.push(OwnedFd::from_raw_fd(*data.add(index))); } - header = libc::CMSG_NXTHDR(&message, header); + header = libc::CMSG_NXTHDR(&raw const message, header); } } if read > MAX_PACKET_BYTES diff --git a/src/runtime_ui_state/controller/lifecycle.rs b/src/runtime_ui_state/controller/lifecycle.rs index a726cd5d4..b23fb6889 100644 --- a/src/runtime_ui_state/controller/lifecycle.rs +++ b/src/runtime_ui_state/controller/lifecycle.rs @@ -125,7 +125,7 @@ impl RuntimeUiStateController { pub(super) fn finish_external_reconciliation_write( &mut self, ) -> Result<(), PipelineProtocolError> { - let Some(staged) = self.staged_reload.as_ref().cloned() else { + let Some(staged) = self.staged_reload.clone() else { let barrier = self.active_barrier.as_ref().expect("barrier checked").id; self.close_barrier_and_resolve_previews( barrier, diff --git a/src/runtime_ui_state/controller/source_mutation.rs b/src/runtime_ui_state/controller/source_mutation.rs index 173e51343..28b474367 100644 --- a/src/runtime_ui_state/controller/source_mutation.rs +++ b/src/runtime_ui_state/controller/source_mutation.rs @@ -250,12 +250,11 @@ impl RuntimeUiStateController { model: model.clone(), passthrough: passthrough.clone(), }; - let (next_seeds, changed_targets, tombstoned_targets) = self - .staged_reload - .as_ref() - .cloned() - .map(StagedSeedReload::into_parts) - .unwrap_or_else(|| (self.seeds.clone(), BTreeSet::new(), BTreeSet::new())); + let (next_seeds, changed_targets, tombstoned_targets) = + self.staged_reload.clone().map_or_else( + || (self.seeds.clone(), BTreeSet::new(), BTreeSet::new()), + StagedSeedReload::into_parts, + ); let mut canonical_model = model; canonical_model.remove_targets(&tombstoned_targets); canonical_model.reconcile(&next_seeds); diff --git a/src/runtime_ui_state/recovery/attempt.rs b/src/runtime_ui_state/recovery/attempt.rs index 815fbcaf0..bf8163e0e 100644 --- a/src/runtime_ui_state/recovery/attempt.rs +++ b/src/runtime_ui_state/recovery/attempt.rs @@ -278,19 +278,16 @@ impl RuntimeUiStateController { } covered.sort_unstable(); covered.dedup(); - let request = match self.pipeline.dispatch_recovery_replace( + let Ok(request) = self.pipeline.dispatch_recovery_replace( canonical, through, covered, self.authority_epoch, - ) { - Ok(request) => request, - Err(_) => { - return self.finish_still_unhealthy( - RuntimeStateIoError::new("canonical recovery command was not dispatched"), - Some(observation), - ); - } + ) else { + return self.finish_still_unhealthy( + RuntimeStateIoError::new("canonical recovery command was not dispatched"), + Some(observation), + ); }; let purpose = RecoveryCanonicalWritePurpose { retry_desired_through: retry, diff --git a/src/runtime_ui_state/recovery/authority.rs b/src/runtime_ui_state/recovery/authority.rs index 164979c7e..e00997756 100644 --- a/src/runtime_ui_state/recovery/authority.rs +++ b/src/runtime_ui_state/recovery/authority.rs @@ -364,8 +364,7 @@ impl RuntimeUiStateController { let attempt = self .active_recovery .as_ref() - .map(|attempt| attempt.id) - .unwrap_or(RecoveryAttemptId(0)); + .map_or(RecoveryAttemptId(0), |attempt| attempt.id); let recovery = self.rotate_and_checkout_handle(); if let Some(barrier) = &mut self.active_barrier { barrier.phase = ControllerBarrierPhase::PersistenceUnhealthy { diff --git a/src/runtime_ui_state/recovery/lifecycle.rs b/src/runtime_ui_state/recovery/lifecycle.rs index 600212b34..0c4bc33d2 100644 --- a/src/runtime_ui_state/recovery/lifecycle.rs +++ b/src/runtime_ui_state/recovery/lifecycle.rs @@ -360,21 +360,20 @@ impl RuntimeUiStateController { path_effect: RuntimeStateFailurePathEffect, failed_replacement: Option<&HeldReplacementStage>, ) -> PersistenceIncidentId { - let barrier = match self.active_barrier.as_ref() { - Some(barrier) => barrier.id, - None => { - let id = ControllerBarrierId(self.next_barrier_id); - self.next_barrier_id = self - .next_barrier_id - .checked_add(1) - .expect("barrier id exhausted"); - self.active_barrier = Some(ActiveControllerBarrier { - id, - operation: ControllerBarrierOperation::PersistenceFailureRecovery, - phase: ControllerBarrierPhase::Inspecting, - }); - id - } + let barrier = if let Some(barrier) = self.active_barrier.as_ref() { + barrier.id + } else { + let id = ControllerBarrierId(self.next_barrier_id); + self.next_barrier_id = self + .next_barrier_id + .checked_add(1) + .expect("barrier id exhausted"); + self.active_barrier = Some(ActiveControllerBarrier { + id, + operation: ControllerBarrierOperation::PersistenceFailureRecovery, + phase: ControllerBarrierPhase::Inspecting, + }); + id }; let id = PersistenceIncidentId( allocate_counter(&mut self.next_incident_id).expect("incident id exhausted"), diff --git a/src/runtime_ui_state/seeds.rs b/src/runtime_ui_state/seeds.rs index 109efece0..dbd17d521 100644 --- a/src/runtime_ui_state/seeds.rs +++ b/src/runtime_ui_state/seeds.rs @@ -102,9 +102,8 @@ impl StagedSeedReload { current: &InteractionSeedRegistry, seeds: &ValidatedInteractionSeeds, ) -> Result { - let mut registry = previous - .map(|staged| staged.registry.clone()) - .unwrap_or_else(|| current.clone()); + let mut registry = + previous.map_or_else(|| current.clone(), |staged| staged.registry.clone()); let mut changed_targets = previous .map(|staged| staged.changed_targets.clone()) .unwrap_or_default(); diff --git a/src/runtime_ui_state/store/fs.rs b/src/runtime_ui_state/store/fs.rs index 5a2fad089..ff9749cc7 100644 --- a/src/runtime_ui_state/store/fs.rs +++ b/src/runtime_ui_state/store/fs.rs @@ -72,8 +72,7 @@ impl PinnedParent { fn current_path(&self) -> io::Result { if fs::metadata(&self.inner.observed_path) - .ok() - .is_some_and(|metadata| file_identity(&metadata) == self.inner.identity) + .is_ok_and(|metadata| file_identity(&metadata) == self.inner.identity) { return Ok(self.inner.observed_path.clone()); } @@ -81,8 +80,7 @@ impl PinnedParent { let proc_path = PathBuf::from(format!("/proc/self/fd/{}", self.fd())); let current = fs::read_link(proc_path)?; if !fs::metadata(¤t) - .ok() - .is_some_and(|metadata| file_identity(&metadata) == self.inner.identity) + .is_ok_and(|metadata| file_identity(&metadata) == self.inner.identity) { return Err(io::Error::new( io::ErrorKind::NotFound, diff --git a/src/runtime_ui_state/store/inspection.rs b/src/runtime_ui_state/store/inspection.rs index b98e912f2..fa5f5b08f 100644 --- a/src/runtime_ui_state/store/inspection.rs +++ b/src/runtime_ui_state/store/inspection.rs @@ -44,16 +44,14 @@ pub(super) fn inspect_path( } if before.len() > MAX_RUNTIME_UI_FILE_BYTES { return Err(RuntimeStateInspectionError::new(format!( - "runtime-state file exceeds the {} byte limit", - MAX_RUNTIME_UI_FILE_BYTES + "runtime-state file exceeds the {MAX_RUNTIME_UI_FILE_BYTES} byte limit" ))); } let bytes = read_bounded(&resolved_path, &mut file)?; if bytes.len() as u64 > MAX_RUNTIME_UI_FILE_BYTES { return Err(RuntimeStateInspectionError::new(format!( - "runtime-state file exceeds the {} byte limit", - MAX_RUNTIME_UI_FILE_BYTES + "runtime-state file exceeds the {MAX_RUNTIME_UI_FILE_BYTES} byte limit" ))); } file.seek(SeekFrom::Start(0)) @@ -128,8 +126,7 @@ pub(super) fn inspect_pinned( } if before.len() > MAX_RUNTIME_UI_FILE_BYTES { return Err(RuntimeStateInspectionError::new(format!( - "runtime-state file exceeds the {} byte limit", - MAX_RUNTIME_UI_FILE_BYTES + "runtime-state file exceeds the {MAX_RUNTIME_UI_FILE_BYTES} byte limit" ))); } @@ -291,8 +288,7 @@ fn read_bounded(path: &Path, file: &mut File) -> Result, RuntimeStateIns .map_err(|error| inspection_error(path, &error))?; if bytes.len() as u64 > MAX_RUNTIME_UI_FILE_BYTES { return Err(RuntimeStateInspectionError::new(format!( - "runtime-state file exceeds the {} byte limit", - MAX_RUNTIME_UI_FILE_BYTES + "runtime-state file exceeds the {MAX_RUNTIME_UI_FILE_BYTES} byte limit" ))); } Ok(bytes) diff --git a/src/runtime_ui_state/store/tests.rs b/src/runtime_ui_state/store/tests.rs index fc2c5ae29..3bde53fb2 100644 --- a/src/runtime_ui_state/store/tests.rs +++ b/src/runtime_ui_state/store/tests.rs @@ -575,12 +575,12 @@ fn stale_board_ids_are_pruned_by_startup_cleanup() { let path = temp.path().join("runtime-ui.toml"); fs::write( &path, - br#"version = 1 + br"version = 1 [boards.pinned.stale-board] seed = false value = true -"#, +", ) .unwrap(); let store = RuntimeUiStateStore::new(&path); diff --git a/src/runtime_ui_state/wire/tests.rs b/src/runtime_ui_state/wire/tests.rs index ccdd4154f..47d5bd191 100644 --- a/src/runtime_ui_state/wire/tests.rs +++ b/src/runtime_ui_state/wire/tests.rs @@ -63,13 +63,13 @@ future_boards = "kept" #[test] fn a_preserved_key_this_build_now_manages_loses_to_the_managed_value() { let decoded = decode_runtime_ui_file( - br#" + br" version = 1 [toolbar.top_pinned] seed = false value = true -"#, +", ); let mut wire = decoded.supported_wire.expect("supported wire"); @@ -218,12 +218,12 @@ fn a_file_without_the_added_toolbar_keys_still_decodes() { // The new keys are optional additions to V1, so a file written before // they existed stays supported and writable. let decoded = decode_runtime_ui_file( - br#"version = 1 + br"version = 1 [toolbar.top_pinned] seed = false value = true -"#, +", ); assert_eq!(decoded.status, RuntimeUiFileStatus::Supported); let wire = decoded.supported_wire.expect("supported wire"); @@ -268,23 +268,23 @@ future_scalar = 7 fn malformed_position_and_display_mode_values_invalidate_the_file() { for source in [ // Non-finite offsets cannot be compared bit-exactly against a seed. - br#"version = 1 + br"version = 1 [toolbar.top_position] seed = { x = 0.0, y = 0.0 } value = { x = nan, y = 1.0 } -"# +" .as_slice(), - br#"version = 1 + br"version = 1 [toolbar.top_position] seed = { x = 0.0, y = 0.0 } value = { x = 1.0 } -"# +" .as_slice(), - br#"version = 1 + br"version = 1 [toolbar.top_position] seed = { x = 0.0, y = 0.0 } value = { x = 1.0, y = 2.0, z = 3.0 } -"# +" .as_slice(), br#"version = 1 [toolbar.top_position] diff --git a/src/runtime_ui_state/wire/v1.rs b/src/runtime_ui_state/wire/v1.rs index f4102fc20..5d4027702 100644 --- a/src/runtime_ui_state/wire/v1.rs +++ b/src/runtime_ui_state/wire/v1.rs @@ -338,81 +338,81 @@ pub(super) fn encode(wire: &RuntimeUiWireState) -> Result { - insert_recognized(&mut toolbar, "top_pinned", entry) + insert_recognized(&mut toolbar, "top_pinned", entry); } InteractionSeedTarget::TopMinimized => { - insert_recognized(&mut toolbar, "top_minimized", entry) + insert_recognized(&mut toolbar, "top_minimized", entry); } InteractionSeedTarget::ItemVisibility(item) => { - insert_recognized(&mut visibility, item.as_str(), entry) + insert_recognized(&mut visibility, item.as_str(), entry); } InteractionSeedTarget::ItemOrder(group) => { - insert_recognized(&mut order, order_group_wire_id(*group), entry) + insert_recognized(&mut order, order_group_wire_id(*group), entry); } InteractionSeedTarget::BoardPin(id) => insert_recognized(&mut boards_pinned, id, entry), InteractionSeedTarget::TopPosition => { - insert_recognized(&mut toolbar, "top_position", entry) + insert_recognized(&mut toolbar, "top_position", entry); } InteractionSeedTarget::ToolbarLayoutMode => { - insert_recognized(&mut toolbar, "layout_mode", entry) + insert_recognized(&mut toolbar, "layout_mode", entry); } InteractionSeedTarget::TopDisplayMode => { - insert_recognized(&mut toolbar, "top_display_mode", entry) + insert_recognized(&mut toolbar, "top_display_mode", entry); } InteractionSeedTarget::StatusBarInteractive => { - insert_recognized(&mut toolbar, "status_bar_interactive", entry) + insert_recognized(&mut toolbar, "status_bar_interactive", entry); } InteractionSeedTarget::StatusBarItem(item) => { - insert_recognized(&mut status_bar_items, item.config_id(), entry) + insert_recognized(&mut status_bar_items, item.config_id(), entry); } InteractionSeedTarget::SectionVisibility(flag) => { - insert_recognized(&mut sections, flag.item_id().as_str(), entry) + insert_recognized(&mut sections, flag.item_id().as_str(), entry); } InteractionSeedTarget::StatusBar => { - insert_recognized(&mut toolbar, "status_bar", entry) + insert_recognized(&mut toolbar, "status_bar", entry); } InteractionSeedTarget::StatusBoardBadge => { - insert_recognized(&mut toolbar, "status_board_badge", entry) + insert_recognized(&mut toolbar, "status_board_badge", entry); } InteractionSeedTarget::StatusPageBadge => { - insert_recognized(&mut toolbar, "status_page_badge", entry) + insert_recognized(&mut toolbar, "status_page_badge", entry); } InteractionSeedTarget::FloatingBadgeAlways => { - insert_recognized(&mut toolbar, "floating_badge_always", entry) + insert_recognized(&mut toolbar, "floating_badge_always", entry); } InteractionSeedTarget::ToolbarIcons => { - insert_recognized(&mut toolbar, "use_icons", entry) + insert_recognized(&mut toolbar, "use_icons", entry); } InteractionSeedTarget::ToolbarMoreColors => { - insert_recognized(&mut toolbar, "show_more_colors", entry) + insert_recognized(&mut toolbar, "show_more_colors", entry); } InteractionSeedTarget::ToolbarContextAwareUi => { - insert_recognized(&mut toolbar, "context_aware_ui", entry) + insert_recognized(&mut toolbar, "context_aware_ui", entry); } InteractionSeedTarget::ToolbarPresetToasts => { - insert_recognized(&mut toolbar, "show_preset_toasts", entry) + insert_recognized(&mut toolbar, "show_preset_toasts", entry); } InteractionSeedTarget::ToolbarIdleFade => { - insert_recognized(&mut toolbar, "idle_fade", entry) + insert_recognized(&mut toolbar, "idle_fade", entry); } InteractionSeedTarget::ToolbarToolPreview => { - insert_recognized(&mut toolbar, "show_tool_preview", entry) + insert_recognized(&mut toolbar, "show_tool_preview", entry); } InteractionSeedTarget::ToolbarDelaySliders => { - insert_recognized(&mut toolbar, "show_delay_sliders", entry) + insert_recognized(&mut toolbar, "show_delay_sliders", entry); } InteractionSeedTarget::HistoryCustomSection => { - insert_recognized(&mut toolbar, "history_custom_section", entry) + insert_recognized(&mut toolbar, "history_custom_section", entry); } InteractionSeedTarget::InputHud => insert_recognized(&mut toolbar, "input_hud", entry), InteractionSeedTarget::ClickHighlight => { - insert_recognized(&mut toolbar, "click_highlight", entry) + insert_recognized(&mut toolbar, "click_highlight", entry); } InteractionSeedTarget::ClickHighlightToolRing => { - insert_recognized(&mut toolbar, "click_highlight_tool_ring", entry) + insert_recognized(&mut toolbar, "click_highlight_tool_ring", entry); } InteractionSeedTarget::FloatingBadge => { - insert_recognized(&mut toolbar, "floating_badge", entry) + insert_recognized(&mut toolbar, "floating_badge", entry); } InteractionSeedTarget::ZoomChip => insert_recognized(&mut toolbar, "zoom_chip", entry), } diff --git a/src/session/catalog.rs b/src/session/catalog.rs index 527349036..0b0d685c1 100644 --- a/src/session/catalog.rs +++ b/src/session/catalog.rs @@ -233,9 +233,10 @@ impl CatalogFile { let mut entry = CatalogEntry { id: generated_catalog_id(now), - display_name: display_name - .map(str::to_string) - .unwrap_or_else(|| display_name_for_path(&identity.exact_path)), + display_name: display_name.map_or_else( + || display_name_for_path(&identity.exact_path), + str::to_string, + ), path: path_to_string(&identity.exact_path)?, canonical_path: optional_path_to_string(identity.canonical_path.as_deref())?, created_at_millis: now, @@ -444,8 +445,7 @@ fn generated_catalog_id(now: u64) -> String { fn now_epoch_millis() -> u64 { let millis = SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|duration| duration.as_millis()) - .unwrap_or(0); + .map_or(0, |duration| duration.as_millis()); u64::try_from(millis).unwrap_or(u64::MAX) } diff --git a/src/session/options/identifiers.rs b/src/session/options/identifiers.rs index 97f6a89fb..ba2cea367 100644 --- a/src/session/options/identifiers.rs +++ b/src/session/options/identifiers.rs @@ -17,14 +17,11 @@ pub(super) fn resolve_display_id(display_id: Option<&str>) -> String { return sanitize_identifier(id); } - match env::var(WAYLAND_DISPLAY_ENV) { - Ok(value) => { - log::info!("Session display id from {WAYLAND_DISPLAY_ENV}='{}'", value); - sanitize_identifier(&value) - } - Err(_) => { - log::info!("Session display id fallback to 'default' ({WAYLAND_DISPLAY_ENV} missing)"); - "default".to_string() - } + if let Ok(value) = env::var(WAYLAND_DISPLAY_ENV) { + log::info!("Session display id from {WAYLAND_DISPLAY_ENV}='{value}'"); + sanitize_identifier(&value) + } else { + log::info!("Session display id fallback to 'default' ({WAYLAND_DISPLAY_ENV} missing)"); + "default".to_string() } } diff --git a/src/session/options/types.rs b/src/session/options/types.rs index c3246d227..cf00b1e23 100644 --- a/src/session/options/types.rs +++ b/src/session/options/types.rs @@ -230,8 +230,7 @@ impl SessionOptions { pub(crate) fn session_file_parent_dir(path: &Path) -> PathBuf { path.parent() .filter(|parent| !parent.as_os_str().is_empty()) - .map(Path::to_path_buf) - .unwrap_or_else(|| PathBuf::from(".")) + .map_or_else(|| PathBuf::from("."), Path::to_path_buf) } pub(crate) fn append_path_suffix(path: &Path, suffix: &str) -> PathBuf { diff --git a/src/session/snapshot/compat_tests.rs b/src/session/snapshot/compat_tests.rs index 359f0416d..0847c4d99 100644 --- a/src/session/snapshot/compat_tests.rs +++ b/src/session/snapshot/compat_tests.rs @@ -2,7 +2,7 @@ //! Sources: tag v0.9.25 and commit a2bb723a. The generator below was added to //! each archive as an integration test and run alone with //! `cargo test --locked --no-default-features -- --ignored --exact --test-threads=1`. -//! COMPAT_FIXTURE_OUT selected an empty output directory. The v0.9.25 generator omits +//! `COMPAT_FIXTURE_OUT` selected an empty output directory. The v0.9.25 generator omits //! BoardSnapshot.appearance because that revision does not have the field. //! //! Historical fixture generator: diff --git a/src/session/snapshot/compression.rs b/src/session/snapshot/compression.rs index 353adf07c..413603fa9 100644 --- a/src/session/snapshot/compression.rs +++ b/src/session/snapshot/compression.rs @@ -72,7 +72,7 @@ pub(super) fn temp_path(target: &Path) -> Result { let mut counter = 0u32; while candidate.exists() { counter += 1; - candidate = target.with_extension(format!("json.tmp{}", counter)); + candidate = target.with_extension(format!("json.tmp{counter}")); } Ok(candidate) } diff --git a/src/session/snapshot/generation/probe.rs b/src/session/snapshot/generation/probe.rs index cae083273..de77f4979 100644 --- a/src/session/snapshot/generation/probe.rs +++ b/src/session/snapshot/generation/probe.rs @@ -71,9 +71,8 @@ fn scan_header(bytes: &[u8]) -> Option { if cursor.peek() == Some(b'}') { return found; } - let key = match cursor.string(MAX_KEY_BYTES, true) { - Some(key) => key, - None => return found, + let Some(key) = cursor.string(MAX_KEY_BYTES, true) else { + return found; }; if cursor.expect(b':').is_none() { return found; diff --git a/src/session/snapshot/load/payload.rs b/src/session/snapshot/load/payload.rs index ea945ff02..914cfa957 100644 --- a/src/session/snapshot/load/payload.rs +++ b/src/session/snapshot/load/payload.rs @@ -77,8 +77,7 @@ pub(super) fn load_snapshot_opened_with_expanded_limit( let max_depth = max_history_depth(&value); if max_depth > MAX_COMPOUND_DEPTH { warn!( - "Session history depth {} exceeds limit {}; dropping history", - max_depth, MAX_COMPOUND_DEPTH + "Session history depth {max_depth} exceeds limit {MAX_COMPOUND_DEPTH}; dropping history" ); strip_history_fields(&mut value); } @@ -88,10 +87,7 @@ pub(super) fn load_snapshot_opened_with_expanded_limit( let session_file: SessionFile = match serde_json::from_value(value) { Ok(file) => file, Err(err) => { - warn!( - "Failed to deserialize session ({}); retrying without history", - err - ); + warn!("Failed to deserialize session ({err}); retrying without history"); let mut stripped: Value = serde_json::from_slice(&decompressed).context("failed to parse session json")?; strip_history_fields(&mut stripped); @@ -280,8 +276,7 @@ fn resolved_active_board_id(requested: Option, boards: &[BoardSnapshot]) requested } else { warn!( - "Session active board '{}' missing from restored boards; falling back to '{}'", - requested, fallback_id + "Session active board '{requested}' missing from restored boards; falling back to '{fallback_id}'" ); fallback_id } diff --git a/src/session/snapshot/save/payload.rs b/src/session/snapshot/save/payload.rs index 54543e9ee..0a19ebc00 100644 --- a/src/session/snapshot/save/payload.rs +++ b/src/session/snapshot/save/payload.rs @@ -263,8 +263,7 @@ fn fitting_history_payload( let max_depth = max_depth.min(history_depth); if max_depth < 2 { debug!( - "Autosave history fallback capped at depth {}; skipping deeper history-depth scan", - max_depth + "Autosave history fallback capped at depth {max_depth}; skipping deeper history-depth scan" ); return Ok(None); } @@ -430,8 +429,9 @@ pub(super) fn is_near_limit(written_size: u64, max_file_size_bytes: u64) -> bool if written_size == 0 { return false; } - let threshold = ((max_file_size_bytes as u128) * (NEAR_LIMIT_PERCENT as u128)).div_ceil(100); - (written_size as u128) >= threshold + let threshold = + (u128::from(max_file_size_bytes) * u128::from(NEAR_LIMIT_PERCENT)).div_ceil(100); + u128::from(written_size) >= threshold } fn max_history_depth(snapshot: &SessionSnapshot) -> usize { diff --git a/src/session/snapshot/tests.rs b/src/session/snapshot/tests.rs index 8db4898f7..b75ceed5c 100644 --- a/src/session/snapshot/tests.rs +++ b/src/session/snapshot/tests.rs @@ -750,9 +750,8 @@ fn load_snapshot_inner_rejects_fifo_without_opening_it() { let mut options = SessionOptions::new(temp.path().to_path_buf(), "fifo"); options.persist_transparent = true; - let err = match load_snapshot_inner(&path, &options) { - Ok(_) => panic!("FIFO session artifact should be rejected before open/read"), - Err(err) => err, + let Err(err) = load_snapshot_inner(&path, &options) else { + panic!("FIFO session artifact should be rejected before open/read"); }; assert!( err.to_string().contains("not a regular file"), @@ -773,9 +772,8 @@ fn load_named_primary_rejects_symlink_without_following_target() { options.persist_transparent = true; options.set_named_file_target(link.clone()); - let err = match load_snapshot_inner(&link, &options) { - Ok(_) => panic!("symlink primary should reject"), - Err(err) => err, + let Err(err) = load_snapshot_inner(&link, &options) else { + panic!("symlink primary should reject"); }; assert!( diff --git a/src/session/storage/inspect.rs b/src/session/storage/inspect.rs index 6034ae07e..a73822e5f 100644 --- a/src/session/storage/inspect.rs +++ b/src/session/storage/inspect.rs @@ -237,9 +237,9 @@ fn history_depth_from_pages(pages: Option<&BoardPagesSnapshot>) -> HistoryDepth } fn page_shape_count(pages: Option<&BoardPagesSnapshot>) -> usize { - pages - .map(|pages| pages.pages.iter().map(|page| page.shapes.len()).sum()) - .unwrap_or(0) + pages.map_or(0, |pages| { + pages.pages.iter().map(|page| page.shapes.len()).sum() + }) } fn find_existing_variant( diff --git a/src/session/tests/limits.rs b/src/session/tests/limits.rs index 864300ea4..74b4ae642 100644 --- a/src/session/tests/limits.rs +++ b/src/session/tests/limits.rs @@ -710,7 +710,7 @@ fn save_snapshot_keeps_depth_one_when_visible_payload_is_near_limit() { .len(); assert!( - (visible_size as u128) * 100 >= (depth_one_size as u128) * 90, + u128::from(visible_size) * 100 >= u128::from(depth_one_size) * 90, "visible-only payload should be near the depth-one cap for this regression" ); assert!( diff --git a/src/systemd_user_service.rs b/src/systemd_user_service.rs index f677f66c0..d5b0af63c 100644 --- a/src/systemd_user_service.rs +++ b/src/systemd_user_service.rs @@ -92,8 +92,7 @@ pub fn render_user_service_unit(binary_path: &Path) -> String { let quoted_exec = quote_systemd_exec(binary_path); let binary_dir = binary_path .parent() - .map(|path| path.display().to_string()) - .unwrap_or_else(|| "/usr/bin".to_string()); + .map_or_else(|| "/usr/bin".to_string(), |path| path.display().to_string()); // Prepended so an install outside the system directories still finds its // own helpers first, and skipped when it is already one of them rather // than emitting the directory twice. @@ -107,8 +106,7 @@ pub fn render_user_service_unit(binary_path: &Path) -> String { }; let escaped_path_env = escape_systemd_env_value(&service_path); format!( - "[Unit]\nDescription=Wayscriber - Screen annotation tool for Wayland\nDocumentation=https://wayscriber.com\nPartOf=graphical-session.target\nAfter=graphical-session.target\n\n[Service]\nType=simple\nExecStartPre=/bin/sh -c '[ -n \"${WAYLAND_DISPLAY_ENV}\" ] && [ -S \"${XDG_RUNTIME_DIR_ENV}/${WAYLAND_DISPLAY_ENV}\" ]'\nExecStart={} --daemon\nRestart=on-failure\nRestartSec=5\nRestartPreventExitStatus=75\nSuccessExitStatus=75\nEnvironment=\"{PATH_ENV}={}\"\n\n[Install]\nWantedBy=graphical-session.target\n", - quoted_exec, escaped_path_env + "[Unit]\nDescription=Wayscriber - Screen annotation tool for Wayland\nDocumentation=https://wayscriber.com\nPartOf=graphical-session.target\nAfter=graphical-session.target\n\n[Service]\nType=simple\nExecStartPre=/bin/sh -c '[ -n \"${WAYLAND_DISPLAY_ENV}\" ] && [ -S \"${XDG_RUNTIME_DIR_ENV}/${WAYLAND_DISPLAY_ENV}\" ]'\nExecStart={quoted_exec} --daemon\nRestart=on-failure\nRestartSec=5\nRestartPreventExitStatus=75\nSuccessExitStatus=75\nEnvironment=\"{PATH_ENV}={escaped_path_env}\"\n\n[Install]\nWantedBy=graphical-session.target\n" ) } diff --git a/src/time_utils.rs b/src/time_utils.rs index 2644e4da0..26d244ae4 100644 --- a/src/time_utils.rs +++ b/src/time_utils.rs @@ -75,8 +75,7 @@ pub fn format_unix_millis(ms: u64, template: &str) -> Option { pub fn now_rfc3339() -> String { system_time_to_unix_seconds(SystemTime::now()) .and_then(utc_datetime_from_unix) - .map(format_rfc3339_utc) - .unwrap_or_else(|| "1970-01-01T00:00:00Z".to_string()) + .map_or_else(|| "1970-01-01T00:00:00Z".to_string(), format_rfc3339_utc) } fn push_padded_u8(out: &mut String, value: u8) { @@ -163,9 +162,9 @@ fn libc_datetime_from_unix(secs: i64, local: bool) -> Option { // one `tm`. The reentrant variants keep no pointer to either. let ptr = unsafe { if local { - libc::localtime_r(&raw, out.as_mut_ptr()) + libc::localtime_r(&raw const raw, out.as_mut_ptr()) } else { - libc::gmtime_r(&raw, out.as_mut_ptr()) + libc::gmtime_r(&raw const raw, out.as_mut_ptr()) } }; if ptr.is_null() { diff --git a/src/toolbar_gtk/bridge.rs b/src/toolbar_gtk/bridge.rs index cc88118f4..abe214f9f 100644 --- a/src/toolbar_gtk/bridge.rs +++ b/src/toolbar_gtk/bridge.rs @@ -182,30 +182,29 @@ impl FeedbackPublisher { break; } } - match replacement { - Some(index) => state.queue[index] = feedback, - None => { - // A boundary may have consumed a slot by reclaiming a - // move from an older segment. Reclaim another move and - // append this one after the boundary instead of moving - // it across ordered feedback or failing the bridge. - let reclaim = state - .queue - .iter() - .position(|queued| queued.move_kind() == Some(kind)) - .or_else(|| { - state - .queue - .iter() - .position(|queued| queued.move_kind().is_some()) - }); - if let Some(index) = reclaim { - state.queue.remove(index); - state.queue.push_back(feedback); - } else { - state.accepting = false; - overflowed = true; - } + if let Some(index) = replacement { + state.queue[index] = feedback; + } else { + // A boundary may have consumed a slot by reclaiming a + // move from an older segment. Reclaim another move and + // append this one after the boundary instead of moving + // it across ordered feedback or failing the bridge. + let reclaim = state + .queue + .iter() + .position(|queued| queued.move_kind() == Some(kind)) + .or_else(|| { + state + .queue + .iter() + .position(|queued| queued.move_kind().is_some()) + }); + if let Some(index) = reclaim { + state.queue.remove(index); + state.queue.push_back(feedback); + } else { + state.accepting = false; + overflowed = true; } } } else { @@ -516,8 +515,7 @@ impl Drop for GtkToolbarBridge { } ThreadShutdownOutcome::TimedOut => { log::warn!( - "GTK toolbar thread did not stop within {:?}; detaching it and leaving it running until process exit", - GTK_THREAD_SHUTDOWN_TIMEOUT + "GTK toolbar thread did not stop within {GTK_THREAD_SHUTDOWN_TIMEOUT:?}; detaching it and leaving it running until process exit" ); } } @@ -578,7 +576,7 @@ mod tests { revents: 0, }; // SAFETY: pollfd and the source descriptor are valid for this non-blocking poll. - let ready = unsafe { libc::poll(&mut pollfd, 1, 0) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 0) }; assert!(ready >= 0); ready > 0 && pollfd.revents & libc::POLLIN != 0 } @@ -825,7 +823,7 @@ mod tests { revents: 0, }; // SAFETY: pollfd and the source descriptor remain valid for the bounded wait. - let ready = unsafe { libc::poll(&mut pollfd, 1, 1_000) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 1_000) }; assert_eq!(ready, 1); assert_ne!(pollfd.revents & libc::POLLIN, 0); }); diff --git a/src/toolbar_gtk/css.rs b/src/toolbar_gtk/css.rs index caafd7d2a..111df3708 100644 --- a/src/toolbar_gtk/css.rs +++ b/src/toolbar_gtk/css.rs @@ -431,7 +431,7 @@ tooltip {{ pub(super) fn capture_stylesheet(scale: f64) -> String { let v = GtkStylesheetValues::new(scale); format!( - r#" + r" .wayscriber-toolbar popover > contents {{ box-shadow: 0 {shadow_offset_y}px {shadow_blur}px {popover_shadow}; }} @@ -485,7 +485,7 @@ popover.{class} > contents {{ tooltip.{class} {{ color: transparent; }} -"#, +", class = CAPTURE_TRANSPARENT_CLASS, shadow_offset_y = v.shadow_offset_y, shadow_blur = v.shadow_blur, diff --git a/src/toolbar_gtk/icons.rs b/src/toolbar_gtk/icons.rs index 77a49f5df..83bc85ae4 100644 --- a/src/toolbar_gtk/icons.rs +++ b/src/toolbar_gtk/icons.rs @@ -39,14 +39,14 @@ impl IconWidget { area.set_draw_func(move |area, ctx, width, height| { let color = area.color(); ctx.set_source_rgba( - color.red() as f64, - color.green() as f64, - color.blue() as f64, - color.alpha() as f64, + f64::from(color.red()), + f64::from(color.green()), + f64::from(color.blue()), + f64::from(color.alpha()), ); - let size = (width.min(height) as f64).max(1.0); - let x = (width as f64 - size) / 2.0; - let y = (height as f64 - size) / 2.0; + let size = f64::from(width.min(height)).max(1.0); + let x = (f64::from(width) - size) / 2.0; + let y = (f64::from(height) - size) / 2.0; (draw_cell.get())(ctx, x, y, size); }); Self { diff --git a/src/toolbar_gtk/runtime.rs b/src/toolbar_gtk/runtime.rs index 87bff301f..05bea772a 100644 --- a/src/toolbar_gtk/runtime.rs +++ b/src/toolbar_gtk/runtime.rs @@ -146,7 +146,7 @@ mod tests { revents: 0, }; // SAFETY: pollfd and the source descriptor are valid for this non-blocking poll. - let ready = unsafe { libc::poll(&mut pollfd, 1, 0) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 0) }; assert_eq!(ready, 1); assert!(health.failed()); assert_ne!(pollfd.revents & libc::POLLIN, 0); @@ -168,7 +168,7 @@ mod tests { revents: 0, }; // SAFETY: pollfd and the source descriptor are valid for this non-blocking poll. - assert_eq!(unsafe { libc::poll(&mut pollfd, 1, 0) }, 0); + assert_eq!(unsafe { libc::poll(&raw mut pollfd, 1, 0) }, 0); } #[test] diff --git a/src/toolbar_gtk/view/capture_suppression.rs b/src/toolbar_gtk/view/capture_suppression.rs index 60f65709e..507b2defb 100644 --- a/src/toolbar_gtk/view/capture_suppression.rs +++ b/src/toolbar_gtk/view/capture_suppression.rs @@ -176,11 +176,11 @@ impl TooltipCapture { self.sync_native_chrome(); self.inner.native_popovers.set_suppressed(suppressed); - if !suppressed { + if suppressed { + self.set_input_enabled(false); + } else { self.set_input_enabled(true); self.inner.mapped_before_capture.set(false); - } else { - self.set_input_enabled(false); } } diff --git a/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy.rs b/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy.rs index d01ce5897..de7a528a5 100644 --- a/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy.rs +++ b/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy.rs @@ -1,6 +1,6 @@ //! Runs one GTK test behind a private headless Weston with one frame event withheld. //! -//! All protocol messages and SCM_RIGHTS descriptors pass through unchanged, except +//! All protocol messages and `SCM_RIGHTS` descriptors pass through unchanged, except //! the selected popup callback and its `delete_id` event. The protocol tables //! compiled into `wayland-client` and `wayland-protocols` provide opcodes and //! new-object types; this fixture neither renders nor invents feedback. diff --git a/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/protocol.rs b/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/protocol.rs index 3c6410406..2753c688f 100644 --- a/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/protocol.rs +++ b/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/protocol.rs @@ -55,7 +55,7 @@ pub(super) fn schema() -> Schema { XdgWmBase::interface(), ]; while let Some(interface) = pending.pop() { - if ptr::eq(interface, &ANONYMOUS_INTERFACE) + if ptr::eq(interface, &raw const ANONYMOUS_INTERFACE) || schema.insert(interface.name, interface).is_some() { continue; diff --git a/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/wire.rs b/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/wire.rs index ac2460838..52087c2b2 100644 --- a/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/wire.rs +++ b/src/toolbar_gtk/view/capture_suppression/tests/wayland_proxy/wire.rs @@ -79,7 +79,7 @@ fn receive_chunk( }; // SAFETY: zero is a valid initial state for msghdr. let mut message: libc::msghdr = unsafe { mem::zeroed() }; - message.msg_iov = &mut iovec; + message.msg_iov = &raw mut iovec; message.msg_iovlen = 1; message.msg_control = control.as_mut_ptr().cast(); message.msg_controllen = RECEIVE_CONTROL_LEN; @@ -87,7 +87,7 @@ fn receive_chunk( let read = loop { // SAFETY: message references the live, writable data and control buffers. let read = - unsafe { libc::recvmsg(socket.as_raw_fd(), &mut message, libc::MSG_CMSG_CLOEXEC) }; + unsafe { libc::recvmsg(socket.as_raw_fd(), &raw mut message, libc::MSG_CMSG_CLOEXEC) }; if read >= 0 { break read as usize; } @@ -164,7 +164,7 @@ fn send_chunk(socket: &UnixStream, bytes: &[u8], descriptors: &[OwnedFd]) -> Res }; // SAFETY: zero is a valid initial state for msghdr. let mut message: libc::msghdr = unsafe { mem::zeroed() }; - message.msg_iov = &mut iovec; + message.msg_iov = &raw mut iovec; message.msg_iovlen = 1; if !raw.is_empty() { @@ -172,7 +172,7 @@ fn send_chunk(socket: &UnixStream, bytes: &[u8], descriptors: &[OwnedFd]) -> Res message.msg_controllen = control_len; // SAFETY: the control buffer holds CMSG_SPACE bytes for these descriptors. unsafe { - let header = libc::CMSG_FIRSTHDR(&message); + let header = libc::CMSG_FIRSTHDR(&raw const message); (*header).cmsg_level = libc::SOL_SOCKET; (*header).cmsg_type = libc::SCM_RIGHTS; (*header).cmsg_len = libc::CMSG_LEN(size_of_val(raw.as_slice()) as u32) as usize; @@ -186,7 +186,8 @@ fn send_chunk(socket: &UnixStream, bytes: &[u8], descriptors: &[OwnedFd]) -> Res loop { // SAFETY: message references the live data and control buffers. - let sent = unsafe { libc::sendmsg(socket.as_raw_fd(), &message, libc::MSG_NOSIGNAL) }; + let sent = + unsafe { libc::sendmsg(socket.as_raw_fd(), &raw const message, libc::MSG_NOSIGNAL) }; if sent > 0 { return Ok(sent as usize); } diff --git a/src/toolbar_gtk/view/drag.rs b/src/toolbar_gtk/view/drag.rs index 0929826fe..fffba3f30 100644 --- a/src/toolbar_gtk/view/drag.rs +++ b/src/toolbar_gtk/view/drag.rs @@ -95,7 +95,7 @@ pub(super) fn drag_frame_position(origin: (f64, f64), delta: (f64, f64)) -> (f64 /// that margin. pub(super) fn rounded_margin_and_offset(base: f64, offset: f64) -> (i32, f64) { let margin = (base + offset).round() as i32; - (margin, margin as f64 - base) + (margin, f64::from(margin) - base) } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -191,15 +191,15 @@ pub(super) fn clamp_drag_offsets( let geometry = monitor.geometry(); let (x, _, _) = wayland::clamp_floating_axis_offset( x, - geometry.width() as f64, - window.width() as f64, + f64::from(geometry.width()), + f64::from(window.width()), base_x, end_x, ); let (y, _, _) = wayland::clamp_floating_axis_offset( y, - geometry.height() as f64, - window.height() as f64, + f64::from(geometry.height()), + f64::from(window.height()), base_y, end_y, ); diff --git a/src/toolbar_gtk/view/sections/canvas_pane.rs b/src/toolbar_gtk/view/sections/canvas_pane.rs index cb3f3b8a6..33eb82889 100644 --- a/src/toolbar_gtk/view/sections/canvas_pane.rs +++ b/src/toolbar_gtk/view/sections/canvas_pane.rs @@ -27,7 +27,7 @@ const DESTRUCTIVE_GUARD_GAP: f64 = 12.0; /// popover's `MENU_PAD` around the shared Canvas content area. const CANVAS_CONTENT_PAD_H: f64 = 10.0; -pub(in crate::toolbar_gtk) fn build_popover_content(ctx: &mut SectionCtx) -> gtk4::Box { +pub(in crate::toolbar_gtk) fn build_popover_content(ctx: &mut SectionCtx<'_>) -> gtk4::Box { let column = gtk4::Box::new(gtk4::Orientation::Vertical, ctx.px(10.0)); let pad_h = ctx.px(CANVAS_CONTENT_PAD_H); column.set_margin_start(pad_h); @@ -71,7 +71,7 @@ pub(in crate::toolbar_gtk) fn build_popover_content(ctx: &mut SectionCtx) -> gtk } /// A bold section header, styled like the collapsible cards' titles. -fn section_title(ctx: &SectionCtx, title: &str) -> gtk4::Label { +fn section_title(ctx: &SectionCtx<'_>, title: &str) -> gtk4::Label { let label = gtk4::Label::new(Some(title)); label.add_css_class("section-title"); label.set_xalign(0.0); @@ -84,7 +84,7 @@ fn section_title(ctx: &SectionCtx, title: &str) -> gtk4::Label { /// gap. Enabled/glyph state is baked in at build time (the popover host /// rebuilds on the inputs that change them). fn command_section( - ctx: &SectionCtx, + ctx: &SectionCtx<'_>, column: >k4::Box, title: &str, noun: &'static str, diff --git a/src/toolbar_gtk/view/sections/session_pane.rs b/src/toolbar_gtk/view/sections/session_pane.rs index ec50b21a6..a9e58d89e 100644 --- a/src/toolbar_gtk/view/sections/session_pane.rs +++ b/src/toolbar_gtk/view/sections/session_pane.rs @@ -19,7 +19,7 @@ use super::SectionCtx; /// The pane's content for the top strip's Session popover. Live updates come /// from content-key rebuilds in the popover host, so no updaters register. pub(in crate::toolbar_gtk) fn build_popover_content( - ctx: &SectionCtx, + ctx: &SectionCtx<'_>, session: &model::ToolbarSessionModel, ) -> gtk4::Box { let column = gtk4::Box::new(gtk4::Orientation::Vertical, ctx.px(6.0)); @@ -66,7 +66,10 @@ pub(in crate::toolbar_gtk) fn build_popover_content( column } -fn session_button(ctx: &SectionCtx, button_model: &model::ToolbarSessionButton) -> gtk4::Button { +fn session_button( + ctx: &SectionCtx<'_>, + button_model: &model::ToolbarSessionButton, +) -> gtk4::Button { let button = gtk4::Button::new(); button.set_size_request(-1, ctx.px(24.0)); button.set_hexpand(true); @@ -105,7 +108,7 @@ fn session_button_icon(event: &ToolbarEvent) -> Option { } fn overwrite_confirmation_rows( - ctx: &SectionCtx, + ctx: &SectionCtx<'_>, confirmation: &model::session::ToolbarSessionOverwriteConfirmation, ) -> gtk4::Box { let rows = gtk4::Box::new(gtk4::Orientation::Vertical, ctx.px(5.0)); @@ -137,7 +140,7 @@ fn overwrite_confirmation_rows( rows } -fn home_button(ctx: &SectionCtx, home: &model::session::ToolbarSessionHome) -> gtk4::Button { +fn home_button(ctx: &SectionCtx<'_>, home: &model::session::ToolbarSessionHome) -> gtk4::Button { let button = gtk4::Button::new(); button.set_size_request(-1, ctx.px(24.0)); let label = gtk4::Label::new(Some(&home.label)); @@ -153,7 +156,7 @@ fn home_button(ctx: &SectionCtx, home: &model::session::ToolbarSessionHome) -> g button } -fn recent_row(ctx: &SectionCtx, recent: &model::ToolbarSessionRecent) -> gtk4::Button { +fn recent_row(ctx: &SectionCtx<'_>, recent: &model::ToolbarSessionRecent) -> gtk4::Button { let button = gtk4::Button::new(); button.set_size_request(-1, ctx.px(22.0)); let row = gtk4::Box::new(gtk4::Orientation::Horizontal, ctx.px(6.0)); diff --git a/src/toolbar_gtk/view/sections/settings_pane.rs b/src/toolbar_gtk/view/sections/settings_pane.rs index 49f443fea..4c836133d 100644 --- a/src/toolbar_gtk/view/sections/settings_pane.rs +++ b/src/toolbar_gtk/view/sections/settings_pane.rs @@ -18,7 +18,7 @@ use super::SectionCtx; /// retains the registered updaters so ordinary checkbox echoes update in /// place. pub(in crate::toolbar_gtk) fn build_popover_content( - ctx: &mut SectionCtx, + ctx: &mut SectionCtx<'_>, settings_model: &model::ToolbarSettingsModel, ) -> gtk4::Box { let column = gtk4::Box::new(gtk4::Orientation::Vertical, ctx.px(6.0)); @@ -58,7 +58,7 @@ pub(in crate::toolbar_gtk) fn build_popover_content( /// The collapsed "Details" disclosure toggle under the notices. The popover /// content key tracks its open state, so a click rebuilds the notices. -fn details_toggle(ctx: &SectionCtx, details: &model::ToolbarSettingsDetails) -> gtk4::Button { +fn details_toggle(ctx: &SectionCtx<'_>, details: &model::ToolbarSettingsDetails) -> gtk4::Button { let button = gtk4::Button::with_label(details.label); button.add_css_class("tab"); button.add_css_class("details"); @@ -76,7 +76,7 @@ fn details_toggle(ctx: &SectionCtx, details: &model::ToolbarSettingsDetails) -> /// Simple / Regular / Advanced presets. Non-destructive: switching /// re-baselines the sections without touching explicit user overrides. -fn layout_mode_segments(ctx: &mut SectionCtx) -> gtk4::Box { +fn layout_mode_segments(ctx: &mut SectionCtx<'_>) -> gtk4::Box { let row = gtk4::Box::new(gtk4::Orientation::Horizontal, ctx.px(4.0)); row.set_homogeneous(true); let control = model::layout_mode_control(ctx.snapshot.layout_mode); @@ -156,7 +156,7 @@ fn settings_toggle_event(template: &ToolbarEvent, checked: bool) -> ToolbarEvent /// Two-column toggle grid: wide toggles span the full row, narrow ones /// pair up, and a lone narrow leftover keeps its half-width cell. fn toggle_grid( - ctx: &mut SectionCtx, + ctx: &mut SectionCtx<'_>, settings_model: &model::ToolbarSettingsModel, ) -> Option { let rows = settings_model.toggle_rows(); @@ -214,7 +214,10 @@ fn toggle_grid( /// Configurator · Config file, or Back · built-in resets while customizing). /// The button set is structural (customize state, hidden overrides), so a /// rebuild follows every change and no updaters are needed. -fn buttons_grid(ctx: &SectionCtx, buttons: &[model::ToolbarSettingsButton]) -> Option { +fn buttons_grid( + ctx: &SectionCtx<'_>, + buttons: &[model::ToolbarSettingsButton], +) -> Option { if buttons.is_empty() { return None; } @@ -229,7 +232,10 @@ fn buttons_grid(ctx: &SectionCtx, buttons: &[model::ToolbarSettingsButton]) -> O Some(grid) } -fn settings_button(ctx: &SectionCtx, button_model: &model::ToolbarSettingsButton) -> gtk4::Button { +fn settings_button( + ctx: &SectionCtx<'_>, + button_model: &model::ToolbarSettingsButton, +) -> gtk4::Button { let button = gtk4::Button::new(); button.set_size_request(-1, ctx.px(24.0)); if ctx.use_icons { @@ -265,7 +271,7 @@ fn settings_button(ctx: &SectionCtx, button_model: &model::ToolbarSettingsButton /// Customize-mode group chooser: "Choose a group" over a two-column grid. fn group_chooser( - ctx: &SectionCtx, + ctx: &SectionCtx<'_>, settings_model: &model::ToolbarSettingsModel, ) -> Option { let groups = settings_model.groups(); @@ -300,7 +306,7 @@ fn group_chooser( /// live in `resolved_toolbar_items` (structural), so every change /// rebuilds the pane and the rows need no updaters. fn item_override_rows( - ctx: &SectionCtx, + ctx: &SectionCtx<'_>, settings_model: &model::ToolbarSettingsModel, ) -> Option { let overrides = settings_model.item_overrides(); diff --git a/src/toolbar_gtk/view/sections/step_undo.rs b/src/toolbar_gtk/view/sections/step_undo.rs index 75df84a1d..ff0ba9a9d 100644 --- a/src/toolbar_gtk/view/sections/step_undo.rs +++ b/src/toolbar_gtk/view/sections/step_undo.rs @@ -19,13 +19,13 @@ use super::SectionCtx; /// step rows, and delay sliders. Callers gate on `show_step_section`; /// liveness comes from the popover host's content-key rebuild, so the /// updaters go to a scratch list. -pub(in crate::toolbar_gtk) fn build_popover_content(ctx: &mut SectionCtx) -> gtk4::Box { +pub(in crate::toolbar_gtk) fn build_popover_content(ctx: &mut SectionCtx<'_>) -> gtk4::Box { let body = gtk4::Box::new(gtk4::Orientation::Vertical, ctx.px(6.0)); populate(ctx, &body); body } -fn populate(ctx: &mut SectionCtx, body: >k4::Box) { +fn populate(ctx: &mut SectionCtx<'_>, body: >k4::Box) { let snapshot = ctx.snapshot; // Both flags live in the structure/content key, so a toggle rebuilds the // section; the checkbox state never needs an updater. @@ -54,7 +54,7 @@ fn populate(ctx: &mut SectionCtx, body: >k4::Box) { } fn toggle_checkbox( - ctx: &SectionCtx, + ctx: &SectionCtx<'_>, label: &str, tooltip: &str, active: bool, @@ -72,7 +72,7 @@ fn toggle_checkbox( /// One Step Undo/Redo row: the multi-step button, the minus / "N steps" / /// plus cluster, and the per-direction delay slider underneath. -fn custom_row(ctx: &mut SectionCtx, body: >k4::Box, is_undo: bool) { +fn custom_row(ctx: &mut SectionCtx<'_>, body: >k4::Box, is_undo: bool) { let snapshot = ctx.snapshot; let row_h = ctx.sz(26.0); let row = gtk4::Box::new(gtk4::Orientation::Horizontal, ctx.px(6.0)); @@ -217,7 +217,7 @@ fn custom_row(ctx: &mut SectionCtx, body: >k4::Box, is_undo: bool) { /// Global Undo/Redo delay sliders: the built-in card puts both labels on /// one line and stacks the two full-width sliders beneath. -fn delay_sliders(ctx: &mut SectionCtx, body: >k4::Box) { +fn delay_sliders(ctx: &mut SectionCtx<'_>, body: >k4::Box) { let snapshot = ctx.snapshot; let labels = gtk4::Box::new(gtk4::Orientation::Horizontal, ctx.px(10.0)); labels.set_homogeneous(true); @@ -256,7 +256,7 @@ fn delay_sliders(ctx: &mut SectionCtx, body: >k4::Box) { })); } -fn global_delay_slider(ctx: &SectionCtx, is_undo: bool, delay_ms: u64) -> SliderRow { +fn global_delay_slider(ctx: &SectionCtx<'_>, is_undo: bool, delay_ms: u64) -> SliderRow { let spec = model::ToolbarSliderSpec::DELAY_SECONDS; let sender = ctx.feedback.clone(); let slider = SliderRow::new( @@ -286,7 +286,7 @@ fn global_delay_slider(ctx: &SectionCtx, is_undo: bool, delay_ms: u64) -> Slider slider } -fn nudge_button(ctx: &SectionCtx, painter: IconPainter, tooltip: &str) -> gtk4::Button { +fn nudge_button(ctx: &SectionCtx<'_>, painter: IconPainter, tooltip: &str) -> gtk4::Button { icon_button(painter, (ctx.sz(26.0), ctx.sz(26.0)), ctx.sz(14.0), tooltip).button } diff --git a/src/toolbar_gtk/view/top_bar.rs b/src/toolbar_gtk/view/top_bar.rs index 9e4a6216b..3184c60a7 100644 --- a/src/toolbar_gtk/view/top_bar.rs +++ b/src/toolbar_gtk/view/top_bar.rs @@ -526,7 +526,7 @@ impl TopBar { move_drag: None, move_drag_cancel: None, offsets: Rc::new(Cell::new((0.0, 0.0))), - base_x: Rc::new(Cell::new(BASE_MARGIN.1 as f64)), + base_x: Rc::new(Cell::new(f64::from(BASE_MARGIN.1))), offset_seq: Rc::new(Cell::new(0)), capture_suppressed: false, mapped_before_capture: false, @@ -680,7 +680,7 @@ impl TopBar { return; } let (left, x) = super::drag::rounded_margin_and_offset(self.base_x.get(), offsets.0); - let (top, y) = super::drag::rounded_margin_and_offset(BASE_MARGIN.0 as f64, offsets.1); + let (top, y) = super::drag::rounded_margin_and_offset(f64::from(BASE_MARGIN.0), offsets.1); self.offsets.set((x, y)); self.window.set_margin(Edge::Left, left); self.window.set_margin(Edge::Top, top); diff --git a/src/toolbar_gtk/view/top_bar/controls.rs b/src/toolbar_gtk/view/top_bar/controls.rs index b4b2cd382..f84250ec5 100644 --- a/src/toolbar_gtk/view/top_bar/controls.rs +++ b/src/toolbar_gtk/view/top_bar/controls.rs @@ -247,7 +247,7 @@ impl TopBar { /// A presets-island slot button: a filled slot draws the saved tool /// glyph in the neutral foreground with the preset color as a separate - /// corner swatch in a DrawingArea child, so a dark preset color never + /// corner swatch in a `DrawingArea` child, so a dark preset color never /// renders the glyph invisible against the slot body. An empty slot shows /// its 1-based number as a plain label. /// Clicking applies a filled slot or saves the current setup into an empty @@ -292,7 +292,7 @@ impl TopBar { area.set_valign(gtk4::Align::Fill); area.set_can_target(false); area.set_draw_func(move |_, ctx, width, height| { - let (fw, fh) = (width as f64, height as f64); + let (fw, fh) = (f64::from(width), f64::from(height)); let short = fw.min(fh).max(1.0); // Neutral glyph, centered. set_color(ctx, COLOR_TEXT_SECONDARY); diff --git a/src/toolbar_gtk/view/top_bar/drag.rs b/src/toolbar_gtk/view/top_bar/drag.rs index 00ad59504..04423d47d 100644 --- a/src/toolbar_gtk/view/top_bar/drag.rs +++ b/src/toolbar_gtk/view/top_bar/drag.rs @@ -150,7 +150,7 @@ impl TopBar { let (cx, cy) = offsets.get(); let (mut x, mut y) = drag_frame_position(drag_origin.get(), frame.delta); (x, y) = - clamp_drag_offsets(&window, (x, y), (base, BASE_MARGIN.0 as f64), END_MARGIN); + clamp_drag_offsets(&window, (x, y), (base, f64::from(BASE_MARGIN.0)), END_MARGIN); offsets.set((x, y)); seq.set(seq.get() + 1); toolbar_gtk::drag_debug_log(format!( diff --git a/src/toolbar_gtk/view/top_bar/stepper.rs b/src/toolbar_gtk/view/top_bar/stepper.rs index f8b2b9f17..1fd992dcb 100644 --- a/src/toolbar_gtk/view/top_bar/stepper.rs +++ b/src/toolbar_gtk/view/top_bar/stepper.rs @@ -61,7 +61,7 @@ impl TopBar { ); refresh(snapshot, control.enabled(snapshot)); self.updaters.borrow_mut().push(Box::new(move |snapshot| { - refresh(snapshot, control.enabled(snapshot)) + refresh(snapshot, control.enabled(snapshot)); })); } diff --git a/src/toolbar_gtk/view/top_bar/strip.rs b/src/toolbar_gtk/view/top_bar/strip.rs index ff6209d61..8f49058a4 100644 --- a/src/toolbar_gtk/view/top_bar/strip.rs +++ b/src/toolbar_gtk/view/top_bar/strip.rs @@ -132,9 +132,9 @@ impl TopBar { area.set_draw_func(move |area, ctx, width, height| { let color = area.color(); let (ring_color, ring_width) = draw_ring.get(); - let chip_size = (width.min(height) as f64).max(1.0); - let x = (width as f64 - chip_size) / 2.0; - let y = (height as f64 - chip_size) / 2.0; + let chip_size = f64::from(width.min(height)).max(1.0); + let x = (f64::from(width) - chip_size) / 2.0; + let y = (f64::from(height) - chip_size) / 2.0; toolbar_icons::draw_micro_chip( ctx, x, @@ -146,10 +146,10 @@ impl TopBar { // Ring width is in spec units; scale with the chip. ring_width: ring_width * (chip_size / MICRO_SIZE), icon_color: ( - color.red() as f64, - color.green() as f64, - color.blue() as f64, - color.alpha() as f64, + f64::from(color.red()), + f64::from(color.green()), + f64::from(color.blue()), + f64::from(color.alpha()), ), hovered: draw_hovered.get(), }, diff --git a/src/toolbar_gtk/view/top_bar/tests/builtin_contract.rs b/src/toolbar_gtk/view/top_bar/tests/builtin_contract.rs index 613d51e4a..fd1285e52 100644 --- a/src/toolbar_gtk/view/top_bar/tests/builtin_contract.rs +++ b/src/toolbar_gtk/view/top_bar/tests/builtin_contract.rs @@ -87,20 +87,17 @@ fn assert_builtin_node_kind(node: &TopToolbarWidgetKind, expected: &SemanticCont .. } => { assert_eq!(*active, expected.active); - match expected.icon { - // A filled slot carries the saved tool glyph; an empty slot - // has no glyph and shows its 1-based number label. - Some(icon) => { - let glyph = glyph.as_ref().expect("filled preset slot has a glyph"); - assert!(ptr::fn_addr_eq( - glyph.0, - toolbar_icons::top_toolbar_icon_painter(icon) - )); - } - None => { - assert!(glyph.is_none(), "empty preset slot has no glyph"); - assert_eq!(*label, expected.label); - } + // A filled slot carries the saved tool glyph; an empty slot + // has no glyph and shows its 1-based number label. + if let Some(icon) = expected.icon { + let glyph = glyph.as_ref().expect("filled preset slot has a glyph"); + assert!(ptr::fn_addr_eq( + glyph.0, + toolbar_icons::top_toolbar_icon_painter(icon) + )); + } else { + assert!(glyph.is_none(), "empty preset slot has no glyph"); + assert_eq!(*label, expected.label); } } W::MicroChip { glyph, .. } => { @@ -152,8 +149,8 @@ fn builtin_semantic_records( let tree = wayland::build_top_toolbar_view( &UiTextEngine::default(), snapshot, - width as f64, - height as f64, + f64::from(width), + f64::from(height), ); let mut records = Vec::new(); for node in tree.nodes() { @@ -166,8 +163,7 @@ fn builtin_semantic_records( let lane = expected .iter() .find(|record| record_id(record) == raw_id) - .map(record_lane) - .unwrap_or(SemanticLane::Strip); + .map_or(SemanticLane::Strip, record_lane); (lane, raw_id) }; let Some(record) = expected @@ -399,8 +395,8 @@ fn assert_builtin_style_pill_scenario(name: &str, snapshot: &ToolbarSnapshot) { let tree = wayland::build_top_toolbar_view( &UiTextEngine::default(), snapshot, - width as f64, - height as f64, + f64::from(width), + f64::from(height), ); assert_eq!( diff --git a/src/toolbar_gtk/view/top_bar/tests/builtin_style_nodes.rs b/src/toolbar_gtk/view/top_bar/tests/builtin_style_nodes.rs index e9d225102..3662f8b20 100644 --- a/src/toolbar_gtk/view/top_bar/tests/builtin_style_nodes.rs +++ b/src/toolbar_gtk/view/top_bar/tests/builtin_style_nodes.rs @@ -29,7 +29,7 @@ pub(super) fn assert_builtin_style_pill_node( *control, ), StylePillNodeExpectation::Readout(control) => { - assert_builtin_style_pill_readout(name, snapshot, kind, has_interaction, id, *control) + assert_builtin_style_pill_readout(name, snapshot, kind, has_interaction, id, *control); } StylePillNodeExpectation::StepHalf(control, index) => assert_builtin_style_pill_step_half( name, @@ -50,7 +50,7 @@ pub(super) fn assert_builtin_style_pill_node( *control, ), StylePillNodeExpectation::Caption(control) => { - assert_builtin_style_pill_caption(name, kind, has_interaction, id, *control) + assert_builtin_style_pill_caption(name, kind, has_interaction, id, *control); } StylePillNodeExpectation::MeterBar(control, index) => assert_builtin_style_pill_meter_bar( name, @@ -108,7 +108,7 @@ pub(super) fn assert_builtin_style_pill_node( id, *control, *index, - ) + ); } } } diff --git a/src/toolbar_gtk/view/top_bar/tests/capture_render.rs b/src/toolbar_gtk/view/top_bar/tests/capture_render.rs index 22e0a775c..5d6d09131 100644 --- a/src/toolbar_gtk/view/top_bar/tests/capture_render.rs +++ b/src/toolbar_gtk/view/top_bar/tests/capture_render.rs @@ -87,10 +87,10 @@ fn capture_roots_override_user_css_and_restore_rendered_pixels() { wait_for_frame(&window); let renderer = window.renderer().unwrap(); eprintln!("optional Vulkan probe selected {}", renderer.type_().name()); - if renderer.type_().name() != "GskVulkanRenderer" { - outcome = Outcome::VulkanUnavailable; - } else { + if renderer.type_().name() == "GskVulkanRenderer" { assert_renderer(&window); + } else { + outcome = Outcome::VulkanUnavailable; } window.destroy(); } @@ -150,13 +150,13 @@ fn roots(user: >k4::CssProvider, case: &str) { if case == "animation" { let mut css = painted_css("window", "none"); css.push_str( - r#" + r" @keyframes capture-fixture { from { background-color: #23252e; } to { background-color: #e86b18; } } window { background-image: none; animation: capture-fixture 400ms linear infinite alternate; } - "#, + ", ); user.load_from_string(&css); } diff --git a/src/toolbar_gtk/view/top_bar/tests/gtk_style_widgets.rs b/src/toolbar_gtk/view/top_bar/tests/gtk_style_widgets.rs index 6af293d68..8b780588e 100644 --- a/src/toolbar_gtk/view/top_bar/tests/gtk_style_widgets.rs +++ b/src/toolbar_gtk/view/top_bar/tests/gtk_style_widgets.rs @@ -25,7 +25,7 @@ pub(super) fn assert_gtk_style_widget( model::StylePillRole::Stepper => assert_gtk_style_stepper(widget, control, snapshot, &id), model::StylePillRole::Meter => assert_gtk_style_meter(widget, control, snapshot, &id), model::StylePillRole::Segmented => { - assert_gtk_style_segmented(widget, control, snapshot, &id) + assert_gtk_style_segmented(widget, control, snapshot, &id); } } } diff --git a/src/toolbar_gtk/view/top_bar/tests/pen_feel_render.rs b/src/toolbar_gtk/view/top_bar/tests/pen_feel_render.rs index 01916db1d..0389bcfe9 100644 --- a/src/toolbar_gtk/view/top_bar/tests/pen_feel_render.rs +++ b/src/toolbar_gtk/view/top_bar/tests/pen_feel_render.rs @@ -184,7 +184,7 @@ fn pixel(surface: &cairo::ImageSurface, x: usize, y: usize) -> [u8; 4] { let mut pixel = [0; 4]; surface .with_data(|bytes| { - pixel.copy_from_slice(&bytes[y * stride + x * 4..y * stride + x * 4 + 4]) + pixel.copy_from_slice(&bytes[y * stride + x * 4..y * stride + x * 4 + 4]); }) .unwrap(); pixel diff --git a/src/toolbar_gtk/widgets.rs b/src/toolbar_gtk/widgets.rs index e8768b14f..3d10b7f13 100644 --- a/src/toolbar_gtk/widgets.rs +++ b/src/toolbar_gtk/widgets.rs @@ -259,7 +259,7 @@ fn release_window_keyboard_focus(widget: &impl IsA) { /// Whether a focus-widget change should drop the toolbar window's keyboard /// mode. Entries keep it: the editable hex field needs the keys it captures. /// Focus inside a popover keeps it too, for a different reason: the popover -/// is an xdg_popup holding a keyboard grab on its own surface. Dropping the +/// is an `xdg_popup` holding a keyboard grab on its own surface. Dropping the /// parent layer surface's keyboard mode there makes the compositor pull /// keyboard focus from the grabbing popup between a click's press and /// release, and that broken grab stalls the release — a Settings checkbox @@ -473,7 +473,7 @@ impl SwatchButton { let draw_color = color_cell.clone(); let draw_selected = selected_cell.clone(); area.set_draw_func(move |_, ctx, width, height| { - let size = width.min(height) as f64; + let size = f64::from(width.min(height)); let (r, g, b, a) = draw_color.get(); // Rounded square with a subtle inner hairline, matching the // built-in bars. The fill is inset so the selected accent ring @@ -481,7 +481,7 @@ impl SwatchButton { // translucent color sits on the checkerboard, as the built-in // bars paint it. let swatch_path = |ctx: &cairo::Context| { - rounded_rect_path(ctx, 4.0, 4.0, size - 8.0, size - 8.0, 4.0) + rounded_rect_path(ctx, 4.0, 4.0, size - 8.0, size - 8.0, 4.0); }; ui::checkerboard_behind(ctx, a, swatch_path); ctx.set_source_rgba(r, g, b, a); diff --git a/src/toolbar_gtk/widgets/slider.rs b/src/toolbar_gtk/widgets/slider.rs index e152193ec..532ba3096 100644 --- a/src/toolbar_gtk/widgets/slider.rs +++ b/src/toolbar_gtk/widgets/slider.rs @@ -88,8 +88,8 @@ impl SliderRow { area.set_valign(gtk4::Align::Center); let draw_state = state.clone(); area.set_draw_func(move |widget, ctx, width, height| { - let w = width as f64; - let h = height as f64; + let w = f64::from(width); + let h = f64::from(height); let track_h = (h * 0.5).min(8.0); let track_y = (h - track_h) / 2.0; let radius = track_h / 2.0; @@ -143,7 +143,7 @@ impl SliderRow { drag.connect_drag_begin(move |gesture, x, _| { drag_state.dragging.set(true); // Jump the knob to the pressed position, like the built-in track. - let width = gesture.widget().map(|w| w.width()).unwrap_or(1).max(1) as f64; + let width = f64::from(gesture.widget().map_or(1, |w| w.width()).max(1)); let t = (x / width).clamp(0.0, 1.0); let value = drag_state.spec.value_from_t(t); drag_state.value.set(value); @@ -159,7 +159,7 @@ impl SliderRow { let change = Rc::new(on_change); let update_change = change.clone(); drag.connect_drag_update(move |gesture, dx, _| { - let width = gesture.widget().map(|w| w.width()).unwrap_or(1).max(1) as f64; + let width = f64::from(gesture.widget().map_or(1, |w| w.width()).max(1)); let (sx, _) = update_start.get(); let t = ((sx + dx) / width).clamp(0.0, 1.0); let value = update_state.spec.value_from_t(t); diff --git a/src/toolbar_icons/actions.rs b/src/toolbar_icons/actions.rs index 405442e0e..0b6a97d6a 100644 --- a/src/toolbar_icons/actions.rs +++ b/src/toolbar_icons/actions.rs @@ -68,7 +68,7 @@ pub fn draw_icon_settings(ctx: &Context, x: f64, y: f64, size: f64) { let inner_r = s * 0.25; let outer_r = s * 0.38; for i in 0..6 { - let angle = (i as f64) * PI / 3.0; + let angle = f64::from(i) * PI / 3.0; let x1 = cx + angle.cos() * inner_r; let y1 = cy + angle.sin() * inner_r; let x2 = cx + angle.cos() * outer_r; @@ -201,8 +201,8 @@ pub fn draw_icon_grid(ctx: &Context, x: f64, y: f64, size: f64) { let cell = (s - pad * 2.0 - gap) / 2.0; for row in 0..2 { for col in 0..2 { - let cx = x + pad + col as f64 * (cell + gap); - let cy = y + pad + row as f64 * (cell + gap); + let cx = x + pad + f64::from(col) * (cell + gap); + let cy = y + pad + f64::from(row) * (cell + gap); ctx.rectangle(cx, cy, cell, cell); let _ = ctx.stroke(); } diff --git a/src/toolbar_icons/mod.rs b/src/toolbar_icons/mod.rs index b94b9c951..f22c88bb5 100644 --- a/src/toolbar_icons/mod.rs +++ b/src/toolbar_icons/mod.rs @@ -277,21 +277,22 @@ mod painter_tests { let action = meta.action; let icon = config::action_meta(action) .and_then(|meta| meta.icon) - .map(action_icon_painter) - .unwrap_or_else(|| panic!("missing icon for {:?}", action)); + .map_or_else( + || panic!("missing icon for {action:?}"), + action_icon_painter, + ); let expected = match action { Action::EnterTextMode => top_toolbar_icon_painter(TopToolbarIcon::Text), Action::EnterStickyNoteMode => top_toolbar_icon_painter(TopToolbarIcon::StickyNote), _ => { let tool = Tool::from_select_action(action) - .unwrap_or_else(|| panic!("{:?} should select a tool", action)); + .unwrap_or_else(|| panic!("{action:?} should select a tool")); top_toolbar_icon_painter(TopToolbarIcon::Tool(semantic_icon_for_tool(tool))) } }; assert!( ptr::fn_addr_eq(icon, expected), - "icon painter for {:?} drifted from the shared semantic painter", - action + "icon painter for {action:?} drifted from the shared semantic painter" ); } } diff --git a/src/toolbar_icons/opacity_preview.rs b/src/toolbar_icons/opacity_preview.rs index 5b2823379..c682e5c05 100644 --- a/src/toolbar_icons/opacity_preview.rs +++ b/src/toolbar_icons/opacity_preview.rs @@ -80,7 +80,7 @@ pub(crate) fn draw_opacity_track( let knob_r = (h / 2.0).min(7.0); let _ = ctx.save(); checkerboard_behind(ctx, 0.0, |ctx| { - draw_rounded_rect(ctx, x, track_y, w, track_h, track_h / 2.0) + draw_rounded_rect(ctx, x, track_y, w, track_h, track_h / 2.0); }); let gradient = cairo::LinearGradient::new(x + knob_r, 0.0, x + w - knob_r, 0.0); for (position, alpha) in alpha_stops { diff --git a/src/tray_action.rs b/src/tray_action.rs index cf4246727..9a5974f82 100644 --- a/src/tray_action.rs +++ b/src/tray_action.rs @@ -106,12 +106,11 @@ fn parse_action_file(path: &Path, content: &str) -> Option { if action_str.is_empty() { return None; } - match TrayAction::parse(action_str) { - Some(action) => Some(action), - None => { - warn!("Unknown tray action '{}' in {}", action_str, path.display()); - None - } + if let Some(action) = TrayAction::parse(action_str) { + Some(action) + } else { + warn!("Unknown tray action '{}' in {}", action_str, path.display()); + None } } diff --git a/src/ui/board_picker.rs b/src/ui/board_picker.rs index 9acc00a78..6c97bdd8d 100644 --- a/src/ui/board_picker.rs +++ b/src/ui/board_picker.rs @@ -66,9 +66,8 @@ pub(crate) fn render_board_picker_with_halo( .iter() .flat_map(|board| board.pages.pages().iter().map(Frame::content_revision)), ); - let layout = match input_state.board_picker_layout() { - Some(layout) => layout, - None => return, + let Some(layout) = input_state.board_picker_layout() else { + return; }; let _ = ctx.save(); @@ -80,7 +79,7 @@ pub(crate) fn render_board_picker_with_halo( OVERLAY_DIM_MEDIUM }; ctx.set_source_rgba(0.0, 0.0, 0.0, dim_alpha); - ctx.rectangle(0.0, 0.0, screen_width as f64, screen_height as f64); + ctx.rectangle(0.0, 0.0, f64::from(screen_width), f64::from(screen_height)); let _ = ctx.fill(); // Panel diff --git a/src/ui/board_picker/helpers.rs b/src/ui/board_picker/helpers.rs index ec4defefe..35bd56884 100644 --- a/src/ui/board_picker/helpers.rs +++ b/src/ui/board_picker/helpers.rs @@ -97,8 +97,8 @@ pub(super) fn draw_drag_handle(ctx: &cairo::Context, x: f64, y: f64, width: f64) constants::set_color(ctx, ICON_DRAG_HANDLE); for row in 0..3 { for col in 0..2 { - let cx = start_x + col as f64 * col_gap; - let cy = start_y + row as f64 * gap; + let cx = start_x + f64::from(col) * col_gap; + let cy = start_y + f64::from(row) * gap; ctx.arc(cx, cy, dot_radius, 0.0, PI * 2.0); let _ = ctx.fill(); } diff --git a/src/ui/board_picker/page_panel.rs b/src/ui/board_picker/page_panel.rs index 99c59af57..c396d2315 100644 --- a/src/ui/board_picker/page_panel.rs +++ b/src/ui/board_picker/page_panel.rs @@ -341,14 +341,15 @@ fn render_sticky_add_button( label, ); let text_x = layout.page_add_button_x + (layout.page_add_button_width - extents.width()) * 0.5; - let text_y = - layout.page_add_button_y + (layout.page_add_button_height + extents.height()) * 0.5 - 1.0; + let text_y = layout.page_add_button_y + + f64::midpoint(layout.page_add_button_height, extents.height()) + - 1.0; engine.draw_baseline(ctx, label_style, label, text_x, text_y, None); } fn point_in_rect(x: i32, y: i32, rx: f64, ry: f64, rw: f64, rh: f64) -> bool { - let x = x as f64; - let y = y as f64; + let x = f64::from(x); + let y = f64::from(y); x >= rx && x <= rx + rw && y >= ry && y <= ry + rh } diff --git a/src/ui/board_picker/page_panel/thumbnail/cards.rs b/src/ui/board_picker/page_panel/thumbnail/cards.rs index 943c2efb5..b7168c4e3 100644 --- a/src/ui/board_picker/page_panel/thumbnail/cards.rs +++ b/src/ui/board_picker/page_panel/thumbnail/cards.rs @@ -342,15 +342,15 @@ pub(in crate::ui::board_picker::page_panel) fn render_page_preview( let base_w = thumb_w * PREVIEW_SCALE; let base_h = thumb_h * PREVIEW_SCALE; let margin = 8.0; - let max_w = (screen_width as f64 - margin * 2.0).max(1.0); - let max_h = (screen_height as f64 - margin * 2.0).max(1.0); + let max_w = (f64::from(screen_width) - margin * 2.0).max(1.0); + let max_h = (f64::from(screen_height) - margin * 2.0).max(1.0); let scale = (max_w / base_w).min(max_h / base_h).min(1.0); let preview_w = base_w * scale; let preview_h = base_h * scale; let mut preview_x = thumb_x + thumb_w + 12.0; let mut preview_y = thumb_y; - let max_x = screen_width as f64 - margin - preview_w; - let max_y = screen_height as f64 - margin - preview_h; + let max_x = f64::from(screen_width) - margin - preview_w; + let max_y = f64::from(screen_height) - margin - preview_h; preview_x = preview_x.clamp(margin, max_x.max(margin)); preview_y = preview_y.clamp(margin, max_y.max(margin)); @@ -391,10 +391,10 @@ pub(in crate::ui::board_picker::page_panel) fn render_page_preview( }, ); - let label = frame - .page_name() - .map(|name| trf("Page {}: {}", &[&page_number, &name])) - .unwrap_or_else(|| trf("Page {}", &[&page_number])); + let label = frame.page_name().map_or_else( + || trf("Page {}", &[&page_number]), + |name| trf("Page {}: {}", &[&page_number, &name]), + ); let label_style = UiTextStyle { family: "Sans", slant: cairo::FontSlant::Normal, diff --git a/src/ui/board_picker/page_panel/thumbnail/content.rs b/src/ui/board_picker/page_panel/thumbnail/content.rs index 3364ecbfe..737a78aa5 100644 --- a/src/ui/board_picker/page_panel/thumbnail/content.rs +++ b/src/ui/board_picker/page_panel/thumbnail/content.rs @@ -74,9 +74,9 @@ pub(super) fn render_page_content( let inset = 2.0; let content_w = (width - inset * 2.0).max(1.0); let content_h = (height - inset * 2.0).max(1.0); - let scale = (content_w / screen_width as f64).min(content_h / screen_height as f64); - let offset_x = (content_w - screen_width as f64 * scale) * 0.5; - let offset_y = (content_h - screen_height as f64 * scale) * 0.5; + let scale = (content_w / f64::from(screen_width)).min(content_h / f64::from(screen_height)); + let offset_x = (content_w - f64::from(screen_width) * scale) * 0.5; + let offset_y = (content_h - f64::from(screen_height) * scale) * 0.5; let _ = ctx.save(); ctx.translate(x + inset + offset_x, y + inset + offset_y); @@ -458,7 +458,7 @@ mod tests { let mut surface = cairo::ImageSurface::create(cairo::Format::ARgb32, 124 * density, 64 * density) .unwrap(); - surface.set_device_scale(density as f64, density as f64); + surface.set_device_scale(f64::from(density), f64::from(density)); { let ctx = cairo::Context::new(&surface).unwrap(); render_page_content( diff --git a/src/ui/board_picker/page_panel/thumbnail/icons.rs b/src/ui/board_picker/page_panel/thumbnail/icons.rs index 85dfe4202..ebe73658c 100644 --- a/src/ui/board_picker/page_panel/thumbnail/icons.rs +++ b/src/ui/board_picker/page_panel/thumbnail/icons.rs @@ -3,7 +3,7 @@ use std::f64::consts::PI; use crate::ui::constants::{self, TEXT_TERTIARY, TEXT_WHITE}; use crate::ui::theme::{ACCENT_RGB, Rgb}; -/// Delete-icon circle: softer than DESTRUCTIVE_RGB — the small filled disc +/// Delete-icon circle: softer than `DESTRUCTIVE_RGB` — the small filled disc /// reads harsh at full saturation (kept from the pre-theme literal). const DELETE_ICON_RGB: Rgb = (0.85, 0.2, 0.2); /// Rename-icon circle: neutral gray with no matching theme token. diff --git a/src/ui/board_picker/palette.rs b/src/ui/board_picker/palette.rs index eb05ab463..2a34436d3 100644 --- a/src/ui/board_picker/palette.rs +++ b/src/ui/board_picker/palette.rs @@ -65,7 +65,7 @@ pub(super) fn render_board_palette( ); let _ = ctx.stroke(); - if active_color.map(|active| active == color).unwrap_or(false) { + if active_color.is_some_and(|active| active == color) { constants::set_color(ctx, INPUT_CARET); ctx.set_line_width(1.5); draw_rounded_rect( diff --git a/src/ui/color_picker_popup.rs b/src/ui/color_picker_popup.rs index ba796fb9f..2f9db21e8 100644 --- a/src/ui/color_picker_popup.rs +++ b/src/ui/color_picker_popup.rs @@ -40,7 +40,7 @@ const INDICATOR_OUTLINE: Rgba = (0.0, 0.0, 0.0, 0.4); /// `theme::toolbar::COLOR_SWATCH_HAIRLINE_DARK`. const SWATCH_BORDER_ON_DARK: Rgba = (0.5, 0.5, 0.5, 0.8); const SWATCH_BORDER_ON_LIGHT: Rgba = (0.2, 0.2, 0.2, 0.6); -/// Validation-error red for the hex field (softer than DESTRUCTIVE_RGB). +/// Validation-error red for the hex field (softer than `DESTRUCTIVE_RGB`). const HEX_INVALID_GLOW: Rgba = (0.9, 0.3, 0.3, 0.25); const HEX_INVALID_BORDER: Rgba = (0.9, 0.35, 0.3, 0.9); /// Hex input border when unfocused. @@ -105,8 +105,8 @@ pub(crate) fn color_picker_popup_visual_geometry_with_engine( tooltip, anchor_x, anchor_y, - screen_width as f64, - screen_height as f64, + f64::from(screen_width), + f64::from(screen_height), ) { bounds = union_bounds( @@ -143,7 +143,7 @@ pub fn render_color_picker_popup( input_state, screen_width, screen_height, - ) + ); } pub(crate) fn render_color_picker_popup_with_engine( @@ -157,14 +157,12 @@ pub(crate) fn render_color_picker_popup_with_engine( return; } - let layout = match input_state.color_picker_popup_layout() { - Some(layout) => layout, - None => return, + let Some(layout) = input_state.color_picker_popup_layout() else { + return; }; - let current_color = match input_state.color_picker_popup_current_color() { - Some(color) => color, - None => return, + let Some(current_color) = input_state.color_picker_popup_current_color() else { + return; }; let hex_buffer = input_state @@ -177,7 +175,7 @@ pub(crate) fn render_color_picker_popup_with_engine( // Dim background ctx.set_source_rgba(0.0, 0.0, 0.0, OVERLAY_DIM_MEDIUM); - ctx.rectangle(0.0, 0.0, screen_width as f64, screen_height as f64); + ctx.rectangle(0.0, 0.0, f64::from(screen_width), f64::from(screen_height)); let _ = ctx.fill(); // Panel background @@ -296,15 +294,10 @@ pub(crate) fn render_color_picker_popup_with_engine( // restore the inline hex actions the pre-overhaul color section carried. let hover_pos = input_state.color_picker_popup_hover(); let size = layout.action_btn_size; - let copy_hover = hover_pos - .map(|(hx, hy)| layout.point_in_copy_button(hx, hy)) - .unwrap_or(false); - let paste_hover = hover_pos - .map(|(hx, hy)| layout.point_in_paste_button(hx, hy)) - .unwrap_or(false); - let eyedropper_hover = hover_pos - .map(|(hx, hy)| layout.point_in_eyedropper_button(hx, hy)) - .unwrap_or(false); + let copy_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_copy_button(hx, hy)); + let paste_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_paste_button(hx, hy)); + let eyedropper_hover = + hover_pos.is_some_and(|(hx, hy)| layout.point_in_eyedropper_button(hx, hy)); draw_action_button( ctx, layout.copy_btn_x, @@ -336,20 +329,15 @@ pub(crate) fn render_color_picker_popup_with_engine( } // Determine button hover states - let ok_hover = hover_pos - .map(|(hx, hy)| layout.point_in_ok_button(hx, hy)) - .unwrap_or(false); - let cancel_hover = hover_pos - .map(|(hx, hy)| layout.point_in_cancel_button(hx, hy)) - .unwrap_or(false); + let ok_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_ok_button(hx, hy)); + let cancel_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_cancel_button(hx, hy)); // "Default" button: only while recoloring a slot the shipped palette // defines. It stages the built-in color instead of committing, so it is a // secondary action next to OK/Cancel. if let Some((default_x, default_y)) = layout.default_btn { - let default_hover = hover_pos - .map(|(hx, hy)| layout.point_in_default_button(hx, hy)) - .unwrap_or(false); + let default_hover = + hover_pos.is_some_and(|(hx, hy)| layout.point_in_default_button(hx, hy)); draw_button( engine, ctx, @@ -421,8 +409,8 @@ pub(crate) fn render_color_picker_popup_with_engine( tooltip, anchor_x, anchor_y, - screen_width as f64, - screen_height as f64, + f64::from(screen_width), + f64::from(screen_height), ); } diff --git a/src/ui/color_picker_popup/tests/engine.rs b/src/ui/color_picker_popup/tests/engine.rs index af6469d99..4c28aa4a1 100644 --- a/src/ui/color_picker_popup/tests/engine.rs +++ b/src/ui/color_picker_popup/tests/engine.rs @@ -5,7 +5,7 @@ use super::*; fn pixels(density: i32, paint: impl FnOnce(&cairo::Context)) -> Vec { let mut surface = cairo::ImageSurface::create(cairo::Format::ARgb32, 800 * density, 600 * density).unwrap(); - surface.set_device_scale(density as f64, density as f64); + surface.set_device_scale(f64::from(density), f64::from(density)); let ctx = cairo::Context::new(&surface).unwrap(); paint(&ctx); drop(ctx); @@ -41,10 +41,10 @@ fn retained_color_popup_engine_shares_tooltip_damage_and_paint_across_targets() assert!(bounds.1 + bounds.3 >= tip.1 + tip.3 + tooltip::TOOLTIP_PAINT_OUTSET); } let actual = pixels(density, |ctx| { - render_color_picker_popup_with_engine(&engine, ctx, &input, 800, 600) + render_color_picker_popup_with_engine(&engine, ctx, &input, 800, 600); }); let expected = pixels(density, |ctx| { - render_color_picker_popup(ctx, &input, 800, 600) + render_color_picker_popup(ctx, &input, 800, 600); }); assert!( actual == expected, diff --git a/src/ui/command_palette.rs b/src/ui/command_palette.rs index 82d5cf12b..883f647b1 100644 --- a/src/ui/command_palette.rs +++ b/src/ui/command_palette.rs @@ -135,7 +135,7 @@ pub fn render_command_palette( input_state, screen_width, screen_height, - ) + ); } pub(crate) fn render_command_palette_with_engine( @@ -186,8 +186,8 @@ pub(crate) fn paint_command_palette( draw_command_palette_frame( theme, ctx, - screen_width as f64, - screen_height as f64, + f64::from(screen_width), + f64::from(screen_height), x, y, palette_width, @@ -254,10 +254,10 @@ pub(crate) fn paint_command_palette( engine, ctx, tooltip, - *pointer_x as f64, - *pointer_y as f64, - screen_width as f64, - screen_height as f64, + f64::from(*pointer_x), + f64::from(*pointer_y), + f64::from(screen_width), + f64::from(screen_height), ); } } @@ -314,10 +314,10 @@ pub(crate) fn command_palette_visual_geometry_with_engine( && let Some(tooltip_bounds) = command_palette_action_tooltip_geometry( engine, tooltip, - pointer_x as f64, - pointer_y as f64, - screen_width as f64, - screen_height as f64, + f64::from(pointer_x), + f64::from(pointer_y), + f64::from(screen_width), + f64::from(screen_height), ) { bounds = union_bounds(bounds, tooltip_bounds); diff --git a/src/ui/command_palette/command_palette_row.rs b/src/ui/command_palette/command_palette_row.rs index 89143b185..c5855b020 100644 --- a/src/ui/command_palette/command_palette_row.rs +++ b/src/ui/command_palette/command_palette_row.rs @@ -258,7 +258,7 @@ pub(super) fn render_command_row_shortcut_badge( desc_x: f64, is_selected: bool, shortcut_labels: &[String], - shortcut_style: &UiTextStyle, + shortcut_style: &UiTextStyle<'_>, ) -> f64 { let mut badge_left_edge = content_right; if let Some(shortcut) = shortcut_labels.first() { @@ -336,7 +336,7 @@ pub(super) fn render_command_row_description( theme: &Theme, engine: &UiTextEngine, ctx: &cairo::Context, - desc_style: &UiTextStyle, + desc_style: &UiTextStyle<'_>, description: &str, desc_x: f64, label_y: f64, diff --git a/src/ui/command_palette/modals.rs b/src/ui/command_palette/modals.rs index f0ad95279..a6d0f4cff 100644 --- a/src/ui/command_palette/modals.rs +++ b/src/ui/command_palette/modals.rs @@ -83,10 +83,10 @@ pub(super) fn keybinding_capture_geometry( screen_width: u32, screen_height: u32, ) -> (f64, f64, f64, f64) { - let width = 520.0_f64.min(screen_width as f64 - 24.0); + let width = 520.0_f64.min(f64::from(screen_width) - 24.0); let height = 170.0; - let x = (screen_width as f64 - width) / 2.0; - let y = screen_height as f64 * COMMAND_PALETTE_TOP_RATIO; + let x = (f64::from(screen_width) - width) / 2.0; + let y = f64::from(screen_height) * COMMAND_PALETTE_TOP_RATIO; (x, y, width, height) } @@ -103,8 +103,8 @@ pub(super) fn render_keybinding_capture( draw_command_palette_frame( theme, ctx, - screen_width as f64, - screen_height as f64, + f64::from(screen_width), + f64::from(screen_height), x, y, width, diff --git a/src/ui/command_palette/tests/engine.rs b/src/ui/command_palette/tests/engine.rs index 9e9066062..e58c5f84e 100644 --- a/src/ui/command_palette/tests/engine.rs +++ b/src/ui/command_palette/tests/engine.rs @@ -10,7 +10,7 @@ use super::*; fn pixels(density: i32, paint: impl FnOnce(&cairo::Context)) -> Vec { let mut surface = cairo::ImageSurface::create(cairo::Format::ARgb32, 800 * density, 600 * density).unwrap(); - surface.set_device_scale(density as f64, density as f64); + surface.set_device_scale(f64::from(density), f64::from(density)); let ctx = cairo::Context::new(&surface).unwrap(); paint(&ctx); drop(ctx); @@ -33,7 +33,7 @@ fn retained_palette_engine_matches_public_paint_and_geometry_across_targets() { ); assert!(bounds.2 > 0.0 && bounds.2 < 800.0); let actual = pixels(density, |ctx| { - render_command_palette_with_engine(&engine, ctx, &input, 800, 600) + render_command_palette_with_engine(&engine, ctx, &input, 800, 600); }); let expected = pixels(density, |ctx| render_command_palette(ctx, &input, 800, 600)); assert!( @@ -67,7 +67,7 @@ fn retained_palette_tooltip_geometry_contains_pixels_and_unicode_highlight_is_vi 560.0, 800.0, 600.0, - ) + ); }); let expected = pixels(density, |ctx| { draw_command_palette_action_tooltip( @@ -79,15 +79,15 @@ fn retained_palette_tooltip_geometry_contains_pixels_and_unicode_highlight_is_vi 560.0, 800.0, 600.0, - ) + ); }); assert!(actual == expected, "tooltip density {density}"); let mut painted = 0; for (index, pixel) in actual.as_chunks::<4>().0.iter().enumerate() { if pixel.iter().any(|byte| *byte != 0) { painted += 1; - let x = (index % (800 * density) as usize) as f64 / density as f64; - let y = (index / (800 * density) as usize) as f64 / density as f64; + let x = (index % (800 * density) as usize) as f64 / f64::from(density); + let y = (index / (800 * density) as usize) as f64 / f64::from(density); assert!(x >= bounds.0 - 2.0 && x <= bounds.0 + bounds.2 + 2.0); assert!(y >= bounds.1 - 2.0 && y <= bounds.1 + bounds.3 + 2.0); } @@ -101,7 +101,7 @@ fn retained_palette_tooltip_geometry_contains_pixels_and_unicode_highlight_is_vi }; let range = find_match_range(text, "測試").unwrap(); let highlight = pixels(density, |ctx| { - draw_highlight_with_engine(&engine, ctx, 30.0, 40.0, text, range, &style) + draw_highlight_with_engine(&engine, ctx, 30.0, 40.0, text, range, &style); }); let fresh = pixels(density, |ctx| { draw_highlight_with_engine( @@ -112,7 +112,7 @@ fn retained_palette_tooltip_geometry_contains_pixels_and_unicode_highlight_is_vi text, range, &style, - ) + ); }); assert!(highlight == fresh, "highlight density {density}"); assert!(highlight.iter().any(|byte| *byte != 0)); @@ -125,7 +125,7 @@ fn retained_palette_tooltip_geometry_contains_pixels_and_unicode_highlight_is_vi text, (range.0 + 1, range.1), &style, - ) + ); }); assert!(invalid.iter().all(|byte| *byte == 0)); } @@ -142,7 +142,7 @@ fn prepared_palette_paints_without_application_state() { &CommandPaletteView::Closed, 800, 600, - ) + ); }); assert!(closed.iter().all(|byte| *byte == 0)); let view = CommandPaletteView::List(PaletteListView { @@ -157,7 +157,7 @@ fn prepared_palette_paints_without_application_state() { tooltip: None, }); let painted = pixels(1, |ctx| { - paint_command_palette(&Theme::dark(), &engine, ctx, &view, 800, 600) + paint_command_palette(&Theme::dark(), &engine, ctx, &view, 800, 600); }); assert!(painted.iter().any(|byte| *byte != 0)); // The dimmer and the panel have different opacity, so this checks the @@ -288,7 +288,7 @@ fn row_shortcut_controls_show_only_on_the_selected_and_hovered_rows() { let (selected_row, other_row) = (command_rows[0], command_rows[2]); let idle = pixels(1, |ctx| { - render_command_palette_with_engine(&engine, ctx, &input, 800, 600) + render_command_palette_with_engine(&engine, ctx, &input, 800, 600); }); assert!( !strip_is_blank(&idle, row_action_strip(&input, selected_row)), @@ -300,9 +300,9 @@ fn row_shortcut_controls_show_only_on_the_selected_and_hovered_rows() { ); let (left, top, _, bottom) = row_action_strip(&input, other_row); - input.update_pointer_position(left - 200, (top + bottom) / 2); + input.update_pointer_position(left - 200, i32::midpoint(top, bottom)); let hovered = pixels(1, |ctx| { - render_command_palette_with_engine(&engine, ctx, &input, 800, 600) + render_command_palette_with_engine(&engine, ctx, &input, 800, 600); }); assert!( !strip_is_blank(&hovered, row_action_strip(&input, other_row)), @@ -328,7 +328,7 @@ fn palette_rows_highlight_literal_label_matches_but_not_fuzzy_matches() { let count_highlight = |query_view: &CommandPaletteView| { let rgba = pixels(1, |ctx| { - paint_command_palette(&theme, &engine, ctx, query_view, 800, 600) + paint_command_palette(&theme, &engine, ctx, query_view, 800, 600); }); rgba.as_chunks::<4>() .0 diff --git a/src/ui/context_menu.rs b/src/ui/context_menu.rs index 70050951b..33b430ef5 100644 --- a/src/ui/context_menu.rs +++ b/src/ui/context_menu.rs @@ -9,7 +9,7 @@ use super::constants::{ RADIUS_PANEL, RADIUS_SM, SHADOW, TEXT_DISABLED, TEXT_HINT, TEXT_PRIMARY, }; -/// Footer hint text: slightly brighter than TEXT_TERTIARY so the key hints +/// Footer hint text: slightly brighter than `TEXT_TERTIARY` so the key hints /// stay legible inside the menu (kept from pre-theme literals). const HINT_FOOTER_TEXT: Rgba = (0.65, 0.68, 0.75, 1.0); /// Accent bar on the parent row of an open submenu. @@ -306,9 +306,9 @@ fn draw_divider(ctx: &cairo::Context, layout: &ContextMenuLayout, y: f64) { /// A soft shadow under a pane: stacked translucent rects widening outward. fn draw_shadow(ctx: &cairo::Context, layout: &ContextMenuLayout) { - let alpha = SHADOW.3 / SHADOW_LAYERS as f64; + let alpha = SHADOW.3 / f64::from(SHADOW_LAYERS); for layer in 1..=SHADOW_LAYERS { - let spread = SHADOW_SPREAD * layer as f64; + let spread = SHADOW_SPREAD * f64::from(layer); constants::set_color(ctx, constants::with_alpha(SHADOW, alpha)); draw_rounded_rect( ctx, diff --git a/src/ui/font_picker.rs b/src/ui/font_picker.rs index ca227c3e0..b50c7f3e2 100644 --- a/src/ui/font_picker.rs +++ b/src/ui/font_picker.rs @@ -139,9 +139,7 @@ fn query_line( // Match count on the right, so a query that narrows to nothing says so // before the empty list has to. Measured first: it is short and always // wanted, so it is the query that gives way when the two would collide. - let count = match_count - .map(|count| count.to_string()) - .unwrap_or_else(|| "…".to_string()); + let count = match_count.map_or_else(|| "…".to_string(), |count| count.to_string()); let count_width = text_width(ctx, "Sans", CHROME_FONT_SIZE, &count); theme::set_color(ctx, overlay::TEXT_HINT); draw_text_right( diff --git a/src/ui/help_overlay/grid.rs b/src/ui/help_overlay/grid.rs index 91b300510..588ab9914 100644 --- a/src/ui/help_overlay/grid.rs +++ b/src/ui/help_overlay/grid.rs @@ -332,11 +332,8 @@ impl GridPainter<'_> { } ctx.new_path(); - let badge_metrics = measured - .badge_text_metrics - .get(badge_index) - .map(|metrics| (metrics.width, metrics.height, metrics.y_bearing)) - .unwrap_or_else(|| { + let badge_metrics = measured.badge_text_metrics.get(badge_index).map_or_else( + || { let extents = text_extents_for_with_engine( self.engine, ctx, @@ -347,7 +344,9 @@ impl GridPainter<'_> { badge.label.as_str(), ); (extents.width(), extents.height(), extents.y_bearing()) - }); + }, + |metrics| (metrics.width, metrics.height, metrics.y_bearing), + ); let badge_width = badge_metrics.0 + style.badge_padding_x * 2.0; draw_rounded_rect( diff --git a/src/ui/help_overlay/nav/state.rs b/src/ui/help_overlay/nav/state.rs index 2e5a95bc5..27c103fb4 100644 --- a/src/ui/help_overlay/nav/state.rs +++ b/src/ui/help_overlay/nav/state.rs @@ -52,7 +52,7 @@ pub(crate) fn build_nav_state( } else { nav_title.to_string() }; - let nav_separator = format!(" {} ", BULLET); + let nav_separator = format!(" {BULLET} "); let nav_secondary_segments: Vec<(String, [f64; 4])> = if search_active { vec![ ("Esc".to_string(), nav_key_color), @@ -122,7 +122,7 @@ pub(crate) fn build_nav_state( cairo::FontWeight::Normal, max_query_width, ); - Some(format!("{}{}", prefix, query_display)) + Some(format!("{prefix}{query_display}")) } else { None }; diff --git a/src/ui/help_overlay/render/frame.rs b/src/ui/help_overlay/render/frame.rs index 32bd1cd03..5a5e6d4ce 100644 --- a/src/ui/help_overlay/render/frame.rs +++ b/src/ui/help_overlay/render/frame.rs @@ -24,7 +24,7 @@ pub(super) fn draw_overlay_frame( // Dim background behind overlay ctx.set_source_rgba(0.0, 0.0, 0.0, OVERLAY_DIM_HELP); - ctx.rectangle(0.0, 0.0, screen_width as f64, screen_height as f64); + ctx.rectangle(0.0, 0.0, f64::from(screen_width), f64::from(screen_height)); let _ = ctx.fill(); // Drop shadow (layered for softer effect) diff --git a/src/ui/help_overlay/render/metrics.rs b/src/ui/help_overlay/render/metrics.rs index 9ad00a627..32fbdd8af 100644 --- a/src/ui/help_overlay/render/metrics.rs +++ b/src/ui/help_overlay/render/metrics.rs @@ -110,8 +110,8 @@ impl RenderMetrics { let extra_line_gap = 30.0 * scale; let extra_line_bottom_spacing = 18.0 * scale; let columns_bottom_spacing = 28.0 * scale; - let max_box_width = screen_width as f64 * HELP_OVERLAY_MAX_WIDTH_RATIO; - let max_box_height = screen_height as f64 * 0.92; + let max_box_width = f64::from(screen_width) * HELP_OVERLAY_MAX_WIDTH_RATIO; + let max_box_height = f64::from(screen_height) * 0.92; let note_font_size = (body_font_size - 2.0 * scale).max(min_font_size); let nav_font_size = (body_font_size - 1.0 * scale).max(min_font_size); let note_to_close_gap = 12.0 * scale; diff --git a/src/ui/help_overlay/render/mod.rs b/src/ui/help_overlay/render/mod.rs index b6215b069..82dc0ca25 100644 --- a/src/ui/help_overlay/render/mod.rs +++ b/src/ui/help_overlay/render/mod.rs @@ -87,13 +87,11 @@ pub(crate) fn render_help_overlay_result_with_content( let palette_binding = bindings .labels_for(Action::ToggleCommandPalette) .and_then(|labels| labels.first()) - .map(|label| label.as_str()) - .unwrap_or(NOT_BOUND_LABEL); + .map_or(NOT_BOUND_LABEL, |label| label.as_str()); let config_binding = bindings .labels_for(Action::OpenConfigurator) .and_then(|labels| labels.first()) - .map(|label| label.as_str()) - .unwrap_or(NOT_BOUND_LABEL); + .map_or(NOT_BOUND_LABEL, |label| label.as_str()); let version_text = format!("v{}", build_info::version()); let header_hints = if quick_mode { vec![HeaderHint { @@ -124,13 +122,11 @@ pub(crate) fn render_help_overlay_result_with_content( let help_binding = bindings .labels_for(Action::ToggleHelp) .and_then(|labels| labels.first()) - .map(|label| label.as_str()) - .unwrap_or("F1"); + .map_or("F1", |label| label.as_str()); let quick_help_binding = bindings .labels_for(Action::ToggleQuickHelp) .and_then(|labels| labels.first()) - .map(|label| label.as_str()) - .unwrap_or("Shift+F1"); + .map_or("Shift+F1", |label| label.as_str()); let note_text_base_owned; let note_text_base: &str = if quick_mode { note_text_base_owned = trf("{} for full help", &[&help_binding]); diff --git a/src/ui/help_overlay/render/state.rs b/src/ui/help_overlay/render/state.rs index d8ecdcbf7..96dad42be 100644 --- a/src/ui/help_overlay/render/state.rs +++ b/src/ui/help_overlay/render/state.rs @@ -92,7 +92,7 @@ pub(super) fn build_overlay_layout( let metrics = RenderMetrics::from_style(style, screen_width, screen_height); let palette = RenderPalette::from_style(style); - let max_search_width = (screen_width as f64 * 0.9 - metrics.padding * 2.0).max(0.0); + let max_search_width = (f64::from(screen_width) * 0.9 - metrics.padding * 2.0).max(0.0); let nav_state = build_nav_state( engine, ctx, @@ -190,7 +190,7 @@ pub(super) fn build_overlay_layout( &[¬e_text_base, &BULLET, &page_label, &BULLET], ) } else { - format!("{} {} {}", note_text_base, BULLET, page_label) + format!("{note_text_base} {BULLET} {page_label}") }; let note_width = text_extents_for_with_engine( engine, @@ -221,8 +221,8 @@ pub(super) fn build_overlay_layout( let box_width = content_width + metrics.padding * 2.0; let box_height = inner_height + metrics.padding * 2.0; - let box_x = (screen_width as f64 - box_width) / 2.0; - let box_y = (screen_height as f64 - box_height) / 2.0; + let box_x = (f64::from(screen_width) - box_width) / 2.0; + let box_y = (f64::from(screen_height) - box_height) / 2.0; OverlayLayout { search_active, diff --git a/src/ui/input_hud.rs b/src/ui/input_hud.rs index 9b03c228a..e7cab37e5 100644 --- a/src/ui/input_hud.rs +++ b/src/ui/input_hud.rs @@ -77,7 +77,7 @@ fn compute_input_hud_layout( let mut measured: Vec<(InputHudChip, f64)> = Vec::new(); let mut row_height = 0.0_f64; let mut content_width = 0.0_f64; - let available = (screen_width as f64 - INPUT_HUD_EDGE_INSET * 2.0).max(0.0); + let available = (f64::from(screen_width) - INPUT_HUD_EDGE_INSET * 2.0).max(0.0); if available <= 0.0 { return None; } @@ -124,13 +124,13 @@ fn compute_input_hud_layout( measured.reverse(); let position = input_state.input_hud_position(); - let x = row_origin_x(position, screen_width as f64, content_width); + let x = row_origin_x(position, f64::from(screen_width), content_width); let y = if position.is_top() { INPUT_HUD_EDGE_INSET } else if position.is_middle() { - ((screen_height as f64 - row_height) / 2.0).max(0.0) + ((f64::from(screen_height) - row_height) / 2.0).max(0.0) } else { - (screen_height as f64 - INPUT_HUD_EDGE_INSET - row_height).max(0.0) + (f64::from(screen_height) - INPUT_HUD_EDGE_INSET - row_height).max(0.0) }; let mut cursor = x; diff --git a/src/ui/input_hud/tests.rs b/src/ui/input_hud/tests.rs index eea2494fa..e67765e3f 100644 --- a/src/ui/input_hud/tests.rs +++ b/src/ui/input_hud/tests.rs @@ -98,7 +98,7 @@ fn the_newest_chip_clamps_to_the_available_width() { state.note_input_hud_key(Key::Backspace, modifiers); let screen_width = 160_u32; - let available = screen_width as f64 - INPUT_HUD_EDGE_INSET * 2.0; + let available = f64::from(screen_width) - INPUT_HUD_EDGE_INSET * 2.0; let layout = compute_input_hud_layout(&UiTextEngine::default(), &state, screen_width, 1080) .expect("layout"); assert_eq!(layout.chips.len(), 1); @@ -108,7 +108,7 @@ fn the_newest_chip_clamps_to_the_available_width() { layout.width ); assert!(layout.x >= 0.0); - assert!(layout.x + layout.width <= screen_width as f64); + assert!(layout.x + layout.width <= f64::from(screen_width)); // A surface no wider than its insets has no drawable span at all. let no_span = (INPUT_HUD_EDGE_INSET * 2.0) as u32; diff --git a/src/ui/measure_badge.rs b/src/ui/measure_badge.rs index e69794b59..19761a306 100644 --- a/src/ui/measure_badge.rs +++ b/src/ui/measure_badge.rs @@ -78,13 +78,13 @@ pub(crate) fn measure_shape_badge( let text = readout.text(); let extents = engine.measure(shape_measure_badge_text_style(), &text, None)?; let width = (extents.width() + PADDING_X * 2.0) - .min((screen_width as f64 - SCREEN_MARGIN * 2.0).max(0.0)); - let height = BADGE_HEIGHT.min((screen_height as f64 - SCREEN_MARGIN * 2.0).max(0.0)); + .min((f64::from(screen_width) - SCREEN_MARGIN * 2.0).max(0.0)); + let height = BADGE_HEIGHT.min((f64::from(screen_height) - SCREEN_MARGIN * 2.0).max(0.0)); if width <= 0.0 || height <= 0.0 { return None; } - let x = trailing_axis(pointer.0, width, screen_width as f64); - let y = trailing_axis(pointer.1, height, screen_height as f64); + let x = trailing_axis(pointer.0, width, f64::from(screen_width)); + let y = trailing_axis(pointer.1, height, f64::from(screen_height)); let baseline = ( x + (width - extents.width()) / 2.0 - extents.x_bearing(), y + (height - extents.height()) / 2.0 - extents.y_bearing(), diff --git a/src/ui/onboarding_card.rs b/src/ui/onboarding_card.rs index 7fe653c13..54b2b8ff6 100644 --- a/src/ui/onboarding_card.rs +++ b/src/ui/onboarding_card.rs @@ -181,14 +181,14 @@ pub(crate) fn render_onboarding_card_with_engine( let item_gap_y = ITEM_GAP_Y * CARD_TYPE_SCALE; let text_offset_y = TEXT_OFFSET_Y * CARD_TYPE_SCALE; - let available_width = (width as f64 - margin * 2.0).max(1.0); + let available_width = (f64::from(width) - margin * 2.0).max(1.0); let card_width = available_width .min(card_max_width) .max(card_min_width.min(available_width)); - let x = (width as f64 - card_width - margin).max(margin); + let x = (f64::from(width) - card_width - margin).max(margin); let min_y = margin; - let max_y = (height as f64 - margin).max(min_y); - let y = (height as f64 * 0.06).clamp(min_y, max_y); + let max_y = (f64::from(height) - margin).max(min_y); + let y = (f64::from(height) * 0.06).clamp(min_y, max_y); let content_x = x + card_padding; let content_w = (card_width - card_padding * 2.0).max(1.0); diff --git a/src/ui/precision_entry.rs b/src/ui/precision_entry.rs index 0224946ba..3a9eb79a7 100644 --- a/src/ui/precision_entry.rs +++ b/src/ui/precision_entry.rs @@ -65,10 +65,10 @@ pub(crate) fn render_precision_entry_popup_with_engine( let x = anchor .0 - .clamp(8.0, (screen_width as f64 - POPUP_W - 8.0).max(8.0)); + .clamp(8.0, (f64::from(screen_width) - POPUP_W - 8.0).max(8.0)); let y = anchor .1 - .clamp(8.0, (screen_height as f64 - POPUP_H - 8.0).max(8.0)); + .clamp(8.0, (f64::from(screen_height) - POPUP_H - 8.0).max(8.0)); // Panel card. draw_rounded_rect(ctx, x, y, POPUP_W, POPUP_H, RADIUS_STD); diff --git a/src/ui/precision_entry/tests.rs b/src/ui/precision_entry/tests.rs index c1340b0ce..30b360e46 100644 --- a/src/ui/precision_entry/tests.rs +++ b/src/ui/precision_entry/tests.rs @@ -50,7 +50,7 @@ fn retained_overlay_owner_matches_fresh_across_density_and_visible_state_changes for density in [1, 2, 1] { state.open_precision_entry(PrecisionEntryTarget::Thickness); assert_owner_parity(&engine, density, |engine, ctx| { - render_precision_entry_popup_with_engine(engine, ctx, &state, 420, 360, (400.0, 350.0)) + render_precision_entry_popup_with_engine(engine, ctx, &state, 420, 360, (400.0, 350.0)); }); let before = assert_owner_parity(&engine, density, |engine, ctx| { render_onboarding_card_with_engine(engine, ctx, 420, 360, &card, None); diff --git a/src/ui/primitives.rs b/src/ui/primitives.rs index 8db79eee4..2c3c9949a 100644 --- a/src/ui/primitives.rs +++ b/src/ui/primitives.rs @@ -208,8 +208,9 @@ pub(crate) fn draw_pill( ) { if let Some((sr, sg, sb, sa)) = shadow { for layer in (1..=PILL_SHADOW_LAYERS).rev() { - let spread = layer as f64; - let alpha = sa * (1.0 - (layer as f64 - 1.0) / PILL_SHADOW_LAYERS as f64) * 0.35; + let spread = f64::from(layer); + let alpha = + sa * (1.0 - (f64::from(layer) - 1.0) / f64::from(PILL_SHADOW_LAYERS)) * 0.35; ctx.set_source_rgba(sr, sg, sb, alpha); draw_rounded_rect( ctx, @@ -520,31 +521,27 @@ pub(crate) fn draw_badge_with_engine( let _ = ctx.fill(); theme::set_color(ctx, theme::overlay::TEXT_WHITE); - match &hint_layout { - Some((hint_text_layout, hint_extents)) => { - label_layout.show_at_baseline( - ctx, - x + text_inset, - top_y + label_extents.height() + padding * 0.3, - ); - // Hint text (dimmer) - theme::set_color(ctx, theme::with_alpha(theme::overlay::TEXT_WHITE, 0.7)); - hint_text_layout.show_at_baseline( - ctx, - x + text_inset, - top_y + label_extents.height() + hint_extents.height() + padding * 0.6, - ); - } - None => { - // Center the label ink vertically. A fixed baseline offset from - // the pill bottom assumed all ink sits above the baseline (true - // for all-caps FROZEN/ZOOM), but mixed-case labels like the - // board/page badge's "Overlay | Page 1/2" have descenders that - // dipped into the bottom padding and nearly touched the edge. - let baseline = - top_y + (height - label_extents.height()) / 2.0 - label_extents.y_bearing(); - label_layout.show_at_baseline(ctx, x + text_inset, baseline); - } + if let Some((hint_text_layout, hint_extents)) = &hint_layout { + label_layout.show_at_baseline( + ctx, + x + text_inset, + top_y + label_extents.height() + padding * 0.3, + ); + // Hint text (dimmer) + theme::set_color(ctx, theme::with_alpha(theme::overlay::TEXT_WHITE, 0.7)); + hint_text_layout.show_at_baseline( + ctx, + x + text_inset, + top_y + label_extents.height() + hint_extents.height() + padding * 0.6, + ); + } else { + // Center the label ink vertically. A fixed baseline offset from + // the pill bottom assumed all ink sits above the baseline (true + // for all-caps FROZEN/ZOOM), but mixed-case labels like the + // board/page badge's "Overlay | Page 1/2" have descenders that + // dipped into the bottom padding and nearly touched the edge. + let baseline = top_y + (height - label_extents.height()) / 2.0 - label_extents.y_bearing(); + label_layout.show_at_baseline(ctx, x + text_inset, baseline); } height diff --git a/src/ui/properties_panel/actions.rs b/src/ui/properties_panel/actions.rs index 23c6c27c3..11dc54059 100644 --- a/src/ui/properties_panel/actions.rs +++ b/src/ui/properties_panel/actions.rs @@ -127,16 +127,13 @@ fn draw_preset_chip( ctx.new_path(); ctx.arc(left + dot, cy, dot, 0.0, consts::TAU); - match color { - Some(color) => { - set_color(ctx, (color.r, color.g, color.b, color.a.max(0.35))); - let _ = ctx.fill(); - } - None => { - set_color(ctx, ink); - ctx.set_line_width(1.0); - let _ = ctx.stroke(); - } + if let Some(color) = color { + set_color(ctx, (color.r, color.g, color.b, color.a.max(0.35))); + let _ = ctx.fill(); + } else { + set_color(ctx, ink); + ctx.set_line_width(1.0); + let _ = ctx.stroke(); } set_color(ctx, ink); engine.draw_baseline( diff --git a/src/ui/properties_panel/controls.rs b/src/ui/properties_panel/controls.rs index 7c47e3628..251245322 100644 --- a/src/ui/properties_panel/controls.rs +++ b/src/ui/properties_panel/controls.rs @@ -414,27 +414,24 @@ pub(super) fn draw_switch( let knob = radius - 3.0; let (_, cy) = rect.center(); - match on { - Some(on) => { - let cx = if on { - rect.right() - 3.0 - knob - } else { - rect.x + 3.0 + knob - }; - ctx.arc(cx, cy, knob, 0.0, TAU); - set_color( - ctx, - state.fade(if on { TEXT_WHITE } else { TEXT_SECONDARY }), - ); - let _ = ctx.fill(); - } + if let Some(on) = on { + let cx = if on { + rect.right() - 3.0 - knob + } else { + rect.x + 3.0 + knob + }; + ctx.arc(cx, cy, knob, 0.0, TAU); + set_color( + ctx, + state.fade(if on { TEXT_WHITE } else { TEXT_SECONDARY }), + ); + let _ = ctx.fill(); + } else { // Mixed: a bar in the middle, neither on nor off. - None => { - let (cx, _) = rect.center(); - set_color(ctx, state.fade(TEXT_WHITE)); - draw_rounded_rect(ctx, cx - 7.0, cy - 2.0, 14.0, 4.0, 2.0); - let _ = ctx.fill(); - } + let (cx, _) = rect.center(); + set_color(ctx, state.fade(TEXT_WHITE)); + draw_rounded_rect(ctx, cx - 7.0, cy - 2.0, 14.0, 4.0, 2.0); + let _ = ctx.fill(); } } diff --git a/src/ui/radial_menu/cache.rs b/src/ui/radial_menu/cache.rs index 5b38eed4f..73259e556 100644 --- a/src/ui/radial_menu/cache.rs +++ b/src/ui/radial_menu/cache.rs @@ -382,7 +382,7 @@ mod tests { // Walk the middle of the color ring; the base centers the menu at // (EXTENT, EXTENT) in its own surface. - let radius = (layout.color_inner + layout.color_outer) / 2.0; + let radius = f64::midpoint(layout.color_inner, layout.color_outer); let samples = 64; let mut surface = surface; let stride = surface.stride() as usize; diff --git a/src/ui/radial_menu/cache/owner_tests.rs b/src/ui/radial_menu/cache/owner_tests.rs index 76e773b26..e303bb4f7 100644 --- a/src/ui/radial_menu/cache/owner_tests.rs +++ b/src/ui/radial_menu/cache/owner_tests.rs @@ -180,7 +180,7 @@ fn transparent_swatches_keep_checkerboard_across_themes_and_densities() { .collect(), )); let layout = state.radial_menu.layout().unwrap(); - let radius = (layout.color_inner + layout.color_outer) / 2.0; + let radius = f64::midpoint(layout.color_inner, layout.color_outer); let mut cache = RadialBaseCache::default(); for scale in [1.0, 2.0] { for theme in [theme::Theme::dark(), theme::Theme::light()] { diff --git a/src/ui/radial_menu/mod.rs b/src/ui/radial_menu/mod.rs index 1d346adea..6e1d76492 100644 --- a/src/ui/radial_menu/mod.rs +++ b/src/ui/radial_menu/mod.rs @@ -96,7 +96,7 @@ pub(crate) fn render_radial_menu_with_context( // Semi-transparent backdrop ctx.set_source_rgba(0.0, 0.0, 0.0, overlay::OVERLAY_DIM_LIGHT); - ctx.rectangle(0.0, 0.0, width as f64, height as f64); + ctx.rectangle(0.0, 0.0, f64::from(width), f64::from(height)); let _ = ctx.fill(); let cx = layout.center_x; @@ -293,7 +293,7 @@ fn draw_compass_hover( return; }; let (seg_angle, offset, tool_gap) = compass_geometry(layout); - let start = offset + idx as f64 * seg_angle; + let start = offset + f64::from(idx) * seg_angle; let end = start + seg_angle; draw_annular_sector( ctx, @@ -337,7 +337,7 @@ fn draw_color_hover( return; }; let (seg_angle, offset, gap) = color_ring_geometry(layout, swatches.len()); - let start = offset + idx as f64 * seg_angle; + let start = offset + f64::from(idx) * seg_angle; let end = start + seg_angle; color_swatch_path(ctx, cx, cy, layout, swatch.recent, start + gap, end - gap); theme::set_color(ctx, COLOR_HOVER_OVERLAY); @@ -363,10 +363,10 @@ fn draw_sub_ring( } let active_tool = input_state.active_tool(); let (seg_angle, offset, _) = compass_geometry(layout); - let parent_start = offset + parent_idx as f64 * seg_angle; + let parent_start = offset + f64::from(parent_idx) * seg_angle; let child_angle = seg_angle / children.len() as f64; - let sub_gap = gap_half_angle((layout.sub_inner + layout.sub_outer) / 2.0); - let mid_r = (layout.sub_inner + layout.sub_outer) / 2.0; + let sub_gap = gap_half_angle(f64::midpoint(layout.sub_inner, layout.sub_outer)); + let mid_r = f64::midpoint(layout.sub_inner, layout.sub_outer); // Narrow sub wedges render glyph-only; wide ones get the full // glyph + label + keycap stack. let show_labels = child_angle * mid_r >= overlay::RADIAL_SUB_LABEL_MIN_ARC; @@ -536,7 +536,7 @@ fn draw_center_well( fn compass_geometry(layout: &RadialMenuLayout) -> (f64, f64, f64) { let seg_angle = 2.0 * PI / RADIAL_TOOL_SEGMENT_COUNT as f64; let offset = -PI / 2.0 - seg_angle / 2.0; - let gap = gap_half_angle((layout.tool_inner + layout.tool_outer) / 2.0); + let gap = gap_half_angle(f64::midpoint(layout.tool_inner, layout.tool_outer)); (seg_angle, offset, gap) } @@ -549,7 +549,7 @@ fn color_ring_geometry(layout: &RadialMenuLayout, count: usize) -> (f64, f64, f6 let seg_angle = 2.0 * PI / count as f64; let offset = -PI / 2.0 - seg_angle / 2.0; let gap = if count > 1 { - gap_half_angle((layout.color_inner + layout.color_outer) / 2.0) + gap_half_angle(f64::midpoint(layout.color_inner, layout.color_outer)) } else { 0.0 }; @@ -584,13 +584,13 @@ fn compass_wedge_midpoint( seg_angle: f64, ) -> (f64, f64) { let mid_angle = start + seg_angle / 2.0; - let mid_r = (layout.tool_inner + layout.tool_outer) / 2.0; + let mid_r = f64::midpoint(layout.tool_inner, layout.tool_outer); (cx + mid_r * mid_angle.cos(), cy + mid_r * mid_angle.sin()) } /// Size-ring track stroke geometry: (arc radius, stroke width). fn size_ring_track_geometry(layout: &RadialMenuLayout) -> (f64, f64) { - let mid_r = (layout.size_inner + layout.size_outer) / 2.0; + let mid_r = f64::midpoint(layout.size_inner, layout.size_outer); let width = (layout.size_outer - layout.size_inner) - 2.0 * overlay::RADIAL_SIZE_TRACK_INSET; (mid_r, width.max(1.0)) } @@ -665,7 +665,7 @@ fn draw_annular_sector( // ── Slice content resolution (ActionMeta registry) ── -/// Short label of a compass slice, resolved through the ActionMeta registry +/// Short label of a compass slice, resolved through the `ActionMeta` registry /// for action slices. fn slice_label(slice: &RadialSlice) -> &'static str { match slice.kind { diff --git a/src/ui/region_capture_picker/cut.rs b/src/ui/region_capture_picker/cut.rs index 5b5b9e55b..3b16fdef9 100644 --- a/src/ui/region_capture_picker/cut.rs +++ b/src/ui/region_capture_picker/cut.rs @@ -24,7 +24,7 @@ pub(super) fn paint_cut_preview(ctx: &cairo::Context, preview: RegionCutPreviewV // pointer, and no other alias mutates the buffer while Cairo holds it. let surface = unsafe { cairo::ImageSurface::create_for_data_unsafe( - pixels.data().as_ptr() as *mut u8, + pixels.data().as_ptr().cast_mut(), cairo::Format::ARgb32, width, height, diff --git a/src/ui/region_capture_picker/tests.rs b/src/ui/region_capture_picker/tests.rs index c49ee825a..e0c20b118 100644 --- a/src/ui/region_capture_picker/tests.rs +++ b/src/ui/region_capture_picker/tests.rs @@ -719,7 +719,7 @@ fn accepted_cut_preview_paints_before_the_scrim_hole() { // writes through the pointer cast from the shared slice. let created = unsafe { cairo::ImageSurface::create_for_data_unsafe( - pixels.data().as_ptr() as *mut u8, + pixels.data().as_ptr().cast_mut(), cairo::Format::ARgb32, 2, 1, diff --git a/src/ui/region_resize_handles.rs b/src/ui/region_resize_handles.rs index 36d878f4f..bdbd51704 100644 --- a/src/ui/region_resize_handles.rs +++ b/src/ui/region_resize_handles.rs @@ -84,8 +84,8 @@ impl RegionResizeHandles { let right = selection.start.0.max(selection.end.0); let top = selection.start.1.min(selection.end.1); let bottom = selection.start.1.max(selection.end.1); - let mid_x = (left + right) / 2.0; - let mid_y = (top + bottom) / 2.0; + let mid_x = f64::midpoint(left, right); + let mid_y = f64::midpoint(top, bottom); let horizontal_room = (right - left) >= MIN_SIDE_FOR_EDGE_HANDLE; let vertical_room = (bottom - top) >= MIN_SIDE_FOR_EDGE_HANDLE; // On a rectangle small enough that four full-size corner targets would diff --git a/src/ui/status/badges.rs b/src/ui/status/badges.rs index 065468e7b..5334b20ae 100644 --- a/src/ui/status/badges.rs +++ b/src/ui/status/badges.rs @@ -73,7 +73,7 @@ pub(crate) fn pan_badge_label(panned: bool) -> &'static str { /// Render a small badge indicating frozen mode (visible even when status bar is hidden). pub fn render_frozen_badge(ctx: &cairo::Context, screen_width: u32, _screen_height: u32) { - render_frozen_badge_with_engine(&UiTextEngine::default(), ctx, screen_width, _screen_height) + render_frozen_badge_with_engine(&UiTextEngine::default(), ctx, screen_width, _screen_height); } pub(crate) fn render_frozen_badge_with_engine( @@ -85,7 +85,7 @@ pub(crate) fn render_frozen_badge_with_engine( draw_badge_with_engine( engine, ctx, - screen_width as f64 - BADGE_PADDING, + f64::from(screen_width) - BADGE_PADDING, BADGE_PADDING, BadgeAlign::Right, frozen_badge_label(), @@ -132,7 +132,7 @@ pub(crate) fn render_zoom_badge_with_engine( let height = draw_badge_with_engine( engine, ctx, - screen_width as f64 - BADGE_PADDING, + f64::from(screen_width) - BADGE_PADDING, BADGE_PADDING, BadgeAlign::Right, &label, @@ -182,7 +182,7 @@ pub(crate) fn render_pan_badge_with_engine( let height = draw_badge_with_engine( engine, ctx, - screen_width as f64 - BADGE_PADDING, + f64::from(screen_width) - BADGE_PADDING, BADGE_PADDING + offset_y, BadgeAlign::Right, &label, @@ -206,7 +206,7 @@ pub fn render_editing_badge( screen_width, _screen_height, offset_y, - ) + ); } pub(crate) fn render_editing_badge_with_engine( @@ -219,7 +219,7 @@ pub(crate) fn render_editing_badge_with_engine( draw_badge_with_engine( engine, ctx, - screen_width as f64 - BADGE_PADDING, + f64::from(screen_width) - BADGE_PADDING, BADGE_PADDING + offset_y, BadgeAlign::Right, editing_badge_label(), @@ -251,7 +251,7 @@ pub fn render_page_badge( board_name, page_index, page_count, - ) + ); } #[allow(clippy::too_many_arguments)] diff --git a/src/ui/status/bar/content.rs b/src/ui/status/bar/content.rs index 3590c3e69..d24d9a656 100644 --- a/src/ui/status/bar/content.rs +++ b/src/ui/status/bar/content.rs @@ -172,14 +172,14 @@ pub(crate) fn compute_status_hud_layout_with_resources( // Unconditional backstop: even a mandatory cluster that still overflows // never widens the pill past the budget. Rendering clips content to the // pill and hit rects are clamped inside it below. - let max_pill_width = screen_width as f64 * STATUS_BAR_MAX_WIDTH_FRACTION; + let max_pill_width = f64::from(screen_width) * STATUS_BAR_MAX_WIDTH_FRACTION; measurement.pill_width = measurement.pill_width.min(max_pill_width); let line_metrics = cluster_line_metrics(&pieces, sep_extents); let (pill_x, pill_y) = pill_origin( position, - screen_width as f64, - screen_height as f64, + f64::from(screen_width), + f64::from(screen_height), measurement.pill_width, measurement.pill_height, ); diff --git a/src/ui/status/bar/helpers.rs b/src/ui/status/bar/helpers.rs index a9dd20b14..f6de7104c 100644 --- a/src/ui/status/bar/helpers.rs +++ b/src/ui/status/bar/helpers.rs @@ -72,7 +72,5 @@ pub(super) fn toolbar_hint_label(input_state: &InputState) -> String { } fn tool_action_label(tool: Tool) -> &'static str { - action_for_tool(tool) - .map(action_display_label) - .unwrap_or(tr("Select")) + action_for_tool(tool).map_or(tr("Select"), action_display_label) } diff --git a/src/ui/status/bar/measurement.rs b/src/ui/status/bar/measurement.rs index 43ad3629f..858171ce6 100644 --- a/src/ui/status/bar/measurement.rs +++ b/src/ui/status/bar/measurement.rs @@ -56,7 +56,7 @@ pub(super) fn measure_status_bar( dot_diameter: f64, screen_width: u32, ) -> Option { - let max_width = screen_width as f64 * STATUS_BAR_MAX_WIDTH_FRACTION - style.padding * 2.0; + let max_width = f64::from(screen_width) * STATUS_BAR_MAX_WIDTH_FRACTION - style.padding * 2.0; let text_style = status_text_style(style.font_size); let sep_advance = engine .measure(text_style, SEGMENT_SEPARATOR, None)? diff --git a/src/ui/status/bar/tests/layout_and_hits.rs b/src/ui/status/bar/tests/layout_and_hits.rs index db51bac9c..4373c3b19 100644 --- a/src/ui/status/bar/tests/layout_and_hits.rs +++ b/src/ui/status/bar/tests/layout_and_hits.rs @@ -71,8 +71,8 @@ fn pill_origin_stays_on_screen_for_all_corners() { pill_width, pill_height, ); - assert!(bx >= inset, "bx {} below inset for {:?}", bx, position); - assert!(by >= inset, "by {} below inset for {:?}", by, position); + assert!(bx >= inset, "bx {bx} below inset for {position:?}"); + assert!(by >= inset, "by {by} below inset for {position:?}"); assert!(by <= screen_height - inset - pill_height); } diff --git a/src/ui/status/bar/tests/width_budget.rs b/src/ui/status/bar/tests/width_budget.rs index 1b1194e84..684218e6b 100644 --- a/src/ui/status/bar/tests/width_budget.rs +++ b/src/ui/status/bar/tests/width_budget.rs @@ -240,7 +240,7 @@ fn pill_width_never_exceeds_max_fraction_of_screen() { let layout = compute_status_hud_layout(&state, position, &style, screen_width, screen_height) .expect("layout"); - let max_pill_width = screen_width as f64 * STATUS_BAR_MAX_WIDTH_FRACTION; + let max_pill_width = f64::from(screen_width) * STATUS_BAR_MAX_WIDTH_FRACTION; assert!( layout.pill_width <= max_pill_width + 1e-6, "pill width {} exceeds cap {} on {}x{} at {:?}", @@ -250,12 +250,10 @@ fn pill_width_never_exceeds_max_fraction_of_screen() { screen_height, position ); - assert!(layout.pill_x >= 0.0, "pill off-screen at {:?}", position); + assert!(layout.pill_x >= 0.0, "pill off-screen at {position:?}"); assert!( - layout.pill_x + layout.pill_width <= screen_width as f64 + 1e-6, - "pill runs off a {}px screen at {:?}", - screen_width, - position + layout.pill_x + layout.pill_width <= f64::from(screen_width) + 1e-6, + "pill runs off a {screen_width}px screen at {position:?}" ); for segment in &layout.segments { assert!( @@ -281,11 +279,10 @@ fn measured_pill_width_stays_within_budget_for_realistic_cluster() { for screen_width in [1280_u32, 1366, 1920] { let measurement = measure(&style, LONG_PREFIX, CLUSTER_WIDTH, screen_width); - let max_pill_width = screen_width as f64 * STATUS_BAR_MAX_WIDTH_FRACTION; + let max_pill_width = f64::from(screen_width) * STATUS_BAR_MAX_WIDTH_FRACTION; assert!( !measurement.overflow, - "cluster {} should fit {}px screen", - CLUSTER_WIDTH, screen_width + "cluster {CLUSTER_WIDTH} should fit {screen_width}px screen" ); assert!( measurement.pill_width <= max_pill_width + 1e-6, @@ -337,7 +334,7 @@ fn width_budget_degrades_board_label_then_drops_help() { // help chip is dropped, yet the cap still holds. let narrow = compute_status_hud_layout(&state, StatusPosition::BottomLeft, &style, 400, 300) .expect("narrow layout"); - assert_eq!(first_text(&narrow), format!("Board {}/{}", index, count)); + assert_eq!(first_text(&narrow), format!("Board {index}/{count}")); assert!( !narrow .segments diff --git a/src/ui/status/zoom_chip.rs b/src/ui/status/zoom_chip.rs index 7c287f8a3..13f098c03 100644 --- a/src/ui/status/zoom_chip.rs +++ b/src/ui/status/zoom_chip.rs @@ -11,8 +11,8 @@ //! The zoom-out/in marks are drawn as bold vector +/- strokes (not circled //! glyphs), sized to the `NN%` digits and using the same adaptive chip color. //! Buttons dispatch through the shared zoom action path: -//! minus = ZoomOut, plus = ZoomIn, `Reset` = ResetZoom (back to 100%), and — only -//! while zoom is active — a compact `Lock` toggle = ToggleZoomLock. The `NN%` +//! minus = `ZoomOut`, plus = `ZoomIn`, `Reset` = `ResetZoom` (back to 100%), and — only +//! while zoom is active — a compact `Lock` toggle = `ToggleZoomLock`. The `NN%` //! readout is a passive display (it consumes clicks but triggers nothing), so //! no drag ever starts on the canvas beneath the chip. @@ -78,13 +78,13 @@ fn zoom_lock_label() -> &'static str { /// Interactive surface a zoom chip button activates on click. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ZoomChipButtonKind { - /// Bold vector minus mark — dispatches ZoomOut. + /// Bold vector minus mark — dispatches `ZoomOut`. Out, - /// Bold vector plus mark — dispatches ZoomIn. + /// Bold vector plus mark — dispatches `ZoomIn`. In, - /// `Reset` — dispatches ResetZoom (back to 100%). + /// `Reset` — dispatches `ResetZoom` (back to 100%). Reset, - /// `Lock` — dispatches ToggleZoomLock (present only while zoomed). + /// `Lock` — dispatches `ToggleZoomLock` (present only while zoomed). Lock, } @@ -249,10 +249,7 @@ fn zoom_glyph_advance(font_size: f64) -> f64 { /// Whether a piece is a vector +/- mark (drawn as strokes) rather than text. fn is_glyph_icon(kind: Option) -> bool { - matches!( - kind, - Some(ZoomChipButtonKind::Out) | Some(ZoomChipButtonKind::In) - ) + matches!(kind, Some(ZoomChipButtonKind::Out | ZoomChipButtonKind::In)) } /// One chip piece before positioning: a glyph/label button or the `NN%` @@ -370,8 +367,8 @@ pub(crate) fn compute_zoom_chip_layout_with_engine( let status_bar_avoid_top = bottom_right_status_bar_avoid_top(input_state, screen_width, screen_height); let (pill_x, pill_y) = chip_origin( - screen_width as f64, - screen_height as f64, + f64::from(screen_width), + f64::from(screen_height), pill_width, pill_height, status_bar_avoid_top, @@ -498,8 +495,8 @@ fn bottom_right_status_bar_avoid_top( } const EDGE_EPS: f64 = 1.0; let inset = ZOOM_CHIP_EDGE_INSET; - let sw = screen_width as f64; - let sh = screen_height as f64; + let sw = f64::from(screen_width); + let sh = f64::from(screen_height); let right_aligned = ((layout.pill_x + layout.pill_width) - (sw - inset)).abs() <= EDGE_EPS; let bottom_anchored = ((layout.pill_y + layout.pill_height) - (sh - inset)).abs() <= EDGE_EPS; // `bounds.1` is the top of the union of the pill and any badges stacked @@ -751,14 +748,16 @@ mod tests { let layout = compute_zoom_chip_layout(&state, &style, w, h).expect("layout"); assert!( - (layout.pill_x + layout.pill_width - (w as f64 - ZOOM_CHIP_EDGE_INSET)).abs() < 1e-6 + (layout.pill_x + layout.pill_width - (f64::from(w) - ZOOM_CHIP_EDGE_INSET)).abs() + < 1e-6 ); assert!( - (layout.pill_y + layout.pill_height - (h as f64 - ZOOM_CHIP_EDGE_INSET)).abs() < 1e-6 + (layout.pill_y + layout.pill_height - (f64::from(h) - ZOOM_CHIP_EDGE_INSET)).abs() + < 1e-6 ); assert!(layout.pill_x >= 0.0 && layout.pill_y >= 0.0); - assert!(layout.pill_x + layout.pill_width <= w as f64 + 1e-6); - assert!(layout.pill_y + layout.pill_height <= h as f64 + 1e-6); + assert!(layout.pill_x + layout.pill_width <= f64::from(w) + 1e-6); + assert!(layout.pill_y + layout.pill_height <= f64::from(h) + 1e-6); } /// The percentage tracks the live scale even at rest (100%), and reflects @@ -1029,7 +1028,7 @@ mod tests { /// Reconciliation invariant (M8): outside Focus Mode, exactly one zoom-% /// indicator shows while zoomed in every - /// {show_zoom_actions}×{show_zoom_chip}×{show_status_bar} combination — + /// `show_zoom_actions` × `show_zoom_chip` × `show_status_bar` combination — /// never zero (the regression), never two. The chip and the status-HUD ZOOM /// badge come from their real layouts; the passive top-corner badge follows /// the backend render gate (`zoom_active && !show_status_bar && @@ -1111,7 +1110,7 @@ mod tests { // Chip stays right-anchored one inset in from the right edge... assert!( - (chip.pill_x + chip.pill_width - (w as f64 - ZOOM_CHIP_EDGE_INSET)).abs() < 1e-6, + (chip.pill_x + chip.pill_width - (f64::from(w) - ZOOM_CHIP_EDGE_INSET)).abs() < 1e-6, "chip stays right-anchored" ); // ...and its bottom edge clears the top of the whole status footprint. @@ -1143,7 +1142,7 @@ mod tests { let chip = compute_zoom_chip_layout(&state, &style, w, h).expect("chip layout"); assert!( - (chip.pill_y + chip.pill_height - (h as f64 - ZOOM_CHIP_EDGE_INSET)).abs() < 1e-6, + (chip.pill_y + chip.pill_height - (f64::from(h) - ZOOM_CHIP_EDGE_INSET)).abs() < 1e-6, "chip stays flush to the bottom with a bottom-left status bar" ); } diff --git a/src/ui/theme.rs b/src/ui/theme.rs index b42bf885a..179074a87 100644 --- a/src/ui/theme.rs +++ b/src/ui/theme.rs @@ -468,7 +468,7 @@ pub mod toolbar { /// Segmented control outer background pub const COLOR_SEGMENT_BG: Rgba = (0.15, 0.17, 0.22, 0.85); /// Active segment background: the accent at reduced alpha, deliberately - /// quieter than COLOR_ACCENT so segmented-control selection (Ico/Txt, + /// quieter than `COLOR_ACCENT` so segmented-control selection (Ico/Txt, /// Simple/Full) never competes with the active-tool highlight pub const COLOR_SEGMENT_ACTIVE: Rgba = rgba(ACCENT_RGB, 0.55); /// Active segment text color diff --git a/src/ui/toasts.rs b/src/ui/toasts.rs index eb3f704da..e9a6d0a23 100644 --- a/src/ui/toasts.rs +++ b/src/ui/toasts.rs @@ -157,8 +157,8 @@ pub(crate) fn preset_toast_geometry_with_engine( /// The four screen-edge strips flashed by blocked-action feedback. #[must_use] pub fn blocked_feedback_rects(screen_width: u32, screen_height: u32) -> [(f64, f64, f64, f64); 4] { - let w = screen_width as f64; - let h = screen_height as f64; + let w = f64::from(screen_width); + let h = f64::from(screen_height); let b = BLOCKED_FEEDBACK_BORDER; [ (0.0, 0.0, w, b), @@ -181,7 +181,7 @@ pub fn render_preset_toast( input_state, screen_width, screen_height, - ) + ); } pub(crate) fn render_preset_toast_with_engine( @@ -216,7 +216,7 @@ pub(crate) fn render_preset_toast_with_engine( return; }; - let fade = preset_toast_fade(progress as f64); + let fade = preset_toast_fade(f64::from(progress)); let (r, g, b) = match kind { PresetFeedbackKind::Apply => TOAST_INFO, PresetFeedbackKind::Save => TOAST_SUCCESS, @@ -273,7 +273,7 @@ pub(crate) fn render_ui_toast_with_engine( let (x, y, width, height) = layout.bounds; let text_style = toast_text_style(UI_TOAST_FONT_SIZE); - let fade = ui_toast_fade(elapsed.as_secs_f64(), duration_secs as f64); + let fade = ui_toast_fade(elapsed.as_secs_f64(), f64::from(duration_secs)); let (r, g, b) = match toast.kind { UiToastKind::Info => TOAST_INFO, UiToastKind::Warning => TOAST_WARNING, @@ -309,7 +309,7 @@ pub(crate) fn render_ui_toast_with_engine( let progress_height = 3.0; let progress_y = y + height - progress_height - 2.0; let progress_width = width - padding_x * 2.0; - let remaining_width = progress_width * (1.0 - progress as f64); + let remaining_width = progress_width * (1.0 - f64::from(progress)); // Track background constants::set_color(ctx, PROGRESS_TRACK); diff --git a/src/ui/toasts/layout.rs b/src/ui/toasts/layout.rs index c6dccc7ba..448d09701 100644 --- a/src/ui/toasts/layout.rs +++ b/src/ui/toasts/layout.rs @@ -26,8 +26,8 @@ pub(super) fn toast_box_geometry( let extents = engine.measure(toast_text_style(font_size), label, None)?; let width = extents.width() + TOAST_PADDING_X * 2.0; let height = extents.height() + TOAST_PADDING_Y * 2.0; - let x = (screen_width as f64 - width) / 2.0; - let center_y = screen_height as f64 * y_ratio; + let x = (f64::from(screen_width) - width) / 2.0; + let center_y = f64::from(screen_height) * y_ratio; let y = center_y - height / 2.0; Some((x, y, width, height)) } @@ -87,7 +87,7 @@ pub(super) fn ui_toast_layout( } else { 0.0 }; - let max_box_width = (screen_width as f64 - TOAST_SCREEN_MARGIN * 2.0).max(1.0); + let max_box_width = (f64::from(screen_width) - TOAST_SCREEN_MARGIN * 2.0).max(1.0); let max_message_width = (max_box_width - TOAST_PADDING_X * 2.0 - action_width - message_action_gap).max(0.0); let message = ellipsize_to_width(engine, &toast.message, max_message_width)?; @@ -100,8 +100,8 @@ pub(super) fn ui_toast_layout( .fold(message_extents.height(), f64::max); let width = (content_width + TOAST_PADDING_X * 2.0).min(max_box_width); let height = content_height + TOAST_PADDING_Y * 2.0; - let x = (screen_width as f64 - width) / 2.0; - let y = screen_height as f64 * UI_TOAST_Y_RATIO - height / 2.0; + let x = (f64::from(screen_width) - width) / 2.0; + let y = f64::from(screen_height) * UI_TOAST_Y_RATIO - height / 2.0; let mut action_x = x + TOAST_PADDING_X + message_extents.width() + message_action_gap; let mut action_bounds = [None, None]; diff --git a/src/ui/toolbar/events.rs b/src/ui/toolbar/events.rs index 5b56454c2..3ab204df8 100644 --- a/src/ui/toolbar/events.rs +++ b/src/ui/toolbar/events.rs @@ -305,7 +305,7 @@ pub enum ToolbarEvent { /// Toggle page counter in the status bar ToggleStatusPageBadge(bool), /// Toggle the board/page badge when the status bar is visible - /// (renamed from TogglePageBadgeWithStatusBar for clarity) + /// (renamed from `TogglePageBadgeWithStatusBar` for clarity) ToggleFloatingBadgeAlways(bool), /// Set toolbar layout mode SetToolbarLayoutMode(ToolbarLayoutMode), diff --git a/src/ui/toolbar/model/activation.rs b/src/ui/toolbar/model/activation.rs index 1ef58344e..05b5c4192 100644 --- a/src/ui/toolbar/model/activation.rs +++ b/src/ui/toolbar/model/activation.rs @@ -353,7 +353,7 @@ mod tests { ] { assert_eq!(spec.curve, SliderCurve::Linear); assert_eq!(spec.tick_positions().count(), 0); - assert_close(spec.t_from_value((spec.min + spec.max) / 2.0), 0.5); + assert_close(spec.t_from_value(f64::midpoint(spec.min, spec.max)), 0.5); } } diff --git a/src/ui/toolbar/model/event_policy.rs b/src/ui/toolbar/model/event_policy.rs index 4616e12d0..5acb9c070 100644 --- a/src/ui/toolbar/model/event_policy.rs +++ b/src/ui/toolbar/model/event_policy.rs @@ -313,9 +313,7 @@ pub(crate) fn short_label_for_event( match event { ToolbarEvent::ToggleFreeze if frozen_active => tr("Unfreeze"), ToolbarEvent::ToggleZoomLock if zoom_locked => tr("Unlock Zoom"), - _ => action_for_event(event) - .map(action_short_label) - .unwrap_or(fallback), + _ => action_for_event(event).map_or(fallback, action_short_label), } } @@ -328,9 +326,7 @@ pub(crate) fn tooltip_label_for_event( match event { ToolbarEvent::ToggleFreeze if frozen_active => tr("Unfreeze"), ToolbarEvent::ToggleZoomLock if zoom_locked => tr("Unlock Zoom"), - _ => action_for_event(event) - .map(action_label) - .unwrap_or(fallback), + _ => action_for_event(event).map_or(fallback, action_label), } } diff --git a/src/ui/toolbar/model/session.rs b/src/ui/toolbar/model/session.rs index c10f64da7..3a6fbb290 100644 --- a/src/ui/toolbar/model/session.rs +++ b/src/ui/toolbar/model/session.rs @@ -31,11 +31,10 @@ impl ToolbarSessionModel { .active_session_name .clone() .unwrap_or_else(|| tr("Default session").to_string()); - let active_path_label = snapshot - .active_session_path - .as_ref() - .map(|path| path.display().to_string()) - .unwrap_or_else(|| tr("No persisted session target").to_string()); + let active_path_label = snapshot.active_session_path.as_ref().map_or_else( + || tr("No persisted session target").to_string(), + |path| path.display().to_string(), + ); let target_active = snapshot.active_session_path.is_some(); let buttons: Vec<_> = vec![ ToolbarSessionButton::new(ToolbarEvent::OpenSession, tr("Open"), target_active), diff --git a/src/ui/toolbar/model/style_pill.rs b/src/ui/toolbar/model/style_pill.rs index a031aebe8..3aa0477eb 100644 --- a/src/ui/toolbar/model/style_pill.rs +++ b/src/ui/toolbar/model/style_pill.rs @@ -152,12 +152,12 @@ pub(crate) enum StylePillControl { EraserModeSegment, /// Docked selection property rendered as a compact cycle button that /// shows the entry's value; clicking steps the property forward - /// through the properties apply machinery (Color, Fill, ArrowHead, - /// TextBackground). + /// through the properties apply machinery (Color, Fill, `ArrowHead`, + /// `TextBackground`). SelectionCycle(SelectionPropertyKind), /// Docked numeric selection property rendered as a −/value/+ stepper; /// the halves step the property through the properties apply - /// machinery (Thickness, FontSize, ArrowLength, ArrowAngle). The + /// machinery (Thickness, `FontSize`, `ArrowLength`, `ArrowAngle`). The /// machinery is relative (direction steps), so the pill uses steppers /// where the tool states use sliders. SelectionStepper(SelectionPropertyKind), diff --git a/src/ui/toolbar/model/style_pill/control.rs b/src/ui/toolbar/model/style_pill/control.rs index e811c9999..b934aba7f 100644 --- a/src/ui/toolbar/model/style_pill/control.rs +++ b/src/ui/toolbar/model/style_pill/control.rs @@ -60,10 +60,12 @@ impl StylePillControl { pub(crate) fn role(self) -> StylePillRole { match self { Self::ColorChip | Self::QuickSwatch(_) => StylePillRole::Swatch, - Self::Slider(StylePillSlider::Thickness) - | Self::Slider(StylePillSlider::Opacity) - | Self::Slider(StylePillSlider::SpotlightMagnification) - | Self::Slider(StylePillSlider::FontSize) => StylePillRole::Slider, + Self::Slider( + StylePillSlider::Thickness + | StylePillSlider::Opacity + | StylePillSlider::SpotlightMagnification + | StylePillSlider::FontSize, + ) => StylePillRole::Slider, Self::ThicknessValue | Self::FontSizeValue => StylePillRole::Value, Self::FillToggle | Self::AutoNumberToggle | Self::FontWeightToggle => { StylePillRole::Toggle @@ -238,8 +240,7 @@ impl StylePillControl { pub(crate) fn carries_inline_readout(self) -> bool { matches!( self, - Self::Slider(StylePillSlider::Opacity) - | Self::Slider(StylePillSlider::SpotlightMagnification) + Self::Slider(StylePillSlider::Opacity | StylePillSlider::SpotlightMagnification) ) } diff --git a/src/ui/toolbar/model/top_spec/tests/structure.rs b/src/ui/toolbar/model/top_spec/tests/structure.rs index d34723fe3..468e06ced 100644 --- a/src/ui/toolbar/model/top_spec/tests/structure.rs +++ b/src/ui/toolbar/model/top_spec/tests/structure.rs @@ -34,8 +34,10 @@ fn regular_spec_owns_control_order_ids_and_events() { let next = ids[position..] .iter() .position(|id| id == expected) - .map(|offset| position + offset) - .unwrap_or_else(|| panic!("{expected} missing from {ids:?}")); + .map_or_else( + || panic!("{expected} missing from {ids:?}"), + |offset| position + offset, + ); position = next + 1; } diff --git a/src/ui/toolbar/session_format.rs b/src/ui/toolbar/session_format.rs index 0a6937af3..929e69604 100644 --- a/src/ui/toolbar/session_format.rs +++ b/src/ui/toolbar/session_format.rs @@ -11,8 +11,7 @@ use std::path::Path; pub fn session_display_name(path: &Path) -> String { path.file_name() .and_then(|name| name.to_str()) - .map(str::to_string) - .unwrap_or_else(|| path.display().to_string()) + .map_or_else(|| path.display().to_string(), str::to_string) } /// Middle-ellipsize so both the head and the distinguishing tail survive. diff --git a/src/ui/toolbar/snapshot/build.rs b/src/ui/toolbar/snapshot/build.rs index 2d7095c37..9bb32756e 100644 --- a/src/ui/toolbar/snapshot/build.rs +++ b/src/ui/toolbar/snapshot/build.rs @@ -35,13 +35,9 @@ impl ToolbarSnapshot { && state.text_editing.mode() == TextInputMode::StickyNote; let override_tool = state.tool_override(); let thickness_targets_eraser = active_tool.uses_eraser_size() - || override_tool - .map(|tool| tool.uses_eraser_size()) - .unwrap_or(false); + || override_tool.is_some_and(|tool| tool.uses_eraser_size()); let thickness_targets_marker = active_tool.uses_marker_opacity() - || override_tool - .map(|tool| tool.uses_marker_opacity()) - .unwrap_or(false); + || override_tool.is_some_and(|tool| tool.uses_marker_opacity()); let eraser_kind = state.style.eraser_kind; let eraser_mode = state.style.eraser_mode; let thickness_value = if thickness_targets_eraser { diff --git a/src/ui/toolbar/snapshot/types.rs b/src/ui/toolbar/snapshot/types.rs index 037325b98..92d115f85 100644 --- a/src/ui/toolbar/snapshot/types.rs +++ b/src/ui/toolbar/snapshot/types.rs @@ -26,7 +26,7 @@ pub enum ToolOptionsKind { Shape, /// Arrow tool: thickness + labels toggle + counter Arrow, - /// StepMarker tool: size + counter + /// `StepMarker` tool: size + counter StepMarker, /// Spotlight tool: magnification only Spotlight, diff --git a/src/ui_text.rs b/src/ui_text.rs index 1fc45b9c6..2f1147fe9 100644 --- a/src/ui_text.rs +++ b/src/ui_text.rs @@ -268,13 +268,13 @@ fn rect_to_extents( logical: pango::Rectangle, baseline: f64, ) -> UiTextExtents { - let scale = pango::SCALE as f64; + let scale = f64::from(pango::SCALE); UiTextExtents { - x_bearing: rect.x() as f64 / scale, - y_bearing: rect.y() as f64 / scale - baseline, - width: rect.width() as f64 / scale, - height: rect.height() as f64 / scale, - x_advance: logical.width() as f64 / scale, + x_bearing: f64::from(rect.x()) / scale, + y_bearing: f64::from(rect.y()) / scale - baseline, + width: f64::from(rect.width()) / scale, + height: f64::from(rect.height()) / scale, + x_advance: f64::from(logical.width()) / scale, y_advance: 0.0, } } @@ -306,18 +306,18 @@ fn pango_style(slant: cairo::FontSlant) -> pango::Style { } fn to_pango_units(value: f64) -> i32 { - let scaled = (value * pango::SCALE as f64).round(); - scaled.clamp(i32::MIN as f64, i32::MAX as f64) as i32 + let scaled = (value * f64::from(pango::SCALE)).round(); + scaled.clamp(f64::from(i32::MIN), f64::from(i32::MAX)) as i32 } fn to_pango_units_f64(value: f64) -> f64 { - let scaled = value * pango::SCALE as f64; - scaled.clamp(i32::MIN as f64, i32::MAX as f64) + let scaled = value * f64::from(pango::SCALE); + scaled.clamp(f64::from(i32::MIN), f64::from(i32::MAX)) } fn layout_metrics(layout: &pango::Layout) -> (pango::Rectangle, pango::Rectangle, f64) { let (ink_rect, logical_rect) = layout.extents(); - let baseline = layout.baseline() as f64 / pango::SCALE as f64; + let baseline = f64::from(layout.baseline()) / f64::from(pango::SCALE); (ink_rect, logical_rect, baseline) } diff --git a/src/unix_signals.rs b/src/unix_signals.rs index 37e19bcc1..d58aaefd7 100644 --- a/src/unix_signals.rs +++ b/src/unix_signals.rs @@ -199,14 +199,14 @@ fn install_handler(signal: libc::c_int) -> io::Result { action.sa_flags = signal_action_flags(); // SAFETY: `action.sa_mask` points to a valid sigset_t field. - if unsafe { libc::sigemptyset(&mut action.sa_mask) } != 0 { + if unsafe { libc::sigemptyset(&raw mut action.sa_mask) } != 0 { return Err(io::Error::last_os_error()); } // SAFETY: Zeroed sigaction is filled by libc when installation succeeds. let mut previous = unsafe { mem::zeroed::() }; // SAFETY: Installs a process-wide handler for the requested signal. - if unsafe { libc::sigaction(signal, &action, &mut previous) } != 0 { + if unsafe { libc::sigaction(signal, &raw const action, &raw mut previous) } != 0 { return Err(io::Error::last_os_error()); } Ok(previous) @@ -255,7 +255,7 @@ extern "C" fn signal_handler(signal: libc::c_int) { let _ = unsafe { libc::write( fd, - (&wakeup as *const u8).cast::(), + (&raw const wakeup).cast::(), mem::size_of::(), ) }; @@ -384,7 +384,7 @@ fn write_pipe_hint(fd: RawFd) -> io::Result<()> { let result = unsafe { libc::write( fd, - (&wakeup as *const u8).cast::(), + (&raw const wakeup).cast::(), mem::size_of::(), ) }; diff --git a/src/unix_signals/tests.rs b/src/unix_signals/tests.rs index e1de81ad3..fbb7ebcb4 100644 --- a/src/unix_signals/tests.rs +++ b/src/unix_signals/tests.rs @@ -23,9 +23,8 @@ fn setup_failure_restores_partial_installation_and_releases_singleton() { let _guard = test_signal_lock(); let before = current_sigaction(TEST_SIGNAL).unwrap(); - let err = match spawn_listener(&[TEST_SIGNAL, i32::MAX], |_| {}, || {}) { - Ok(_) => panic!("invalid signal unexpectedly installed"), - Err(err) => err, + let Err(err) = spawn_listener(&[TEST_SIGNAL, i32::MAX], |_| {}, || {}) else { + panic!("invalid signal unexpectedly installed"); }; assert_eq!(err.kind(), io::ErrorKind::InvalidInput); @@ -373,7 +372,7 @@ fn stale_old_generation_handler_cannot_write_to_reused_numeric_descriptor() { let count = unsafe { libc::read( reuse_read.as_raw_fd(), - (&mut byte as *mut u8).cast::(), + (&raw mut byte).cast::(), 1, ) }; @@ -397,7 +396,7 @@ fn wait_for_owner_wake(source: &RuntimeWakeSource) { revents: 0, }; // SAFETY: source owns the descriptor throughout this bounded wait. - let ready = unsafe { libc::poll(&mut pollfd, 1, 1_000) }; + let ready = unsafe { libc::poll(&raw mut pollfd, 1, 1_000) }; assert_eq!(ready, 1, "owner was not woken"); assert_ne!(pollfd.revents & libc::POLLIN, 0); source.drain().unwrap(); @@ -478,7 +477,7 @@ fn current_sigaction(signal: libc::c_int) -> io::Result { // SAFETY: Zeroed sigaction is filled by libc when the query succeeds. let mut action = unsafe { mem::zeroed::() }; // SAFETY: Null new action queries the current handler for `signal`. - if unsafe { libc::sigaction(signal, ptr::null(), &mut action) } != 0 { + if unsafe { libc::sigaction(signal, ptr::null(), &raw mut action) } != 0 { return Err(io::Error::last_os_error()); } Ok(action) diff --git a/src/update_check/cache.rs b/src/update_check/cache.rs index 790cb06f8..a0e47d66c 100644 --- a/src/update_check/cache.rs +++ b/src/update_check/cache.rs @@ -243,8 +243,7 @@ fn store_at(path: &Path, cache: &UpdateCache) -> bool { pub(crate) fn now_unix() -> u64 { SystemTime::now() .duration_since(UNIX_EPOCH) - .map(|elapsed| elapsed.as_secs()) - .unwrap_or(0) + .map_or(0, |elapsed| elapsed.as_secs()) } /// Seconds since `then`, saturating at 0 when the clock has moved backwards. diff --git a/src/update_check/fetch.rs b/src/update_check/fetch.rs index c4b6746fc..def8be40b 100644 --- a/src/update_check/fetch.rs +++ b/src/update_check/fetch.rs @@ -135,7 +135,7 @@ fn failure_detail(program: &str, stderr: &str, code: Option) -> String { ("curl", Some(7)) => tr("could not connect").to_string(), ("curl", Some(22)) => tr("server returned an error response").to_string(), ("curl", Some(28)) => tr("request timed out").to_string(), - ("curl", Some(35) | Some(60)) => tr("TLS verification failed").to_string(), + ("curl", Some(35 | 60)) => tr("TLS verification failed").to_string(), ("curl", Some(63)) => tr("response larger than expected").to_string(), (_, Some(4)) => tr("network failure").to_string(), (_, Some(5)) => tr("TLS verification failed").to_string(), diff --git a/src/update_check/mod.rs b/src/update_check/mod.rs index 79a02c7cc..05feb0ab0 100644 --- a/src/update_check/mod.rs +++ b/src/update_check/mod.rs @@ -111,15 +111,13 @@ pub fn background_checks_enabled(config_enabled: bool) -> bool { /// switch whose only job is to stop network access, an unrecognized value is /// honored rather than ignored, so a typo cannot silently re-enable the check. fn env_opt_out() -> bool { - env::var_os(DISABLE_UPDATE_CHECK_ENV) - .map(|value| { - let value = value.to_string_lossy().trim().to_ascii_lowercase(); - !matches!( - value.as_str(), - "" | "0" | "false" | "no" | "off" | "disable" | "disabled" - ) - }) - .unwrap_or(false) + env::var_os(DISABLE_UPDATE_CHECK_ENV).is_some_and(|value| { + let value = value.to_string_lossy().trim().to_ascii_lowercase(); + !matches!( + value.as_str(), + "" | "0" | "false" | "no" | "off" | "disable" | "disabled" + ) + }) } /// Report the last stored result without any network access. @@ -403,7 +401,7 @@ mod tests { #[test] fn due_when_never_attempted_or_interval_elapsed() { - let day = Duration::from_secs(86_400); + let day = Duration::from_hours(24); assert!(is_due(0, 1_750_000_000, day)); assert!(is_due(1_750_000_000, 1_750_086_400, day)); @@ -426,13 +424,13 @@ mod tests { attempted.note_attempt(); let untouched = CheckThrottle::default(); - assert!(attempted.attempted_within(Duration::from_secs(86_400))); + assert!(attempted.attempted_within(Duration::from_hours(24))); // A zero interval means "no throttle", so the guard must not block. assert!(!attempted.attempted_within(Duration::ZERO)); // One watcher's attempt does not become ambient process-wide state. - assert!(!attempted.is_due_now(Duration::from_secs(86_400))); - assert!(untouched.is_due_now(Duration::from_secs(86_400))); + assert!(!attempted.is_due_now(Duration::from_hours(24))); + assert!(untouched.is_due_now(Duration::from_hours(24))); // SAFETY: this test still holds the environment mutex in `_lock`. unsafe { @@ -540,7 +538,7 @@ mod tests { assert!(!is_due( cache::load().last_attempt_unix, cache::now_unix(), - Duration::from_secs(86_400) + Duration::from_hours(24) )); // A record with no success on it (a migrated v1 file) is unknown rather diff --git a/src/util/arrow.rs b/src/util/arrow.rs index 02fcb3962..6210d26d5 100644 --- a/src/util/arrow.rs +++ b/src/util/arrow.rs @@ -78,10 +78,10 @@ fn arrow_axis( arrow_length: f64, arrow_angle: f64, ) -> Option { - let tip_x = tip_x as f64; - let tip_y = tip_y as f64; - let tail_x = tail_x as f64; - let tail_y = tail_y as f64; + let tip_x = f64::from(tip_x); + let tip_y = f64::from(tip_y); + let tail_x = f64::from(tail_x); + let tail_y = f64::from(tail_y); let dir_x = tail_x - tip_x; let dir_y = tail_y - tip_y; @@ -401,8 +401,8 @@ impl ArrowAxis { fn curve_control(&self, bend: f64) -> (f64, f64) { let chord_len = self.chord_length(); let mid = ( - (self.tip.0 + self.tail.0) / 2.0, - (self.tip.1 + self.tail.1) / 2.0, + f64::midpoint(self.tip.0, self.tail.0), + f64::midpoint(self.tip.1, self.tail.1), ); let offset = clamp_arrow_bend(bend) * chord_len; (mid.0 + self.perp.0 * offset, mid.1 + self.perp.1 * offset) diff --git a/src/util/geometry.rs b/src/util/geometry.rs index 40fb6ab2e..e7c998393 100644 --- a/src/util/geometry.rs +++ b/src/util/geometry.rs @@ -132,7 +132,7 @@ pub fn ellipse_bounds(x1: i32, y1: i32, x2: i32, y2: i32) -> (i32, i32, i32, i32 fn ellipse_axis_bounds(first: i32, second: i32) -> (i32, i32) { let first = i64::from(first); let second = i64::from(second); - let center = (first + second) / 2; + let center = i64::midpoint(first, second); let radius = (second - first).abs() / 2; // An average of two i32 values and half their distance always fit in i32. diff --git a/src/util/tests.rs b/src/util/tests.rs index 03879038a..8894de933 100644 --- a/src/util/tests.rs +++ b/src/util/tests.rs @@ -31,8 +31,8 @@ fn head_triangle( /// Midpoint of the head's back edge, where the shaft meets the head. fn head_base(geometry: &super::arrow::ArrowheadTriangle) -> (f64, f64) { ( - (geometry.left.0 + geometry.right.0) / 2.0, - (geometry.left.1 + geometry.right.1) / 2.0, + f64::midpoint(geometry.left.0, geometry.right.0), + f64::midpoint(geometry.left.1, geometry.right.1), ) } @@ -490,8 +490,8 @@ fn curved_head_aims_along_the_end_tangent_not_the_chord() { let skeleton = styled_skeleton(ArrowStyle::Curved, 0.8); let head = skeleton.head; let base = ( - (head.left.0 + head.right.0) / 2.0, - (head.left.1 + head.right.1) / 2.0, + f64::midpoint(head.left.0, head.right.0), + f64::midpoint(head.left.1, head.right.1), ); // Direction from the base to the tip: the axis the head is aimed along. let aim = (head.tip.0 - base.0, head.tip.1 - base.1); diff --git a/tests/repository_guards/config_writers.rs b/tests/repository_guards/config_writers.rs index 79f83a99e..f11af6c69 100644 --- a/tests/repository_guards/config_writers.rs +++ b/tests/repository_guards/config_writers.rs @@ -491,7 +491,7 @@ struct Audit<'tree> { test_sources: TestSources, } -impl<'tree> Audit<'tree> { +impl Audit<'_> { fn fail(&mut self, failure: String) { self.failures.push(failure); } @@ -681,7 +681,7 @@ impl<'tree> Audit<'tree> { } /// No write leaves an implementing file as a value. - fn const_initializers(&mut self, source: &Source, capable: &BTreeSet) { + fn const_initializers(&mut self, source: &Source<'_>, capable: &BTreeSet) { for item in const_items(&source.masked, &source.test_spans) { let named: BTreeSet<&str> = words(&source.masked[item.start..item.end]) .map(|(_, word)| word) @@ -704,7 +704,7 @@ impl<'tree> Audit<'tree> { /// No write leaves an implementing file through a trait. fn trait_writers( &mut self, - source: &Source, + source: &Source<'_>, items: &[FunctionItem], capable: &BTreeSet, ) { @@ -726,7 +726,7 @@ impl<'tree> Audit<'tree> { /// A trait declared here may not name a method that can write, even /// without a body: the offer itself is the capability. - fn trait_declarations(&mut self, source: &Source, capable: &BTreeSet) { + fn trait_declarations(&mut self, source: &Source<'_>, capable: &BTreeSet) { for declaration in trait_declarations(&source.masked, &source.test_spans) { for method in declaration.methods.intersection(capable) { self.fail(format!( @@ -741,7 +741,7 @@ impl<'tree> Audit<'tree> { } } - fn io_write_surface(&mut self, source: &Source) { + fn io_write_surface(&mut self, source: &Source<'_>) { let items = function_items(&source.masked, &source.test_spans); if !items .iter() @@ -776,7 +776,7 @@ impl<'tree> Audit<'tree> { } } - fn document_write_surface(&mut self, source: &Source) { + fn document_write_surface(&mut self, source: &Source<'_>) { let items = function_items(&source.masked, &source.test_spans); let seeds: BTreeSet = names(WRITE_PRIMITIVES) .into_iter() diff --git a/tests/repository_guards/translations.rs b/tests/repository_guards/translations.rs index a955b2357..d11a5799b 100644 --- a/tests/repository_guards/translations.rs +++ b/tests/repository_guards/translations.rs @@ -58,11 +58,11 @@ const ACCESSOR_ARGUMENTS: [(&str, &str); 4] = [ ("src/config/action_meta/mod.rs", "source_label(action)"), ( "src/config/action_meta/mod.rs", - "action_meta(action).map(|meta|meta.short_label()).unwrap_or(\"Action\")", + "action_meta(action).map_or(\"Action\",|meta|meta.short_label())", ), ( "src/config/action_meta/mod.rs", - "action_meta(action).map(|meta|meta.description).unwrap_or(\"\")", + "action_meta(action).map_or(\"\",|meta|meta.description)", ), ("src/config/action_meta/mod.rs", "stripped"), ]; @@ -153,9 +153,8 @@ fn collect_marks(path: &Path, source: &str, reading: &mut Reading) { .any(|(file, allowed)| path == Path::new(file) && argument == *allowed); if !exempt { reading.failures.push(format!( - "{site}: `{}{argument})` is not a literal the guard can read; \ - write the string at the call", - mark + "{site}: `{mark}{argument})` is not a literal the guard can read; \ + write the string at the call" )); } } diff --git a/tests/ui.rs b/tests/ui.rs index ce305e77e..3339f90a6 100644 --- a/tests/ui.rs +++ b/tests/ui.rs @@ -31,8 +31,7 @@ fn surface_with_context(width: i32, height: i32) -> (ImageSurface, Context) { fn surface_has_pixels(surface: &mut ImageSurface) -> bool { surface .data() - .map(|data| data.iter().any(|byte| *byte != 0)) - .unwrap_or(false) + .is_ok_and(|data| data.iter().any(|byte| *byte != 0)) } fn alpha_at(surface: &mut ImageSurface, x: i32, y: i32) -> u8 { @@ -309,7 +308,7 @@ fn help_overlay_footer_offers_clickable_replay_and_about() { for y in 0..1000 { for x in 0..1400 { if let Some(HelpOverlayRegion::Row(action)) = - result.hit_map.region_at(x as f64, y as f64) + result.hit_map.region_at(f64::from(x), f64::from(y)) && !found.contains(&action) { found.push(action); @@ -345,7 +344,8 @@ fn help_overlay_footer_offers_the_unbound_actions_toggle() { let toggle = (0..1000) .flat_map(|y| (0..1400).map(move |x| (x, y))) .find(|&(x, y)| { - result.hit_map.region_at(x as f64, y as f64) == Some(HelpOverlayRegion::ToggleUnbound) + result.hit_map.region_at(f64::from(x), f64::from(y)) + == Some(HelpOverlayRegion::ToggleUnbound) }) .expect("rendered unbound-actions toggle"); @@ -374,7 +374,7 @@ fn help_result_owns_rendered_footer_hits_and_matches_drawing_only_pixels() { let mut about = None; for y in 0..1000 { for x in 0..1400 { - match result.hit_map.region_at(x as f64, y as f64) { + match result.hit_map.region_at(f64::from(x), f64::from(y)) { Some(HelpOverlayRegion::Row(Action::ReplayTour)) => replay = Some((x, y)), Some(HelpOverlayRegion::Row(Action::OpenAbout)) => about = Some((x, y)), _ => {} @@ -426,7 +426,7 @@ fn help_result_owns_rendered_footer_hits_and_matches_drawing_only_pixels() { ); let (x, y) = about.unwrap(); assert_eq!( - result.hit_map.region_at(x as f64, y as f64), + result.hit_map.region_at(f64::from(x), f64::from(y)), Some(HelpOverlayRegion::Row(Action::OpenAbout)), "another paint must not replace the owned result" ); @@ -443,8 +443,8 @@ fn small_palette_surface_and_shadow_fit_the_screen() { let (x, y, panel_width, panel_height) = ui::command_palette_visual_geometry(&input, width, height).unwrap(); assert!(x >= 0.0 && y >= 0.0); - assert!(x + panel_width <= width as f64); - assert!(y + panel_height <= height as f64); + assert!(x + panel_width <= f64::from(width)); + assert!(y + panel_height <= f64::from(height)); let (mut surface, ctx) = surface_with_context(width as i32, height as i32); ui::render_command_palette(&ctx, &input, width, height); drop(ctx);