[image]

News: PC-Phone USB Sync

This page documents the releases of the PC-Phone USB Sync app, from newest to oldest:

Version 1.1.0, June 19, 2023: Multiple Enhancements and Fixes

Update: the Windows and Linux 1.1.0 packages (only) were rereleased on September 19, 2023, with an additional fix for initial window size. Like buttons, this size is now scaled to screen density, to avoid overly small windows at startup on higher-resolution displays (e.g., 4K). Please reinstall on these platforms if this affects your usage. macOS and Android packages are not impacted, and were not rebuilt.

This release adds five new usability features; works around four glitches in the underlying GUI toolkit plus one general issue that cropped up after 1.0.0; and makes seven additional minor mods. It's numbered 1.1.0 instead of 1.0.1 because it includes both enhancements and fixes. All its changes are backward compatible with 1.0.0, and apply to all platforms except as noted. Click here or scroll for info on all the upgrades in 1.1.0:

Enhancements

Fixes

Other Mods

Etcetera

New: Show Paths and Storage Names in Action Confirmations

The confirmation popups shown for Main-tab action taps now display the FROM and TO paths about to be operated on, to remind you of the actions' subjects. You don't need to cancel the dialog and check the Main tab to see these paths.

In addition, these popups label the new path displays with storage names shown in the folder choosers, in case you don't recall the name of the storage types that corresponds to physical paths. For example, the FROM folder's path display on all platforms takes the form:

FROM: (label)
path...

Where label is the logical name of the drive or storage, and path... is the full physical path. This same format is used to show FROM and TO folders when they apply to the selected action, so you can verify your choices.

Less abstractly, a FROM or TO removable-drive path on Windows that starts with D:\... is shown in the confirmation popups as (drivename) plus D:\.... Other Windows paths may be labeled (PC) or (ROOT), and the popups on Android similarly add labels (PHONE), (APP), or (drivename) before the full physical path (for a primer on paths, see this).

For live examples of the new confirmation-dialog displays on Android and PCs, try the Android shots here and here, and the PC shots here and here. This has no impact on GUI operation or behavior, apart from providing useful cross-check info prior to launching actions.

New: Run TAIL and OPEN on Double and Triple Taps in Logs

The Logs tab now catches double and triple taps (or clicks) on logfile-name buttons, and automatically runs TAIL for double taps, and TAIL+OPEN for triple taps. These shortcuts display logfiles made by Main-tab actions, and work for touch screens, touch pads, and mice on all platforms.

While useful, this is just a convenience: you can still run both TAIL and OPEN as before, by tapping a logfile-name button to select, and then tapping TAIL or OPEN. Double and triple taps are an extra option that mimics behavior expected from file explorers, and may be deemed quicker by some users.

Special case: TAIL is never run for taps when WATCH is active and the TAIL button is disabled, because the text area is being used by WATCH. By contrast, OPEN is run for taps whether WATCH is active or not.

New: Show Logfile Summary Info in Action-Exit Popups

For ease, this app now parses out crucial summary details from action logfiles, and presents them in an info popup when Main-tab actions exit. Viewing logfiles on narrow phones may require scrolling or rotating to landscape, and the brief summary bits now shown in the info popup often suffice, especially when simply verifying SYNCs or comparing summary counts against runs on another device.

in fact, in many cases the new info-popup summaries can make it unnecessary to open logfiles at all. When SHOW and DIFF are run to check that two folder copies are the same, for example, the simple "No differences" summary line in the popup saves a logfile view and multiple taps. To see the popup in action, view screenshots here and here.

That being said, it's still often useful or required to view logfiles after action runs. Most actions' logfiles include important details not given in the popup's summary. Moreover, the new summary may alert you to errors listed in the logfile that warrant further exploration—look for a line like this and search the logfile for "*" for more details; or let you know that the summary cannot be extracted—look for a line like this which may or may not be due to run failure, but you should see the log either way.

This change is cross platform, convenience only, and backward compatible. Its only app-behavior impacts are to list more details on action exit, and use popup dialogs instead of toasts on Android for action-exit messages; they're now too big for a simple toast, and too useful to vanish in seconds.

New: Allow Android Screen Timeouts to Be Toggled by Users

In the prior release, this app used a tool in its software stack which caused the screen to always remain on while the app was being used on Android. This prevented screen timeouts, and could drain battery power if users didn't press the power button or navigate away from the app.

In 1.1.0, this is now switchable by the user: the Config tab has a new toggle, Keep the screen on while using this app?, which controls this behavior. If toggled on, the screen stays on in the app as before; if off, screen timeouts are allowed to turn the screen off in the app per user display settings on the device. See the new Config tab screenshots here, here, and here.

