Skip to content

PhotoReview 2.0.510

Choose a tag to compare

@github-actions github-actions released this 14 Oct 12:22
· 17 commits to master since this release
d92d6aa

Requires Windows 10/11 x64 and the .NET 10 Windows Desktop Runtime. Unzip and run PhotoReview.App.exe (the WPF app).
PhotoReview.exe (the Win32 + Direct2D shell) is a parallel build in the same folder; it does not change your file associations.

SHA256 of PhotoReview-v2.0.510-win-x64.zip: 48A3E9469A6B620E0348AF0758E66F1ECE0B870A563B0905FEA4F8776CE16959
SHA256 of PhotoReview.App.exe: 1A082A1B778885D0BCC7BA87484ADFCBDC7972CC08F2361F85BE36A588E55538
SHA256 of PhotoReview.exe: 677BEBE5042CFA62E5776548EEA32DEB686ED2446D0CB0CE69734FB44F8CCE08

Changes since v2.0.371

Features

  • External Editor menu item always visible; opens Settings when unconfigured in #383
  • Second Fit width (anchored at bottom third, own key) + assignable middle-click action in #385
  • context menu Copy File Name / Copy Full Pathname + compact menu rows in #384
  • WebP and HEIC/HEIF via Windows codecs (Q-FMT-WEBP-HEIC) in #388
  • customisable right-click menu + Explorer 'Browse with PhotoReview' folder command in #390
  • two-finger touchpad swipe (pan when zoomed, change image by swipe distance) + Refresh command (R / menu) in #391
  • WP-01 Shell.* project skeleton + App.Shared, v1 contract and architecture tests in #399
  • WP-13a interop Win32 (LibraryImport user32/kernel32/gdi32/dwmapi/shcore/comctl32/ole32/shell32) in #400
  • WP-11 JSON source generation for the serializer in Core in #401
  • WP-13b interop D3D11/DXGI/D2D1/DWrite + COM shell in #402
  • WP-07 input and non-WPF UI seams (C-04 adapter, C-06, C-07) in #410
  • WP-02 PixelBuffer, codec, PixelOps (C-01..C-03) + PixelAssert in #408
  • WP-19a native dialogs + clipboard in #404
  • WP-08 placement and F11 per HWND (C-14) in #403
  • WP-14 window, message loop, dispatcher, frame clock (C-04/C-05/C-15 Win32) in #406
  • WP-18 right-click menu model + native menu host in #409
  • WP-10 golden recorder from the WPF build (G-VIEW/INPUT/KEY/MENU/OVL) in #405
  • WP-16 pure viewport engine + ViewportController (do NOT merge before WP-10) in #411
  • WP-05 TurboJpeg and LibRaw to PixelBuffer in #413
  • WP-03 WIC Direct, embedded thumbnail, EXIF to PixelBuffer in #414
  • WP-04 disk cache encode/decode via WIC, byte-compatible in #412
  • WP-15 renderer Direct2D + GpuImageCache + tile (WIP) in #415
  • contract v1.1 - C-07 App.Shared, C-09 IRenderSurfaceFactory, ExifOrientation locked in #441
  • WP-06 split out PhotoReview.Imaging.Wpf, remove UseWPF from Imaging*, codecs mandatory in #442
  • WP-17 DirectWrite text + overlay rounding + animator (C-11) in #443
  • WP-12 WIC moved to [GeneratedComInterface] + LibraryImport (P2) in #444
  • WP-09 split out PhotoReview.App.Shared (move files, AddPhotoReviewShared, inject clipboard/sink) in #445
  • WP-19b App.WpfWindows + Shell.WpfBridge (late-loaded secondary WPF windows) in #446
  • WP-20 composition root + startup shell (Win32 PhotoReview.exe actually runs) in #447
  • WP-21 image presentation, compare, crossfade (Win32 shell) in #450
  • WP-22 shell input (keys, mouse, wheel, touchpad, drag-drop) in #449
  • WP-24 right-click menu, Zoom submenu, custom zoom in #453
  • WP-23 HUD overlay, toolbar, status, auto-hide, native folder picker in #448
  • WP-26 custom-drawn scrollbar (NE-3 a) matching WPF ScrollViewer in #451
  • WP-25 F11, multi-monitor, DPI, dark title bar (Win32 shell) in #452
  • WP-30 two-exe packaging, CI, Explorer association for PhotoReview.Shell in #458
  • WP-29 perf host + probe, perf gate wave 3 (shell vs WPF, R2R) in #460
  • WP-33 COM shell / Recycle Bin without late binding (IFileOperation, IShellItem2/IContextMenu, IShellWindows) in #470
  • WP-36 Native AOT publish for PhotoReview.exe (separate artifact) + CI job in #475
  • WP-34 IsAotCompatible everywhere + LibraryImport + AOT publish gate with 0 warnings in #477
  • AOT - secondary windows stub: Settings opens config.json, other windows report they are unavailable in this build in #481
  • bridge secondary WPF windows into the Win32 shell (Settings/Diagnostics/Recovery/... now open) in #486
  • JSON measurement results with schema + compare + -PerfGate in #485
  • WP-35 Phase 1 - native Win32 dialogs (ZoomPrompt, Diagnostics, Skipped, BatchReview) + secondary window router in #489
  • WP-35 Phase 2 - new Win32 controls + Action profiles + modeless Benchmark in #490
  • WP-35 Phase 3a - Win32 Settings frame + page contract + first 3 pages in #493
  • WP-35 Phase 4 - Recovery as a native Win32 dialog in #494
  • WP-35 Phase 3b - Performance page of Win32 Settings in #495
  • WP-35 Phase 3b - Files page of Win32 Settings (Radio + FocusExternalEditor) in #497
  • WP-35 Phase 3b - Shortcuts page of Win32 Settings (27 key-capture boxes, nested Action profiles) in #498
  • WP-35 Phase 3b - Mouse page of Win32 Settings (20 properties, 18 right-click menu slots) in #496

