Class LoginKeys
Shared keyboard wiring for the login-flow panels: Enter submits, Escape backs out, and Tab walks the fields in the order they are authored.
public static class LoginKeys
- Inheritance
-
LoginKeys
- Inherited Members
Remarks
There was no keyboard handling anywhere in the login tree at all. A player typing a password had to reach for the mouse to sign in, Escape did nothing on any of the six screens, and Tab moved between whichever elements UI Toolkit happened to consider focusable — which includes the container elements, so it took several presses to get from the username field to the password field.
The handlers are registered in the trickle-down phase deliberately. A focused UnityEngine.UIElements.TextField consumes Return before it bubbles, and the field is exactly where the player is standing when they want to submit; a focused UnityEngine.UIElements.Button consumes Escape the same way. Reading the keys on the way down is the only placement that sees them from every field on the panel.
Every method is unregister-then-register and takes named methods rather than fresh
lambdas where it can, because OnStarting runs again on every visual tree rebuild
(see UITKControl) and a second registration on a surviving element would
submit the form twice per key press.
Methods
Attach(UITKControl, VisualElement, Action, Action, Func<bool>)
Wires Enter and Escape onto a panel root.
public static void Attach(UITKControl owner, VisualElement root, Action onSubmit, Action onCancel, Func<bool> canSubmit = null)
Parameters
ownerUITKControlThe panel these keys belong to, used to tell whether it is still the front-most thing on screen. Null disables that check.
rootVisualElementThe panel root to capture on. Null is tolerated.
onSubmitActionInvoked on Return/KeypadEnter. May be null.
onCancelActionInvoked on Escape. May be null.
canSubmitFunc<bool>Consulted before
onSubmitruns. Null means always.
Remarks
canSubmit exists because Enter here does not go through the button
it mirrors, and so never saw that the button was disabled. A player who pressed Enter
while a registration or a sign-in was already in flight re-entered the submit handler,
which fell down its validation path — the fields having been cleared on the first
press — and unlocked the form, clearing the flag that gates the panel's own auth-result
handler and disarming its watchdog. The server then created the account and every
message about it was dropped on the floor. Escape is deliberately not gated: backing
out of a request that is in flight is the one thing that must always work.
FocusFirst(VisualElement, VisualElement)
Moves keyboard focus to the first element of a panel that the player should type into.
public static void FocusFirst(VisualElement fallbackRoot, VisualElement first)
Parameters
fallbackRootVisualElementFocused when
firstis null.firstVisualElementThe preferred element.
SetTabOrder(VisualElement, params VisualElement[])
Gives a panel's interactive elements a deliberate Tab order.
public static void SetTabOrder(VisualElement root, params VisualElement[] order)
Parameters
rootVisualElementThe panel root. Null is tolerated.
orderVisualElement[]The elements, in the order Tab should visit them. Nulls are skipped.
Remarks
UI Toolkit's default order is a depth-first walk of every focusable element, and the generated inner parts of a UnityEngine.UIElements.TextField and the containers wrapping each row are focusable, so Tab landed on things that look like nothing. Assigning explicit ascending indices and taking everything else out of the ring makes the order the one the panel visibly has.