This new toggle defaults to on (timeouts disabled) both for backward compatibility, and because this app presents textual information in logfiles and popups that may take time to view; toggle it off and save your settings to enable screen timeouts permanently. Though less impactful, this new toggle also applies to screen savers on PCs: on means screen savers will not run while the app has focus, and off means they will.

As part of this change, this app now also better ensures that Main-tab actions will keep running on Android if the screen turns off due to either timeouts or power-button presses. It does so by using an Android partial wake lock during Main-tab actions to keep the CPU running, whether the screen is set to stay on or not. This new wake lock is held only while an action is in progress. The former screen-on scheme may reduce throttling too, but drains battery power needlessly, and won't apply if users switch to another app or press the power button.

Technical readers can find more details on Android wake locks here, here, and here. See also the discussion of app stops in Tech Notes.

New: Enable Grab+Move Scrolling for Path Fields on PCs

The GUI's folder-path fields—in both the Main-tab's FROM and TO choices, and the folder chooser's path display—can now be scrolled horizontally on PCs by a grab-and-move gesture. To scroll, click in a path field's text and quickly move the cursor while holding down your mouse or touchpad button. To select text in these fields instead, click and hold longer before moving. These fields also support manual edits and copy/paste on all platforms.

This change applies only to PCs (Windows, macOS, and Linux). Android devices have always scrolled these fields with touch swipe gestures as usual, and similarly select with a longer press and move. While scrolling is useful on PCs too, their wider screens naturally makes it less vital.

Fix: Avoid More Blacked-Out Lines in Logs-Tab Text

The underlying GUI library cannot display text lines that are atypically long, and instead shows them as empty black boxes. This was first addressed in 1.0.0 by truncating lines at 512 characters, but this proved to be still too long in some rare cases. Just one blacked-out line has cropped up among thousands seen, but it can be glaring when it happens.

To fix, 1.1.0 drops the truncation limit to 400 characters instead of 512 for Logs-tab text. This is both tradeoff and guess: it sacrifices more TAIL and WATCH content, and the actual line-length limit is context-dependent. But blacked-out lines will be less likely.

Fix: Work around Rare GUI Crashes on Logs Filename Taps

The underlying GUI toolkit has a race condition (i.e., timing issue) in its code, which can cause an app crash due to an uncaught exception. This could be triggered by tapping a Logs-tab filename button after a new Main-tab action was started, but was exceedingly rare, and observed just once after both hundreds (or thousands) of taps, and months of actual usage.

To fix, 1.1.0 avoids the crash potential in full by mutating filename buttons before they are deleted, in a way that ensures that the GUI's perilous code will not be run. The mutation is not user visible, and is harmless to the GUI's behavior. For full technical details on the fix, tap the button below (JavaScript required).

The Kivy GUI toolkit's toggle-button code does not fully allow for the asynchronous nature of object garbage-collection (GC) callbacks. These callbacks can be run at any time—including at arbitrary points in the GUI's other event-handling code.

In this app, logfile toggle buttons are deleted on tab switches to update the Logs tab's list for new folder contents. Deleting these buttons can naturally trigger GC, which runs the GUI's GC callback. As coded, the GUI's GC callback and button-tap handler both remove the same cached items, and assume the two operations will not overlap unexpectedly.

In the crash observed, however, the GUI's tap handler attempted to remove an item from a cache which had already been removed by the GUI's GC callback. The net effect triggered an uncaught exception deep in the GUI's code. Although the timing required to cause this is rare in the extreme, this could happen anytime users started a new action, switched to Logs, and tapped a logfile button, thereby interleaving GC with taps.

Until this is fixed in the GUI toolkit, setting toggle buttons' group ID to a Python None prior to deletion suffices to avoid the rare but fatal app crashes. This workaround is a coincidental artifact of the GUI's code, and not by design; to encourage a more robust fix, the underlying race-condition bug will be also be reported to the Kivy project.

Fix: Avoid Lag for Info-Popup Text on Older and Slower Phones

The underlying GUI toolkit fills text displays so slowly on Android that the initial draw is glitchy and noticeable: text appears as a single one-character column, before being drawn in full. The app formerly worked around this lag in its Help and About tabs by delaying the setting of text content until the next GUI frame, but some info popups have enough text to cause a lag too, including the first-run screen.

To fix, 1.1.0 now extends the Help/About workaround to text in all info popups, including those shown on first run. This avoids lag on slower phones. The lag was most apparent on one older and slower test device (a 2018 Note 9), but may have been noticeable on lower-end phones in general. The workaround has no impact on faster phones.

Fix: Stop Prior Scroll before Auto-Scrolls in Logs-Tab Text

The underling GUI toolkit runs an animation at the end of manual text scrolls, which keeps scrolling slowly for a few seconds. Unfortunately, the animation is not automatically cancelled when the app tries to automatically scroll the same widget to the bottom or left of text newly added by TAIL or WATCH.

