Skip to content

Fix/linux clipboard and BLE reconnect - #14

Merged
zoir-dev merged 2 commits into
zoir-dev:mainfrom
X-Ryl669:fix/linux-clipboard-and-ble-reconnect
Aug 28, 2026
Merged

Fix/linux clipboard and BLE reconnect#14
zoir-dev merged 2 commits into
zoir-dev:mainfrom
X-Ryl669:fix/linux-clipboard-and-ble-reconnect

Conversation

@X-Ryl669

Copy link
Copy Markdown
Contributor

This one is a combination of fixes for both issues I've found in the software usage.
The first issue is the very slow BLE reconnect (when leaving and coming back) that can take more than 5mn to happen. This is due to the phone having rotated its RPA and thus lost its sync with the laptop. The commit reduces the reconnect time to something more manageable (around 1mn).

The second fix is an issue with clipboard not sent to the phone when using Wayland and BLE is reconnecting (lost clipboard content in that case).

X-Ryl669 and others added 2 commits August 23, 2026 21:48
On a Wayland session arboard was reading a different clipboard than the one
being copied into, so laptop→phone sync fired on maybe one copy in ten.

`wayland-data-control` is not one of arboard's default features and we asked
for no features, which makes it X11-only on Linux: it talks to XWayland and
depends on the compositor bridging the two selections. Measured on Plasma 6 —
a probe holding one handle returned a four-minute-old value forever while
`wl-paste` reported the truth, and a fresh handle per read behaved identically,
so it was never staleness. With the feature it tracked every change. X11 stays
the fallback when there is no Wayland display.

That moves the password-manager guard, too. It probes the X11 CLIPBOARD for
`x-kde-passwordManagerHint`, and once arboard reads the Wayland selection an
X11-only probe answers about text that was never captured — reporting "not
secret" for a KeePassXC copy it cannot see, which would sync a password to the
phone. It fails open by design, so that would have been silent. It now asks
Wayland first via the offer's MIME list, falling back to the X11 round trip.
Verified live: ordinary text → false, a copy offering the hint type → true.

Second bug, independent of the first: BLE is the only laptop→phone clipboard
transport (LAN carries the other direction and images), its writer exists only
while the GATT link is up, and the sender dropped the copy when it was absent.
Anything copied during a reconnect backoff, an RPA rotation or a screen-off
vanished with no trace. It now holds the newest undelivered copy and retries
until the link returns, with a 5-minute TTL so a copy made before lunch cannot
silently overwrite the phone's clipboard on the next reconnect. One slot, not a
queue: a clipboard is last-write-wins, so three copies during an outage should
land as the third, not as a burst with the oldest last. A failed write stays
pending instead of being dropped on the first error. Same fix on the image path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three separate reasons a cold start took minutes to get a BLE link up, all
measured from one run's log.

The BLE loop has no learned RPA at startup, so it cannot take its
direct-connect fast path and sits in presence discovery instead — monitor
registration, or 15 s scans backing off 5→10→20→45 s. LAN meanwhile is up in
about two seconds and knows the phone is right there, and there is already a
cross-transport nudge for exactly this. It was gated on `consec_lan_fail > 0`,
which cannot see the cold-start edge: the counter starts at 0 and a first
success leaves it at 0, so "the last attempt succeeded" and "there has not been
one yet" were the same value. The nudge never fired on the run that needed it
most. Tracked with a separate flag; the original edge-trigger intent is kept, so
a steady-state tick still will not poke BLE when the phone has Bluetooth off.

The connect that follows presence had no timeout, while the last-RPA fast path
above it is capped at 3 s with a comment explaining why — a dead RPA is the only
case that burns. Uncapped it burned 13-18 s, six times, two minutes of it. The
phone rotates its presence RPA every 60 s, so one doomed attempt plus the next
15 s scan is ~33 s: the same order as the rotation, meaning most attempts dial
an address the phone has already abandoned and each failure costs another
rotation. Capped at 8 s — above a healthy connect plus service discovery, well
below what a dead address was costing — routed through the existing
`clear_pending_connect` cleanup, since BlueZ keeps a dropped connect in flight.
For scale: once the address was fresh, IK completed in 570 ms.

Third, unrelated to timing: a peer-initiated forget only propagated over LAN.
The phone sets `revoked` in the snapshot it pushes over BOTH transports, and the
BLE consumer dispatches calls, handoff, remote lock, media and proximity from
that same snapshot while skipping this one flag. The phone commits its local
forget after a 1.5 s grace regardless, so any revoke that did not land over LAN
in that window was simply lost and the laptop kept trusting a peer that had
dropped it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@zoir-dev
zoir-dev merged commit 697536c into zoir-dev:main Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants