Skip to content

fix(ui): the overlay layers follow the interface root's size - #209

Merged
eriknihlen merged 1 commit into
eriknihlen:mainfrom
davidc-smith:fix/overlay-viewport-upstream
Oct 8, 2026
Merged

eriknihlen merged 1 commit into
eriknihlen:mainfrom
davidc-smith:fix/overlay-viewport-upstream

Conversation

@davidc-smith

Copy link
Copy Markdown
Contributor

Problem

After entering the world, plugin canvases are clipped to the top-left 800x600 of the screen.

RetailUiRuntime.RestoreLayout() runs when the character enters the world. That is when the window switches from the pre-game 800x600 to the game resolution. It sizes the interface root and records the new size in _lastScreenSize, but never tells the overlay host. The next Draw sees no change, so its guarded SetViewport(screenSize) never runs, and every overlay layer keeps its 800x600 rectangle. Layers clip their children, so a canvas outside that rectangle is cut off.

It looks intermittent because the world label and projectile overlays call SetViewport(camera.Viewport) whenever they have something to draw. While labels are on screen, they push the right size in and hide the bug.

Fix

  • UiOverlayHost.SetViewport is replaced by FollowRoot(), which takes its size from the interface root. RetailUiRuntime.Draw calls it every frame, so a resize made anywhere reaches the layers.
  • The world overlays no longer write the host's shared rectangle. They still size their own elements from the camera.

Tests

  • UiOverlayHostTests: layers follow a root resized behind the host's back, and a world overlay ticking with a different camera viewport leaves the layers at screen size.
  • The existing canvas anchor test now resizes through the root.
  • I checked it live on macOS with a plugin canvas. Before the fix, the overlay layers stayed at 800x600 after the login resize. After it, they followed the new window size.

https://claude.ai/code/session_01SY57mHJLZ6djpWZ5nP37Tw

Entering the world restores the window layout, which sizes the interface
root and records the screen size without telling the overlay host. The
next draw then saw no change and never resized the overlay layers, so
they stayed at the pre-game 800x600 and a plugin canvas was clipped
outside that rectangle. It only came right when a world overlay with
something to draw pushed its camera viewport into the shared rectangle,
or the window was resized again.

The host now follows its interface root: the runtime calls FollowRoot
every frame, and the world overlays no longer write the shared
rectangle. They still size their own elements from the camera.

Claude-Session: https://claude.ai/code/session_01SY57mHJLZ6djpWZ5nP37Tw
@eriknihlen
eriknihlen merged commit e8c7670 into eriknihlen:main Oct 8, 2026
3 of 7 checks passed
@davidc-smith
davidc-smith deleted the fix/overlay-viewport-upstream branch October 10, 2026 21:38
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