The net result is noticeably glitchy: if a manual scroll's animation is still in progress, the app's auto-scrolls do nothing, and can leave the new text's display in an odd location. Worse, the new text may also begin its tenure by scrolling incorrectly as a continuation of the prior scroll's animation.

To fix, 1.1.0 uses a (wildly obscure) coding workaround to cancel a manual scroll in progress, so that auto-scrolls always position the view as intended. The glitch was arguably rare: it required a TAIL during the trailing animation of a manual text scroll, or a vertical scroll in the limited text of WATCH. Still, the fix avoids a visual glitch without harm.

Fix: Prevent GUI Hangs for Inaccessible Drives of All Types

On all platforms, this app now avoids GUI lags and hangs for drives that are mounted but inaccessible. This includes both network drives that have been disconnected on PCs, as well as USB drives on Android and elsewhere that have not finished mounting in full. Formerly, such drives could cause the app to pause in multiple contexts for a noticeable number of seconds—up to 15 for network drives on Windows, and roughly half as much in other cases.

To fix, 1.1.0 uses parallel threads with timeouts to run system calls that are prone to hang when drives are not accessible. This fully removes the app hangs (apart from a brief half-second wait), and has no other impact on the app's behavior. If a drive access times out, simply rerun your action to access the drive once it's available.

For more info on using network drives with this app, click the button below (JavaScript required).

Network-drive support
On all PCs, network drives are fully supported by this app as FROM or TO subjects of all Main-tab actions. Keep in mind, though, that this works only if the network server is mounted on macOS or Linux per platform conventions, or mapped to a drive letter on Windows. The procedures for mounting and mapping network drives are beyond this doc's scope; please see the web for help. Unrooted Android has no notion of mounted network drives, so this is a PC-only tool. See the App Packages doc's tips for more on mounts.
Network-drive paths
As part of this fix, network drives on Windows now also automatically use UNC paths instead of mapped drive letters. For example, a network drive used in testing is presented by the app as name T_Drive, and as path \\readyshare\T_drive instead of the mapped Z:\. Formerly, the drive letter was shown at first, but confusingly morphed into UNC on any chooser tap (this reflects a recent change in the Python language's realpath call used by the Kivy GUI).

By comparison, on macOS this server is smb://readyshare, named T_Drive in the app, and with Finder automatically mounts at path /Volumes/T_Drive. On Linux, this server's manually mounted path should be in either /media/user or /mnt for use in this app.

Network-drive disclaimer
A gentle reminder: while this app can happily process any folder on your devices that has a filesystem pathname—including BDRs and network shares—it's focused on USB-drive backups and syncs per its name. Mounted and mapped network drives will almost always be much slower, much less secure, and much more prone to timestamp skew and other glitches. Use remote storage with care.

Mod: Distinguish Trial App by Name in Android Notifications

In 1.1.0, the Android trial app's name displays with a ": Trial" suffix in notifications to distinguish it from the full app. This mod is minor and trivial, because the two apps are unlikely to be used at the same time (and in fact shouldn't be used to run update actions in parallel unless content folders are disjoint). Also note that some other contexts treat the two apps' names the same on purpose; the logfiles folder, for example, ignores the trial version's suffix so that all logs show up in the same place.

Mod: Scale Button Sizes for More Consistent Look and Feel

On all platforms, this app now scales the sizes of some of its GUI components to the density of the host display. This makes some buttons larger at higher resolutions and smaller at lower resolutions, which in turn makes the GUI look similar across all devices. In terms of function, buttons are now easier to tap on higher-resolution phones, and lower-resolution screens avoid GUI blowup and allow more on-screen content. All screenshots reflect the new sizes.

This mod's effect will naturally vary per screen, and may be more noticeable on some than on others. It superseded an earlier 1.1.0 change that reduced the absolute pixel sizes of logfile buttons on PCs, but this was really just catering to specific low-resolution devices, and didn't address other buttons in the GUI (e.g., responses in popups, and storage types in choosers). Using density-scaled pixels is a much more universal solution. See also the related 1.1.0 update.

Mod: Look for Storage in Both /media and /mnt on Linux

On Linux, this app now searches for mounted storage in both the /media/user and /mnt folders (where user is your user name). The former, used in 1.0.0, is where automatically mounted storage appears, including USB drives. The latter, new in 1.1.0, is often used for manual user mounts. This distinction is somewhat subjective, but be sure to mount network drives and other types of storage to one of these two folders to use them in this app.

Mod: Prevent COPY of a Folder into Its Own Subfolder

This app now disallows attempts to use its COPY action to copy a folder into any of the folder's own subfolders. If allowed, such copies would be recursive, and may loop until stopped only by the host platform's path-length limits.