Fixes

  • Fit HUD percent, click-zoom key no-toggle setting, no stale-scroll frame on keyboard zoom in #387
  • open file at its real position, undo Delete in place, refuse Delete without Recycle Bin up front in #386
  • verify-all -Hidden -Parallel false failure + unique hidden-runner log names in #389
  • arrow-key step equal in pixels on both axes (short viewport side) in #407
  • clean up empty destination folder when the journal fails at Begin in #427
  • single Recycle post-checks that the source has disappeared (B-06) in #433
  • back up a newer config.json before Save overwrites it (C-04) in #434
  • return graphics when child HWND is alive (fixes Flush hang on CI) + standalone shell test in #455
  • WicCom.Wrap - failed QI exception no longer depends on leftover IErrorInfo (flaky CI) in #454
  • agent-finish-check no longer falsely flags pre-existing empty files in #459
  • Win32PresentationSink keeps FIFO when a UI-thread update arrives after a pending cross-thread update in #476
  • Settings version line shows the build time again in #491
  • owner-draw dark menu, app icon, shell-errors.log + Menu error in #492
  • Win32 dialog dark theme no longer depends on uxtheme ordinals/DarkMode_* in #499
  • scrolling Settings pages leaves no ghost images (WS_CLIPSIBLINGS) in #503
  • Settings pages show full content (group boxes sent to bottom of Z-order) + not-all-background-color test in #511
  • color emoji in the Win32 shell (L2 WP-27) in #516
  • text in tall input boxes vertically centered + test that Tab does not blank the page (WP-35) in #517
  • vertically center text in single-line inputs of Benchmark/ActionProfiles/ZoomPrompt in #522
  • combobox has only one paint style after focus/selection (WP-35) in #523

Performance

  • opening an image from Explorer - placement before showing, cloak until first frame (no white frame), decode launch image early in #394
  • P-1 - decode first image from App_Startup, warm up config parser, remove JIT/preload from first frame (-31 %) in #396
  • WP21-STALL keep GPU warm - key->frame P95 ~220 -> 8.8 ms in #461
  • re-measured wave 3 gate on a quiet machine + keep GPU warm after first image + dropped frame returns immediately in #519

Tests

  • pin the two ComparePair tie-breaks and the prefetch placement result (P-1) in #397
  • group Recycle without opt-in must be refused before doing anything (audit B-02) in #417
  • lock the names of the 70 released config.json keys (audit C-01) in #418
  • production IRecycleBin must declare CanRecycle/FitsInRecycleBin/DeletePermanently itself (audit B-03) in #419
  • the 2 gating tests for zoom-to-100% and Refresh must run in CI (audit D-01) in #420
  • pin performance/viewing defaults with literal values (audit C-03) in #421
  • lock Save after loading a newer config (C-04) and the optional<->mandatory conflict (C-05) in #423
  • AppLog.Error turns UI tests red + record dialogs + undo in-place delete (audit D-02/D-03/D-05) in #424
  • kill 3 surviving mutants M7/M23/M24 of the Win32 dispatcher in #425
  • kill surviving audit B mutants (WindowsRecycleBin / FileActionController) in #426
  • audit B - kill surviving file-action mutants (M18, M21b/c, M23, M28, M30) in #428
  • re-record 5 arrow-key pan scripts under the new rule in #437
  • APP-P01 deterministic, no more random red in #440
  • WP-28 G-PIX golden pixels (WPF vs Win32 shell) in #457
  • GpuKeepAlive sleeps after deadline + native decode on a dedicated thread independent of thread scheduling/ThreadId in #463
  • PreloadScheduler caller-thread test is no longer flaky in #464
  • wait for the session writer to settle before re-reading (fixes randomly red Skip test) in #469
  • WP-28b extend G-PIX golden pixels (compare, crossfade, F11/DPI, RAW) in #471
  • RawPreviewToFullDecode - evidence-based threshold for WARP noise in the HQ downscaled frame in #474
  • audit thread identity + wall-clock time in tests (Journal, GpuKeepAlive, TEST-THREADID rule) in #472
  • fix three randomly failing shell integration tests (wait for condition, injectable clock) in #479
  • fault-point x operation matrix for Move/Copy/Delete/Undo/journal + recovery in #482
  • deterministic evidence for stale preview overwriting a new preview (presenter, composer, GPU cache, prefetcher, shell) in #483
  • Shell.Tests - Benchmark (activation context, 2 items) + StartupCloak (injectable timer) in #512
  • ManyWritersOneFile no longer counts appends against the retry budget (CPU scheduling) in #514
  • fix root cause of Integration/App.Tests flaking under load (FLAKY-INTEGRATION-APP) in #513
  • pixel regression for repaint when scrolling Win32 Settings pages (RED until the fix is merged) in #501
  • fixed Join/Wait ceilings around cold WPF startup -> anti-hang limits (FLAKY-FIXED-JOIN-CEILINGS) in #518

