This release candidate focuses on reliability improvements across all platforms,
smarter accessibility permission handling, and a more robust clipboard paste flow.
-
The macOS system permissions prompt no longer fires automatically on first launch.
The app now checks accessibility status silently (read-only, via checkAccessibility)
on startup and shows its own explanation dialog first. The user chooses when to
open System Settings. Previously, checkAndShow called requestAccessibility which
triggered the macOS system prompt immediately via AXIsProcessTrustedWithOptions. -
When a paste attempt fails because accessibility is denied (ACCESSIBILITY_DENIED),
the permissions dialog is now surfaced using a persistent navigator key, ensuring
it always appears even if the widget tree has been rebuilt or the window state
has changed since the last paste. -
After granting permissions, the dialog now cancels its polling timer and closes
cleanly without attempting to show a snackbar on a dismounted context (which
previously caused gray screen crashes). -
The macOS paste mechanism now polls for the target application to be frontmost
before sending Cmd+V, instead of relying on a single fixed delay. It checks in
10 ms increments (up to max(delay/10, 15) attempts) and only fires the keystroke
once focus is confirmed. This eliminates paste misses when the target app takes
slightly longer to activate. -
Clipboard polling interval reduced from 500 ms to 250 ms and debounce from 500 ms
to 250 ms for faster detection of copied content. -
Extracted simulatePaste() as a dedicated private helper for clarity.
-
ConvertDibToBmp now returns an empty vector instead of the raw DIB data when the
buffer is too small to be a valid BITMAPINFOHEADER, preventing garbage from being
passed to the clipboard. -
GetView() is null-checked before calling GetNativeWindow() in StartListening
and in SetImageToClipboard, avoiding a null-dereference crash during teardown. -
GetDIBits return value is now validated; if zero scan lines were copied the
allocated memory is freed and the operation returns false cleanly. -
Clipboard update events for corrupt or empty image DIBs are suppressed entirely
(no event emitted if the converted bytes are empty). -
After a successful restore that includes clipboard data, the app now shows a
"restart required" notice and exits automatically after 2 seconds so the restored
data loads cleanly on next launch. -
Backup files are now written to a system temp path first, then copied to the
user-selected destination. This prevents macOS NSSavePanel security-scoped access
from expiring mid-write during large backups, which could leave a corrupt file. -
The fallback restore path (no manifest) still shows the original "restore completed"
message without forcing a restart. -
CleanupService.runCleanup and cleanOrphanImages now log failures via
AppLogger.error instead of silently discarding exceptions with catch () {}. -
MainScreen._loadItems now logs load errors via AppLogger.error.
-
ClipboardWriter metadata parse errors are now surfaced via debugPrint in debug
builds instead of being silently swallowed. -
Wrapped MainScreen in a LayoutBuilder that renders an empty box when the window
height is less than 100 px. This prevents rendering errors and gray screens that
could appear during window transitions or when the tray window collapses. -
Removed a redundant filter condition in the items query that had no effect on
results but added unnecessary complexity to the SQL expression. -
The Homebrew Cask uses a flat app declaration (app "CopyPaste.app") without
conditional on_arm/on_intel blocks, keeping the cask simple and compatible.
The cask still declares depends_on macos: ">= :ventura". -
Switched to a tab-stripping heredoc (<<-) in the CI workflow, eliminating the
sed post-processing step that stripped leading indentation from the generated
cask file. -
Added an automated release step that pushes the updated Homebrew Cask to
rgdevment/homebrew-tap on every new release, so the tap is always in sync
without manual intervention. -
Added accessibility dialog tests covering: dialog shown when not granted, dialog
skipped when already granted, timer cancelled and dialog closed on grant, and
error path for ClipboardWriter failures. -
Added backup service tests covering rollback on failure and invalid zip path handling.
-
Added cleanup service tests covering error logging paths for both runCleanup
and orphan image cleanup. -
Added main screen tests covering _loadItems error path and color filter behavior.
brew tap rgdevment/homebrew-tap
brew install --cask copypaste
To install the release candidate specifically:
brew tap rgdevment/homebrew-tap
brew install --cask copypaste-beta
Download the .dmg from the assets below, open it, and drag CopyPaste to your
Applications folder.
Requires macOS Ventura (13) or later on Apple Silicon.
Full Changelog: v2.0.0-beta.2...v2.0.0-RC.1