Repository navigation
v4.5 — Refinement, plus one freeze and one thing quietly wrong
Refinement, mostly — plus one freeze and one thing quietly wrong. A bulk sync on a large
comparison locked the window for about eleven seconds at each end, doing nothing in that time but
setting a flag. And a file rewritten while it was being hashed could be remembered under a
digest belonging to no version of it. Alongside those, “Text contains” means one thing on every
surface rather than two, the “None” accent finally reads as no accent, and the markers saying
which workspace and which tab you are in travel instead of blinking.
On the v4 line, so it requires macOS 26 — coming from 3.x or 2.x, read the v4.0 section first.
Organize
- “Text contains” now means the exact phrase, everywhere. It had two readings: the loose
word-by-word one on the Organize scan, which is the path that moves files, and the strict one
in the Automations preview. So “tax return” could move a document that said “tax” and “return”
pages apart, after a preview that said it would not. Separate words are still matchable, as
“Mentions the words”.
Duplicates and comparison
- A file rewritten while it was being hashed could be remembered under the wrong digest.
Everything the scan knew about a file came from its path, read before the file was opened, so
none of it was provably about the bytes that followed — and a rewrite of the same byte count
produced a digest of two files spliced together. The file is now stat'd through its own
descriptor before the read and after, where the timestamp catches what a byte count cannot. - Files a duplicate scan could not read are counted now, instead of vanishing from it. A
candidate that was gone, unreadable, or changed while it was being hashed was dropped with
nothing recording it — no pill, no note, no log — while every other skip reason was tallied
and named. They join the “skipped” note now, as “unreadable or changed while being read”. - A duplicate scan does less work to reach the same answer. It read a file's path three
times before opening it; now once, plus one more for a symlink and one for a file it is about
to open. On a repeat scan every digest is cached, so that first read is all the hashing does.
Digest text is now a table lookup, and a long scan publishes progress about a hundred times
instead of several hundred. - Duplicate thumbnails no longer decompress while you scroll. Each was compressed to PNG
purely to satisfy a rule about what may cross between threads, then decompressed again —
lazily, which means at draw time, on the main thread, during the scroll that asked for it. - A comparison with ignore patterns set folds them once per scan rather than once per item
compared, and folds each name once rather than once per pattern it is tested against. - Starting or finishing a bulk sync no longer locks the window while it marks the rows.
Flagging each row as in-flight rewrote the whole difference list and asked for a redraw, once
per row. On a comparison with tens of thousands of differences that cost about eleven seconds
at each end, doing nothing but setting a flag. The rows are marked in one pass now, and drawn
once. - Rebuilding the difference list stops taking every path apart to ask one question of it.
Deciding whether a path is hidden split it into components and built a string for each, once
per difference, on every rebuild — and hiding hidden files is the one filter of five that runs
unless you turn it off. On 29,000 differences that was about 37 ms a pass, now about 2 ms,
with exactly the same files hidden. - Scanning a large tree resolves far fewer paths. Every directory the walk entered had its
whole path resolved so the scan could tell whether it had been there before — a symlink-loop
guard that fires essentially never, and about half the cost of entering a directory. Only a
directory whose last component is a symlink needs it now, and every cycle is still caught.
Appearance
- The “None” accent now reads white in light, not the faintest gray. At low Tint, bare
material and Graphite's neutral wash landed within a couple of points of the same gray, so the
two were told apart by their swatches and nothing else. “None” now lays a white film over the
background in light, titlebar included. Dark is untouched. - The Info inspector's toolbar button moved to the far right. The trailing pill read Go to,
Info, Logs, Settings, which put the control that opens the right-hand rail three glyphs from the
edge it opens against. It now reads Go to, Settings, Logs, Info, mirroring the folder-sidebar
toggle at the far left. Same buttons, same ⌘I. - The selected workspace and the active pane tab now slide between positions. Both markers
were drawn per item, so switching cut one out where it was and cut a new one in where it was
going — two bars, one above the other, both blinking. Reduce Motion takes the destination and
skips the journey. - A count that changes rolls its digits instead of cutting to a new number. Diff totals,
duplicate-group counts and the filing backlog hard-swapped: the old number vanished, a new one
appeared, and nothing said they were the same quantity. Words are left alone — rolling a
word's glyphs reads as a glitch. - The first-run sheet answers the pointer. Seven of its controls drew their own chrome,
which means macOS contributes no hover state at all — so the app's first impression was its
least responsive surface. Each has an affordance now, chosen for what the control does. - One vocabulary for corner radii. Eleven distinct radii were hand-written across the app,
so three chips inside one card could round by different amounts. Four named stops now, each a
value the app already used most, with the strays moved to their nearest by a point. - Twenty-two of the app's animations honour Reduce Motion that did not before. Opting in used
to mean wiring an environment read into whatever view owned the animation, so most motion was
unconditional — friction rather than a decision. What is gated now is anything that travels:
panes collapsing, a workspace switch, the inspector, tabs sliding under a drag, the focus ring
moving between panes, the search field growing out of its magnifier, Browse's folder sidebar.
Motion that reports rather than travels — a hover wash, a rolling count — is left alone. - The small inline spinners are drawn at their size instead of shrunk to it. Three status
rows scaled an already-drawn spinner down to seven-tenths, and scaling resamples, so those
three read softer than identical spinners a few files away. They are framed to occupy exactly
what the old recipe reserved, so no row moves. - Twenty-seven controls that are nothing but an icon now have names. A tooltip is not a name
on macOS, so VoiceOver read them as “button” and Voice Control could not be told to click them
at all. Toolbars, row actions, dismiss glyphs and the new-tab plus now say what they do.
Nothing about this is visible on screen.