Skip to content

Releases: vdavid/prvw

Prvw v0.13.0

05 May 22:00
39d0319

Choose a tag to compare

Added

  • View → Sort by → {Name | Date | File type}. Name (natural alphanumeric, case-insensitive) is the default and fixes
    the photo_1, photo_10, photo_11, photo_2 problem — photo_2 now sorts before photo_10. All comparators ascending;
    Name is the tiebreaker for Date (file mtime) and File type (lowercased extension, empty extension first). Persists
    across launches. Changing the sort updates the in-memory cache transparently: in-window decoded images stay,
    out-of-window entries get evicted, missing in-window slots get queued for preload — loop navigation respected. The
    underlying path-keyed cache (refactor that makes this work) also unblocks a future directory-watcher rescan
    (9a80ec3e,
    bb95700e,
    04ca1311).

Changed

  • Release script runs full ./scripts/check.sh before bumping the version, so lint/format/test regressions and the
    changelog-links validator (fabricated commit SHAs) abort the release before any tag exists. Also auto-detaches stale
    /Volumes/Prvw* mounts and brings the self-hosted runner back up via svc.sh start if its LaunchAgent died — both
    scenarios broke v0.12.0's first attempt (eb9b4196).
  • Release skill caffeinates the MacBook through the build (caffeinate -i, idle-sleep only) and verifies the GitHub
    Release assets + https://getprvw.com/latest.json after the run succeeds, surfacing webhook deploy failures without
    blocking release success (d09d6471).

Fixed

  • Flaky integration tests under load. histogram_hover_bin_updates and narrow_window_overlays_dont_crash used
    fixed sleep(100..200ms) between an MCP/HTTP command and the state-read assertion; under release-script load (full
    check suite + nextest parallelism on a busy machine), processing exceeded the sleep budget and the assertion fired on
    stale state. Both now poll via the existing wait_for_state helper. Surfaced during v0.13.0 release prep
    (5a567c0e).

Prvw v0.12.0

27 Apr 18:55

Choose a tag to compare

Added

  • RGB histogram overlay. Toggle via View → Histogram or bare H. Top-right of the window, rounded translucent
    backdrop matching the existing pill style, off by default. Hover the histogram for per-bin R/G/B counts. Computed
    lazily on first toggle and cached per-image; rayon-parallel scan handles 20+ MP buffers in a few ms. Persists
    across launches (d811bb32,
    a6c833c6).
  • EXIF info overlay. Toggle via View → Exif info or bare E. Below the histogram with a small gap when both
    visible, same width and backdrop. Curated photographer-friendly grouping: camera, exposure triplet
    (1/250 s f/2.8 ISO 400), lens, date taken, image dimensions, software, GPS. Hidden entirely on formats with no
    EXIF data. Long values wrap and grow the panel while preserving the row pitch. Backed by nom-exif for JPEG /
    Generic and rawler::RawMetadata::exif for RAW (419c6d54,
    a6c833c6,
    6846416a).
  • Loop navigation. Toggle via Navigate → Loop navigation or bare L. At the last image Next wraps to the first
    and vice versa. The preloader is wrap-aware too — toggling on near a directory edge triggers preloads of the
    wrap-side indices, toggling off evicts them, so the cache always matches the active window. Off by default,
    persists (88b37740).
  • Home / End jump to first / last image. Navigate menu gains "Go to first" (Home) and "Go to last" (End)
    entries, with separators grouping the menu by intent. Absolute jumps; loop navigation does not affect them
    (1e8c316c).
  • Dev-only screenshot_window MCP tool that captures the entire native window — overlays, vibrancy, modal
    panels — by shelling out to /usr/sbin/screencapture -l <windowID>. Compile-time gated to debug builds; release
    builds neither register the tool nor link the dispatch arm. Requires Screen Recording permission on first use
    (9954a91d).
  • Website download buttons now show the file size next to the architecture
    (b3b17f46).

