v0.2.11
·
34 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
What's Changed
New Features
- Changed a few labels to make them less confusing
Bugfix
- Hashing a folder no longer crashes when the file set shrinks underneath
the pool. The duplicate model reads an immutable snapshot of the file
set instead of the live slice — the old liveCount()/KeyAt(i)pair
could index past the end, reproducible in about a second on a 48-file
drop under-race. - A file the scanner produced no URI for no longer panics the hashing
pass. - A crash when pressing 0 after rotating an image and returning to the
drop zone.clearToDropzonecleared the frames but left the rotation
set, and the 0 key is handled ahead of the navigation guard, so
resetRotationindexed an empty frame slice. Reproducible in four
keystrokes: open, R, Escape, 0.
Internal
internal/dupes.FileSetis a singleSnapshot()method; everyModel
method takes one snapshot at entry.- Arrow keys with inspect or hide-duplicates on no longer rescan the whole
file set per step (InspectSourceis an O(1) map lookup; the
hidden-extra walk takes the model mutex once per call, not once per
candidate). - A new hashing pass no longer inherits the previous pass's hide-apply
throttle floor. - Deleted
grid/dupes.go'srememberHashFailandhashFailedOf, two
duplicate-hash wrappers with no callers anywhere in the tree; the
hashing pass already callsdupes.Model.PutFailed/Faileddirectly.
Dropped the stalehashFailedOfmention fromhashengine.go's
wrapper comment. internal/dupesnow exportsVisibility(), a frozen read of the
hide flag plus the installed group snapshot taken in one model-mutex
acquisition, withHiddenExtra/Visible/RepresentativeOf/Size
methods for testing many indices against it without re-locking per
index.applyVisibleFilter's filter pass andjumpIfHiddenExtranow
take one such read instead of one (in fact two) model-mutex
acquisitions per file.- Split the
viewergod object from 87 fields to 55: four new
subpackages, each reading a valueStatesnapshot built in exactly one
internal/uifunction rather than aHostinterface —
internal/ui/menus(the 20 File/Window/Actions menu items and their
whole Checked/Disabled matrix asApply(State), −19 fields),
internal/ui/autoupdate(the release check/download policy, staged-
update lifecycle, and What's-New cache, −4 fields),internal/ui/infoview
(the persistent info overlay's widgets and text formatting, −6 fields),
andinternal/ui/display(decoded frames, frame index, view-only
rotation, and crossfade, −3 fields). AHostformenusalone would
have needed roughly a dozen methods, which is why these four read a
snapshot instead. Also lands needs_refactoring.md item 5 (menuState()/
syncMenus()replace the per-site Checked/Disabled push and
HighlightChanged's four-boolean hand-diff with one recompute-and-diff
entry point, called from 16 choke points instead of the previous 23 call
sites) and the rest of item 6 (appStatenow evicts the image cache
itself on file removal via anonRemovehook, wired inbuild.go).
Full Changelog: v0.2.10...v0.2.11