Class FocusTracker
FocusTracker.install(); // once per UI, from SwingBridgeEmulatorsBootstrap's UI-init leg
Component focused = FocusTracker.getFocusOwner(); // null when nothing of ours has it
Fed by one focusin listener on the UI's own element, which
covers every peer regardless of type — a per-peer FocusNotifier
subscription would miss everything sitting on a bare Div. The focused
peer is identified by FOCUS_HOST, whose caveat is worth reading
before touching this wiring.
Per UI, not per session: a browser tab has its own DOM and its own
activeElement, so focus cannot be shared across tabs — deliberately
the opposite call from D_session_scoped_pools's session-scoped Timer /
SwingWorker pools.
Never throws: an unpopulated pointer means "nothing focused", a legitimate
state rather than the wiring mistake BrowserTimeZone.get() fails loud
on.
UI-thread-confined.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceNotified when this UI's focus pointer moves, so a layer above can turn the move into events of its own —vaadinx.awt.KeyboardFocusManager's bound properties are the one consumer shape this was built for. -
Method Summary
Modifier and TypeMethodDescriptionstatic com.vaadin.flow.shared.RegistrationSubscribes to the current UI's focus transitions:static com.vaadin.flow.component.ComponentThe focused Vaadin component in the current UI, ornullwhen nothing our side owns has focus (including: no current UI, orinstall()was never called because the app skippedSwingBridgeEmulatorsBootstrap).static voidinstall()Installs this UI'sfocusin/focusoutlisteners.static voidnoteFocusGained(com.vaadin.flow.component.Component owner) A peer's own Vaadin focus event moved focus toowner.static voidnoteFocusLost(com.vaadin.flow.component.Component loser) A peer's own Vaadin blur event: focus leftloser.static voidsetFocusOwner(com.vaadin.flow.component.Component owner) Moves the pointer without waiting for the browser, so arequestFocusand agetFocusOwner()read in the same round trip agree.
-
Method Details
-
install
public static void install()Installs this UI'sfocusin/focusoutlisteners. Idempotent; a no-op without a current UI.Registered browser or browserless — the registration is inert under Karibu, which never dispatches DOM events, so gating it would only make production and test wiring diverge.
-
getFocusOwner
public static com.vaadin.flow.component.Component getFocusOwner()The focused Vaadin component in the current UI, ornullwhen nothing our side owns has focus (including: no current UI, orinstall()was never called because the app skippedSwingBridgeEmulatorsBootstrap). -
setFocusOwner
public static void setFocusOwner(com.vaadin.flow.component.Component owner) Moves the pointer without waiting for the browser, so arequestFocusand agetFocusOwner()read in the same round trip agree. No-op without a current UI.Best-effort: if the browser refuses the focus (hidden element, not focusable) the next real
focusincorrects us. -
addFocusOwnerListener
public static com.vaadin.flow.shared.Registration addFocusOwnerListener(FocusTracker.FocusOwnerListener listener) Subscribes to the current UI's focus transitions:Registration r = FocusTracker.addFocusOwnerListener( (oldOwner, newOwner) -> fireFocusProperties(oldOwner, newOwner));Per UI, like the pointer itself — a listener registered from one tab never hears another's. Registering without a current UI returns a no-op registration rather than throwing, matching
getFocusOwner()'s stance on the same situation.- Returns:
- the handle that unsubscribes; never
null
-
noteFocusGained
public static void noteFocusGained(com.vaadin.flow.component.Component owner) A peer's own Vaadin focus event moved focus toowner. Same effect assetFocusOwner(Component), named apart because the caller is reporting a browser fact rather than requesting a move.Additive to the
focusinbridge, not a replacement: it fires only for peers something subscribed to, where the pointer has to answer for every component. Free on a round trip the peer was already making — and the only path a browserless test can drive. -
noteFocusLost
public static void noteFocusLost(com.vaadin.flow.component.Component loser) A peer's own Vaadin blur event: focus leftloser. Clears the pointer only ifloserstill holds it — the browser firesfocusouton the old element beforefocusinon the new one, so an unconditional clear here would wipe a pointer the newer event has already moved on.
-