Skip to content

fix: prevent browser paste freeze from xclip hammering clipboard on Linux#18

Merged
offbyonebit merged 1 commit into
mainfrom
claude/paste-freeze-bug-p3jxkr
Jun 17, 2026
Merged

fix: prevent browser paste freeze from xclip hammering clipboard on Linux#18
offbyonebit merged 1 commit into
mainfrom
claude/paste-freeze-bug-p3jxkr

Conversation

@offbyonebit

Copy link
Copy Markdown
Owner

Summary

  • Root cause: _out_tick called _read_clipboard_image() on every 0.5 s poll tick. On Linux this spawns xclip -t image/png -o, which sends an X11 SelectionRequest to the clipboard owner (typically a browser). Browsers service these on their main thread — hitting them at 2 req/s caused the browser to freeze when the user pressed Ctrl+V.
  • Fix 1 — TARGETS pre-check: _read_image_from_system_clipboard() now runs xclip -t TARGETS -o (or wl-paste --list-types) first. The clipboard owner responds to TARGETS immediately with a list of format atoms; if image/png is absent we return None without ever sending the expensive image/png SelectionRequest. This eliminates the problematic request for the common case (text on clipboard).
  • Fix 2 — rate-limit image checks: _out_tick throttles image checks to _LINUX_IMAGE_CHECK_INTERVAL (2 s) on Linux. Even the cheap TARGETS request spawns a subprocess and touches the X server, so throttling 4× reduces X11 traffic to a level that doesn't interfere with paste.

Windows and macOS are unaffected (ImageGrab.grabclipboard() is in-process, no SelectionRequests). Image sync latency on Linux increases to ~2 s worst case, which is acceptable. Text sync latency is unchanged.

Test plan

  • Run python -m pytest tests/ --ignore=tests/integration — all 59 tests pass
  • 16 new regression tests in tests/test_linux_paste_freeze.py cover:
    • _linux_clipboard_has_image() unit tests (no tools, text-only TARGETS, image TARGETS, fallback to wl-paste, timeout handling)
    • TARGETS gate prevents image/png fetch when clipboard has text
    • _out_tick rate-limiter skips image check when interval hasn't elapsed
    • _out_tick runs image check after interval elapses
    • Text sync is not blocked by the image throttle
    • _LINUX_IMAGE_CHECK_INTERVAL guard (≥ 2 s)
    • End-to-end image and text sync still work with throttle active
    • Image polling frequency is bounded to the configured interval

https://claude.ai/code/session_01YGXA5W7KpwGtsufDugcxDS


Generated by Claude Code

…y 0.5 s

On Linux, _out_tick called _read_clipboard_image() on every 0.5 s poll
tick. That spawned xclip which sent an X11 SelectionRequest to the
clipboard owner (typically a browser). Browsers service these on their
main thread, so 2 requests/second caused the browser to freeze the moment
the user pressed Ctrl+V.

Two-layer fix:

1. TARGETS pre-check (_linux_clipboard_has_image): before requesting image
   bytes, run xclip/wl-paste with TARGETS/--list-types. The clipboard owner
   responds immediately with a list of formats; if image/png is absent we
   return None without ever sending an image/png SelectionRequest. This
   eliminates the expensive request for the common case (text on clipboard).

2. Rate-limit image checks in _out_tick to _LINUX_IMAGE_CHECK_INTERVAL
   (2 s) on Linux. Even the cheap TARGETS request spawns a subprocess and
   touches the X server, so throttling to 2 s reduces X11 traffic 4x vs
   the previous 0.5 s rate.

Windows and macOS are unaffected (ImageGrab.grabclipboard() is in-process).
Image sync latency on Linux increases to ~2 s in the worst case, which is
acceptable. Text sync latency is unchanged.

16 regression tests added in tests/test_linux_paste_freeze.py covering the
TARGETS gate, rate-limiter logic, and end-to-end image/text sync correctness.
@offbyonebit offbyonebit merged commit e40a32d into main Jun 17, 2026
1 check failed
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