github thaw-app/Thaw 2.0.0-rc.5

pre-release6 hours ago

Please report issues at
github.com/thaw-app/Thaw/issues.

Planned as the last release candidate before 2.0 stable. Almost all of it comes from field logs, and the reports fall into two clusters: layout repair that damaged the arrangement it was trying to fix (#958, #863), and scans that re-probed every running application until the machine stuttered and every item answered to "Menu Bar Item" (#956).


Upgrade from 2.0.0-rc.4

  1. Update in place through Sparkle.
  2. Move budgets now default to 250 ms, or 350 for Bento Boxes. An explicit
    defaults write override still takes precedence over either value.

Main fixes

  1. Hidden-divider recovery no longer collapses the bar. Both recovery paths discarded a stale autosave position by writing the fresh-install seed through the route that bypasses the guard, so the divider landed back beside the visible chevron and the next save persisted the collapsed span. On the five-hour log attached to #958, a routine notch overflow scored one boundary mismatch, the rebuild fired, and three seconds later the visible section held nothing but Thaw's own icon.
  2. Boundary repair moves items instead of dragging the divider across them. Phase 1 reached for one drag of H_ctrl whenever any managed item sat on the wrong side of it; when that drag would have crossed the entire visible section, the bar collapsed to a 33-point span and the apply still reported a clean classification afterwards. Small mismatches now walk the offending items back one drag each, and the divider drag stays reserved for the empty-side cases it was built for (#879, #958).
  3. Ejected items stop bouncing between the overflow planner and the repair pass. On bars persistently over the notch budget, every apply ejected the same item and then recalled it as wrongly concealed, two synthetic drags per cycle for as long as the bar stayed over budget. That matches the "icons jumping randomly and relocating between layouts" reports. Ejected items are now exempt from the boundary tally until the budget frees up (#958).
  4. Items keep their names while source-PID resolution catches up. Naming requires knowing which process created an item, and the first cache pass deliberately runs without waiting for the accessibility scan, so for its duration every item answered to the generic "Menu Bar Item" on hover and in Search. An item now falls back to the name it resolved to last time. Control Center's generic Item-N slots are refused because their key encodes hosting order rather than identity and a wrong name gets clicked; custom names still take precedence (#956).
  5. Slow item owners get room to answer. The move budget started at 100 ms, but escalation averaged each raise against the standing value, so even eight attempts reached only 476 ms, and every unresponsive-owner failure was filed twice, burning through the ledger's mark threshold right away. Defaults are now 250 ms (350 for Bento Boxes), growth is adopted as computed up to a one-second ceiling, failures are filed once, and marking takes three. Fixes the cursor hijack of #687 and the misplaced relaunched items of #960.

Source-PID scanning

  • The negative-cache flag was cleared for every reused app on every cache cleanup, and cleanup runs whenever any process starts or exits because NSWorkspace.runningApplications drives it; the #956 log shows 46 cleanups in seven minutes. The flag is now a deadline that survives cleanup and backs off as consecutive empty checks accumulate. Early rungs stay inside the startup window, so an application that publishes its status item shortly after launch is still found quickly.
  • Consecutive-miss counts are remembered per bundle identifier across launches and seed the first scan of a session, which measured 3.85 s in the log. Seeding decides where to look, never what was found: skipping an application can reorder work but cannot attribute an item to the wrong owner.
  • A zero-area window no longer selects scan drivers. An unresolved window is what picks the driver, and one zero-area window started eight of nine scans in seven minutes with nothing else on the bar asking for one. Bounds are re-read on every request, so a window that gains area stops being skipped.
  • Scan summaries now log total wall time and name any single app whose extras-bar probe exceeds 50 ms, since accessibility reads are serviced by the target process and bounded only by its unresponsive timeout.

Save gates

  • saveSectionOrder honours the same five-second post-move cooldown as applySavedLayout, except when the user's own move was the most recent one, so a Layout-editor drag cannot undo itself. In the #958 log the save landed one millisecond after the restore stood down.
  • The multi-display gate counted visible items, so a relocation that stranded items in the wrong section erased its own evidence: it fired correctly with sixteen visible items and passed when four were left, which was the save that did the damage. It now reads whether the menu bar changed display since the cache cycle being compared, a signal that never looks at the items and therefore survives misclassification.

Divider recovery

  • A hidden-divider rebuild stamps a seed position only when the bar holds no managed items. Discarding the stale NSStatusItem still gives the divider a window on the current bar, and the follow-up apply walks it to the saved boundary (#958).
  • The H_ctrl boundary move no longer anchors on Thaw's own chevron. When every profile item has been dragged to the other side, anchoring on the last remaining candidate dragged H_ctrl past it and concealed it; returning nil leaves the boundary alone and hands the work to the per-item LCS pass, which has barred Thaw's own items as anchors since #924. The two nil cases log separately (#958).
  • Parked dividers are measured at their leading edge instead of their centre. A collapsed hidden divider is 5000 points wide, so its centre sat 2500 points to the right and read as on-screen on multi-display arrangements, defeating both the parked-divider drag guard (#899) and the rebuild detector; five hours of log recorded neither warning.
  • Chevron relocation and always-hidden control-item ordering skip when the hidden divider fails the on-screen check, so neither drops its target into the parked zone beside a physically parked divider. Existing recovery paths already handle the states these guards refuse.
  • An enabled always-hidden section whose divider stops resolving gets its status item recreated once per episode, after three authoritative cycles with no reading, and keeps its stored position rather than seeding. Provisional AX-frame correlations never advance, reset, or re-arm the streak. The #863 re-plug log showed alwaysHidden=nil on every cycle for 12+ hours while the whole always-hidden section drained into Visible (#863).
  • The one-pixel drop-point bias now applies to every control-item divider regardless of width. Expanded dividers thousands of points wide still produced placements landing one point into the wrong section: a divider's width provides visual concealment, not hit-test slack (#923).

Appearance & capture

  • Preview batches exclude degenerate zero-width windows from the bounds union. Capture APIs dropped them from the composite while including them in the union, which dragged the geometry across the gap between displays, mismatched the widths, and discarded the whole batch. The windows behind this were Control Center-hosted slots orphaned by an earlier Thaw process: Control Center owns them, they outlive restarts, and their bundle-ID names keep them out of ControlItemPair's strip list (#962, thanks @alvst).

Dependencies & docs

  • Sparkle bumped in the swift group (#971); github-actions group bumped with four updates (#972).
  • README OpenSSF badges switched to live shieldcn scorecard/openssf endpoints (#920); contributor image source updated; repository notice added.
  • FUNDING.yml gained Ko-fi and PayPal entries.

Don't miss a new Thaw release

NewReleases is sending notifications on new releases.