Skip to content

backends: per-node frame reporting for drive coordinate taps - #60

Merged
tiensonqin merged 1 commit into
mainfrom
devin/1790448876-frame-reporting
Sep 26, 2026
Merged

tiensonqin merged 1 commit into
mainfrom
devin/1790448876-frame-reporting

Conversation

@tiensonqin

Copy link
Copy Markdown
Collaborator

Summary

Adds an opt-in frame-reporting hook to both retained backends so a drive --socket attach can hit-test coordinates (tap x y) against real layout geometry.

LUIAppleBackend (macOS/iOS):

  • frameReportingEnabled gates emission; onFramesReport: (([Int: CGRect]) -> Void)? delivers the full node-id → frame map once per coalesced layout flush (one DispatchQueue.main.async hop regardless of how many nodes moved).
  • emitFramesSnapshot() re-pushes the current table — needed because a driver can attach after the runtime is already up.
  • LUIFrameReportModifier hangs on LUIAnyNodeView, the single per-node choke point: onGeometryChange in .global space + onDisappear removal. Collection is unconditional (a dict write per geometry change) so enabling mid-session sees the latest geometry without waiting for a relayout.

LUIFlutterBackend (Android):

  • Same contract: frameReportingEnabled + onFrames: void Function(Map<int, Rect>)?.
  • A _FrameProbe wraps widget() output and registers its BuildContext in _frameProbes; a self-rearming post-frame callback measures every probe via localToGlobal(Offset.zero) & size each frame while enabled — scrolling moves nodes without rebuilds, so a one-shot measure is not enough. Emits only when the map actually changed.

Host contract: forward each snapshot to the live socket as {"frames":[[id,x,y,w,h],...]} (see logseq/drive PR; tiensonqin/meng wires it for macOS). Web hosts can implement the same contract via DOM rects later.

Verified end-to-end: Meng.app + MENG_DRIVE_SOCKET streams 40+ node frames and tap resolves/presses real controls.

Link to Devin session: https://app.devin.ai/sessions/ae1476f4d79f40c0be25bb63fc36b0c5
Open in Devin Desktop: https://app.devin.ai/desktop/session/ae1476f4d79f40c0be25bb63fc36b0c5?variant=devin
Requested by: @tiensonqin

LUIAppleBackend collects every rendered node's frame (global coordinate
space, via onGeometryChange on the single LUIAnyNodeView choke point)
and emits the full map once per coalesced layout flush through
onFramesReport while frameReportingEnabled is on. emitFramesSnapshot()
pushes the current table for late-attaching drivers.

The Flutter backend does the same via a _FrameProbe element table and a
post-frame measure loop that re-measures every frame while enabled —
scrolling moves nodes without rebuilds.

Feeds drive's live-attach 'tap x y' hit-testing; hosts forward the map
to the live socket as {"frames":[[id,x,y,w,h],...]}.
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@tiensonqin
tiensonqin merged commit 3511463 into main Sep 26, 2026
4 checks passed
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.

1 participant