Skip to content

feat(tracking): follow the caret in Java apps via the Java Access Bridge (#281) - #282

Merged
Maxaubert merged 2 commits into
mainfrom
feat/281-java-caret
Sep 29, 2026
Merged

Maxaubert merged 2 commits into
mainfrom
feat/281-java-caret

Conversation

@Maxaubert

Copy link
Copy Markdown
Owner

Closes #281.

Caret tracking now works in Java apps (IntelliJ, PyCharm, other Swing/AWT apps), which neither Wind nor Windows Magnifier followed before.

  • Source: the Java Access Bridge. The Authenticode-signed client DLL is loaded from the Java app's own folder the first time a Java window is foreground (src/java_bridge.*).
  • UIPI: Wind is UIAccess, and Windows dropped the JVM's handshake messages. The bridge's hidden windows now allow exactly the 7 protocol messages (OpenJDK AccessBridgeMessages.h).
  • No hitches: all bridge calls run on the tracker thread, never the tick. Reads happen only after bridge caret/focus callbacks or a Java window switch, never on the 60 Hz poll, so the Java app's UI thread gets no steady load. Hung Java windows are skipped.
  • No manual steps: Wind enables the bridge in %USERPROFILE%\.accessibility.properties (what jabswitch -enable does); a Java app picks it up at its next start. The file is never rewritten from a failed read.
  • Version 0.11.0.

Review

A 3-lens review (correctness, performance, security; sonnet reviewer plus adversarial sonnet verifier per lens) confirmed 7 findings, 2 rejected. All fixed in the second commit: per-folder retry, safe properties rewrite, signed-DLL loading with a pinned dependency search, narrowed UIPI allowance, hung-window skip, event-only reads.

Verification

  • build.bat test: all doctests pass (new test_java_bridge_util.cpp)
  • Native probe against IntelliJ 2026.2: correct moving caret rect, 1-12 ms per read
  • Deployed the signed UIAccess build; owner field-tested in IntelliJ (tracks while typing)
  • Installer unchanged; CI builds and tests the PR

🤖 Generated with Claude Code

https://claude.ai/code/session_01KPUNAWcwghXdHCApcKKjSG

Maxaubert and others added 2 commits September 29, 2026 12:42
…dge (#281)

Java apps (IntelliJ, PyCharm) report the caret only through the Java Access
Bridge. The client DLL is loaded from the Java app's own folder the first time
a Java window is foreground; the bridge is enabled in .accessibility.properties
for future launches so users need no manual step. Reads run on the tracker
thread only, triggered by events (bridge callbacks, WinEvents), never the 60 Hz
poll. Wind is a UIAccess process, so UIPI dropped the Java side's handshake
messages: the bridge's own hidden windows now allow exactly that traffic.
Version 0.11.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPUNAWcwghXdHCApcKKjSG
- per-folder failure cache instead of a session-wide latch
- .accessibility.properties is only rewritten after a clean read or when
  it does not exist; a locked file is left alone and retried in 30 s
- the bridge DLL (and a vcruntime shipped beside it) must be Authenticode
  signed, held open while verified and loaded, deps from its folder and
  System32 only: Wind is UIAccess and window classes are spoofable
- UIPI allowance narrowed to the 7 bridge protocol messages
- skip bridge calls while the Java window is not responding
- reads only after a Java event or window switch, never unrelated wakes
Docs: findings, cursor chapter, README, spec scope note, CLAUDE.md gotcha.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPUNAWcwghXdHCApcKKjSG
@Maxaubert
Maxaubert merged commit eabeae6 into main Sep 29, 2026
1 check passed
@Maxaubert
Maxaubert deleted the feat/281-java-caret branch September 29, 2026 12:34
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.

Tracking: follow the caret in Java apps (IntelliJ, PyCharm) via the Java Access Bridge

1 participant