Changed

  • Markdown / prose formatting unified across the monorepo via oxfmt (Cmdr's setup). Replaces Prettier; runs
    from repo root over docs/, every CLAUDE.md, root markdown, and website source. Auto-fixes locally, checks in
    CI (a30c1e5d,
    cdaa80af,
    47742664).
  • Histogram and EXIF overlay backdrop alpha bumped from 0.55 to 0.66 for legibility against bright images
    (6846416a).
  • workflow_dispatch can now trigger website deploys directly from the Actions tab
    (446b8ae0).

Fixed

  • Stale prvw://state snapshot on background preloads. Found while building loop navigation: poll_preloader
    only updated shared state when a Ready matched the pending current index, so neighbor preloads left
    cache_indices (and other fields) stale until the next user action. Now updated on every preload arrival
    (88b37740).
  • Histogram briefly showed the previous image's curve on cache-miss navigation while the QuickLook thumbnail
    placeholder was on screen. display_thumbnail_placeholder now clears the cached histogram data so the right
    histogram appears once the full image arrives (a6c833c6).
  • Pricing card on the website was clipping the Download dropdown via overflow-hidden; the 1px accent line is now
    inset within the rounded corners so the parent doesn't have to clip
    (c1e467ec).

Prvw v0.11.0

26 Apr 07:35

Choose a tag to compare

Added

  • Blurry thumbnail placeholder while the full image decodes. Cache-miss navigation now uploads the QuickLook thumbnail through the same display pipeline as the full image, so zoom, EDR, and auto-fit match. New thumbnails/ module with a centered-outward scheduler (80fa5102).
  • Parallel pixel-dimensions prefetcher. A 16-thread worker reads dimensions for every index in current ± WINDOW_RADIUS upfront, so placeholder display drops from 200 ms – 1.3 s on slow shares to 1 – 2 ms post-warmup. Three-tier dispatcher: image::image_dimensions for PNG/GIF/BMP, a single-buffer JPEG parse for one SMB round trip, ImageIO for the rest (d02e61d7).
  • Updater now surfaces "update available" on no-file launches from Finder / Dock too; download is deferred to viewer init so an admin prompt can't interrupt onboarding (0ee6b337).

Changed

  • Navigation no longer freezes on slow network shares. QuickLook submission moved off the main thread to a dedicated prvw-thumbgen worker (was costing ~150 ms per submit on SMB), completion blocks batch into a shared queue so a 38-thumb burst wakes winit 1 – 2 times instead of 38, and mark_ready no longer pre-reads source dims (~7 s of main-thread blocking on a 38-thumb burst, now lazy) (16d63b46).
  • Thumbnail scheduler prioritises immediate neighbours first, then outside-window, then current. The previous order left the next-arrow target without a placeholder for ~5 s after launch on slow folders (d02e61d7).
  • Updater bundle swap is now atomic via renamex_np(RENAME_SWAP) — no window where the app is absent or partial, and a crash mid-update leaves one intact bundle either way (0b52f850).
  • Updater deregisters the old bundle from Launch Services before swapping so the "Open With" menu no longer shows both old and new Prvw side by side after an update (bb0bbbe0).
  • Updater only runs on bundles installed in /Applications; dev builds and ~/Downloads copies are skipped (0ee6b337).
  • Website tagline + features section refreshed (0664402f); terms and conditions updated (5bae3ce1).

Fixed

  • Escape now closes About, Onboarding, and Settings windows again. The hidden Escape button was excluded from performKeyEquivalent: traversal; switched to borderless + zero-size frame (dc8ee8da).
  • Integration tests no longer flake from a port-keyed PRVW_DATA_DIR; each TestApp now gets its own tempfile::TempDir (5fd0f0de).

Prvw v0.10.0

19 Apr 08:52

Choose a tag to compare

Changed

  • Navigation is now near-instant in RAW folders. End-to-end rework of the preloader to route the current image
    through the background pipeline on a cache miss instead of blocking the main thread, so a fast key press never
    freezes the UI. The pool switched from a custom rayon pool to a single dedicated std::thread worker — rawler's
    internal par_iter inherits the caller's pool, so a 1-thread custom pool was starving rawler's parallel stages
    (demosaic, chroma_nr, sharpen) of cores. A plain OS thread isn't a rayon worker, so par_iter falls back to the
    global pool and each 20 MP ARW preload now decodes in ~300-450 ms instead of ~2 s. Preload priority is now
    direction-aware: forward navigation loads N+1, N+2, N-1, N-2 in that order, backward mirrors, and startup
    interleaves. In-flight decodes for indices still wanted are no longer restarted across successive request_preload
    calls — they keep their cancellation token and continue from where they left off. A 30 ms debounce coalesces wheel
    spins: 20 fast clicks collapse into a single navigate_by(±20) jump with one decode. Cache entries outside N±2
    get evicted on every navigation (previously they lingered until the LRU budget pushed them out — visible on small
    JPEGs where 50+ could fit the 512 MB budget). The wgpu Texture for the currently-displayed image is now
    explicitly destroy()'d on image swap — fixes a 4 GB+ RSS bloat on long RAW sessions where Metal on unified memory
    wasn't returning the backing just by replacing the bind group. File I/O moved to an abandonable detached thread
    with channel-based polling, so a wedged network share (SMB, flaky NFS) can't block the caller — std::fs::File::read
    has no timeout, so the old in-thread cancellation check did nothing until the kernel unblocked the syscall.
  • Preloader debug logs are now structured and greppable. Each preload task emits one line on start and one on
    finish with the file name, position label (N+1, N-2, ...), 1-based directory position, and total wall time:
    Initiated loading 9.jpg (N+1, 10/17) / Fully loaded 9.jpg (N+1, 10/17) in 25ms. Cache evictions log
    Evicted 7.jpg (N-3) from memory - 2.5 MB freed (out of window) or ... (LRU) depending on the trigger. Enable
    with RUST_LOG=prvw::navigation=debug.

Fixed

  • Scrolling through a folder of RAWs no longer stutters when decodes can't keep up. The old preloader kept
    submitting low-priority neighbor decodes that shared CPU with the currently-needed image, so pressing right six
    times at 400 ms intervals pushed the priority-zero decode from ~500 ms to 2-3 s. Navigation now defers the
    priority-zero render until the decode lands on the main thread via poll_preloader, with a clean "Loading…" title
    in the meantime. Side effect: no more double-decoding of the same image (main thread + rayon) on cache miss.
  • Lens correction polarity was doubling distortion instead of correcting it on some lenses. The sign was
    reversed in apply_distortion_resample so barrel correction turned into barrel amplification and pincushion
    correction turned into pincushion amplification. Fixed; distortion now goes the right way.
  • HDR / EDR output now actually renders HDR-bright on XDR displays (Phase 5.2). The original Phase 5.1 path decoded
    RAWs into a half-float buffer but routed them through moxcms with a gamma-encoded kCGColorSpaceExtendedDisplayP3
    layer, which clipped above-1.0 linear values at ICC-transform time and left the EDR compositor with nothing above
    display-white to brighten. Two fixes: (1) on the HDR path only, bypass moxcms and apply a direct linear Rec.2020 →
    linear Display P3 3×3 matrix (color::profiles::rec2020_to_linear_display_p3_inplace) that preserves above-white
    values. (2) Flip the CAMetalLayer colorspace to kCGColorSpaceExtendedLinearDisplayP3 so the compositor
    interprets the buffer's linear values correctly. SDR path still goes through moxcms → user's display ICC and is
    bit-identical to Phase 6.1. Trade-off to name: HDR output uses Display P3 rather than the user's calibrated display
    profile, since the OS's EDR compositor takes over colorspace conversion on that path — inherent to going into EDR
    mode, not a choice. See docs/notes/raw-support-phase5.md.

Added

  • RAW per-stage timing + benchmark table (Phase 6.4): decoding::raw::decode now emits one DEBUG log line per
    pipeline stage plus a comma-separated summary line, ready to grep. Enable with RUST_LOG=prvw::decoding::raw=debug.
    apps/desktop/src/decoding/CLAUDE.md ships a reference table of typical warm-decode timings on a 20 MP ARW (M3 Max,
    release, defaults) so agents and humans can spot regressions without a profiler. Pairs with a new
    Settings → General → "Preload next/prev images" toggle that disables background preloading so single-image
    cold-start decodes can be measured without concurrent work interfering.
  • HDR brightness gain (Phase 5.2): a new 0.5 – 4.0 slider in Settings → RAW → Output (default 2.0) pushes
    scene-white content into the EDR headroom so HDR output reads genuinely "HDR-bright" on an XDR / OLED panel instead
    of timidly preserving SDR brightness and only using headroom for sparse specular highlights. Matches the visual
    brightness of Preview.app / Photos on the same display. Ignored on the SDR path; hdr_gain = 1.0 restores the
    pre-5.2 HDR behavior (above-white content preserved but no overall brightness lift).
  • Clarity (local contrast) for RAW (Phase 6.2): RAWs now get a larger-radius unsharp-mask pass on luminance before
    capture sharpening. Lifts midtone features — shape silhouettes, textures, the mid-frequency content — that survive
    display downscaling, so the image reads crisper at fit-to-window zoom, not just at 100 %. Same math as capture
    sharpening, σ ≈ 10 px instead of 0.8 px, luminance-only. New "Clarity (local contrast)" toggle at the top of
    Settings → RAW → Detail, with "Clarity radius" (2 – 50 px, default 10 px) and "Clarity amount" (0.00 – 1.00,
    default 0.40) sliders directly beneath. On by default; toggling off reproduces pre-6.2 output. Closes the visible
    "crispness gap" against Affinity's "Detail Refinement" pass. Adds ~200 – 400 ms to a 20 MP decode on Apple Silicon.
    See docs/notes/raw-support-phase6.md.

Changed

  • DCP ~1.6× faster (Phase 6.5): the per-camera HueSatMap / LookTable trilinear-interpolation LUT apply in
    color::dcp::apply is now #[multiversion]-annotated (NEON / AVX2+FMA) with branchless HSV conversion,
    f32::mul_add on all seven trilinear lerps, and rem_euclid calls on the hot path replaced with compare-and-add
    (the single biggest win — rem_euclid(6.0) in rgb_to_hsv invoked fmodf per pixel). Processes pixels in
    1024-wide rayon chunks to amortise scheduling overhead. ~36 ms → ~22 ms per 20 MP decode (Apple Silicon M3 Max,
    release). Applies to both HueSatMap and LookTable paths since they share apply_hue_sat_map. Output is
    bit-equivalent to the scalar reference within float rounding (max channel Δ 1.79e-7 across a 256×256 synthetic
    buffer; well below the golden regression's < 3.0 ΔE tolerance).
  • Clarity ~10× faster on 20 MP (Phase 6.4): the σ=10 local-contrast pass now takes ~14 ms instead of ~144 ms on a
    20 MP image (Apple Silicon M3 Max, release). For σ ≥ 4 and images ≥ 1 MP, clarity now downsamples the luma plane 4×
    (box average), blurs at σ' = σ/4 (~15-tap kernel instead of 61), then bilinearly upsamples — the Gaussian-blurred
    signal is low-frequency by design, so the round-trip is near-invisible. Small σ and small images still take the
    direct-convolution path for byte-identical output against pre-6.4. Total per-decode budget on a 20 MP HDR ARW drops
    from ~650 ms to ~293 ms warm, a ~2.2× overall speedup when paired with the HDR-diagnostic log gating below. See
    apps/desktop/src/decoding/CLAUDE.md § "Per-stage timing" for the reference table.
  • HDR-diagnostic log scans now run only when info logging is active (Phase 6.4): the three post-pipeline
    peak-value scans (peak linear value, peak post-ICC, peak f16) are now gated behind log::log_enabled!(Info)
    and, on the HDR branch, parallelized via rayon. ~40 ms saved per HDR decode when info logging is off; ~30 ms when
    it's on. No observable behavior change — release builds that don't ship info logging pay nothing.
  • RAW defaults tuned against Affinity / Preview (Phase 6.1.1): the parametric RAW stages now ship with values
    closer to Affinity Photo's per-camera-tuned output on our sample set — DEFAULT_SATURATION_BOOST 0.08 → 0.18,
    DEFAULT_MIDTONE_ANCHOR 0.40 → 0.45, and a new baseline_exposure_offset slider (default +0.73 EV) adds a
    user-controllable offset on top of the camera's baseline EV. The Settings → RAW layout co-locates each slider
    under its matching toggle instead of the standalone "Tuning" section (saturation slider under the saturation
    toggle, midtone slider under the default-tone-curve toggle, etc.) so the tune-by-eye UX is obvious. Flipping a
    toggle off continues to reproduce pre-6.1.1 output bit-for-bit on a per-image basis.
  • Lens correction resampler is now SIMD-accelerated (Phase 6.3): the bilinear resampler inner loops in
    apply_distortion_resample and apply_tca_resample are compiled for NEON (aarch64) and AVX2+FMA (x86-64)
    via multiversion. The sampler is now branchless (NaN/inf coords handled without a conditional early return)
    and uses f32::mul_add for FMA hints. The TCA path additionally extracts per-channel sampling into
    sample_single_channel_bilinear_fast, eliminating 2/3 of the redundant channel computation the original
    sample_rgb_bilinear calls did. Measured per-row speedup on M-series Apple Silicon: distortion ~1.0×
    (already memory-bandwidth-bound), TCA ~1.6×. Output is bit-identical within f32 FMA rounding tolerance.
  • **Capture sharpening now runs o...
Read more

Prvw v0.9.0

17 Apr 12:52

Choose a tag to compare

Added

  • Camera RAW support via rawler: open DNG, CR2, CR3, NEF, ARW, ORF, RAF, RW2, PEF, and SRW files. Decode pipeline
    includes black/white level correction, PPG demosaic for Bayer sensors, bilinear for Fuji X-Trans, white balance,
    camera color matrix with Bradford chromatic adaptation, and sRGB gamma. NEON SIMD on Apple Silicon, rayon
    parallelism. Orientation is pulled from EXIF metadata since rawler hard-codes RawImage.orientation. Known limits
    in this first pass: no DNG OpcodeList interpretation (iPhone ProRAW gain maps), no DCP profiles, X-Trans demosaic
    is bilinear. See docs/notes/raw-support-phase1.md for design decisions and the Phase 2/3 outlook
    (b4bc775)
  • File associations for all 10 RAW formats: Finder now recognizes Prvw as a handler for DNG, CR2, CR3, NEF, ARW, ORF,
    RAF, RW2, PEF, and SRW via their standard Apple UTIs. Info.plist carries all 16 document types now (6 standard + 10
    RAW)
  • Settings > File associations: redesigned into two sections, "Standard image formats" (JPEG, PNG, GIF, WebP, BMP,
    TIFF) and "Camera RAW formats" (DNG, CR2 + CR3, NEF, ARW, ORF, RAF, RW2, PEF, SRW) with vendor labels. Each section
    has a master "Set all" toggle with tri-state support: when some formats are on and others off, the master shows a
    "Mixed" indicator; clicking mixed or off sets all on, clicking on sets all off. Per-format small toggles keep fine
    control

Changed

  • Onboarding window: redesigned into a four-step checklist (Install Prvw.app, Set as default viewer, Move to
    /Applications, Open images). Each step uses a custom green checkmark (dimmed for pending steps) rendered at runtime
    from the source SVG path via NSBezierPath. Step 2 holds the "Set Prvw as the default viewer for all of these
    files" button and shows a natural-language sentence summarizing which app currently opens each of the 16 supported
    image formats. Step 3 checks whether the binary is in /Applications/ and shows a drag hint when it isn't. Step 4's
    copy adapts to step 2's state: "double-click any image" once Prvw is the default, or "right-click any image and
    choose Open with → Prvw" beforehand. Content is left-aligned, the window is wider and taller to give the checklist
    breathing room, and the title drops the v prefix ("Prvw 0.8.0")
  • Decoding module: single-file decoding.rs split into a decoding/ module with per-backend files (jpeg.rs,
    generic.rs, raw.rs) plus shared dispatch.rs and orientation.rs. Public API unchanged
    (b4bc775)
  • CI: macOS-only modules (AppKit settings panels, color transform tests) gated behind #[cfg(target_os = "macos")]
    so cross-platform builds compile cleanly. Groundwork for Windows and Linux support later
    (e9b5de4,
    3f00979,
    815b727,
    96218dd)

Fixed

  • apply_orientation underflowed on zero-width or zero-height input for EXIF orientation 2. Now early-returns
    (b4bc775)
  • Restored per-row handler transparency in Settings > File associations: each format row again shows which app currently
    handles it, or which app handled it before Prvw took over. Covers all 16 formats (6 standard + 10 RAW)

Prvw v0.8.0

17 Apr 07:23

Choose a tag to compare

Added

  • Settings window: new sidebar layout with General, Zoom, Color, and File associations sections. Cross-dependencies
    disable dependent toggles automatically (ICC off → Color match / Relative colorimetric disabled; Auto-fit on →
    Enlarge disabled) (dc43505,
    0dd4849)
  • File associations panel: per-UTI toggles, "Set all" master toggle, 1-second polling of handler state, previous
    handler rollback when you turn a toggle off (0dd4849,
    17b76a3)
  • Rendering intent toggle (View menu + Settings > Color, Cmd+Shift+R). Default is perceptual; toggle to relative
    colorimetric. Disabled when ICC color management is off. Persisted as use_relative_colorimetric
    (b42814f)
  • Scroll-to-zoom toggle in Settings > General (off by default). When off, scroll navigates between images (down = next,
    up = prev). Cmd+scroll always zooms regardless of the setting
    (d55b7e9)
  • Pinch-to-zoom on trackpad, cursor-centered. Works with auto-fit window resize, same as scroll zoom
    (ef8d0bf)
  • Keyboard shortcuts for zoom: Cmd+= (zoom in), Cmd+- (zoom out), Cmd+0 (actual size)
    (ec2aba4)
  • Title bar toggle in Settings > General (on by default): reserves a 32px strip at the top so the filename and zoom
    pills don't cover the image. Screenshot-friendly when off
    (64e0d87)
  • Title bar vibrancy: Liquid Glass on macOS 26, classic frosted glass on older versions. The area around the image
    (when the image doesn't fill the window) gets a darker HUD-style vibrancy. Fullscreen switches both to opaque black
    so screenshots and projector-style viewing aren't distracted by the desktop blurring through
    (7eede14)
  • Integration test suite (17 tests): Settings open/close/switch, zoom in/out, fit/actual, auto-fit toggle, navigate,
    refresh, window geometry. Each test spawns its own app instance on a dynamic port
    (0dd4849)

Changed

  • Source layout: flat src/ with infrastructure (app/, render/, platform/) and features (about, color,
    decoding, navigation, onboarding, qa, settings, window, zoom, …) as siblings. Each feature owns its
    runtime state via a State struct on App instead of ~20 flat fields. No behavior change
    (27eca5e,
    e88027b)

Fixed

  • Closing the onboarding window now quits the app. Previously, a no-file launch (Dock or cargo run with no args)
    left the event loop running with nothing visible after the user clicked Close, because the onboarding is a raw
    AppKit window and doesn't generate a winit close event
    (e81bbdf)
  • CGColor / CGColorSpace encoding crashes in setColorspace: (display profile) and the Settings separator:
    msg_send! encoded these as ^v instead of ^{CGColorSpace=} / ^{CGColor=}. Fix uses raw objc_msgSend to
    bypass the type check (17b76a3)

Prvw v0.7.0

15 Apr 23:26

Choose a tag to compare

Added

  • ICC color management: embedded source profiles (JPEG, PNG, TIFF, WebP) are transformed to accurate output colors.
    Level 1 converts to sRGB, Level 2 targets the actual display profile via CoreGraphics FFI
    (CGDisplayCopyColorSpace). Images without profiles assumed sRGB. Display changes flush the cache and re-decode
    (ee226ac,
    94820a8)
  • View menu toggles: "ICC color management" (Cmd+Shift+I) and "Color match display" (Cmd+Shift+C), both persisted in
    settings. Disabling ICC grays out color matching (L2 depends on L1)
    (a088330,
    b952b64)

Changed

  • ICC engine: replaced lcms2 (C bindings) with moxcms (pure Rust, NEON SIMD). 24MP transform: 247ms -> 45ms on M3 Max.
    No C toolchain needed for cross-compilation
    (f568b18)

Fixed

  • Screen detection: replaced unreliable current_monitor() + CGDisplayBounds position matching with
    NSWindow.screen.deviceDescription for authoritative CGDirectDisplayID
    (fcdefe3)
  • Pre-existing BGRA->RGBA swap bug in screenshot capture
    (ee226ac)

Prvw v0.6.3

15 Apr 08:41

Choose a tag to compare

Fixed

  • Finder double-click file opening: replaced NSAppleEventManager handler (overridden by AppKit's
    NSDocumentController) with ObjC runtime method injection (class_addMethod) that adds
    application:openURLs: directly to winit's WinitApplicationDelegate class
    (9417ab0)

Changed

  • Zoom model uses logical pixels: zoom=1.0 = 100% = one image pixel per logical pixel. The overlay
    correctly shows 100% for naturally-sized images on Retina displays (was 200%)
  • Compiler-enforced Logical<T> / Physical<T> newtypes prevent mixing logical and physical pixel
    values. Winit interop via from_logical_size, to_logical_pos, etc.
  • Removed 329 lines of dead modal onboarding code

Prvw v0.6.2

15 Apr 06:43

Choose a tag to compare

Fixed

  • Finder double-click "cannot open files in JPEG Image format": CFBundleTypeRole was missing from Info.plist
    document type entries. macOS requires this to know the app can actually open files, not just be registered as a handler
  • CI: add libxdo-dev to Linux apt-get for muda dependency
  • Auto-updater: call lsregister -f after replacing the .app bundle so macOS picks up new document types in future
    updates

Prvw v0.6.1

15 Apr 00:20

Choose a tag to compare

Fixed

  • Finder double-click now works: macOS sends file paths via Apple Events (not CLI args), but the app was exiting before
    the event loop started. Now the event loop always runs, with a 500ms wait for Apple Events before showing onboarding
    (f6e0fef)

Changed

  • Onboarding window is now non-modal (doesn't block the event loop), allowing Apple Events and QA commands to arrive
    while it's showing
  • Code refactors: scale_factor stored on App, TextBlock builder pattern, MonitorBounds helper, LogicalF64 /
    LogicalF32 type aliases for coordinate clarity