Skip to content

feat: experimental anvil keyboard text prompt for full-screen windows - #131

Open
oglassdev wants to merge 8 commits into
feat/fullscreen-examplefrom
feat/fullscreen-keyboard
Open

oglassdev wants to merge 8 commits into
feat/fullscreen-examplefrom
feat/fullscreen-keyboard

Conversation

@oglassdev

@oglassdev oglassdev commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Part of #115

The full-screen text prompt was a native dialog that covers the whole canvas, so the player can't see the window they're typing into. This lets them type straight onto the canvas: an untitled anvil captures the keys, the pack's shaders hide it, and the view draws the text itself. It is now the default promptText, marked experimental, and the dialog stays available as promptTextDialog.

API

@ExperimentalFullscreenApi
protected fun promptText(initial: String = "", onEdit: (String) -> Unit, onDone: (String?) -> Unit)
protected fun promptTextDialog(title: Component = Component.empty(), initial: String = "", onDone: (String?) -> Unit)
  • Keyboard: onEdit gets the whole text after each accepted rename and re-renders at once, without waiting for the next tick. Escape or any click in the anvil's window, including outside it (slot -999), finishes with the text. There is no cancel; apps that need one use promptTextDialog. onDone(null) happens only when the prompt is replaced, a server container takes over (next tick), or the window ends.
  • Shared slot: both kinds share one pending prompt (MinestomTextPrompt). Replacing a prompt of either kind resolves it with null after the replaced kind is off the client: the dialog is cleared, or the anvil is closed and the band, slots, and XP are restored. A keyboard replacing a keyboard reseeds the same anvil. Canvas input stays disabled and the hovered tooltip is hidden while either kind is open.
  • OpenFullscreen gets the matching promptText and promptTextDialog. show does nothing once the window has ended.

Clipping

While the anvil is open, the client's world age sits in a prompt band 204800 ticks above the HUD band. That gap is two full cloud cycles, so the clouds don't move when the anvil opens or closes. The band comes from the manifest's prompt_world_age. In that band, GUI passes hide only what the 26.2 anvil draws:

  • sprites (core/position_tex_color): anything inside the 176×166 anvil rect;
  • fills (core/gui, newly overridden): the exact 0xC0101010/0xD0101010 dimming gradient at the screen corners, 0x80FFFFFF quick-craft highlights at the anvil's slot positions, and the rename field's band (caret and selection);
  • text (core/text): the field band and the two label bands only.

So chat, titles, the action bar, and HUD panes over the anvil stay visible. All of the anvil's geometry and colours, checked against the 26.2 client, are in crates/window-core/src/hud/renderer/prompt.rs.

Notes

  • While the anvil is open, server updates to any of the 36 storage slots are re-blanked, not just the hotbar, since the anvil shows them.
  • Window-end restore now calls player.inventory.update(player), so the inventory goes to the player directly instead of through the inventory's viewers.
  • Limitations are in the README: the caret is drawn at the end; the text continues in 50-character pieces, so earlier pieces can't be edited and keys typed at a reopen can be lost; GUI text and fills in the field and label bands are hidden; the system pointer shows; each edit costs one round trip; without the pack's shaders the player sees a vanilla anvil.

Checks

  • just test-rust -p window-core fullscreen, just test-rust -p window-core hud
  • golden: all cases ok, with fullscreen updated (new gui.*, changed text and sprite shaders, debug.json fingerprints, and promptWorldAge in the generated entries)
  • just gradle :runtime:test --tests '*Fullscreen*' and :minestom:test --tests '*Fullscreen*', :example:compileKotlin
  • pnpm check:ts, just fmt-check, just lint
  • Not yet run in a real client.

Full-screen packs now override core/gui and pass prompt clip inputs
through core/text and core/position_tex_color. While the client's world
age sits in the prompt band (12000 ticks above the HUD band), they hide
only what Minecraft 26.2's anvil draws: sprites inside its rect, the
screen's dimming gradient, quick-craft slot highlights, fills in the
rename field's band, and text in the field and label bands. Chat,
titles, the action bar, and HUD panes overlapping the anvil stay.

The anvil geometry and colours live in hud/renderer/prompt.rs, and the
canvas contract gains prompt_world_age.
…n windows

FullscreenView.promptText(initial, onEdit, onDone) is now the keyboard:
an untitled anvil the pack hides, whose renames the view draws on its
canvas, re-rendering at once. Escape or any click finishes with the
text; there is no cancel. It is marked @ExperimentalFullscreenApi.

The native dialog stays as promptTextDialog(title, initial, onDone).
Both kinds share one pending prompt in MinestomTextPrompt: opening one
replaces the other, clearing the dialog or closing the anvil and
restoring the band, slots, and XP first. A container takeover or the
window ending resolves null, as before. The hovered tooltip is hidden
while any prompt is open.
…aracters, and take over open containers

Clicks on the rename field or inside the anvil send no packet, so only Escape reliably finishes the prompt; slot and outside clicks remain best-effort. Text past the anvil's 50 characters is no longer continued in a fresh field, as the client cannot edit the kept prefix. A keyboard anvil opening over a server container now replaces it in the fullscreen's container state, so the prompt band applies and finishing restores the hidden band and slots.
Clouds scroll with the world age, so the 12000-tick jump between the HUD and prompt bands moved them. The prompt band now sits a whole number of cloud periods above the HUD band.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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