Releases: JavanXD/pixel_backup
Releases · JavanXD/pixel_backup
Release list
Pixel Backup v0.1.0
Download
| File | Description |
|---|---|
PixelBackup-0.1.0.dmg |
macOS app — drag to Applications and run |
pixel_backup.sh |
Shell script — works standalone with adb in PATH |
System requirements: macOS 13 Ventura or later · Apple Silicon and Intel
Install
- Download
PixelBackup-0.1.0.dmg - Open the DMG and drag PixelBackup to your Applications folder
- Launch from Applications (or Spotlight)
"App can't be opened" warning?
Right-click (Control-click) the app icon → Open. You only need to do this once.
This prompt does not appear on notarized releases.
Shell script (no installer)
brew install android-platform-tools
chmod +x pixel_backup.sh
./pixel_backup.sh --helpNo DMG, no trust decisions, works on any macOS with bash and adb.
What's new
Changes in this release
Added
- Wireless ADB support — connect to any Android device over Wi-Fi without a USB cable:
- "Connect wirelessly" expandable section in the device panel: enter an IP address and tap Connect
- Saved addresses persist across app restarts and auto-reconnect every poll cycle
- Android Wireless Debugging pairing flow (Settings → Developer options → Wireless debugging → Pair device with pairing code) via a dedicated
WirelessPairingSheet - Connected wireless devices show a Wi-Fi icon; USB devices show a cable icon
- Disconnect button per wireless device; offline saved addresses shown as "reconnecting…" with a remove button
Documentsadded as a default copy folder- App icon — custom 1024×1024 design with all required macOS sizes bundled as
AppIcon.icns build.shnow auto-installs the built.appto/Applicationsafter every build (removes the old copy first to prevent nesting)- Real-time transfer speed (MB/s) and ETA displayed in the progress view
- Elapsed time counter (
Xm Ys elapsed) during active backups - Current filename shown live under the progress bar while copying
- Free disk space indicator on the destination picker (colour-coded: red <5 GB, orange <20 GB)
- Last backup summary strip on config panel (date, file count, GB — read from manifest, not filesystem scan)
- "Try Again" / "New Backup" button on failed and cancelled states
⌘Returnkeyboard shortcut to start a backup from the config panel+toolbar button to open a new independent window when only one window is open- USB debugging step-by-step inline guide shown when no device is detected
- Music and Backups added as default copy folders
- Custom folder paths: add any Android path via the UI (shown as purple pills)
- Drag-and-drop destination folder onto the window or destination picker row
- History view shows "Folder moved or deleted" warning for stale entries
- English, German, Spanish, and French localization
--helpflag onpixel_backup.shprints all environment variable parameters
Changed
- Backup history now reads
.transfer_meta/manifest.tsvinstead of walking every file — critical performance fix for large backups (18k stat() calls → 1 file read) - Multiple independent windows (
⌘N) — each window owns its ownBackupManagerso two devices can be backed up simultaneously - Menu bar replaced SwiftUI
MenuBarExtrawithNSApplicationDelegate-managedNSStatusItem— fixes context menu appearing on the wrong display in multi-monitor setups - Backup folder names are now dated:
YYYY-MM-DD_DeviceName_Serial/ sanitize_name()now strips Unicode, emoji, and multi-byte characters; TCP/IP serials (containing colons) are sanitised for use in macOS paths
Fixed
- App crash near backup summary caused by
@MainActorisolation:DispatchQueue.main.asyncreplaced withTask { @MainActor in }in termination handler - Thread-safety warning in
readabilityHandler— buffer access confined to a dedicated serialDispatchQueue NotificationManagercrash when running viaswift runwithout a bundle identifier- Off-screen windows (e.g. from a disconnected external monitor) are relocated to the main display on launch and focus
- Cancel crash: if the user started a new backup while a previously-cancelled process was still winding down,
handleTerminationwould callprocess?.standardOutput = nilon the new (running) process — Foundation raises an exception for this. The pipe is now disconnected inside theterminationHandlerclosure (whereprocis the already-terminated instance), and abackupIDUUID guards against stale terminations ever touching a newer backup's state - Cancelled summary not shown: clicking Cancel while the script was in progress showed only the raw log tail;
handleTermination(exit 130)now parses the partial summary thaton_interrupt()prints and transitions to.done(summary:)withwasCancelled = true— so the structured SummaryCard appears with a "Backup Cancelled" header and a "Back" button - State race after completion: log-line tasks still queued on the main actor when
handleTerminationfires could overwrite.done(summary:)with.failed;isTerminatingflag prevents this readabilityHandlerresource leak: the pipe's file handle handler was never set tonilafter process exit; it is now cleared at the start ofhandleTermination