Docs

  • sync status after user feedback of 2026-10-09 (#383-#391) in #392
  • per-file T1 budget overrides for architecture.md and OPEN-DECISIONS.md (32 KB) in #393
  • plan to drop WPF (Win32 + Direct2D, toward Native AOT) and assessment of moving to Rust in #395
  • no-WPF execution plan for parallel agents (contracts, 37 work packages, waves) in #398
  • NO-WPF handoff 2026-10-10 (status, pending work, CI test audit, operational pitfalls) + branch sync script in #416
  • progress after handoff (test PRs #417-#421) in #422
  • decide WP-05 fine-scale = WIC Fant; .jpg -> publish R2R in #429
  • AGENTS.md/INDEX.md record the 48 KB ceiling for OPEN-DECISIONS.md in #436
  • decisions taken per recommendation, unconfirmed (NE-3/4/6/7/9, B-06, C-04) in #430
  • STARTUP-2 measured (not pursued); keyboard pan goldens re-recorded in #439
  • guard against hung/orphaned agents (AGENT-HYGIENE.md + agent-finish-check.ps1) in #456
  • status 2026-10-12 in #462
  • WP-31 Win32 shell documentation in #465
  • WP-32 spike S1 Native AOT - feasible, first image 355-390 ms vs R2R 821-933 ms in #467
  • two-step mutation + shared-machine load rules in #468
  • spike S3 - replacing secondary WPF windows (WP-35/NW-3): inventory, comparison, prototype, recommendation in #478
  • CI-PARALLEL-TEST-JOBS diagram (added after #502) in #504
  • WP-31 - Win32 shell documentation (ADR 0010, README, architecture, TESTING) in #505
  • local Native AOT vs R2R trial run + default recommendation in #506
  • WP-27 hidden-desktop visual check - Settings blank after #503, single-color emoji in #507
  • Settings-via-Direct2D spike result, decision to keep the GDI version in #510
  • fix stale comments/docs (AOT, OPEN-DECISIONS mojibake, 6 CI jobs, NE-4) in #515
  • sync handoff 2026-10-14 in #520

CI / Tooling

  • remove "by @author" from release notes in #438
  • Bump actions/upload-artifact from 7.0.1 to 7.0.2 in the github-actions group across 1 directory in #435
  • split the test step into 3 parallel jobs (build-test-publish becomes an aggregate job) in #502
  • round 2 - 6 test jobs + compile-gate, test build skips analyzers (wall clock ~395 s -> ~200 s) in #508
  • publish-aot runs the real AOT exe with --smoke and --smoke (CI-AOT-SMOKE) in #521

Other

  • docs-budget: raise the OPEN-DECISIONS.md ceiling to 48 KB in #432
  • build(shell): -p:ShellAot=true switch for Native AOT publish (spike WP-32) in #466
  • docs-budget: double every documentation ceiling in #473
  • refactor(nowpf): WP-35 G0 - split presenters out of WPF (Settings, ActionProfiles, ClickZoomCustom, Diagnostics, BatchReview, SkippedFiles) in #480
  • refactor(nowpf): WP-35 G0 - split Recovery out of WPF (RecoveryWindowPresenter) in #484
  • docs+tools: auto-fix/auto-merge rules + sync-pr-branch auto-fixes duplicate order in #487
  • refactor(nowpf): WP-35 G2a - split Benchmark logic out of WPF (BenchmarkPresenter) in #488
  • refactor(nowpf): WP-35 Phase 5 - remove the WPF bridge from the Win32 shell in #500

Full Changelog: v2.0.371...v2.0.510