Table of Contents

Class LoginKeys

Namespace
FishMMO.Client
Assembly
FishMMO.Client.dll

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

owner UITKControl

The panel these keys belong to, used to tell whether it is still the front-most thing on screen. Null disables that check.

root VisualElement

The panel root to capture on. Null is tolerated.

onSubmit Action

Invoked on Return/KeypadEnter. May be null.

onCancel Action

Invoked on Escape. May be null.

canSubmit Func<bool>

Consulted before onSubmit runs. 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

fallbackRoot VisualElement

Focused when first is null.

first VisualElement

The 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

root VisualElement

The panel root. Null is tolerated.

order VisualElement[]

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.