The app formerly disallowed copying a folder into itself directly, but this not enough: copies are always recursive if TO is nested anywhere in FROM (technically, if the absolute path of TO begins with the absolute path of FROM). While this subfolder case seems unlikely to crop up except accidentally, the app now detects it and cancels the COPY with an info popup, to avoid loops (and storage-space explosions).

Mod: Don’t Let UNDO Be Enabled If an Action Is Running

This app disables its UNDO button when SYNC rollbacks cannot be used, and reeanables it when they can. In short, UNDO is precluded when TO is known to have no SYNC backups, and is allowed otherwise. Any change to the TO path reinstates UNDO until TO's backups status is known.

Formerly, it was possible to reenable UNDO while another action was running, by changing TO with manual edits or chooser selections. Though obscure, this made it theoretically possible to launch an UNDO in parallel with a running action, with potentially dire consequences. In 1.1.0, this unintended loophole has been closed: UNDO is never reenabled on TO changes until an action in progress finishes.

Mod: Support Symlink Modtimes Better in the macOS App

This release repairs an obscure coding snafu which caused the modification times of symlinks (only) to be ignored by the macOS app (only), and was triggered by using Python 3.10 for universal 2 binaries. Symlinks' values were still compared and propagated correctly, so this was a very minor regression, and too arcane to detail here. Symlinks themselves are atypical, and not recommended in cross-platform content copies per the Tech Note.

Mod: Avoid Redundant Text Sizings for Speed (Internal)

Though it has no user-visible impact on the app, the Logs tab has been optimized to reset its text's size only on changes to display width, not height. This reset is required to enable horizontal scrolls after PC resizes and phone rotations due to a GUI quirk. However, it is not required for height changes on PCs, and width changes suffice to catch rotations on phones (a perfectly square phone would violate this rule, but none is known to exist, and its rotations wouldn't be very useful in any event).

Etc: More Info on a Known Android Rotations Glitch

Per this usage note, this app's top-of-display tabs bar sometimes fails to redraw on Android devices after rotating to landscape (wide) orientation when the Android 12L+ taskbar is open. This is relatively rare, and can occur only on large-screen devices because it's triggered by the Android large-screen taskbar, but is obvious when it crops up. A simple rerotate restores the app's tabs bar.

This glitch, seen only on a Samsung Fold4 to date, stems from an event-processing bug in the software stack below this app's GUI. The 1.1.0 project did not work around it, but did uncover reasons that prevent it from doing so, and will be reporting the underlying bug to spur a fix. For more in-depth coverage of the glitch, click the button below (JavaScript required):

This rotations glitch reflects a bug in the underlying GUI stack that's defied this app's best workaround efforts (the app runs some twenty GUI workarounds to date, but this one proved unfixable). Per forensics, a crucial window-resize event that gives the correct size of the display above the Android taskbar is never fired; it's either being dropped by the Kivy GUI toolkit or the SDL2 graphics layer below it, or not being sent properly by Android or Samsung code.

Specifically, when rotates to landscape work, the app receives either just one event with correct viewport size (excluding the taskbar), or two events: one with incorrect size (including the taskbar), and then another with correct size (excluding the taskbar). In the two-event case, there's a momentary visual effect for the redraw from incorrect to correct sizes, but the GUI's tabs bar appears.

When landscape rotates fail, however, there is just one event with incorrect size (the size of the full display, including the taskbar), and the tabs bar is drawn offscreen. Because the event with the correct size is never received, it's futile for the app to forcibly redraw the wrongly sized display, and impossible for the app to reset a correct size when none exists.

Importantly, this glitch is not unique to either this app or its tabs bar. In another Kivy app running on the same large-screen phone, a portion of a simple button at the top of the display is also occasionally clipped vertically when rotating to landscape with the Android taskbar open. Hence, the lack of correct-size events renders part of the Kivy display offscreen on landscape rotations; a top-of-display tabs bar like that in this app just happens to be lost in full.

If this analysis is correct, addressing this glitch requires a core-code fix in SDL2 or Kivy, and this bug will be reported in hope of a repair. Until then, a regrettable but rare user rerotate will have to suffice as workaround.

Version 1.0.0, May 5, 2023: Fully Functional Initial Release

This first release is functionally complete, and has been verified to work on Androids 8 through 13, Windows 10 and 11, macOS Catalina+, and Linux Ubuntu.

Beyond its core utility, 1.0.0 includes workarounds for eighteen glitches in the underlying GUI toolkit (to be published elsewhere), and addresses multiple interoperability hurdles on supported platforms. While additional enhancements and repairs are normal and expected to appear over this app's lifetime, its 1.0.0 release is already robust and fully usable as is.

For more on the app on 1.0.0 and later, see its user guide.

For More Info

Watch this page for news about future releases. For info on using the app in general, see the User Guide.