Skip to content

Improve cross-realm portability of editor animation frames - #55

Draft
hiroshisuga wants to merge 14 commits into
bigbluebutton:mainfrom
hiroshisuga:patch-6
Draft

Improve cross-realm portability of editor animation frames#55
hiroshisuga wants to merge 14 commits into
bigbluebutton:mainfrom
hiroshisuga:patch-6

Conversation

@hiroshisuga

@hiroshisuga hiroshisuga commented Aug 12, 2026

Copy link
Copy Markdown

What does this PR do?

This PR makes editor-related animation frames use the window that owns the editor container instead of implicitly using the global window. Thus this would make a good workaround to the problem posted here: bigbluebutton/bigbluebutton#25597 on the second part.

It adds editor.getContainerDocument() and editor.getContainerWindow(), and uses the container window for requestAnimationFrame() / cancelAnimationFrame() calls in the editor and tldraw packages.

This improves the portability of this tldraw fork when the editor is rendered in a different browser window, and brings the fork closer to the direction taken by upstream tldraw.

It also prepares the fork for future BigBlueButton use cases where the whiteboard or presentation may be rendered in another window without replacing global browser APIs, for instance, bigbluebutton/bigbluebutton#25461

Relation to upstream

Upstream tldraw has moved in the same general direction by avoiding assumptions about the global browser realm and by introducing broader timer abstractions.

This PR intentionally takes a smaller approach for this older fork; rather than backporting the complete upstream timer infrastructure, editor-level animation frames directly use: editor.getContainerWindow()

This is sufficient for the current cross-window requirements and keeps the change limited to the editor and tldraw packages.

Generic timer helpers in lower-level packages are left unchanged because they do not have access to an editor container. Extending the change to those packages would require a quite larger backport.

The goal here is to make the minimum practical change needed to improve cross-window portability while keeping the fork stable and easy to maintain.

Compatibility

Normal single-window tldraw behavior is unchanged.

In the usual case, the editor container belongs to the application's current window, so editor.getContainerWindow() resolves to the same window that was previously used implicitly.

The behavior only differs when the editor is actually hosted in another browser window.

TickManager - a relatively large change

TickManager also remembers the window used when requesting a frame so that the frame is cancelled through the same window, even if the editor container moves between windows.

Change Type

  • patch — Bug fix
  • minor — New feature
  • major — Breaking change
  • dependencies — Changes to package dependencies1
  • documentation — Changes to the documentation only2
  • tests — Changes to any test code only2
  • internal — Any other changes that don't affect the published package2
  • I don't know

Test Plan

  1. Build and run tldraw normally and verify standard editor behavior.
  2. Verify drawing, selection, zooming, panning, and UI interactions.
  3. Render the editor in another browser window and verify the same operations ([3.0 feat] Detachable presentation, showing next slide and presenter's note bigbluebutton#25461 does it).
  4. Confirm that no global requestAnimationFrame / cancelAnimationFrame replacement is required.
  • Unit Tests
  • End to end tests

Release Notes

Footnotes

  1. publishes a patch release, for devDependencies use internal

  2. will not publish a new version 2 3

@hiroshisuga hiroshisuga changed the title Improve cross-window portability of editor animation frames Improve cross-realm portability of editor animation frames Aug 12, 2026
@hiroshisuga
hiroshisuga marked this pull request as ready for review August 12, 2026 14:15
@hiroshisuga
hiroshisuga marked this pull request as draft August 12, 2026 14:16
ButtonPicker did not work correctly when the tldraw editor was rendered in another window, such as a detached popup. In that case, the pointerdown and pointerup events occurred in the popup window, while the listener was attached to the main window.

As a result, handlePointerUp was never called, rPointing.current remained true, and moving the pointer over other buttons in the style panel could unintentionally select them without clicking.

This was visible in style controls using ButtonPicker, including color, fill, dash, and size selectors.
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