Fix audit findings, expand tests, and add a CI quality gate
Some checks failed
CI / check (pull_request) Failing after 6s

Addresses the deep codebase audit:

- Center the static wallpaper cover-fit crop so the software (wl_shm)
  path agrees with the GPU path and the greeter, instead of anchoring
  the crop top-left.
- Desktop-entry Exec tokenizer: respect single quotes and proper
  backslash escaping per the freedesktop spec.
- Greeter: dispatch CancelSession whenever the UI resets to the
  username stage so the error path can't leave greetd holding a stale
  PAM conversation; add a per-roundtrip timeout so a wedged greetd peer
  can't strand the "Working" spinner.
- start_locker: return an error instead of spawning a child that
  expect()-panics when WAYLAND_DISPLAY is unset.
- Bound in-flight PAM checks with a concurrency cap, since libpam
  cannot be cancelled and a stuck module would otherwise leak one
  uncancellable thread per retry.
- Expand unit/regression tests (157 total): tokenizer edge cases and a
  pseudo-fuzz, blit offset/clamp cases, horizontal+vertical cover
  centering, greetd roundtrip-timeout and connection-recovery.
- Reformat the workspace to rustfmt-clean and add a Forgejo CI gate
  (fmt --check, clippy -D warnings, all-target tests, locked release
  build) — previously the only workflow was an Arch package builder.
This commit is contained in:
Breadway 2026-08-31 18:46:19 +08:00
parent 94289865c0
commit 1636eb86d0
15 changed files with 1242 additions and 262 deletions

View file

@ -107,7 +107,10 @@ mod tests {
fn defaults_match_design_system() {
let a = Appearance::default();
assert_eq!(a.background.mode, BackgroundMode::Color);
assert!(!a.background.ken_burns, "Ken Burns must be opt-in (CPU cost)");
assert!(
!a.background.ken_burns,
"Ken Burns must be opt-in (CPU cost)"
);
assert_eq!(a.clock.format, "%H:%M");
assert_eq!(a.clock.date_format, "%A · %b %d");
assert_eq!(a.font.family, "Varela Round");

View file

@ -213,7 +213,14 @@ impl TextRenderer {
origin_y: f32,
) {
self.draw_line_weighted(
pixmap, text, family, size_px, color, origin_x, origin_y, Weight::NORMAL,
pixmap,
text,
family,
size_px,
color,
origin_x,
origin_y,
Weight::NORMAL,
);
}
@ -317,9 +324,8 @@ fn blend_over(pixmap: &mut Pixmap, x: u32, y: u32, r: u8, g: u8, b: u8, a: u8) {
// out_a = sa + da*(255-sa)/255; out_rgb = src_rgb*sa/255 + dst_rgb*(1-sa).
let da = dst.alpha() as u32;
let out_a = (sa + da * (255 - sa) / 255) as u8;
let out_c = |c: u8, dc: u8| -> u8 {
(c as u32 * sa / 255 + dc as u32 * (255 - sa) / 255) as u8
};
let out_c =
|c: u8, dc: u8| -> u8 { (c as u32 * sa / 255 + dc as u32 * (255 - sa) / 255) as u8 };
if let Some(blended) = PremultipliedColorU8::from_rgba(
out_c(r, dst.red()),
out_c(g, dst.green()),
@ -386,7 +392,10 @@ mod tests {
0.0,
);
let full_max = full.pixels().iter().map(|p| p.red()).max().unwrap();
assert!(full_max > 200, "full-alpha text should render bright, got {full_max}");
assert!(
full_max > 200,
"full-alpha text should render bright, got {full_max}"
);
let faint = tiny_skia::Color::from_rgba(1.0, 1.0, 1.0, 0.1).unwrap();
let mut low = Pixmap::new(200, 40).unwrap();
@ -439,10 +448,7 @@ mod tests {
// Full-coverage glyph cores are legitimately opaque, but the AA
// edges must carry real intermediate alphas — the old forced-255
// blend made *every* drawn pixel (edges included) fully opaque.
let has_edge = t
.pixels()
.iter()
.any(|p| p.alpha() > 0 && p.alpha() < 255);
let has_edge = t.pixels().iter().any(|p| p.alpha() > 0 && p.alpha() < 255);
assert!(
has_edge,
"glyph AA edges must keep intermediate alphas onto a transparent pixmap"